diff --git a/DEPS b/DEPS index 2634016..27f3f168 100644 --- a/DEPS +++ b/DEPS
@@ -262,7 +262,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '0ea0cd51026f96232359b78a32ce21eaf41bef1e', + 'catapult_revision': 'cdb0ce794bb76b49a46a5b80ef0ab4818a21c9c3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -270,7 +270,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '2a41471831919582f75a836c80716ebecc6f2acf', + 'devtools_frontend_revision': 'f6d8669ad9a0eebd62a2093c27de6cd2fd3bf114', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -306,7 +306,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spv_tools_revision': '4c33fb0d3dbaf8b2579c112cdbb7e9794143e337', + 'spv_tools_revision': '7221ccf85e26a29459729b3d296b71346c538a94', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -322,7 +322,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '82961129b0543b27edd3fc185be7bc47e41b2a10', + 'dawn_revision': '1b9b53a395769e15ca7b79a5b964f1b254fc3f84', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -350,7 +350,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling nearby # and whatever else without interference from each other. - 'nearby_revision': '31ab07b5d7183572a4250be2e0ff26a03f920e77', + 'nearby_revision': 'ae277748ce068ef1730d5104002d4324fc4ed89e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling securemessage # and whatever else without interference from each other. @@ -899,7 +899,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '5fcb48536cceaa77db9af14cd00e049e3a74b9b9', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'e9e8c01f3c5a92657c57adc134d074454f29933d', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -947,10 +947,10 @@ Var('chromium_git') + '/external/github.com/google/emoji-segmenter.git' + '@' + Var('emoji_segmenter_revision'), 'src/third_party/libgav1/src': - Var('chromium_git') + '/codecs/libgav1.git' + '@' + 'ba8dd2919fcaf65646858a6d7fd5e75ed4946cb1', + Var('chromium_git') + '/codecs/libgav1.git' + '@' + 'e46493b9148e0d1e63f55b5890bff503822616e5', 'src/third_party/glslang/src': - Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + 'b481744aea1ecf52ee4591afaa0f5e270b9d1636', + Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + 'f3cb1896971f449706bb1df5053d0e8fad6b0675', 'src/third_party/google_toolbox_for_mac/src': { 'url': Var('chromium_git') + '/external/github.com/google/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'), @@ -1252,7 +1252,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'c63cdce64c9e4dc5fb9fa4f820b39bac1de8553b', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '8d8e2e15743a5134fe9ebd8b8ed77353e244be55', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1552,7 +1552,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@d6108deaa5b33b2e1991ae864bef83f50e04224b', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@21731f72a5879d1c7974267e2ae098ee550d4420', 'condition': 'checkout_src_internal', }, @@ -1571,7 +1571,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'kja0EkIEJxvfaxk2OLA8JxNbZ4dGj9MBSTSAZFoPEkAC', + 'version': '2Ci5mbO7xjTsQepp4zPBnSBFD21jNiVQSncC7uK12TwC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/ash/shelf/home_button_unittest.cc b/ash/shelf/home_button_unittest.cc index d44803c0..18145dd 100644 --- a/ash/shelf/home_button_unittest.cc +++ b/ash/shelf/home_button_unittest.cc
@@ -559,7 +559,8 @@ AssistantUiController::Get()->GetModel()->visibility()); } -TEST_P(HomeButtonTest, LongPressGestureInTabletMode) { +// Started failing consistently https://crbug.com/1106253 +TEST_P(HomeButtonTest, DISABLED_LongPressGestureInTabletMode) { // Simulate two users with primary user as active. CreateUserSessions(2);
diff --git a/ash/style/ash_color_provider.cc b/ash/style/ash_color_provider.cc index a66b16d0..4bc105f 100644 --- a/ash/style/ash_color_provider.cc +++ b/ash/style/ash_color_provider.cc
@@ -315,10 +315,10 @@ dark_color = SkColorSetA(SK_ColorWHITE, 0x24); break; case ContentLayerType::kTextColorPrimary: - return cros_colors::ResolveColor(ColorName::kDefaultTextColor, + return cros_colors::ResolveColor(ColorName::kTextColorPrimary, color_mode); case ContentLayerType::kTextColorSecondary: - return cros_colors::ResolveColor(ColorName::kDefaultTextColorSecondary, + return cros_colors::ResolveColor(ColorName::kTextColorSecondary, color_mode); case ContentLayerType::kTextColorAlert: light_color = gfx::kGoogleRed600; @@ -333,7 +333,7 @@ dark_color = gfx::kGoogleGreen300; break; case ContentLayerType::kIconColorPrimary: - return cros_colors::ResolveColor(ColorName::kDefaultIconColorPrimary, + return cros_colors::ResolveColor(ColorName::kIconColorPrimary, color_mode); case ContentLayerType::kIconColorSecondary: light_color = dark_color = gfx::kGoogleGrey500; @@ -352,7 +352,7 @@ break; case ContentLayerType::kIconColorProminent: case ContentLayerType::kSliderThumbColorEnabled: - return cros_colors::ResolveColor(ColorName::kDefaultIconColorProminent, + return cros_colors::ResolveColor(ColorName::kIconColorProminent, color_mode); case ContentLayerType::kButtonLabelColor: case ContentLayerType::kButtonIconColor:
diff --git a/ash/wm/client_controlled_state.cc b/ash/wm/client_controlled_state.cc index 155692c..1d410ea 100644 --- a/ash/wm/client_controlled_state.cc +++ b/ash/wm/client_controlled_state.cc
@@ -12,6 +12,7 @@ #include "ash/shell.h" #include "ash/wm/pip/pip_positioner.h" #include "ash/wm/screen_pinning_controller.h" +#include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_positioning_utils.h" #include "ash/wm/window_state.h" @@ -82,11 +83,18 @@ return; } + auto* window = window_state->window(); switch (event->type()) { case WM_EVENT_NORMAL: case WM_EVENT_MAXIMIZE: case WM_EVENT_MINIMIZE: case WM_EVENT_FULLSCREEN: { + // Clients handle a window state change asynchronously. So in the case + // that the window is in a transitional state (already snapped but not + // applied to its window state yet), we here skip to pass WM_EVENT. + if (SplitViewController::Get(window)->IsWindowInTransitionalState(window)) + return; + // Reset window state window_state->UpdateWindowPropertiesFromStateType(); WindowStateType next_state = @@ -102,15 +110,14 @@ if (window_state->CanSnap()) { // Get the desired window bounds for the snap state. gfx::Rect bounds = GetSnappedWindowBoundsInParent( - window_state->window(), event->type() == WM_EVENT_SNAP_LEFT - ? WindowStateType::kLeftSnapped - : WindowStateType::kRightSnapped); + window, event->type() == WM_EVENT_SNAP_LEFT + ? WindowStateType::kLeftSnapped + : WindowStateType::kRightSnapped); window_state->set_bounds_changed_by_user(true); // We don't want Unminimize() to restore the pre-snapped state during // the transition. - window_state->window()->ClearProperty( - aura::client::kPreMinimizedShowStateKey); + window->ClearProperty(aura::client::kPreMinimizedShowStateKey); window_state->UpdateWindowPropertiesFromStateType(); WindowStateType next_state =
diff --git a/ash/wm/client_controlled_state_unittest.cc b/ash/wm/client_controlled_state_unittest.cc index fba017af..6724557 100644 --- a/ash/wm/client_controlled_state_unittest.cc +++ b/ash/wm/client_controlled_state_unittest.cc
@@ -11,6 +11,7 @@ #include "ash/wm/desks/desks_util.h" #include "ash/wm/pip/pip_positioner.h" #include "ash/wm/screen_pinning_controller.h" +#include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" @@ -588,4 +589,35 @@ EXPECT_EQ(WindowStateType::kMaximized, delegate()->new_state()); } +TEST_F(ClientControlledStateTest, + IgnoreWmEventWhenWindowIsInTransitionalSnappedState) { + auto* split_view_controller = + SplitViewController::Get(window_state()->window()); + + widget_delegate()->EnableSnap(); + split_view_controller->SnapWindow(window_state()->window(), + SplitViewController::SnapPosition::RIGHT); + + EXPECT_EQ(WindowStateType::kRightSnapped, delegate()->new_state()); + EXPECT_FALSE(window_state()->IsSnapped()); + + // Ensures the window is in a transitional snapped state. + EXPECT_TRUE(split_view_controller->IsWindowInTransitionalState( + window_state()->window())); + EXPECT_EQ(WindowStateType::kRightSnapped, delegate()->new_state()); + EXPECT_FALSE(window_state()->IsSnapped()); + + // Ignores WMEvent if in a transitional state. + widget()->Maximize(); + EXPECT_NE(WindowStateType::kMaximized, delegate()->new_state()); + + // Applies snap request. + state()->EnterNextState(window_state(), delegate()->new_state()); + EXPECT_TRUE(window_state()->IsSnapped()); + + // After exiting the transitional state, works normally. + widget()->Maximize(); + EXPECT_EQ(WindowStateType::kMaximized, delegate()->new_state()); +} + } // namespace ash
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc index 841bd66..42ea38b7 100644 --- a/ash/wm/splitview/split_view_controller.cc +++ b/ash/wm/splitview/split_view_controller.cc
@@ -36,6 +36,7 @@ #include "ash/wm/window_transient_descendant_iterator.h" #include "ash/wm/window_util.h" #include "ash/wm/wm_event.h" +#include "base/containers/flat_set.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/numerics/ranges.h" @@ -57,6 +58,7 @@ #include "ui/wm/core/coordinate_conversion.h" #include "ui/wm/core/shadow_controller.h" #include "ui/wm/core/window_util.h" +#include "ui/wm/public/activation_change_observer.h" #include "ui/wm/public/activation_client.h" namespace ash { @@ -356,6 +358,187 @@ base::Optional<ui::ThroughputTracker> tracker_; }; +// The controller that observes the window state and performs auto snapping +// for the window if needed. When it's created, it observes the root window +// and all windows in a current active desk. When 1) an observed window is +// activated or 2) changed to visible from minimized, this class performs +// auto snapping for the window if it's possible. +class SplitViewController::AutoSnapController + : public wm::ActivationChangeObserver, + public aura::WindowObserver { + public: + explicit AutoSnapController(SplitViewController* split_view_controller) + : split_view_controller_(split_view_controller) { + Shell::Get()->activation_client()->AddObserver(this); + AddWindow(split_view_controller->root_window()); + for (auto* window : + Shell::Get()->mru_window_tracker()->BuildMruWindowList(kActiveDesk)) { + AddWindow(window); + } + } + + ~AutoSnapController() override { + for (auto* window : observed_windows_) + window->RemoveObserver(this); + Shell::Get()->activation_client()->RemoveObserver(this); + } + + AutoSnapController(const AutoSnapController&) = delete; + AutoSnapController& operator=(const AutoSnapController&) = delete; + + // wm::ActivationChangeObserver: + void OnWindowActivated(ActivationReason reason, + aura::Window* gained_active, + aura::Window* lost_active) override { + if (!gained_active) + return; + + // If |gained_active| was activated as a side effect of a window disposition + // change, do nothing. For example, when a snapped window is closed, another + // window will be activated before OnWindowDestroying() is called. We should + // not try to snap another window in this case. + if (reason == ActivationReason::WINDOW_DISPOSITION_CHANGED) + return; + + AutoSnapWindowIfNeeded(gained_active); + } + + // aura::WindowObserver: + void OnWindowVisibilityChanging(aura::Window* window, bool visible) override { + // TODO(toshikikikuchi): Consider avoiding to use kAnimationsDisabledKey + // here just for |DragWindowFromShelfController|. + if (visible && WindowState::Get(window) && + WindowState::Get(window)->IsMinimized() && + !window->GetProperty(aura::client::kAnimationsDisabledKey)) { + // A visible but minimized window state triggers an implicit un-minimizing + // by someone (e.g. + // |WorkspaceLayoutManager::OnChildWindowVisibilityChanged| or + // |WorkspaceLayoutManager::OnWindowActivating|). This emits a window + // state change event but it is unnecessary for to-be-snapped windows + // because some clients (e.g. ARC app) handle a window state change + // asynchronously. So in the case, we here try to snap a window before + // other's handling. Animation-disabled visibility changes are used for + // transient hide & show operations so not applicable for auto snapping. + AutoSnapWindowIfNeeded(window); + } + } + + void OnWindowAddedToRootWindow(aura::Window* window) override { + AddWindow(window); + } + + void OnWindowRemovingFromRootWindow(aura::Window* window, + aura::Window* new_root) override { + RemoveWindow(window); + } + + void OnWindowDestroying(aura::Window* window) override { + RemoveWindow(window); + } + + private: + void AutoSnapWindowIfNeeded(aura::Window* window) { + DCHECK(window); + + if (window->GetRootWindow() != split_view_controller_->root_window()) + return; + + // We perform an "auto" snapping only if split view mode is active. + if (!split_view_controller_->InSplitViewMode()) + return; + + if (DesksController::Get()->AreDesksBeingModified()) { + // Activating a desk from its mini view will activate its most-recently + // used window, but this should not result in snapping and ending overview + // mode now. Overview will be ended explicitly as part of the desk + // activation animation. + return; + } + + // Only windows that are in the MRU list and are not already in split view + // can be auto-snapped. + if (split_view_controller_->IsWindowInSplitView(window) || + !base::Contains( + Shell::Get()->mru_window_tracker()->BuildMruWindowList(kActiveDesk), + window)) { + return; + } + + // We do not auto snap windows in clamshell splitview mode if a new window + // is activated when clamshell splitview mode is active. In this case we'll + // just end overview mode which will then end splitview mode. + // TODO(xdai): Handle this logic in OverivewSession::OnWindowActivating(). + if (split_view_controller_->InClamshellSplitViewMode()) { + Shell::Get()->overview_controller()->EndOverview(); + return; + } + + DCHECK(split_view_controller_->InTabletSplitViewMode()); + + // Do not snap the window if the activation change is caused by dragging a + // window, or by dragging a tab. Note the two values + // WindowState::is_dragged() and IsDraggingTabs() might not be exactly the + // same under certain circumstance, e.g., when a tab is dragged out from a + // browser window, a new browser window will be created for the dragged tab + // and then be activated, and at that time, IsDraggingTabs() is true, but + // WindowState::is_dragged() is still false. And later after the window drag + // starts, WindowState::is_dragged() will then be true. + if (WindowState::Get(window)->is_dragged() || + window_util::IsDraggingTabs(window)) { + return; + } + + // If the divider is animating, then |window| cannot be snapped (and is + // not already snapped either, because then we would have bailed out by + // now). Then if |window| is user-positionable, we should end split view + // mode, but the cannot snap toast would be inappropriate because the user + // still might be able to snap |window|. + if (split_view_controller_->IsDividerAnimating()) { + if (WindowState::Get(window)->IsUserPositionable()) + split_view_controller_->EndSplitView( + EndReason::kUnsnappableWindowActivated); + return; + } + + // If it's a user positionable window but can't be snapped, end split view + // mode and show the cannot snap toast. + if (!split_view_controller_->CanSnapWindow(window)) { + if (WindowState::Get(window)->IsUserPositionable()) { + split_view_controller_->EndSplitView( + EndReason::kUnsnappableWindowActivated); + ShowAppCannotSnapToast(); + } + return; + } + + // Snap the window on the non-default side of the screen if split view mode + // is active. + split_view_controller_->SnapWindow( + window, (split_view_controller_->default_snap_position() == LEFT) + ? RIGHT + : LEFT); + } + + void AddWindow(aura::Window* window) { + if (split_view_controller_->root_window() != window->GetRootWindow()) + return; + + if (!window->HasObserver(this)) + window->AddObserver(this); + observed_windows_.insert(window); + } + + void RemoveWindow(aura::Window* window) { + window->RemoveObserver(this); + observed_windows_.erase(window); + } + + SplitViewController* split_view_controller_; + + // Tracks observed windows. + base::flat_set<aura::Window*> observed_windows_; +}; + // static SplitViewController* SplitViewController::Get(const aura::Window* window) { DCHECK(window); @@ -459,7 +642,8 @@ // Add observers when the split view mode starts. Shell::Get()->AddShellObserver(this); Shell::Get()->overview_controller()->AddObserver(this); - Shell::Get()->activation_client()->AddObserver(this); + + auto_snap_controller_ = std::make_unique<AutoSnapController>(this); // If there is pre-set |divider_position_|, use it. It can happen during // tablet <-> clamshell transition or multi-user transition. @@ -867,7 +1051,8 @@ // Remove observers when the split view mode ends. Shell::Get()->RemoveShellObserver(this); Shell::Get()->overview_controller()->RemoveObserver(this); - Shell::Get()->activation_client()->RemoveObserver(this); + + auto_snap_controller_.reset(); StopObserving(LEFT); StopObserving(RIGHT); @@ -907,6 +1092,14 @@ divider_position_ = divider_position; } +bool SplitViewController::IsWindowInTransitionalState( + const aura::Window* window) const { + if (!IsWindowInSplitView(window)) + return false; + return WindowState::Get(window)->GetStateType() != + GetStateTypeFromSnapPosition(GetPositionOfSnappedWindow(window)); +} + void SplitViewController::OnOverviewButtonTrayLongPressed( const gfx::Point& event_location) { // Do nothing if split view is not enabled. @@ -1128,86 +1321,6 @@ } } -void SplitViewController::OnWindowActivated(ActivationReason reason, - aura::Window* gained_active, - aura::Window* lost_active) { - if (!gained_active || gained_active->GetRootWindow() != root_window_) - return; - - if (DesksController::Get()->AreDesksBeingModified()) { - // Activating a desk from its mini view will activate its most-recently used - // window, but this should not result in snapping and ending overview mode - // now. Overview will be ended explicitly as part of the desk activation - // animation. - return; - } - - // If |gained_active| was activated as a side effect of a window disposition - // change, do nothing. For example, when a snapped window is closed, another - // window will be activated before OnWindowDestroying() is called. We should - // not try to snap another window in this case. - if (reason == ActivationReason::WINDOW_DISPOSITION_CHANGED) - return; - - // Only windows that are in the MRU list and are not already in split view can - // be auto-snapped. - if (IsWindowInSplitView(gained_active) || - !base::Contains( - Shell::Get()->mru_window_tracker()->BuildMruWindowList(kActiveDesk), - gained_active)) { - return; - } - - // We do not auto snap windows in clamshell splitview mode if a new window - // is activated when clamshell splitview mode is active. In this case we'll - // just end overview mode which will then end splitview mode. - // TODO(xdai): Handle this logic in OverivewSession::OnWindowActivating(). - if (InClamshellSplitViewMode()) { - Shell::Get()->overview_controller()->EndOverview(); - return; - } - - DCHECK(InTabletSplitViewMode()); - - // Do not snap the window if the activation change is caused by dragging a - // window, or by dragging a tab. Note the two values WindowState::is_dragged() - // and IsDraggingTabs() might not be exactly the same under certain - // circumstance, e.g., when a tab is dragged out from a browser window, a new - // browser window will be created for the dragged tab and then be activated, - // and at that time, IsDraggingTabs() is true, but WindowState::is_dragged() - // is still false. And later after the window drag starts, - // WindowState::is_dragged() will then be true. - if (WindowState::Get(gained_active)->is_dragged() || - window_util::IsDraggingTabs(gained_active)) { - return; - } - - // If the divider is animating, then |gained_active| cannot be snapped (and is - // not already snapped either, because then we would have bailed out by now). - // Then if |gained_active| is user-positionable, we should end split view - // mode, but the cannot snap toast would be inappropriate because the user - // still might be able to snap |gained_active|. - if (IsDividerAnimating()) { - if (WindowState::Get(gained_active)->IsUserPositionable()) - EndSplitView(EndReason::kUnsnappableWindowActivated); - return; - } - - // If it's a user positionable window but can't be snapped, end split view - // mode and show the cannot snap toast. - if (!CanSnapWindow(gained_active)) { - if (WindowState::Get(gained_active)->IsUserPositionable()) { - EndSplitView(EndReason::kUnsnappableWindowActivated); - ShowAppCannotSnapToast(); - } - return; - } - - // Snap the window on the non-default side of the screen if split view mode - // is active. - SnapWindow(gained_active, (default_snap_position_ == LEFT) ? RIGHT : LEFT); -} - void SplitViewController::OnPinnedStateChanged(aura::Window* pinned_window) { // Disable split view for pinned windows. if (WindowState::Get(pinned_window)->IsPinned() && InSplitViewMode())
diff --git a/ash/wm/splitview/split_view_controller.h b/ash/wm/splitview/split_view_controller.h index c83047a..6b481be 100644 --- a/ash/wm/splitview/split_view_controller.h +++ b/ash/wm/splitview/split_view_controller.h
@@ -23,7 +23,6 @@ #include "ui/display/display.h" #include "ui/display/display_observer.h" #include "ui/gfx/geometry/point.h" -#include "ui/wm/public/activation_change_observer.h" namespace ui { class Layer; @@ -43,7 +42,6 @@ // TODO(xdai): Make it work for multi-display non mirror environment. class ASH_EXPORT SplitViewController : public aura::WindowObserver, public WindowStateObserver, - public wm::ActivationChangeObserver, public ShellObserver, public OverviewObserver, public display::DisplayObserver, @@ -204,6 +202,13 @@ // on the middle split position). void InitDividerPositionForTransition(int divider_position); + // Returns true if |window| is in a transitinal state which means that + // |SplitViewController| has already changed its internal snapped state for + // |window| but the snapped state has not been applied to |window|'s window + // state yet. The transional state can be happen in some clients (e.g. ARC + // app) which handle window states asynchronously. + bool IsWindowInTransitionalState(const aura::Window* window) const; + // Called when the overview button tray has been long pressed. Enters // splitview mode if the active window is snappable. Also enters overview mode // if device is not currently in overview mode. @@ -236,11 +241,6 @@ void OnPostWindowStateTypeChange(WindowState* window_state, WindowStateType old_type) override; - // wm::ActivationChangeObserver: - void OnWindowActivated(ActivationReason reason, - aura::Window* gained_active, - aura::Window* lost_active) override; - // ShellObserver: void OnPinnedStateChanged(aura::Window* pinned_window) override; @@ -279,6 +279,7 @@ friend class SplitViewOverviewSessionTest; class TabDraggedWindowObserver; class DividerSnapAnimation; + class AutoSnapController; // These functions return |left_window_| and |right_window_|, swapped in // nonprimary screen orientations. Note that they may return null. @@ -507,6 +508,9 @@ // Records the presentation time of resize operation in split view mode. std::unique_ptr<PresentationTimeRecorder> presentation_time_recorder_; + // Observes windows and performs auto snapping if needed. + std::unique_ptr<AutoSnapController> auto_snap_controller_; + DISALLOW_COPY_AND_ASSIGN(SplitViewController); };
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc index b3fef33..f8660b26 100644 --- a/ash/wm/splitview/split_view_controller_unittest.cc +++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -2706,6 +2706,54 @@ 1); } +// Tests that auto snapping is properly triggered if a window is going to +// unminimized (visible but minimized) in tablet split view mode. +TEST_P(SplitViewControllerTest, AutoSnapFromMinimizedState) { + const gfx::Rect bounds(0, 0, 400, 400); + std::unique_ptr<aura::Window> window1(CreateWindow(bounds)); + std::unique_ptr<aura::Window> window2(CreateNonSnappableWindow(bounds)); + std::unique_ptr<aura::Window> window3(CreateWindow(bounds)); + + // Nothing should happen in clamshell mode. + Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false); + WindowState::Get(window1.get())->Minimize(); + window1->Show(); + EXPECT_FALSE(split_view_controller()->InSplitViewMode()); + EXPECT_FALSE(split_view_controller()->IsWindowInSplitView(window1.get())); + + // Nothing should happen not in tablet split view mode. + Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); + WindowState::Get(window1.get())->Minimize(); + window1->Show(); + EXPECT_FALSE(split_view_controller()->InSplitViewMode()); + EXPECT_FALSE(split_view_controller()->IsWindowInSplitView(window1.get())); + + // Nothing should happen for a non-snappable window. + Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); + WindowState::Get(window2.get())->Minimize(); + window2->Show(); + EXPECT_FALSE(split_view_controller()->InSplitViewMode()); + EXPECT_FALSE(split_view_controller()->IsWindowInSplitView(window2.get())); + + // Should performs auto snapping when showing a snappable window in table + // split view mode. + Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); + split_view_controller()->SnapWindow(window3.get(), SplitViewController::LEFT); + EXPECT_TRUE(split_view_controller()->InTabletSplitViewMode()); + EXPECT_TRUE(split_view_controller()->IsWindowInSplitView(window3.get())); + EXPECT_EQ(split_view_controller()->GetPositionOfSnappedWindow(window3.get()), + SplitViewController::LEFT); + + WindowState::Get(window1.get())->Minimize(); + window1->Show(); + EXPECT_TRUE(split_view_controller()->InTabletSplitViewMode()); + EXPECT_TRUE(split_view_controller()->IsWindowInSplitView(window1.get())); + EXPECT_EQ(split_view_controller()->GetPositionOfSnappedWindow(window1.get()), + SplitViewController::RIGHT); + + EndSplitView(); +} + // Test the tab-dragging related functionalities in tablet mode. Tab(s) can be // dragged out of a window and then put in split view mode or merge into another // window.
diff --git a/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc b/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc index 033e673..24aab8f 100644 --- a/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc +++ b/base/allocator/allocator_shim_default_dispatch_to_partition_alloc.cc
@@ -11,14 +11,8 @@ namespace { base::ThreadSafePartitionRoot& Allocator() { - static base::NoDestructor<base::ThreadSafePartitionRoot> allocator; - allocator->Init(false /* enforce_alignment */); - return *allocator; -} - -base::ThreadSafePartitionRoot& AlignedAllocator() { - static base::NoDestructor<base::ThreadSafePartitionRoot> allocator; - allocator->Init(true /* enforce_alignment */); + static base::NoDestructor<base::ThreadSafePartitionRoot> allocator{ + false /* enforce_alignment */}; return *allocator; } @@ -39,7 +33,9 @@ size_t alignment, size_t size, void* context) { - return AlignedAllocator().AlignedAlloc(alignment, size); + static base::NoDestructor<base::ThreadSafePartitionRoot> aligned_allocator{ + true /* enforce_alignment */}; + return aligned_allocator->AlignedAlloc(alignment, size); } void* PartitionRealloc(const AllocatorDispatch*,
diff --git a/base/allocator/partition_allocator/partition_alloc.cc b/base/allocator/partition_allocator/partition_alloc.cc index 2b94f89..96bc8571 100644 --- a/base/allocator/partition_allocator/partition_alloc.cc +++ b/base/allocator/partition_allocator/partition_alloc.cc
@@ -193,10 +193,9 @@ } template <bool thread_safe> -void PartitionRoot<thread_safe>::InitSlowPath(bool enforce_alignment) { +void PartitionRoot<thread_safe>::Init(bool enforce_alignment) { ScopedGuard guard{lock_}; - - if (initialized.load(std::memory_order_relaxed)) + if (initialized) return; #if defined(ARCH_CPU_64_BITS) && !defined(OS_NACL)
diff --git a/base/allocator/partition_allocator/partition_alloc.h b/base/allocator/partition_allocator/partition_alloc.h index 970395a..55dfc1d0 100644 --- a/base/allocator/partition_allocator/partition_alloc.h +++ b/base/allocator/partition_allocator/partition_alloc.h
@@ -404,8 +404,7 @@ // nothing) instead of true|false, so that we can just add or subtract the // size instead of having an if branch on the hot paths. bool allow_extras; - // Atomic as initialization can be concurrent. - std::atomic<bool> initialized = {}; + bool initialized = false; char* next_super_page = nullptr; char* next_partition_page = nullptr; char* next_partition_page_end = nullptr; @@ -432,6 +431,9 @@ Bucket buckets[kGenericNumBuckets] = {}; PartitionRoot() = default; + explicit PartitionRoot(bool enable_tag_pointers) { + Init(enable_tag_pointers); + } ~PartitionRoot() = default; // Public API @@ -444,15 +446,7 @@ // // Moving it a layer lower couples PartitionRoot and PartitionBucket, but // preserves the layering of the includes. - ALWAYS_INLINE void Init(bool enforce_alignment) { - if (LIKELY(initialized.load(std::memory_order_relaxed))) - return; - - InitSlowPath(enforce_alignment); -#if ENABLE_TAG_FOR_CHECKED_PTR2 || ENABLE_TAG_FOR_MTE_CHECKED_PTR - current_partition_tag = base::RandUint64(); -#endif - } + void Init(bool enforce_alignment); ALWAYS_INLINE static bool IsValidPage(Page* page); ALWAYS_INLINE static PartitionRoot* FromPage(Page* page); @@ -507,7 +501,6 @@ internal::PartitionBucket<thread_safe>* SizeToBucket(size_t size) const; private: - void InitSlowPath(bool enforce_alignment); ALWAYS_INLINE void* AllocFromBucket(Bucket* bucket, int flags, size_t size) EXCLUSIVE_LOCKS_REQUIRED(lock_); bool ReallocDirectMappedInPlace(internal::PartitionPage<thread_safe>* page,
diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc index 091d9ef..148d52b 100644 --- a/base/files/file_util_posix.cc +++ b/base/files/file_util_posix.cc
@@ -531,7 +531,17 @@ ssize_t count = ::readlink(symlink_path.value().c_str(), buf, base::size(buf)); - if (count <= 0) { +#if defined(OS_ANDROID) && defined(__LP64__) + // A few 64-bit Android L/M devices return INT_MAX instead of -1 here for + // errors; this is related to bionic's (incorrect) definition of ssize_t as + // being long int instead of int. Cast it so the compiler generates the + // comparison we want here. https://crbug.com/1101940 + bool error = static_cast<int32_t>(count) <= 0; +#else + bool error = count <= 0; +#endif + + if (error) { target_path->clear(); return false; }
diff --git a/base/memory/checked_ptr_unittest.cc b/base/memory/checked_ptr_unittest.cc index 8018b49e..e7929703 100644 --- a/base/memory/checked_ptr_unittest.cc +++ b/base/memory/checked_ptr_unittest.cc
@@ -11,6 +11,7 @@ #include <utility> #include "base/allocator/partition_allocator/partition_alloc.h" +#include "base/allocator/partition_allocator/partition_alloc_features.h" #include "base/allocator/partition_allocator/partition_tag.h" #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" @@ -740,6 +741,34 @@ LOG(FATAL) << "Out of memory"; } +// This test works only when PartitionAlloc is used, when tags are enabled. +// Don't enable it when MEMORY_TOOL_REPLACES_ALLOCATOR is defined, because it +// makes PartitionAlloc take a different path that doesn't provide tags, thus no +// crash on UaF, thus missing the EXPECT_DEATH_IF_SUPPORTED expectation. +#if BUILDFLAG(USE_PARTITION_ALLOC) && \ + (ENABLE_TAG_FOR_CHECKED_PTR2 || ENABLE_TAG_FOR_MTE_CHECKED_PTR) && \ + !defined(MEMORY_TOOL_REPLACES_ALLOCATOR) + +TEST(CheckedPtr2OrMTEImpl, CrashOnUseAfterFree) { + // This test works only if GigaCage is enabled. Bail out otherwise. + if (!IsPartitionAllocGigaCageEnabled()) + return; + + // TODO(bartekn): Avoid using PartitionAlloc API directly. Switch to + // new/delete once PartitionAlloc Everywhere is fully enabled. + PartitionAllocGlobalInit(HandleOOM); + PartitionAllocator<ThreadSafe> allocator; + allocator.init(); + void* raw_ptr = allocator.root()->Alloc(sizeof(int), "int"); + CheckedPtr<int> ptr = static_cast<int*>(raw_ptr); + *ptr = 42; + EXPECT_TRUE(*ptr == 42); + allocator.root()->Free(raw_ptr); + EXPECT_DEATH_IF_SUPPORTED(if (*ptr == 42) return, ""); +} + +#endif + } // namespace internal } // namespace base
diff --git a/base/stl_util.h b/base/stl_util.h index d8db9b14..8e9fab3 100644 --- a/base/stl_util.h +++ b/base/stl_util.h
@@ -447,10 +447,22 @@ std::forward<Args>(args)...); } -// Returns true if the container is sorted. +// Returns true if the container is sorted. Requires constexpr std::begin/end, +// which exists for arrays in C++14. +// Note that std::is_sorted is constexpr beginning C++20 and this should be +// switched to use it when C++20 is supported. template <typename Container> -bool STLIsSorted(const Container& cont) { - return std::is_sorted(std::begin(cont), std::end(cont)); +constexpr bool STLIsSorted(const Container& cont) { + auto it = std::begin(cont); + const auto end = std::end(cont); + if (it == end) + return true; + + for (auto prev = it++; it != end; prev = it++) { + if (*it < *prev) + return false; + } + return true; } // Returns a new ResultType containing the difference of two sorted containers.
diff --git a/base/stl_util_unittest.cc b/base/stl_util_unittest.cc index 2440064..55980a51 100644 --- a/base/stl_util_unittest.cc +++ b/base/stl_util_unittest.cc
@@ -808,5 +808,16 @@ EXPECT_NE(nullptr, base::OptionalOrNullptr(optional)); } +TEST(STLUtilTest, STLIsSortedConstexpr) { + constexpr int kArrayAscending[] = {1, 2, 3, 4}; + static_assert(base::STLIsSorted(kArrayAscending), ""); + + constexpr int kArrayDescending[] = {4, 3, 2, 1}; + static_assert(!base::STLIsSorted(kArrayDescending), ""); + + constexpr int kArrayEqual[] = {1, 1, 1, 1}; + static_assert(base::STLIsSorted(kArrayEqual), ""); +} + } // namespace } // namespace base
diff --git a/base/trace_event/traced_value.h b/base/trace_event/traced_value.h index 67d788ca8..58a3ec4 100644 --- a/base/trace_event/traced_value.h +++ b/base/trace_event/traced_value.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include <memory> +#include <sstream> #include <string> #include <vector> @@ -130,6 +131,14 @@ KeptValueType kept_value_type_; }; + // Return std::string representation given by |value|'s ostream operator<<. + template <class T> + static std::string ValueToString(const T& value) { + std::stringstream ss; + ss << value; + return ss.str(); + } + // A custom serialization class can be supplied by implementing the // Writer interface and supplying a factory class to SetWriterFactoryCallback. // Primarily used by Perfetto to write TracedValues directly into its proto
diff --git a/base/trace_event/traced_value_unittest.cc b/base/trace_event/traced_value_unittest.cc index 652db8f..657a390 100644 --- a/base/trace_event/traced_value_unittest.cc +++ b/base/trace_event/traced_value_unittest.cc
@@ -15,6 +15,11 @@ namespace base { namespace trace_event { +TEST(TraceEventArgumentTest, ValueToString) { + std::string zero = TracedValue::ValueToString(0); + EXPECT_EQ("0", zero); +} + TEST(TraceEventArgumentTest, InitializerListCreatedFlatDictionary) { std::string json; TracedValue::Build({{"bool_var", true},
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 4d465b18..22b77fa 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -3037,7 +3037,8 @@ [ get_label_info(":$target_name", "label_no_toolchain") ], [ "//base*", - "//chrome*", + "//chrome/browser*", + "//chromecast*", "//clank*", "//components*", "//content*", @@ -3050,6 +3051,9 @@ "//third_party*", "//ui*", "//weblayer*", + + # This is due to the "special group" bypass. + "*_bundle_module__java__header", ]) == [] if (invoker.use_turbine && !_allow_transitive_interfaces) {
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index d6f26911..4e48046 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20200715.2.1 +0.20200716.0.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index e7bda5f..4e48046 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20200715.1.1 +0.20200716.0.1
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index ba82a5a5..38260acc 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -866,10 +866,12 @@ "//third_party/android_deps:androidx_recyclerview_recyclerview_java", "//third_party/android_deps:androidx_swiperefreshlayout_swiperefreshlayout_java", "//third_party/android_deps:androidx_test_core_java", + "//third_party/android_deps:androidx_test_runner_java", "//third_party/android_deps:com_google_dagger_dagger_java", "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", "//third_party/android_deps:com_googlecode_java_diff_utils_diffutils_java", "//third_party/android_sdk/androidx_browser:androidx_browser_java", + "//third_party/android_support_test_runner:runner_java", "//third_party/blink/public:blink_headers_java", "//third_party/blink/public/mojom:android_mojo_bindings_java", "//third_party/blink/public/mojom:mojom_platform_java", @@ -1107,6 +1109,7 @@ "//third_party/android_deps:androidx_lifecycle_lifecycle_common_java", "//third_party/android_deps:androidx_preference_preference_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", + "//third_party/android_deps:androidx_test_runner_java", "//third_party/android_deps:androidx_viewpager_viewpager_java", "//url:origin_java", @@ -1211,6 +1214,7 @@ "//chrome/android:app_hooks_java", "//chrome/android:chrome_java", "//chrome/android/features/vr:java", + "//chrome/browser/flags:java", "//chrome/browser/tab:java", "//chrome/browser/ui/messages/android:java", "//chrome/browser/util:java", @@ -1225,6 +1229,7 @@ "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_lifecycle_lifecycle_common_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", + "//third_party/android_deps:androidx_test_runner_java", "//third_party/android_sdk/androidx_browser:androidx_browser_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", @@ -1866,6 +1871,7 @@ "//components/sync/protocol:protocol_java", "//content/public/android:content_java", "//content/public/test/android:content_java_test_support", + "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", "//third_party/junit", ] @@ -2430,6 +2436,7 @@ "//base:base_java_test_support", "//chrome/test/android:chrome_java_test_pagecontroller", "//content/public/test/android:content_java_test_support", + "//third_party/android_deps:androidx_test_runner_java", "//third_party/android_support_test_runner:runner_java", "//third_party/junit", "//third_party/ub-uiautomator:ub_uiautomator_java", @@ -2470,6 +2477,7 @@ "//base:base_java_test_support", "//chrome/test/android:chrome_java_test_pagecontroller", "//content/public/test/android:content_java_test_support", + "//third_party/android_deps:androidx_test_runner_java", "//third_party/android_support_test_runner:runner_java", "//third_party/junit", ] @@ -3227,6 +3235,7 @@ "//ui/android:ui_java", "//ui/android:ui_java_test_support", "//url:gurl_java", + "//url:origin_java", "//url/mojom:url_mojom_gurl_java", ]
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 696a869..eeebf6f 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -467,6 +467,7 @@ "java/src/org/chromium/chrome/browser/customtabs/content/CustomTabIntentHandler.java", "java/src/org/chromium/chrome/browser/customtabs/content/CustomTabIntentHandlingStrategy.java", "java/src/org/chromium/chrome/browser/customtabs/content/DefaultCustomTabIntentHandlingStrategy.java", + "java/src/org/chromium/chrome/browser/customtabs/content/ProfileProvider.java", "java/src/org/chromium/chrome/browser/customtabs/content/TabCreationMode.java", "java/src/org/chromium/chrome/browser/customtabs/content/TabObserverRegistrar.java", "java/src/org/chromium/chrome/browser/customtabs/dependency_injection/BaseCustomTabActivityComponent.java",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni index 00b2ce0..1625124 100644 --- a/chrome/android/chrome_junit_test_java_sources.gni +++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -47,6 +47,7 @@ "junit/src/org/chromium/chrome/browser/compositor/animation/CompositorAnimatorTest.java", "junit/src/org/chromium/chrome/browser/compositor/layouts/CompositorModelChangeProcessorUnitTest.java", "junit/src/org/chromium/chrome/browser/compositor/layouts/MockLayoutUpdateHost.java", + "junit/src/org/chromium/chrome/browser/compositor/layouts/StaticLayoutUnitTest.java", "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java", "junit/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuCoordinatorTest.java", "junit/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuHeaderMediatorTest.java", @@ -212,6 +213,7 @@ "junit/src/org/chromium/chrome/browser/signin/SigninPromoUtilTest.java", "junit/src/org/chromium/chrome/browser/signin/SigninUtilsStartActivityTest.java", "junit/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerMediatorTest.java", + "junit/src/org/chromium/chrome/browser/site_settings/SingleWebsiteSettingsTest.java", "junit/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorMediatorTest.java", "junit/src/org/chromium/chrome/browser/suggestions/SuggestionsImageFetcherTest.java", "junit/src/org/chromium/chrome/browser/suggestions/tile/TileGroupUnitTest.java",
diff --git a/chrome/android/features/autofill_assistant/BUILD.gn b/chrome/android/features/autofill_assistant/BUILD.gn index d1bcfdad..e78311e3 100644 --- a/chrome/android/features/autofill_assistant/BUILD.gn +++ b/chrome/android/features/autofill_assistant/BUILD.gn
@@ -63,6 +63,7 @@ "//third_party/android_deps:androidx_lifecycle_lifecycle_common_java", "//third_party/android_deps:androidx_lifecycle_lifecycle_runtime_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/android_deps:com_google_android_material_material_java", "//third_party/blink/public/mojom:android_mojo_bindings_java", "//ui/android:ui_java", @@ -227,9 +228,11 @@ deps = [ ":java", ":test_support_jni_headers", + "//base:base_java", "//base:jni_java", "//components/autofill_assistant/browser:proto_java", "//content/public/test/android:content_java_test_support", + "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", "//third_party/hamcrest:hamcrest_java", ] @@ -277,6 +280,7 @@ "//base:base_java_test_support", "//chrome/android:chrome_java", "//chrome/android:chrome_test_util_java", + "//chrome/browser/flags:java", "//chrome/browser/image_fetcher:java", "//chrome/browser/password_manager/android_test_helpers:test_support_java", "//chrome/browser/preferences:java", @@ -290,16 +294,20 @@ "//content/public/android:content_java", "//content/public/test/android:content_java_test_support", "//net/android:net_java_test_support", + "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_coordinatorlayout_coordinatorlayout_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", + "//third_party/android_deps:androidx_test_runner_java", "//third_party/android_deps:com_google_android_material_material_java", "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", "//third_party/android_deps:espresso_java", "//third_party/android_support_test_runner:runner_java", + "//third_party/gif_player:gif_player_java", "//third_party/hamcrest:hamcrest_java", "//third_party/junit", "//third_party/mockito:mockito_java", "//ui/android:ui_full_java", + "//ui/android:ui_java_test_support", "//url:gurl_java", ]
diff --git a/chrome/android/features/keyboard_accessory/BUILD.gn b/chrome/android/features/keyboard_accessory/BUILD.gn index 9e61e4e8..54ffffd 100644 --- a/chrome/android/features/keyboard_accessory/BUILD.gn +++ b/chrome/android/features/keyboard_accessory/BUILD.gn
@@ -60,6 +60,7 @@ "//chrome/android:chrome_java", "//chrome/android:chrome_test_java", "//chrome/android:chrome_test_util_java", + "//chrome/browser/flags:java", "//chrome/browser/profiles/android:java", "//chrome/browser/tab:java", "//chrome/browser/ui/messages/android:java", @@ -73,7 +74,9 @@ "//content/public/android:content_java", "//content/public/test/android:content_java_test_support", "//net/android:net_java_test_support", + "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", + "//third_party/android_deps:androidx_test_runner_java", "//third_party/android_deps:com_google_android_material_material_java", "//third_party/android_deps:espresso_java", "//third_party/android_support_test_runner:runner_java", @@ -111,10 +114,12 @@ "//chrome/browser/tabmodel:java", "//chrome/test/android:chrome_java_test_support", "//components/autofill/android:autofill_java", + "//components/browser_ui/android/bottomsheet:java", "//components/embedder_support/android:content_view_java", "//components/feature_engagement/public:public_java", "//components/module_installer/android:module_installer_java", "//content/public/android:content_java", + "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", "//third_party/android_deps:com_google_android_material_material_java", "//third_party/hamcrest:hamcrest_java",
diff --git a/chrome/android/features/keyboard_accessory/internal/BUILD.gn b/chrome/android/features/keyboard_accessory/internal/BUILD.gn index 4243bd3b..e5cd846 100644 --- a/chrome/android/features/keyboard_accessory/internal/BUILD.gn +++ b/chrome/android/features/keyboard_accessory/internal/BUILD.gn
@@ -29,6 +29,7 @@ "//components/feature_engagement/public:public_java", "//content/public/android:content_java", "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_appcompat_appcompat_resources_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", "//third_party/android_deps:androidx_viewpager_viewpager_java",
diff --git a/chrome/android/features/keyboard_accessory/public/BUILD.gn b/chrome/android/features/keyboard_accessory/public/BUILD.gn index a88bcc3..5a7b7f1 100644 --- a/chrome/android/features/keyboard_accessory/public/BUILD.gn +++ b/chrome/android/features/keyboard_accessory/public/BUILD.gn
@@ -10,6 +10,7 @@ "//components/autofill/android:autofill_java", "//components/browser_ui/android/bottomsheet:java", "//third_party/android_deps:androidx_annotation_annotation_java", + "//ui/android:ui_full_java", ] sources = [ "java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponent.java",
diff --git a/chrome/android/features/media_router/BUILD.gn b/chrome/android/features/media_router/BUILD.gn index 2d21e33b1..1001a754 100644 --- a/chrome/android/features/media_router/BUILD.gn +++ b/chrome/android/features/media_router/BUILD.gn
@@ -21,6 +21,7 @@ "//components/browser_ui/media/android:java", "//services/media_session/public/cpp/android:media_session_java", "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_collection_collection_java", "//third_party/android_deps:androidx_core_core_java", "//third_party/android_deps:androidx_mediarouter_mediarouter_java", @@ -94,13 +95,17 @@ "//base:base_java_test_support", "//chrome/android:chrome_java", "//chrome/android:chrome_test_util_java", + "//chrome/browser/flags:java", "//chrome/test/android:chrome_java_test_support", "//content/public/android:content_java", "//content/public/test/android:content_java_test_support", "//net/android:net_java_test_support", + "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:androidx_test_runner_java", "//third_party/android_support_test_runner:runner_java", "//third_party/hamcrest:hamcrest_java", "//third_party/junit", + "//ui/android:ui_java_test_support", ] } @@ -131,6 +136,7 @@ "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support", + "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_mediarouter_mediarouter_java", ] }
diff --git a/chrome/android/features/start_surface/internal/BUILD.gn b/chrome/android/features/start_surface/internal/BUILD.gn index 3cd34ad..4599e022 100644 --- a/chrome/android/features/start_surface/internal/BUILD.gn +++ b/chrome/android/features/start_surface/internal/BUILD.gn
@@ -79,6 +79,7 @@ "//components/prefs/android:java", "//components/user_prefs/android:java", "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:com_google_android_material_material_java", "//ui/android:ui_full_java", ]
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java index 6eb11e7..185d39db 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
@@ -54,10 +54,11 @@ import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.ChromeTabbedActivity; +import org.chromium.chrome.browser.compositor.layouts.Layout; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChromePhone; import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChromeTablet; import org.chromium.chrome.browser.compositor.layouts.OverviewModeState; -import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; +import org.chromium.chrome.browser.compositor.layouts.StaticLayout; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -774,7 +775,7 @@ @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE}) @Features.DisableFeatures(ChromeFeatureList.START_SURFACE_ANDROID) public void testInstantStartWithoutStartSurface() throws IOException { - createTabStateFile(new int[] {0}); + createTabStateFile(new int[] {123}); mActivityTestRule.startMainActivityFromLauncher(); Assert.assertTrue(TabUiFeatureUtilities.supportInstantStart(false)); @@ -783,10 +784,9 @@ Assert.assertEquals(1, mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel().getCount()); - LayoutTab layoutTab = - mActivityTestRule.getActivity().getLayoutManager().getLayoutTabForTesting( - mActivityTestRule.getActivity().getTabModelSelector().getCurrentTabId()); - Assert.assertNotNull(layoutTab); + Layout activeLayout = mActivityTestRule.getActivity().getLayoutManager().getActiveLayout(); + Assert.assertTrue(activeLayout instanceof StaticLayout); + Assert.assertEquals(123, ((StaticLayout) activeLayout).getCurrentTabIdForTesting()); } /**
diff --git a/chrome/android/features/tab_ui/java/res/layout/tab_grid_dialog_layout.xml b/chrome/android/features/tab_ui/java/res/layout/tab_grid_dialog_layout.xml index 47bef58..98fb055d 100644 --- a/chrome/android/features/tab_ui/java/res/layout/tab_grid_dialog_layout.xml +++ b/chrome/android/features/tab_ui/java/res/layout/tab_grid_dialog_layout.xml
@@ -13,6 +13,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/dialog_container_view" + android:focusable="true" + android:focusableInTouchMode="true" android:background="@drawable/tab_grid_dialog_background"> <!-- Ignore useless parents here for two reasons: 1. Content recyclerView and toolbar view will be added programmatically later.
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java index bf08684e..d358488 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java
@@ -19,6 +19,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; +import android.view.accessibility.AccessibilityEvent; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.PopupWindow; @@ -187,6 +188,8 @@ @Override public void onAnimationEnd(Animator animation) { mCurrentDialogAnimator = null; + mDialogContainerView.requestFocus(); + mDialogContainerView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED); } }; mHideDialogAnimationListener = new AnimatorListenerAdapter() { @@ -194,6 +197,7 @@ public void onAnimationEnd(Animator animation) { setVisibility(View.GONE); mCurrentDialogAnimator = null; + mDialogContainerView.clearFocus(); } };
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogViewTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogViewTest.java index 104f081..c601cf0f 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogViewTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogViewTest.java
@@ -281,6 +281,7 @@ View sourceView = new View(getActivity()); mTabGridDialogView.setupDialogAnimation(sourceView); parentViewReference.set((ViewGroup) mTabGridDialogContainer.getParent()); + Assert.assertFalse(mTabGridDialogContainer.isFocused()); }); ViewGroup parent = parentViewReference.get(); @@ -304,8 +305,10 @@ mTabGridDialogView.getCurrentDialogAnimatorForTesting(), Matchers.nullValue())); - TestThreadUtils.runOnUiThreadBlocking( - () -> Assert.assertEquals(0f, mBackgroundFrameView.getAlpha(), 0.0)); + TestThreadUtils.runOnUiThreadBlocking(() -> { + Assert.assertEquals(0f, mBackgroundFrameView.getAlpha(), 0.0); + Assert.assertTrue(mTabGridDialogContainer.isFocused()); + }); // Hide the dialog with zoom-in animation. TestThreadUtils.runOnUiThreadBlocking(() -> { @@ -336,6 +339,7 @@ Assert.assertEquals(0f, mTabGridDialogContainer.getTranslationY(), 0.0); Assert.assertEquals(1f, mTabGridDialogContainer.getScaleX(), 0.0); Assert.assertEquals(1f, mTabGridDialogContainer.getScaleY(), 0.0); + Assert.assertFalse(mTabGridDialogContainer.isFocused()); }); } @@ -346,6 +350,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { View sourceView = new View(getActivity()); mTabGridDialogView.setupDialogAnimation(sourceView); + Assert.assertFalse(mTabGridDialogContainer.isFocused()); }); // Show the dialog. TestThreadUtils.runOnUiThreadBlocking(() -> mTabGridDialogView.showDialog()); @@ -358,6 +363,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { Assert.assertEquals(0f, mAnimationCardView.getAlpha(), 0.0); Assert.assertEquals(0f, mBackgroundFrameView.getAlpha(), 0.0); + Assert.assertTrue(mTabGridDialogContainer.isFocused()); }); // Hide the dialog with basic fade-out animation. @@ -381,6 +387,7 @@ Assert.assertEquals(View.GONE, mTabGridDialogView.getVisibility()); Assert.assertEquals(0f, mAnimationCardView.getAlpha(), 0.0); Assert.assertEquals(0f, mBackgroundFrameView.getAlpha(), 0.0); + Assert.assertFalse(mTabGridDialogContainer.isFocused()); }); } @@ -393,6 +400,7 @@ // Initially alpha of animation related views should be 0. Assert.assertEquals(0f, mAnimationCardView.getAlpha(), 0.0); Assert.assertEquals(0f, mBackgroundFrameView.getAlpha(), 0.0); + Assert.assertFalse(mTabGridDialogContainer.isFocused()); }); // Show the dialog with basic fade-in animation. @@ -411,6 +419,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { Assert.assertEquals(0f, mAnimationCardView.getAlpha(), 0.0); Assert.assertEquals(0f, mBackgroundFrameView.getAlpha(), 0.0); + Assert.assertTrue(mTabGridDialogContainer.isFocused()); }); // Hide the dialog with basic fade-out animation. @@ -436,6 +445,7 @@ Assert.assertEquals(View.GONE, mTabGridDialogView.getVisibility()); Assert.assertEquals(0f, mAnimationCardView.getAlpha(), 0.0); Assert.assertEquals(0f, mBackgroundFrameView.getAlpha(), 0.0); + Assert.assertFalse(mTabGridDialogContainer.isFocused()); }); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java b/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java index 5617063..83745ce 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java
@@ -354,7 +354,7 @@ mWebContentsCreatedForCCT = forCCT; mSpareWebContents = new WebContentsFactory().createWebContentsWithWarmRenderer( - false /* incognito */, true /* initiallyHidden */); + Profile.getLastUsedRegularProfile(), true /* initiallyHidden */); mObserver = new RenderProcessGoneObserver(); mSpareWebContents.addObserver(mObserver); mWebContentsCreationTimeMs = SystemClock.elapsedRealtime();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/WebContentsFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/WebContentsFactory.java index 8677c2a..94358b4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/WebContentsFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/WebContentsFactory.java
@@ -59,26 +59,6 @@ * * Also creates and initializes the renderer. * - * @param incognito Whether or not the {@link WebContents} should be built with an - * off-the-record profile or not. - * @param initiallyHidden Whether or not the {@link WebContents} should be initially hidden. - * @return A newly created {@link WebContents} object. - * - * @deprecated use {@link #createWebContentsWithWarmRenderer(Profile, boolean)} instead. - */ - @Deprecated - public WebContents createWebContentsWithWarmRenderer( - boolean incognito, boolean initiallyHidden) { - Profile profile = Profile.getLastUsedRegularProfile(); - if (incognito) profile = profile.getPrimaryOTRProfile(); - return createWebContents(profile, initiallyHidden, true); - } - - /** - * A factory method to build a {@link WebContents} object. - * - * Also creates and initializes the renderer. - * * @param profile The profile to be used by the WebContents. * @param initiallyHidden Whether or not the {@link WebContents} should be initially hidden. * @return A newly created {@link WebContents} object.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/CompositorModelChangeProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/CompositorModelChangeProcessor.java index f881278..e429358 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/CompositorModelChangeProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/CompositorModelChangeProcessor.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.compositor.layouts; +import androidx.annotation.VisibleForTesting; + import org.chromium.base.Callback; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; @@ -26,17 +28,18 @@ * request another frame. */ public static class FrameRequestSupplier extends ObservableSupplierImpl<Long> { - private final LayoutManagerHost mHost; + private final LayoutUpdateHost mHost; - public FrameRequestSupplier(LayoutManagerHost host) { + public FrameRequestSupplier(LayoutUpdateHost host) { mHost = host; } /** * Request to generate a new frame. */ - private void request() { - mHost.requestRender(); + @VisibleForTesting + void request() { + mHost.requestUpdate(); } } @@ -124,4 +127,4 @@ mFrameSupplier.request(); } -} \ No newline at end of file +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java index 3c30dd4a..ca90a4d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
@@ -27,6 +27,7 @@ import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelUtils; +import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.resources.ResourceManager; import java.lang.annotation.Retention; @@ -284,13 +285,13 @@ * Update snapping to pixel. To be called once every frame. * * TODO(crbug.com/1070281): Temporary placement. This is some Mediator logic and should move to - * the appropriate location when doing MVC. + * the appropriate location when doing MVC. Maybe move to {@link LayoutMediator}. * * @param dt The delta time between update frames in ms. * @param layoutTab The {@link LayoutTab} that needs to be updating. * @return True if the snapping requests to render at least one more frame. */ - protected boolean updateSnap(long dt, LayoutTab layoutTab) { + protected boolean updateSnap(long dt, PropertyModel layoutTab) { final float step = dt * SNAP_SPEED / 1000.0f; final float renderX = layoutTab.get(LayoutTab.RENDER_X); final float renderY = layoutTab.get(LayoutTab.RENDER_Y);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java index f46f7fb..8b5f9f43 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java
@@ -18,6 +18,8 @@ import org.chromium.base.ObserverList; import org.chromium.base.TraceEvent; +import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.browser_controls.BrowserControlsUtils; import org.chromium.chrome.browser.browser_controls.BrowserControlsVisibilityManager; import org.chromium.chrome.browser.compositor.LayerTitleCache; @@ -150,6 +152,14 @@ */ private Tab mCurrentTab; + private final ObservableSupplierImpl<TabModelSelector> mTabModelSelectorSupplier = + new ObservableSupplierImpl<>(); + private final ObservableSupplierImpl<TabContentManager> mTabContentManagerSupplier = + new ObservableSupplierImpl<>(); + private final ObservableSupplierImpl<BrowserControlsStateProvider> + mBrowserControlsStateProviderSupplier = new ObservableSupplierImpl<>(); + private final CompositorModelChangeProcessor.FrameRequestSupplier mFrameRequestSupplier; + /** * Protected class to handle {@link TabModelObserver} related tasks. Extending classes will * need to override any related calls to add new functionality */ @@ -239,8 +249,13 @@ mOverlayPanelManager = new OverlayPanelManager(); + mFrameRequestSupplier = new CompositorModelChangeProcessor.FrameRequestSupplier(this); + + // TODO(crbug.com/1070281): Move this to #init. // Build Layouts - mStaticLayout = new StaticLayout(mContext, this, renderHost, null, mOverlayPanelManager); + mStaticLayout = new StaticLayout(mContext, this, renderHost, mHost, mFrameRequestSupplier, + mTabModelSelectorSupplier, mTabContentManagerSupplier, + mBrowserControlsStateProviderSupplier); // Set up layout parameters mStaticLayout.setLayoutHandlesTabLifecycles(true); @@ -366,11 +381,15 @@ // has its own timer. boolean areAnimatorsComplete = mAnimationHandler.pushUpdate(); + // TODO(crbug.com/1070281): Remove after the FrameRequestSupplier migrates to the animation + // system. final Layout layout = getActiveLayout(); if (layout != null && layout.onUpdate(timeMs, dtMs) && layout.isHiding() && areAnimatorsComplete) { layout.doneHiding(); } + + mFrameRequestSupplier.set(timeMs); return mUpdateRequested; } @@ -410,6 +429,8 @@ // Initialize Layouts mStaticLayout.setTabModelSelector(selector, content); + mTabContentManagerSupplier.set(content); + mBrowserControlsStateProviderSupplier.set(mHost.getBrowserControlsManager()); // Initialize Contextual Search Panel mContextualSearchPanel.setManagementDelegate(contextualSearchDelegate); @@ -432,7 +453,7 @@ public void setTabModelSelector(TabModelSelector selector) { mTabModelSelector = selector; - mStaticLayout.setTabModelSelector(selector, null); + mTabModelSelectorSupplier.set(selector); mTabModelSelectorTabObserver = new TabModelSelectorTabObserver(mTabModelSelector) { @Override public void onShown(Tab tab, @TabSelectionType int type) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java index 22668da..d3902701 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java
@@ -5,28 +5,41 @@ package org.chromium.chrome.browser.compositor.layouts; import android.content.Context; +import android.content.res.Resources; import android.graphics.RectF; import android.os.Handler; +import androidx.annotation.VisibleForTesting; + +import org.chromium.base.Callback; +import org.chromium.base.supplier.ObservableSupplier; import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.compositor.LayerTitleCache; +import org.chromium.chrome.browser.compositor.animation.CompositorAnimationHandler; import org.chromium.chrome.browser.compositor.animation.CompositorAnimator; -import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilter; import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer; import org.chromium.chrome.browser.compositor.scene_layer.StaticTabSceneLayer; +import org.chromium.chrome.browser.native_page.NativePageFactory; +import org.chromium.chrome.browser.tab.SadTab; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tab.TabSelectionType; +import org.chromium.chrome.browser.tab.TabThemeColorHelper; import org.chromium.chrome.browser.tabmodel.TabModelImpl; import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver; +import org.chromium.chrome.browser.toolbar.ToolbarColors; +import org.chromium.components.embedder_support.util.UrlConstants; +import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.resources.ResourceManager; import java.util.Arrays; import java.util.LinkedList; +// TODO(meiliang): Rename to StaticLayoutMediator. /** * A {@link Layout} that shows a single tab at full screen. This tab is chosen based on the * {@link #tabSelecting(long, int)} call, and is used to show a thumbnail of a {@link Tab} @@ -44,40 +57,184 @@ @Override public void run() { mUnstalling = false; - if (mLayoutTabs == null || mLayoutTabs.length == 0) return; CompositorAnimator - .ofWritableFloatPropertyKey(getAnimationHandler(), mLayoutTabs[0], - LayoutTab.SATURATION, mLayoutTabs[0].getSaturation(), 1.0f, - HIDE_DURATION_MS) + .ofWritableFloatPropertyKey(mAnimationHandler, mModel, LayoutTab.SATURATION, + mModel.get(LayoutTab.SATURATION), 1.0f, HIDE_DURATION_MS) .start(); CompositorAnimator - .ofWritableFloatPropertyKey(getAnimationHandler(), mLayoutTabs[0], - LayoutTab.STATIC_TO_VIEW_BLEND, mLayoutTabs[0].getStaticToViewBlend(), - 0.0f, HIDE_DURATION_MS) + .ofWritableFloatPropertyKey(mAnimationHandler, mModel, + LayoutTab.STATIC_TO_VIEW_BLEND, + mModel.get(LayoutTab.STATIC_TO_VIEW_BLEND), 0.0f, HIDE_DURATION_MS) .start(); - mLayoutTabs[0].setShouldStall(false); + mModel.set(LayoutTab.SHOULD_STALL, false); } } + private final Context mContext; + private final LayoutManagerHost mViewHost; + private final CompositorModelChangeProcessor.FrameRequestSupplier mRequestSupplier; + + private final PropertyModel mModel; + private CompositorModelChangeProcessor mMcp; + + private StaticTabSceneLayer mSceneLayer; private final UnstallRunnable mUnstallRunnable; private final Handler mHandler; private boolean mUnstalling; - private StaticTabSceneLayer mSceneLayer; + + private TabModelSelector mTabModelSelector; + private TabModelSelectorTabModelObserver mTabModelSelectorTabModelObserver; + private TabModelSelectorTabObserver mTabModelSelectorTabObserver; + + private BrowserControlsStateProvider mBrowserControlsStateProvider; + private BrowserControlsStateProvider.Observer mBrowserControlsStateProviderObserver; + + private TabContentManager mTabContentManager; + + private final CompositorAnimationHandler mAnimationHandler; + + private boolean mIsActive; + private boolean mIsInitialized; + + private static Integer sToolbarTextBoxBackgroundColorForTesting; + private static Float sToolbarTextBoxAlphaForTesting; + + private float mPxToDp; /** * Creates an instance of the {@link StaticLayout}. * @param context The current Android's context. * @param updateHost The {@link LayoutUpdateHost} view for this layout. * @param renderHost The {@link LayoutRenderHost} view for this layout. - * @param panelManager The {@link OverlayPanelManager} responsible for showing panels. */ public StaticLayout(Context context, LayoutUpdateHost updateHost, LayoutRenderHost renderHost, - EventFilter eventFilter, OverlayPanelManager panelManager) { + LayoutManagerHost viewHost, + CompositorModelChangeProcessor.FrameRequestSupplier requestSupplier, + ObservableSupplier<TabModelSelector> tabModelSelectoSupplier, + ObservableSupplier<TabContentManager> tabContentManagerSupplier, + ObservableSupplier<BrowserControlsStateProvider> browserControlsStateProviderSupplier) { super(context, updateHost, renderHost); + mContext = context; + mViewHost = viewHost; + mRequestSupplier = requestSupplier; + + tabModelSelectoSupplier.addObserver(new Callback<TabModelSelector>() { + @Override + public void onResult(TabModelSelector tabModelSelector) { + setTabModelSelector(tabModelSelector); + tabModelSelectoSupplier.removeObserver(this); + } + }); + + tabContentManagerSupplier.addObserver(new Callback<TabContentManager>() { + @Override + public void onResult(TabContentManager tabContentManager) { + setTabContentManager(tabContentManager); + tabContentManagerSupplier.removeObserver(this); + } + }); + + browserControlsStateProviderSupplier.addObserver( + new Callback<BrowserControlsStateProvider>() { + @Override + public void onResult( + BrowserControlsStateProvider browserControlsStateProvider) { + setBrowserControlsStateProvider(browserControlsStateProvider); + browserControlsStateProviderSupplier.removeObserver(this); + } + }); + + mModel = new PropertyModel.Builder(LayoutTab.ALL_KEYS) + .with(LayoutTab.SCALE, 1.0f) + .with(LayoutTab.X, 0.0f) + .with(LayoutTab.Y, 0.0f) + .with(LayoutTab.RENDER_X, 0.0f) + .with(LayoutTab.RENDER_Y, 0.0f) + .with(LayoutTab.SATURATION, 1.0f) + .with(LayoutTab.STATIC_TO_VIEW_BLEND, 0.0f) + .with(LayoutTab.BRIGHTNESS, 1.0f) + .build(); + + mAnimationHandler = updateHost.getAnimationHandler(); mHandler = new Handler(); mUnstallRunnable = new UnstallRunnable(); mUnstalling = false; + + Resources res = context.getResources(); + float dpToPx = res.getDisplayMetrics().density; + mPxToDp = 1.0f / dpToPx; + } + + private void setTabModelSelector(TabModelSelector tabModelSelector) { + assert tabModelSelector != null; + assert mTabModelSelector == null : "The TabModelSelector should set at most once"; + + mTabModelSelector = tabModelSelector; + // TODO(crbug.com/1070281): Investigating to use ActivityTabProvider instead. + mTabModelSelectorTabModelObserver = new TabModelSelectorTabModelObserver(tabModelSelector) { + @Override + public void didSelectTab(Tab tab, int type, int lastId) { + if (mIsActive) setStaticTab(tab); + } + }; + + mTabModelSelectorTabObserver = new TabModelSelectorTabObserver(tabModelSelector) { + @Override + public void onPageLoadFinished(Tab tab, String url) { + if (mIsActive) unstallImmediately(tab.getId()); + } + @Override + public void onShown(Tab tab, @TabSelectionType int type) { + if (mModel.get(LayoutTab.TAB_ID) != tab.getId()) { + setStaticTab(tab); + } else { + updateStaticTab(tab); + } + } + + @Override + public void onContentChanged(Tab tab) { + updateStaticTab(tab); + } + + @Override + public void onBackgroundColorChanged(Tab tab, int color) { + updateStaticTab(tab); + } + + @Override + public void onDidChangeThemeColor(Tab tab, int color) { + updateStaticTab(tab); + } + }; + } + + private void setTabContentManager(TabContentManager tabContentManager) { + assert tabContentManager != null; + assert mTabContentManager == null : "The TabContentManager should set at most once"; + + mTabContentManager = tabContentManager; + mSceneLayer.setTabContentManager(tabContentManager); + } + + private void setBrowserControlsStateProvider( + BrowserControlsStateProvider browserControlsStateProvider) { + assert browserControlsStateProvider != null; + assert mBrowserControlsStateProvider + == null : "The ChromeFullscreenManager should set at most once"; + + mModel.set(LayoutTab.CONTENT_OFFSET, browserControlsStateProvider.getContentOffset()); + mBrowserControlsStateProvider = browserControlsStateProvider; + mBrowserControlsStateProviderObserver = new BrowserControlsStateProvider.Observer() { + @Override + public void onControlsOffsetChanged(int topOffset, int topControlsMinHeightOffset, + int bottomOffset, int bottomControlsMinHeightOffset, boolean needsAnimate) { + mModel.set( + LayoutTab.CONTENT_OFFSET, browserControlsStateProvider.getContentOffset()); + } + }; + mBrowserControlsStateProvider.addObserver(mBrowserControlsStateProviderObserver); } /** @@ -90,7 +247,16 @@ @Override public void onFinishNativeInitialization() { - mSceneLayer = new StaticTabSceneLayer(); + assert !mIsInitialized : "StaticLayoutMediator should initialize at most once"; + + mIsInitialized = true; + + if (mSceneLayer == null) { + mSceneLayer = new StaticTabSceneLayer(); + } + + mMcp = CompositorModelChangeProcessor.create( + mModel, mSceneLayer, StaticTabSceneLayer::bind, mRequestSupplier); } @Override @@ -107,100 +273,152 @@ public void show(long time, boolean animate) { super.show(time, animate); - mLayoutTabs = null; - setStaticTab(mTabModelSelector.getCurrentTabId()); + mIsActive = true; + Tab tab = mTabModelSelector.getCurrentTab(); + if (tab == null) return; + setStaticTab(tab); } @Override protected void updateLayout(long time, long dt) { super.updateLayout(time, dt); - if (mLayoutTabs != null && mLayoutTabs.length > 0) updateSnap(dt, mLayoutTabs[0]); + updateSnap(dt, mModel); + } + + @Override + public void doneHiding() { + super.doneHiding(); + mIsActive = false; } @Override public void onTabSelected(long time, int id, int prevId, boolean incognito) { - setStaticTab(id); - super.onTabSelected(time, id, prevId, incognito); + } @Override public void onTabSelecting(long time, int id) { - setStaticTab(id); - super.onTabSelecting(time, id); + } @Override public void onTabCreated(long time, int tabId, int tabIndex, int sourceTabId, boolean newIsIncognito, boolean background, float originX, float originY) { - super.onTabCreated( - time, tabId, tabIndex, sourceTabId, newIsIncognito, background, originX, originY); - if (!background) setStaticTab(tabId); + } @Override public void onTabModelSwitched(boolean incognito) { - super.onTabModelSwitched(incognito); - setStaticTab(mTabModelSelector.getCurrentTabId()); + } @Override - public void setTabModelSelector(TabModelSelector modelSelector, TabContentManager manager) { - super.setTabModelSelector(modelSelector, manager); - new TabModelSelectorTabObserver(mTabModelSelector) { - @Override - public void onPageLoadFinished(Tab tab, String url) { - if (isActive()) unstallImmediately(tab.getId()); - } - }; - } + public void setTabModelSelector(TabModelSelector modelSelector, TabContentManager manager) {} private void setPreHideState() { mHandler.removeCallbacks(mUnstallRunnable); - mLayoutTabs[0].setStaticToViewBlend(1.0f); - mLayoutTabs[0].setSaturation(0.0f); + mModel.set(LayoutTab.STATIC_TO_VIEW_BLEND, 1.0f); + mModel.set(LayoutTab.SATURATION, 0.0f); mUnstalling = true; } private void setPostHideState() { mHandler.removeCallbacks(mUnstallRunnable); - mLayoutTabs[0].setStaticToViewBlend(0.0f); - mLayoutTabs[0].setSaturation(1.0f); + mModel.set(LayoutTab.STATIC_TO_VIEW_BLEND, 0.0f); + mModel.set(LayoutTab.SATURATION, 1.0f); mUnstalling = false; } - private void setStaticTab(final int id) { - if (mLayoutTabs != null && mLayoutTabs.length > 0 && mLayoutTabs[0].getId() == id) { - if (!mLayoutTabs[0].shouldStall()) setPostHideState(); + private void setStaticTab(Tab tab) { + assert tab != null; + + if (mModel.get(LayoutTab.TAB_ID) == tab.getId() && !mModel.get(LayoutTab.SHOULD_STALL)) { + setPostHideState(); return; } - TabModel model = mTabModelSelector.getModelForTabId(id); - if (model == null) return; - updateCacheVisibleIdsAndPrimary(new LinkedList<Integer>(Arrays.asList(id)), id); + if (mTabContentManager != null) { + mTabContentManager.updateVisibleIds( + new LinkedList<Integer>(Arrays.asList(tab.getId())), tab.getId()); + } - if (mLayoutTabs == null || mLayoutTabs.length != 1) mLayoutTabs = new LayoutTab[1]; - mLayoutTabs[0] = createLayoutTab(id, model.isIncognito(), NO_CLOSE_BUTTON, NO_TITLE); - mLayoutTabs[0].setDrawDecoration(false); - if (mLayoutTabs[0].shouldStall()) { + mModel.set(LayoutTab.TAB_ID, tab.getId()); + mModel.set(LayoutTab.IS_INCOGNITO, tab.isIncognito()); + mModel.set(LayoutTab.ORIGINAL_CONTENT_WIDTH_IN_DP, mViewHost.getWidth() * mPxToDp); + mModel.set(LayoutTab.ORIGINAL_CONTENT_HEIGHT_IN_DP, mViewHost.getHeight() * mPxToDp); + mModel.set(LayoutTab.MAX_CONTENT_WIDTH, mViewHost.getWidth() * mPxToDp); + mModel.set(LayoutTab.MAX_CONTENT_HEIGHT, mViewHost.getHeight() * mPxToDp); + + updateStaticTab(tab); + + if (mModel.get(LayoutTab.SHOULD_STALL)) { setPreHideState(); mHandler.postDelayed(mUnstallRunnable, HIDE_TIMEOUT_MS); } else { setPostHideState(); } - requestRender(); + } + + private void updateStaticTab(Tab tab) { + if (!mIsActive || mModel.get(LayoutTab.TAB_ID) != tab.getId()) return; + + mModel.set(LayoutTab.BACKGROUND_COLOR, TabThemeColorHelper.getBackgroundColor(tab)); + mModel.set(LayoutTab.TOOLBAR_BACKGROUND_COLOR, + ToolbarColors.getToolbarSceneLayerBackground(tab)); + mModel.set(LayoutTab.TEXT_BOX_ALPHA, getTextBoxAlphaForToolbarBackground(tab)); + mModel.set(LayoutTab.SHOULD_STALL, shouldStall(tab)); + mModel.set(LayoutTab.TEXT_BOX_BACKGROUND_COLOR, getToolbarTextBoxBackgroundColor(tab)); + + String url = tab.getUrlString(); + boolean isNativePage = tab.isNativePage() + || (url != null && url.startsWith(UrlConstants.CHROME_NATIVE_URL_PREFIX)); + boolean canUseLiveTexture = + tab.getWebContents() != null && !SadTab.isShowing(tab) && !isNativePage; + mModel.set(LayoutTab.CAN_USE_LIVE_TEXTURE, canUseLiveTexture); + } + + private int getToolbarTextBoxBackgroundColor(Tab tab) { + if (sToolbarTextBoxBackgroundColorForTesting != null) { + return sToolbarTextBoxBackgroundColorForTesting; + } + + int themeColor = TabThemeColorHelper.getColor(tab); + return ToolbarColors.getTextBoxColorForToolbarBackground( + mContext.getResources(), tab, themeColor); + } + + @VisibleForTesting + void setTextBoxBackgroundColorForTesting(Integer color) { + sToolbarTextBoxBackgroundColorForTesting = color; + } + + private float getTextBoxAlphaForToolbarBackground(Tab tab) { + if (sToolbarTextBoxAlphaForTesting != null) return sToolbarTextBoxAlphaForTesting; + return ToolbarColors.getTextBoxAlphaForToolbarBackground(tab); + } + + @VisibleForTesting + void setToolbarTextBoxAlphaForTesting(Float alpha) { + sToolbarTextBoxAlphaForTesting = alpha; + } + + // Whether the tab is ready to display or it should be faded in as it loads. + private boolean shouldStall(Tab tab) { + return (tab.isFrozen() || tab.needsReload()) + && !NativePageFactory.isNativePageUrl(tab.getUrlString(), tab.isIncognito()); } @Override public void unstallImmediately(int tabId) { - if (mLayoutTabs != null && mLayoutTabs.length > 0 && mLayoutTabs[0].getId() == tabId) { + if (mModel.get(LayoutTab.TAB_ID) == tabId && mModel.get(LayoutTab.SHOULD_STALL) + && mUnstalling) { unstallImmediately(); } } @Override public void unstallImmediately() { - if (mLayoutTabs != null && mLayoutTabs.length > 0 && mLayoutTabs[0].shouldStall() - && mUnstalling) { + if (mModel.get(LayoutTab.SHOULD_STALL) && mUnstalling) { mHandler.removeCallbacks(mUnstallRunnable); mUnstallRunnable.run(); } @@ -244,19 +462,11 @@ resourceManager, browserControls); assert mSceneLayer != null; - final LayoutTab[] tabs = getLayoutTabsToRender(); - if (tabs == null || tabs.length != 1 || tabs[0].getId() == Tab.INVALID_TAB_ID) { - return; - } - LayoutTab layoutTab = tabs[0]; - final float dpToPx = getContext().getResources().getDisplayMetrics().density; - - mSceneLayer.update(dpToPx, layerTitleCache, tabContentManager, browserControls, layoutTab); - - // TODO(dtrainor): Find the best way to properly track this metric for cold starts. - // We should probably erase the thumbnail when we select a tab that we need to restore. + // TODO(dtrainor, crbug.com/1070281): Find the best way to properly track this metric for + // cold starts. We should probably erase the thumbnail when we select a tab that we need to + // restore. Potentially move to show(). if (tabContentManager != null - && tabContentManager.hasFullCachedThumbnail(layoutTab.getId())) { + && tabContentManager.hasFullCachedThumbnail(mModel.get(LayoutTab.TAB_ID))) { TabModelImpl.logPerceivedTabSwitchLatencyMetric(); } } @@ -267,5 +477,43 @@ mSceneLayer.destroy(); mSceneLayer = null; } + if (mMcp != null) { + mMcp.destroy(); + mMcp = null; + } + if (mTabModelSelector != null) { + mTabModelSelectorTabModelObserver.destroy(); + mTabModelSelectorTabObserver.destroy(); + } + } + + @VisibleForTesting + PropertyModel getModelForTesting() { + return mModel; + } + + @VisibleForTesting + void setSceneLayerForTesting(StaticTabSceneLayer sceneLayer) { + mSceneLayer = sceneLayer; + } + + @VisibleForTesting + TabModelSelector getTabModelSelectorForTesting() { + return mTabModelSelector; + } + + @VisibleForTesting + TabContentManager getTabContentManagerForTesting() { + return mTabContentManager; + } + + @VisibleForTesting + BrowserControlsStateProvider getBrowserControlsStateProviderForTesting() { + return mBrowserControlsStateProvider; + } + + @VisibleForTesting + public int getCurrentTabIdForTesting() { + return mModel.get(LayoutTab.TAB_ID); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/LayoutTab.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/LayoutTab.java index 1ab3bcb..b7e8494 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/LayoutTab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/LayoutTab.java
@@ -28,7 +28,7 @@ public static final float SHADOW_ALPHA_ON_LIGHT_BG = 0.8f; public static final float SHADOW_ALPHA_ON_DARK_BG = 1.0f; - private static float sDpToPx; + public static float sDpToPx; private static float sPxToDp; // End section -------------- @@ -158,7 +158,10 @@ // End section -------------- - private static final PropertyKey[] ALL_KEYS = new PropertyKey[] {TAB_ID, IS_INCOGNITO, SCALE, + public static final PropertyModel.WritableFloatPropertyKey CONTENT_OFFSET = + new PropertyModel.WritableFloatPropertyKey(); + + public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {TAB_ID, IS_INCOGNITO, SCALE, TILT_X_IN_DEGREES, TILT_Y_IN_DEGREES, TILT_X_PIVOT_OFFSET, TILT_Y_PIVOT_OFFSET, X, Y, RENDER_X, RENDER_Y, CLIPPED_X, CLIPPED_Y, CLIPPED_WIDTH, CLIPPED_HEIGHT, ALPHA, SATURATION, BORDER_ALPHA, BORDER_CLOSE_BUTTON_ALPHA, BORDER_SCALE, @@ -167,7 +170,8 @@ CAN_USE_LIVE_TEXTURE, SHOW_TOOLBAR, ANONYMIZE_TOOLBAR, TOOLBAR_ALPHA, INSET_BORDER_VERTICAL, TOOLBAR_Y_OFFSET, SIDE_BORDER_SCALE, CLOSE_BUTTON_IS_ON_RIGHT, BOUNDS, CLOSE_PLACEMENT, DECORATION_ALPHA, IS_TITLE_NEEDED, INIT_FROM_HOST_CALLED, - BACKGROUND_COLOR, TOOLBAR_BACKGROUND_COLOR, TEXT_BOX_BACKGROUND_COLOR, TEXT_BOX_ALPHA}; + BACKGROUND_COLOR, TOOLBAR_BACKGROUND_COLOR, TEXT_BOX_BACKGROUND_COLOR, TEXT_BOX_ALPHA, + CONTENT_OFFSET}; /** * Default constructor for a {@link LayoutTab}.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/StaticTabSceneLayer.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/StaticTabSceneLayer.java index 296ac45..840fc9b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/StaticTabSceneLayer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/StaticTabSceneLayer.java
@@ -6,45 +6,59 @@ import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; -import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; -import org.chromium.chrome.browser.compositor.LayerTitleCache; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel; /** * A SceneLayer to render a static tab. */ @JNINamespace("android") public class StaticTabSceneLayer extends SceneLayer { + /** + * ViewBinder for the StaticTabSceneLayer. + * @param model The model to bind. + * @param view The View that the model bind to. + * @param propertyKey The property of the view that changed. This is NULL until SceneLayer is + * able to do partial update. + */ + public static void bind( + PropertyModel model, StaticTabSceneLayer view, PropertyKey propertyKey) { + view.update(model); + } + // NOTE: If you use SceneLayer's native pointer here, the JNI generator will try to // downcast using reinterpret_cast<>. We keep a separate pointer to avoid it. private long mNativePtr; /** - * Update {@link StaticTabSceneLayer} with the given parameters. - * - * @param dpToPx The ratio of dp to px. - * @param contentViewport The viewport of the content. - * @param layerTitleCache The LayerTitleCache. - * @param tabContentManager The TabContentManager. - * @param browserControls The BrowserControlsStateProvider. - * @param layoutTab The LayoutTab. + * Update {@link StaticTabSceneLayer} with the given {@link PropertyModel}. + * @param model The {@link PropertyModel} to use. */ - public void update(float dpToPx, LayerTitleCache layerTitleCache, - TabContentManager tabContentManager, BrowserControlsStateProvider browserControls, - LayoutTab layoutTab) { - if (layoutTab == null) { + public void update(PropertyModel model) { + if (model == null) { return; } - float contentOffset = browserControls != null ? browserControls.getContentOffset() : 0.f; - float x = layoutTab.getRenderX() * dpToPx; - float y = contentOffset + layoutTab.getRenderY() * dpToPx; + float x = model.get(LayoutTab.RENDER_X) * LayoutTab.sDpToPx; + float y = model.get(LayoutTab.CONTENT_OFFSET) + + model.get(LayoutTab.RENDER_Y) * LayoutTab.sDpToPx; StaticTabSceneLayerJni.get().updateTabLayer(mNativePtr, StaticTabSceneLayer.this, - tabContentManager, layoutTab.getId(), layoutTab.canUseLiveTexture(), - layoutTab.getBackgroundColor(), x, y, layoutTab.getStaticToViewBlend(), - layoutTab.getSaturation(), layoutTab.getBrightness()); + model.get(LayoutTab.TAB_ID), model.get(LayoutTab.CAN_USE_LIVE_TEXTURE), + model.get(LayoutTab.BACKGROUND_COLOR), x, y, + model.get(LayoutTab.STATIC_TO_VIEW_BLEND), model.get(LayoutTab.SATURATION), + model.get(LayoutTab.BRIGHTNESS)); + } + + /** + * Set {@link TabContentManager}. + * @param tabContentManager {@link TabContentManager} to set. + */ + public void setTabContentManager(TabContentManager tabContentManager) { + StaticTabSceneLayerJni.get().setTabContentManager( + mNativePtr, StaticTabSceneLayer.this, tabContentManager); } @Override @@ -64,9 +78,10 @@ @NativeMethods interface Natives { long init(StaticTabSceneLayer caller); - void updateTabLayer(long nativeStaticTabSceneLayer, StaticTabSceneLayer caller, - TabContentManager tabContentManager, int id, boolean canUseLiveLayer, - int backgroundColor, float x, float y, float staticToViewBlend, float saturation, - float brightness); + void updateTabLayer(long nativeStaticTabSceneLayer, StaticTabSceneLayer caller, int id, + boolean canUseLiveLayer, int backgroundColor, float x, float y, + float staticToViewBlend, float saturation, float brightness); + void setTabContentManager(long nativeStaticTabSceneLayer, StaticTabSceneLayer caller, + TabContentManager tabContentManager); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabListSceneLayer.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabListSceneLayer.java index f2b51d7c..0a49a2f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabListSceneLayer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabListSceneLayer.java
@@ -35,11 +35,20 @@ private TabModelSelector mTabModelSelector; private int[] mAdditionalIds = new int[4]; private boolean mUseAdditionalIds; + private boolean mIsInitialized; public void setTabModelSelector(TabModelSelector tabModelSelector) { mTabModelSelector = tabModelSelector; } + public void init(LayerTitleCache layerTitleCache, TabContentManager tabContentManager, + ResourceManager resourceManager) { + if (mNativePtr == 0 || mIsInitialized) return; + TabListSceneLayerJni.get().setDependencies(mNativePtr, TabListSceneLayer.this, + tabContentManager, layerTitleCache, resourceManager); + mIsInitialized = true; + } + /** * Pushes all relevant {@link LayoutTab}s from a {@link Layout} to the CC Layer tree. This will * let them be rendered on the screen. This should only be called when the Compositor has @@ -72,11 +81,16 @@ LayoutTab[] tabs = layout.getLayoutTabsToRender(); int tabsCount = tabs != null ? tabs.length : 0; + if (!mIsInitialized) { + init(layerTitleCache, tabContentManager, resourceManager); + } + TabListSceneLayerJni.get().beginBuildingFrame(mNativePtr, TabListSceneLayer.this); + // TODO(crbug.com/1070281): Use Supplier to get viewport and forward it to native, then + // updateLayer can become obsolete. TabListSceneLayerJni.get().updateLayer(mNativePtr, TabListSceneLayer.this, tabListBgColor, - viewport.left, viewport.top, viewport.width(), viewport.height(), layerTitleCache, - tabContentManager, resourceManager); + viewport.left, viewport.top, viewport.width(), viewport.height()); if (backgroundResourceId != INVALID_RESOURCE_ID) { TabListSceneLayerJni.get().putBackgroundLayer(mNativePtr, TabListSceneLayer.this, @@ -189,10 +203,12 @@ long init(TabListSceneLayer caller); void beginBuildingFrame(long nativeTabListSceneLayer, TabListSceneLayer caller); void finishBuildingFrame(long nativeTabListSceneLayer, TabListSceneLayer caller); + void setDependencies(long nativeTabListSceneLayer, TabListSceneLayer caller, + TabContentManager tabContentManager, LayerTitleCache layerTitleCache, + ResourceManager resourceManager); void updateLayer(long nativeTabListSceneLayer, TabListSceneLayer caller, int backgroundColor, float viewportX, float viewportY, float viewportWidth, - float viewportHeight, LayerTitleCache layerTitleCache, - TabContentManager tabContentManager, ResourceManager resourceManager); + float viewportHeight); // TODO(meiliang): Need to provide a resource that indicates the selected tab on the layer. void putTabLayer(long nativeTabListSceneLayer, TabListSceneLayer caller, int selectedId, int[] ids, boolean useAdditionalIds, int toolbarResourceId,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java index af569db..96fcc464 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java
@@ -41,6 +41,7 @@ import org.chromium.chrome.browser.init.StartupTabPreloader; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.InflationObserver; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.RedirectHandlerTabHelper; import org.chromium.chrome.browser.tab.Tab; @@ -102,6 +103,7 @@ private final StartupTabPreloader mStartupTabPreloader; private final ReparentingTaskProvider mReparentingTaskProvider; private final Lazy<CustomTabIncognitoManager> mCustomTabIncognitoManager; + private final ProfileProvider mProfileProvider; @Nullable private final CustomTabsSessionToken mSession; @@ -127,7 +129,8 @@ CustomTabNavigationEventObserver tabNavigationEventObserver, CustomTabActivityTabProvider tabProvider, StartupTabPreloader startupTabPreloader, ReparentingTaskProvider reparentingTaskProvider, - Lazy<CustomTabIncognitoManager> customTabIncognitoManager) { + Lazy<CustomTabIncognitoManager> customTabIncognitoManager, + ProfileProvider profileProvider) { mCustomTabDelegateFactory = customTabDelegateFactory; mActivity = activity; mConnection = connection; @@ -145,6 +148,7 @@ mStartupTabPreloader = startupTabPreloader; mReparentingTaskProvider = reparentingTaskProvider; mCustomTabIncognitoManager = customTabIncognitoManager; + mProfileProvider = profileProvider; mSession = mIntentDataProvider.getSession(); mIntent = mIntentDataProvider.getIntent(); @@ -429,8 +433,10 @@ return mWebContentsFactory.createWebContentsWithWarmRenderer( mCustomTabIncognitoManager.get().getProfile(), false); } else { - return mWebContentsFactory.createWebContentsWithWarmRenderer( - mIntentDataProvider.isIncognito(), false); + Profile profile = mIntentDataProvider.isIncognito() + ? mProfileProvider.getPrimaryOTRProfile() + : mProfileProvider.getLastUsedRegularProfile(); + return mWebContentsFactory.createWebContentsWithWarmRenderer(profile, false); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/ProfileProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/ProfileProvider.java new file mode 100644 index 0000000..535db5d0 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/ProfileProvider.java
@@ -0,0 +1,25 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.customtabs.content; + +import org.chromium.chrome.browser.profiles.Profile; + +import javax.inject.Inject; + +/** + * Wrapper for the Profile class that allows for easier mocking. + */ +public class ProfileProvider { + @Inject + public ProfileProvider() {} + + public Profile getLastUsedRegularProfile() { + return Profile.getLastUsedRegularProfile(); + } + + public Profile getPrimaryOTRProfile() { + return Profile.getLastUsedRegularProfile().getPrimaryOTRProfile(); + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/BaseCustomTabActivityComponent.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/BaseCustomTabActivityComponent.java index 7972d6c..eef7f609 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/BaseCustomTabActivityComponent.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/BaseCustomTabActivityComponent.java
@@ -25,6 +25,7 @@ import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabFactory; import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabProvider; import org.chromium.chrome.browser.customtabs.content.CustomTabIntentHandler; +import org.chromium.chrome.browser.customtabs.content.ProfileProvider; import org.chromium.chrome.browser.customtabs.content.TabObserverRegistrar; import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbarCoordinator; import org.chromium.chrome.browser.dependency_injection.ActivityScope; @@ -59,6 +60,7 @@ CustomTabStatusBarColorProvider resolveCustomTabStatusBarColorProvider(); CustomTabTaskDescriptionHelper resolveTaskDescriptionHelper(); CustomTabToolbarCoordinator resolveToolbarCoordinator(); + ProfileProvider resolveProfileProvider(); TabObserverRegistrar resolveTabObserverRegistrar(); TwaFinishHandler resolveTwaFinishHandler(); Verifier resolveVerifier();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java index 16d0d67..c7a580f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -20,7 +20,6 @@ import androidx.annotation.StringRes; import androidx.annotation.VisibleForTesting; -import org.chromium.base.ActivityState; import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.IntentUtils; @@ -579,8 +578,7 @@ // When invoked directly from a browser, we want to trigger switch to tab animation. // If invoded from other activitiies, ex. searchActivity, we do not need to trigger the // animation since Android will show the animation for switching apps. - if (tab.getWindowAndroid().getActivityState() != ActivityState.STOPPED - && tab.getWindowAndroid().getActivityState() != ActivityState.DESTROYED) { + if (mWindowAndroid.equals(tab.getWindowAndroid())) { // TODO(1097292): Do not use Activity to get TabModelSelector. assert tab.getWindowAndroid().getActivity().get() instanceof ChromeActivity; @@ -591,13 +589,13 @@ chromeActivity.getTabModelSelector().getCurrentModel().setIndex( tabIndex, TabSelectionType.FROM_OMNIBOX); } else { - // Browser is in background, bring to to foreground and switch to the tab. Intent newIntent = ChromeIntentUtil.createBringTabToFrontIntent(tab.getId()); if (newIntent != null) { newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); IntentUtils.safeStartActivity(ContextUtils.getApplicationContext(), newIntent); } } + recordMetrics(position, WindowOpenDisposition.SWITCH_TO_TAB, suggestion); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java index 6488c7be..4d7b810 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialog.java
@@ -16,6 +16,7 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.components.browser_ui.settings.ManagedPreferencesUtils; import org.chromium.components.browser_ui.widget.RadioButtonWithDescription; @@ -106,8 +107,10 @@ mConfirmImportOption.setRadioButtonGroup(radioGroup); mKeepSeparateOption.setRadioButtonGroup(radioGroup); + SigninManager signinManager = IdentityServicesProvider.get().getSigninManager( + Profile.getLastUsedRegularProfile()); // If the account is managed, disallow merging information. - if (IdentityServicesProvider.get().getSigninManager().getManagementDomain() != null) { + if (signinManager.getManagementDomain() != null) { mKeepSeparateOption.setChecked(true); mConfirmImportOption.setOnClickListener( view -> ManagedPreferencesUtils.showManagedByAdministratorToast(getActivity()));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java index 6604006d..ff9c003b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java
@@ -11,6 +11,7 @@ import androidx.annotation.Nullable; import org.chromium.base.ThreadUtils; +import org.chromium.chrome.browser.profiles.Profile; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -172,8 +173,9 @@ } private void requestNewAccountManagementStatus() { - IdentityServicesProvider.get().getSigninManager().isAccountManaged( - mNewAccountName, this::setIsNewAccountManaged); + IdentityServicesProvider.get() + .getSigninManager(Profile.getLastUsedRegularProfile()) + .isAccountManaged(mNewAccountName, this::setIsNewAccountManaged); } private void setIsNewAccountManaged(Boolean isManaged) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDownloader.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDownloader.java index b16fd3e..f6014b1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDownloader.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ProfileDownloader.java
@@ -79,7 +79,7 @@ if (sPendingProfileDownloads == null) { sPendingProfileDownloads = new PendingProfileDownloads(); IdentityServicesProvider.get() - .getAccountTrackerService() + .getAccountTrackerService(Profile.getLastUsedRegularProfile()) .addSystemAccountsSeededListener(sPendingProfileDownloads); } return sPendingProfileDownloads; @@ -125,7 +125,7 @@ ThreadUtils.assertOnUiThread(); Profile profile = Profile.getLastUsedRegularProfile(); if (!IdentityServicesProvider.get() - .getAccountTrackerService() + .getAccountTrackerService(profile) .checkAndSeedSystemAccounts()) { PendingProfileDownloads.get(context).pendProfileDownload( profile, accountId, imageSidePixels);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java index 7484862..1cded3e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SignOutDialogFragment.java
@@ -17,6 +17,7 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.ProfileAccountManagementMetrics; import org.chromium.components.signin.GAIAServiceType; @@ -64,7 +65,9 @@ mGaiaServiceType = getArguments().getInt( SHOW_GAIA_SERVICE_TYPE_EXTRA, mGaiaServiceType); } - String domain = IdentityServicesProvider.get().getSigninManager().getManagementDomain(); + String domain = IdentityServicesProvider.get() + .getSigninManager(Profile.getLastUsedRegularProfile()) + .getManagementDomain(); if (domain != null) { return createDialogForManagedAccount(domain); } @@ -100,7 +103,9 @@ public void onClick(DialogInterface dialog, int which) { if (which == AlertDialog.BUTTON_POSITIVE) { SigninUtils.logEvent(ProfileAccountManagementMetrics.SIGNOUT_SIGNOUT, mGaiaServiceType); - if (IdentityServicesProvider.get().getSigninManager().getManagementDomain() == null) { + SigninManager signinManager = IdentityServicesProvider.get().getSigninManager( + Profile.getLastUsedRegularProfile()); + if (signinManager.getManagementDomain() == null) { RecordHistogram.recordBooleanHistogram( "Signin.UserRequestedWipeDataOnSignout", mWipeUserData.isChecked()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java index e6ffe9922..2bab8a7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java
@@ -140,7 +140,9 @@ callback.run(); return; } - IdentityServicesProvider.get().getSigninManager().signIn( + SigninManager signinManager = IdentityServicesProvider.get().getSigninManager( + Profile.getLastUsedRegularProfile()); + signinManager.signIn( mSigninAccessPoint, account, new SigninManager.SignInCallback() { @Override public void onSignInComplete() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java index b28e514..d9bc9ea 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java
@@ -404,7 +404,8 @@ // as this is needed for the previous account check. final long seedingStartTime = SystemClock.elapsedRealtime(); final AccountTrackerService accountTrackerService = - IdentityServicesProvider.get().getAccountTrackerService(); + IdentityServicesProvider.get().getAccountTrackerService( + Profile.getLastUsedRegularProfile()); if (accountTrackerService.checkAndSeedSystemAccounts()) { recordAccountTrackerServiceSeedingTime(seedingStartTime); runStateMachineAndSignin(settingsClicked); @@ -655,8 +656,9 @@ && mGooglePlayServicesUpdateErrorHandler.isShowing()) { return; } - boolean cancelable = - !IdentityServicesProvider.get().getSigninManager().isForceSigninEnabled(); + boolean cancelable = !IdentityServicesProvider.get() + .getSigninManager(Profile.getLastUsedRegularProfile()) + .isForceSigninEnabled(); mGooglePlayServicesUpdateErrorHandler = new UserRecoverableErrorHandler.ModalDialog(getActivity(), cancelable); mGooglePlayServicesUpdateErrorHandler.handleError(getActivity(), gmsErrorCode);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java index 4cb04dba..6e6028a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
@@ -18,6 +18,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.task.AsyncTask; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.SigninManager.SignInCallback; import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.components.signin.AccountManagerFacadeProvider; @@ -102,8 +103,9 @@ private SigninHelper() { mProfileSyncService = ProfileSyncService.get(); - mSigninManager = IdentityServicesProvider.get().getSigninManager(); - mAccountTrackerService = IdentityServicesProvider.get().getAccountTrackerService(); + Profile profile = Profile.getLastUsedRegularProfile(); + mSigninManager = IdentityServicesProvider.get().getSigninManager(profile); + mAccountTrackerService = IdentityServicesProvider.get().getAccountTrackerService(profile); mPrefsManager = SigninPreferencesManager.getInstance(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java index da86770a..14f5bd2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java
@@ -18,6 +18,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.components.signin.AccountManagerFacadeProvider; import org.chromium.components.signin.AccountUtils; +import org.chromium.components.signin.identitymanager.IdentityManager; import org.chromium.components.signin.metrics.SigninAccessPoint; import org.chromium.components.user_prefs.UserPrefs; import org.chromium.ui.base.WindowAndroid; @@ -46,9 +47,10 @@ List<String> accountNames = AccountUtils.toAccountNames( AccountManagerFacadeProvider.getInstance().tryGetGoogleAccounts()); Supplier<Set<String>> accountNamesSupplier = () -> new ArraySet<>(accountNames); + IdentityManager identityManager = IdentityServicesProvider.get().getIdentityManager( + Profile.getLastUsedRegularProfile()); if (!shouldLaunchSigninPromo(preferencesManager, currentMajorVersion, - IdentityServicesProvider.get().getIdentityManager().hasPrimaryAccount(), - wasSignedIn, accountNamesSupplier)) { + identityManager.hasPrimaryAccount(), wasSignedIn, accountNamesSupplier)) { return false; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninUtils.java index a6dc6e6..e9e0bc1d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninUtils.java
@@ -18,6 +18,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.account_picker.AccountPickerBottomSheetCoordinator; import org.chromium.chrome.browser.signin.account_picker.AccountPickerDelegate; import org.chromium.chrome.browser.sync.settings.AccountManagementFragment; @@ -75,7 +76,9 @@ private static void openAccountPickerBottomSheet( WindowAndroid windowAndroid, String continueUrl) { ThreadUtils.assertOnUiThread(); - if (IdentityServicesProvider.get().getSigninManager().isSignInAllowed()) { + SigninManager signinManager = IdentityServicesProvider.get().getSigninManager( + Profile.getLastUsedRegularProfile()); + if (signinManager.isSignInAllowed()) { ChromeActivity activity = (ChromeActivity) windowAndroid.getActivity().get(); AccountPickerBottomSheetCoordinator coordinator = new AccountPickerBottomSheetCoordinator(activity, @@ -91,7 +94,8 @@ */ public static boolean startSigninActivityIfAllowed( Context context, @SigninAccessPoint int accessPoint) { - SigninManager signinManager = IdentityServicesProvider.get().getSigninManager(); + SigninManager signinManager = IdentityServicesProvider.get().getSigninManager( + Profile.getLastUsedRegularProfile()); if (signinManager.isSignInAllowed()) { SigninActivityLauncher.get().launchActivity(context, accessPoint); return true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegate.java index dac4fc40..970a460c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/account_picker/AccountPickerDelegate.java
@@ -11,6 +11,7 @@ import org.chromium.base.task.PostTask; import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.IdentityServicesProvider; import org.chromium.chrome.browser.signin.SigninManager; import org.chromium.chrome.browser.signin.SigninUtils; @@ -31,12 +32,15 @@ private final ChromeActivity mChromeActivity; private final Tab mTab; private final String mContinueUrl; + private final SigninManager mSigninManager; public AccountPickerDelegate(ChromeActivity chromeActivity, String continueUrl) { mChromeActivity = chromeActivity; // TODO(https://crbug.com/1095554): Check if website redirects after sign-in mTab = mChromeActivity.getActivityTab(); mContinueUrl = continueUrl; + mSigninManager = IdentityServicesProvider.get().getSigninManager( + Profile.getLastUsedRegularProfile()); } /** * Signs the user into the account of the given accountName. @@ -44,7 +48,7 @@ public void signIn(String accountName) { Account account = AccountUtils.findAccountByName( AccountManagerFacadeProvider.getInstance().tryGetGoogleAccounts(), accountName); - IdentityServicesProvider.get().getSigninManager().signIn( + mSigninManager.signIn( SigninAccessPoint.WEB_SIGNIN, account, new SigninManager.SignInCallback() { @Override public void onSignInComplete() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java index 782cc37..bc72e28 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
@@ -36,6 +36,7 @@ import org.chromium.chrome.browser.accessibility_tab_switcher.OverviewListLayout; import org.chromium.chrome.browser.compositor.animation.CompositorAnimationHandler; import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; +import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; import org.chromium.chrome.browser.compositor.layouts.eventfilter.ScrollDirection; import org.chromium.chrome.browser.compositor.layouts.phone.StackLayout; @@ -152,6 +153,8 @@ } mTabModelSelector.selectModel(incognitoSelected); LayoutManagerHost layoutManagerHost = new MockLayoutHost(context); + TabContentManager tabContentManager = new TabContentManager(context, null, false, null); + tabContentManager.initWithNative(); // Build a fake content container FrameLayout parentContainer = new FrameLayout(context); @@ -161,7 +164,7 @@ mManagerPhone = new LayoutManagerChromePhone(layoutManagerHost, null); mManager = mManagerPhone; CompositorAnimationHandler.setTestingMode(true); - mManager.init(mTabModelSelector, null, null, container, null, null, null); + mManager.init(mTabModelSelector, null, tabContentManager, container, null, null, null); initializeMotionEvent(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/SwitchToTabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/SwitchToTabTest.java index 5398a26..c87a762 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/SwitchToTabTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/SwitchToTabTest.java
@@ -8,6 +8,7 @@ import android.app.Instrumentation; import android.app.Instrumentation.ActivityMonitor; import android.content.Intent; +import android.os.Build; import android.support.test.InstrumentationRegistry; import android.util.Pair; import android.view.ViewGroup; @@ -23,9 +24,8 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.chromium.base.ActivityState; -import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisableIf; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.flags.ChromeSwitches; @@ -42,7 +42,6 @@ import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; -import org.chromium.content_public.browser.test.util.CriteriaNotSatisfiedException; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TestTouchUtils; import org.chromium.net.test.EmbeddedTestServer; @@ -95,47 +94,30 @@ * * @param activity The Activity which url_bar is in. * @param locationBarLayout The layout which omnibox suggestions will show in. - * @param input The text will be typed into url_bar. - * @param expectedMatchUrl The expected url to visit after clicking tab switch button. + * @param text The text will be typed into url_bar. */ - private void typeAndClickMatchingTabMatchSuggestion(Activity activity, - LocationBarLayout locationBarLayout, String input, String expectedMatchUrl) - throws InterruptedException { + private void typeAndWaitForTabMatchSuggestions(Activity activity, + LocationBarLayout locationBarLayout, String input) throws InterruptedException { typeInOmnibox(activity, input); OmniboxTestUtils.waitForOmniboxSuggestions(locationBarLayout); // waitForOmniboxSuggestions only wait until one suggestion shows up, we need to wait util // autocomplete return more suggestions. CriteriaHelper.pollUiThread(() -> { - Pair<Integer, OmniboxSuggestion> matchSuggestion = - findFirstTabMatchOmniboxSuggestion(locationBarLayout); - - Criteria.checkThat(matchSuggestion.first, Matchers.not(INVALID_INDEX)); - Criteria.checkThat( - matchSuggestion.second.getUrl().getSpec(), Matchers.is(expectedMatchUrl)); - - OmniboxSuggestionsDropdown suggestionsDropdown = - AutocompleteCoordinatorTestUtils.getSuggestionsDropdown( - locationBarLayout.getAutocompleteCoordinator()); - try { - clickSuggestionActionAt(suggestionsDropdown, matchSuggestion.first); - } catch (InterruptedException e) { - throw new CriteriaNotSatisfiedException(e); - } + Criteria.checkThat(findFirstTabMatchOmniboxSuggestion(locationBarLayout).first, + Matchers.not(INVALID_INDEX)); }); } /** * Find the first switch to tab suggestion in the omnibox suggestion list, and return the - * suggestion and its index. This method needs to run on the UI thread. + * suggestion and its index. * * @param locationBarLayout The layout which omnibox suggestions will show in. - * @return The first switch to tab suggestion's index, and the suggesstion. + * @return The the first switch to tab suggestion's index, and the suggesstion. */ private Pair<Integer, OmniboxSuggestion> findFirstTabMatchOmniboxSuggestion( LocationBarLayout locationBarLayout) { - ThreadUtils.assertOnUiThread(); - OmniboxSuggestionsDropdown suggestionsDropdown = AutocompleteCoordinatorTestUtils.getSuggestionsDropdown( locationBarLayout.getAutocompleteCoordinator()); @@ -189,6 +171,9 @@ @Test @MediumTest + @DisableIf.Build(message = "https://crbug.com/1101433", + sdk_is_greater_than = Build.VERSION_CODES.LOLLIPOP_MR1, + sdk_is_less_than = Build.VERSION_CODES.N) @EnableFeatures("OmniboxTabSwitchSuggestions") public void testSwitchToTabSuggestion() throws InterruptedException { @@ -204,8 +189,20 @@ LocationBarLayout locationBarLayout = (LocationBarLayout) mActivityTestRule.getActivity().findViewById(R.id.location_bar); - typeAndClickMatchingTabMatchSuggestion( - mActivityTestRule.getActivity(), locationBarLayout, "about", testHttpsUrl1); + typeAndWaitForTabMatchSuggestions( + mActivityTestRule.getActivity(), locationBarLayout, "about"); + + Pair<Integer, OmniboxSuggestion> matchSuggestion = + findFirstTabMatchOmniboxSuggestion(locationBarLayout); + + Assert.assertNotEquals(INVALID_INDEX, (int) matchSuggestion.first); + Assert.assertNotNull("No Switch to Tab suggestion returned.", matchSuggestion.second); + Assert.assertEquals(matchSuggestion.second.getUrl().getSpec(), testHttpsUrl1); + + OmniboxSuggestionsDropdown suggestionsDropdown = + AutocompleteCoordinatorTestUtils.getSuggestionsDropdown( + locationBarLayout.getAutocompleteCoordinator()); + clickSuggestionActionAt(suggestionsDropdown, (int) matchSuggestion.first); CriteriaHelper.pollUiThread(() -> { Tab tab = mActivityTestRule.getActivity().getActivityTab(); @@ -238,18 +235,17 @@ mActivityTestRule.typeInOmnibox("about", false); OmniboxTestUtils.waitForOmniboxSuggestions(locationBarLayout); - CriteriaHelper.pollUiThread(() -> { - Pair<Integer, OmniboxSuggestion> matchSuggestion = - findFirstTabMatchOmniboxSuggestion(locationBarLayout); + Pair<Integer, OmniboxSuggestion> matchSuggestion = + findFirstTabMatchOmniboxSuggestion(locationBarLayout); - Criteria.checkThat(matchSuggestion.first, Matchers.is(INVALID_INDEX)); - }); + Assert.assertNull( + "Should no Switch to Incognito Tab from normal tab.", matchSuggestion.second); } @Test @MediumTest @EnableFeatures("OmniboxTabSwitchSuggestions") - public void testSwitchToTabInSearchActivity() throws InterruptedException { + public void testSwitchToTabInSearchActiviy() throws InterruptedException { mTestServer = EmbeddedTestServer.createAndStartHTTPSServer( InstrumentationRegistry.getInstrumentation().getContext(), ServerCertificate.CERT_OK); @@ -261,26 +257,30 @@ mActivityTestRule.loadUrlInNewTab(testHttpsUrl3); final SearchActivity searchActivity = startSearchActivity(); - CriteriaHelper.pollUiThread(() -> { - Tab tab = mActivityTestRule.getActivity().getActivityTab(); - Criteria.checkThat(tab, Matchers.notNullValue()); - // Make sure chrome fully in background. - Criteria.checkThat(tab.getWindowAndroid().getActivityState(), - Matchers.isOneOf(ActivityState.STOPPED, ActivityState.DESTROYED)); - }); final LocationBarLayout locationBarLayout = (LocationBarLayout) searchActivity.findViewById(R.id.search_location_bar); - typeAndClickMatchingTabMatchSuggestion( - searchActivity, locationBarLayout, "about", testHttpsUrl1); + typeAndWaitForTabMatchSuggestions(searchActivity, locationBarLayout, "about"); + + Pair<Integer, OmniboxSuggestion> matchSuggestion = + findFirstTabMatchOmniboxSuggestion(locationBarLayout); + + Assert.assertNotEquals(INVALID_INDEX, (int) matchSuggestion.first); + Assert.assertNotNull("No Switch to Tab suggestion returned.", matchSuggestion.second); + Assert.assertEquals(matchSuggestion.second.getUrl().getSpec(), testHttpsUrl1); + + OmniboxSuggestionsDropdown suggestionsDropdown = + AutocompleteCoordinatorTestUtils.getSuggestionsDropdown( + locationBarLayout.getAutocompleteCoordinator()); + clickSuggestionActionAt(suggestionsDropdown, (int) matchSuggestion.first); CriteriaHelper.pollUiThread(() -> { Tab tab = mActivityTestRule.getActivity().getActivityTab(); - Criteria.checkThat(tab, Matchers.notNullValue()); - Criteria.checkThat(tab.getUrlString(), Matchers.is(testHttpsUrl1)); - // Make sure tab is loaded and in foreground. - Criteria.checkThat( - tab.getWindowAndroid().getActivityState(), Matchers.is(ActivityState.RESUMED)); + if (tab == null) return false; + // Make sure tab is in either upload page or result page. cannot only verify one of + // them since on fast device tab jump to result page really quick but on slow device + // may stay on upload page for a really long time. + return tab.getUrlString().equals(testHttpsUrl1); }); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/profiles/ProfileTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/profiles/ProfileTest.java index 05f4a631..3ca00b22 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/profiles/ProfileTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/profiles/ProfileTest.java
@@ -58,6 +58,7 @@ Profile incognitoProfile1 = mRegularProfile.getPrimaryOTRProfile(); Assert.assertTrue(incognitoProfile1.isOffTheRecord()); + Assert.assertTrue(incognitoProfile1.isPrimaryOTRProfile()); Assert.assertTrue(incognitoProfile1.isNativeInitialized()); Assert.assertTrue(mRegularProfile.hasPrimaryOTRProfile()); @@ -80,6 +81,7 @@ Profile nonPrimaryOtrProfile1 = mRegularProfile.getOffTheRecordProfile(profileID); Assert.assertTrue(nonPrimaryOtrProfile1.isOffTheRecord()); + Assert.assertFalse(nonPrimaryOtrProfile1.isPrimaryOTRProfile()); Assert.assertTrue(nonPrimaryOtrProfile1.isNativeInitialized()); Assert.assertTrue(mRegularProfile.hasOffTheRecordProfile(profileID)); Assert.assertFalse(mRegularProfile.hasPrimaryOTRProfile()); @@ -108,10 +110,12 @@ Profile nonPrimaryOtrProfile2 = mRegularProfile.getOffTheRecordProfile(profileID2); Assert.assertTrue(nonPrimaryOtrProfile1.isOffTheRecord()); + Assert.assertFalse(nonPrimaryOtrProfile1.isPrimaryOTRProfile()); Assert.assertTrue(nonPrimaryOtrProfile1.isNativeInitialized()); Assert.assertTrue(mRegularProfile.hasOffTheRecordProfile(profileID1)); Assert.assertTrue(nonPrimaryOtrProfile2.isOffTheRecord()); + Assert.assertFalse(nonPrimaryOtrProfile2.isPrimaryOTRProfile()); Assert.assertTrue(nonPrimaryOtrProfile2.isNativeInitialized()); Assert.assertTrue(mRegularProfile.hasOffTheRecordProfile(profileID2));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ConfirmSyncDataIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ConfirmSyncDataIntegrationTest.java index 651887f..39c5ea9b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ConfirmSyncDataIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/ConfirmSyncDataIntegrationTest.java
@@ -35,6 +35,7 @@ import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.DummyUiActivityTestCase; @@ -71,6 +72,9 @@ @Mock private ConfirmSyncDataStateMachine.Listener mListenerMock; + @Mock + private Profile mProfile; + private ConfirmSyncDataStateMachineDelegate mDelegate; @Before @@ -78,7 +82,8 @@ initMocks(this); mocker.mock(SigninManagerJni.TEST_HOOKS, mSigninManagerNativeMock); IdentityServicesProvider.setInstanceForTests(mIdentityServicesProviderMock); - when(IdentityServicesProvider.get().getSigninManager()).thenReturn(mSigninManagerMock); + Profile.setLastUsedProfileForTesting(mProfile); + when(IdentityServicesProvider.get().getSigninManager(any())).thenReturn(mSigninManagerMock); mDelegate = new ConfirmSyncDataStateMachineDelegate(getActivity().getSupportFragmentManager()); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/IdentityManagerIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/IdentityManagerIntegrationTest.java index ab89d09..1b994f18 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/IdentityManagerIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/IdentityManagerIntegrationTest.java
@@ -14,6 +14,7 @@ import org.junit.runner.RunWith; import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule; import org.chromium.components.signin.AccountManagerFacadeProvider; import org.chromium.components.signin.ChromeSigninController; @@ -58,9 +59,10 @@ mAccountManagerTestRule.waitForSeeding(); TestThreadUtils.runOnUiThreadBlocking(() -> { + Profile profile = Profile.getLastUsedRegularProfile(); mIdentityMutator = - IdentityServicesProvider.get().getSigninManager().getIdentityMutator(); - mIdentityManager = IdentityServicesProvider.get().getIdentityManager(); + IdentityServicesProvider.get().getSigninManager(profile).getIdentityMutator(); + mIdentityManager = IdentityServicesProvider.get().getIdentityManager(profile); }); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SignOutDialogRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SignOutDialogRenderTest.java index ec5e012e..05bc9c9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SignOutDialogRenderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SignOutDialogRenderTest.java
@@ -8,6 +8,7 @@ import static androidx.test.espresso.action.ViewActions.pressBack; import static androidx.test.espresso.matcher.ViewMatchers.isRoot; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @@ -28,6 +29,7 @@ import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.ChromeRenderTestRule; import org.chromium.components.signin.GAIAServiceType; @@ -58,12 +60,16 @@ @Mock private SigninManager mSigninManagerMock; + @Mock + private Profile mProfile; + @Before public void setUp() { initMocks(this); mocker.mock(SigninUtilsJni.TEST_HOOKS, mSigninUtilsNativeMock); + Profile.setLastUsedProfileForTesting(mProfile); IdentityServicesProvider.setInstanceForTests(mock(IdentityServicesProvider.class)); - when(IdentityServicesProvider.get().getSigninManager()).thenReturn(mSigninManagerMock); + when(IdentityServicesProvider.get().getSigninManager(any())).thenReturn(mSigninManagerMock); } @After
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFragmentTest.java index 9d5f529..910103c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFragmentTest.java
@@ -39,6 +39,7 @@ import org.chromium.base.test.util.Matchers; import org.chromium.chrome.R; import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.chrome.browser.sync.SyncTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -159,7 +160,7 @@ // Wait for sign in process to finish. CriteriaHelper.pollUiThread(() -> { return IdentityServicesProvider.get() - .getSigninManager() + .getSigninManager(Profile.getLastUsedRegularProfile()) .getIdentityManager() .hasPrimaryAccount(); }, CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL, CriteriaHelper.DEFAULT_POLLING_INTERVAL);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninSignoutIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninSignoutIntegrationTest.java index 6aacaba7..609e02bb 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninSignoutIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninSignoutIntegrationTest.java
@@ -94,8 +94,10 @@ initMocks(this); mocker.mock(SigninUtilsJni.TEST_HOOKS, mSigninUtilsNativeMock); mActivityTestRule.startMainActivityOnBlankPage(); - TestThreadUtils.runOnUiThreadBlocking( - () -> { mSigninManager = IdentityServicesProvider.get().getSigninManager(); }); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mSigninManager = IdentityServicesProvider.get().getSigninManager( + Profile.getLastUsedRegularProfile()); + }); mSigninManager.addSignInStateObserver(mSignInStateObserverMock); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/CompositorModelChangeProcessorUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/CompositorModelChangeProcessorUnitTest.java index d50baf4..5b33562 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/CompositorModelChangeProcessorUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/CompositorModelChangeProcessorUnitTest.java
@@ -37,7 +37,7 @@ @Mock private PropertyModelChangeProcessor.ViewBinder mViewBinder; @Mock - private LayoutManagerHost mLayoutManagerHost; + private LayoutUpdateHost mLayoutUpdateHost; private CompositorModelChangeProcessor.FrameRequestSupplier mFrameSupplier; private CompositorModelChangeProcessor mCompositorMCP; @@ -48,8 +48,7 @@ public void setUp() { MockitoAnnotations.initMocks(this); - mFrameSupplier = - new CompositorModelChangeProcessor.FrameRequestSupplier(mLayoutManagerHost); + mFrameSupplier = new CompositorModelChangeProcessor.FrameRequestSupplier(mLayoutUpdateHost); mModel = new PropertyModel(PROPERTY_CHANGED); mCompositorMCP = CompositorModelChangeProcessor.create( @@ -59,7 +58,7 @@ @Test public void testBindAndRequestFrame() { mModel.set(PROPERTY_CHANGED, mPropertyChangedValue.getAndSet(!mPropertyChangedValue.get())); - verify(mLayoutManagerHost).requestRender(); + verify(mLayoutUpdateHost).requestUpdate(); mFrameSupplier.set(System.currentTimeMillis()); verify(mViewBinder).bind(eq(mModel), eq(mView), eq(null)); @@ -70,14 +69,14 @@ mFrameSupplier.set(System.currentTimeMillis()); verify(mViewBinder).bind(eq(mModel), eq(mView), eq(null)); - verify(mLayoutManagerHost, never()).requestRender(); + verify(mLayoutUpdateHost, never()).requestUpdate(); } @Test public void testRequestFrameAndNoBindOnPropertyChanged() { mModel.set(PROPERTY_CHANGED, mPropertyChangedValue.getAndSet(!mPropertyChangedValue.get())); - verify(mLayoutManagerHost).requestRender(); + verify(mLayoutUpdateHost).requestUpdate(); verify(mViewBinder, never()).bind(any(), any(), any()); } } \ No newline at end of file
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/StaticLayoutUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/StaticLayoutUnitTest.java new file mode 100644 index 0000000..f8ed861 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/layouts/StaticLayoutUnitTest.java
@@ -0,0 +1,342 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.compositor.layouts; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Color; +import android.util.DisplayMetrics; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +import org.chromium.base.UserDataHost; +import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; +import org.chromium.chrome.browser.compositor.animation.CompositorAnimationHandler; +import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; +import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; +import org.chromium.chrome.browser.compositor.scene_layer.StaticTabSceneLayer; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tab.TabObserver; +import org.chromium.chrome.browser.tab.TabSelectionType; +import org.chromium.chrome.browser.tab.TabThemeColorHelper; +import org.chromium.chrome.browser.tabmodel.TabModel; +import org.chromium.chrome.browser.tabmodel.TabModelObserver; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.content_public.browser.WebContents; +import org.chromium.ui.modelutil.PropertyModel; + +import java.util.Arrays; +import java.util.LinkedList; + +/** + * Unit tests for {@link StaticLayout}. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class StaticLayoutUnitTest { + private static final int TAB1_ID = 456; + private static final int TAB2_ID = 789; + private static final int POSITION1 = 0; + private static final int POSITION2 = 1; + private static final String TAB1_URL = "https://tab1.com"; + private static final String TAB2_URL = "https://tab2.com"; + + private static final int BACKGROUND_COLOR = Color.WHITE; + private static final int TOOLBAR_BACKGROUND_COLOR = Color.BLUE; + private static final int TEXT_BOX_BACKGROUND_COLOR = Color.BLACK; + private static final float TEXT_BOX_ALPHA = 1.0f; + private static final int WIDTH = 9; + private static final int HEIGHT = 16; + + @Mock + private Context mContext; + @Mock + private Resources mResource; + @Mock + private DisplayMetrics mDisplayMetrics; + @Mock + private LayoutUpdateHost mUpdateHost; + @Mock + private LayoutRenderHost mRenderHost; + @Mock + private LayoutManagerHost mViewHost; + @Mock + private CompositorModelChangeProcessor.FrameRequestSupplier mRequestSupplier; + @Mock + StaticTabSceneLayer mStaticTabSceneLayer; + + @Mock + private TabContentManager mTabContentManager; + + @Mock + private TabModelSelector mTabModelSelector; + @Mock + private TabModel mTabModel; + @Captor + private ArgumentCaptor<TabModelObserver> mTabModelObserverCaptor; + + @Mock + private BrowserControlsStateProvider mBrowserControlsStateProvider; + @Captor + private ArgumentCaptor<BrowserControlsStateProvider.Observer> + mBrowserControlsStateProviderObserverCaptor; + + private UserDataHost mUserDataHost = new UserDataHost(); + @Mock + private TabThemeColorHelper mTabThemeColorHelper; + + private Tab mTab1; + private Tab mTab2; + @Captor + private ArgumentCaptor<TabObserver> mTabObserverCaptor; + + private CompositorAnimationHandler mCompositorAnimationHandler; + private ObservableSupplierImpl<TabModelSelector> mTabModelSelectoSupplier = + new ObservableSupplierImpl<>(); + private ObservableSupplierImpl<TabContentManager> mTabContentManagerSupplier = + new ObservableSupplierImpl<>(); + private ObservableSupplierImpl<BrowserControlsStateProvider> + mBrowserControlsStateProviderSupplier = new ObservableSupplierImpl<>(); + + private StaticLayout mStaticLayout; + private PropertyModel mModel; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mCompositorAnimationHandler = new CompositorAnimationHandler(mUpdateHost); + CompositorAnimationHandler.setTestingMode(true); + + mTab1 = prepareTab(TAB1_ID, TAB1_URL); + mTab2 = prepareTab(TAB2_ID, TAB2_URL); + + doReturn(mResource).when(mContext).getResources(); + doReturn(mDisplayMetrics).when(mResource).getDisplayMetrics(); + mDisplayMetrics.density = 1; + + doReturn(mTabModel).when(mTabModel).getComprehensiveModel(); + doReturn(2).when(mTabModel).getCount(); + doReturn(mTab1).when(mTabModel).getTabAt(0); + doReturn(mTab2).when(mTabModel).getTabAt(1); + doNothing().when(mTab1).addObserver(mTabObserverCaptor.capture()); + doNothing().when(mTab2).addObserver(mTabObserverCaptor.capture()); + doReturn(POSITION1).when(mTabModel).indexOf(mTab1); + doReturn(POSITION2).when(mTabModel).indexOf(mTab2); + doReturn(POSITION1).when(mTabModel).index(); + + doReturn(mTab1).when(mTabModelSelector).getCurrentTab(); + doReturn(Arrays.asList(mTabModel)).when(mTabModelSelector).getModels(); + doNothing().when(mTabModel).addObserver(mTabModelObserverCaptor.capture()); + + doNothing().when(mRequestSupplier).request(); + doNothing() + .when(mBrowserControlsStateProvider) + .addObserver(mBrowserControlsStateProviderObserverCaptor.capture()); + doNothing().when(mTabContentManager).updateVisibleIds(any(), anyInt()); + doReturn(WIDTH).when(mViewHost).getWidth(); + doReturn(HEIGHT).when(mViewHost).getHeight(); + doReturn(mCompositorAnimationHandler).when(mUpdateHost).getAnimationHandler(); + + mStaticLayout = new StaticLayout(mContext, mUpdateHost, mRenderHost, mViewHost, + mRequestSupplier, mTabModelSelectoSupplier, mTabContentManagerSupplier, + mBrowserControlsStateProviderSupplier); + mModel = mStaticLayout.getModelForTesting(); + + mStaticLayout.setSceneLayerForTesting(mStaticTabSceneLayer); + mStaticLayout.onFinishNativeInitialization(); + + mUserDataHost.setUserData(TabThemeColorHelper.class, mTabThemeColorHelper); + doReturn(BACKGROUND_COLOR).when(mTabThemeColorHelper).getBackgroundColor(); + doReturn(TOOLBAR_BACKGROUND_COLOR).when(mTabThemeColorHelper).getColor(); + mStaticLayout.setTextBoxBackgroundColorForTesting(TEXT_BOX_BACKGROUND_COLOR); + mStaticLayout.setToolbarTextBoxAlphaForTesting(TEXT_BOX_ALPHA); + + initAndAssertAllDependencies(); + + mStaticLayout.show(System.currentTimeMillis(), false); + } + + @After + public void tearDown() { + CompositorAnimationHandler.setTestingMode(false); + mUserDataHost.removeUserData(TabThemeColorHelper.class); + mStaticLayout.setSceneLayerForTesting(null); + mStaticLayout.setTextBoxBackgroundColorForTesting(null); + mStaticLayout.setToolbarTextBoxAlphaForTesting(null); + mStaticLayout.destroy(); + } + + private void initAndAssertAllDependencies() { + assertNull(mStaticLayout.getTabModelSelectorForTesting()); + mTabModelSelectoSupplier.set(mTabModelSelector); + assertEquals(mTabModelSelector, mStaticLayout.getTabModelSelectorForTesting()); + + assertNull(mStaticLayout.getTabContentManagerForTesting()); + mTabContentManagerSupplier.set(mTabContentManager); + assertEquals(mTabContentManager, mStaticLayout.getTabContentManagerForTesting()); + + assertNull(mStaticLayout.getBrowserControlsStateProviderForTesting()); + mBrowserControlsStateProviderSupplier.set(mBrowserControlsStateProvider); + assertEquals(mBrowserControlsStateProvider, + mStaticLayout.getBrowserControlsStateProviderForTesting()); + } + + private Tab prepareTab(int id, String url) { + Tab tab = mock(Tab.class); + doReturn(id).when(tab).getId(); + doReturn(false).when(tab).isIncognito(); + doReturn(url).when(tab).getUrlString(); + doReturn(false).when(tab).isNativePage(); + doReturn(mock(WebContents.class)).when(tab).getWebContents(); + doReturn(true).when(tab).isInitialized(); + when(tab.getUserDataHost()).thenReturn(mUserDataHost); + return tab; + } + + private TabModelObserver getTabModelSelectorTabModelObserverFromCaptor() { + // Index 1 captured the TabModelSelectorTabObserver. + return mTabModelObserverCaptor.getAllValues().get(0); + } + + @Test + public void testBrowserControlsContentOffsetChanged() { + final int offset = 10; + doReturn(offset).when(mBrowserControlsStateProvider).getContentOffset(); + mBrowserControlsStateProviderObserverCaptor.getValue().onControlsOffsetChanged( + offset, offset, 0, 0, true); + assertEquals(offset, (int) mModel.get(LayoutTab.CONTENT_OFFSET)); + } + + @Test + public void testTabSelection() { + assertNotEquals(mTab2.getId(), mModel.get(LayoutTab.TAB_ID)); + + getTabModelSelectorTabModelObserverFromCaptor().didSelectTab( + mTab2, TabSelectionType.FROM_USER, TAB1_ID); + + assertEquals(mTab2.getId(), mModel.get(LayoutTab.TAB_ID)); + assertFalse(mModel.get(LayoutTab.SHOULD_STALL)); + assertEquals(0.0f, mModel.get(LayoutTab.STATIC_TO_VIEW_BLEND), 0); + assertEquals(1.0f, mModel.get(LayoutTab.SATURATION), 0); + } + + @Test + public void testTabSelection_Stall() { + doReturn(true).when(mTab2).isFrozen(); + + getTabModelSelectorTabModelObserverFromCaptor().didSelectTab( + mTab2, TabSelectionType.FROM_USER, TAB1_ID); + + assertTrue(mModel.get(LayoutTab.SHOULD_STALL)); + assertEquals(1.0f, mModel.get(LayoutTab.STATIC_TO_VIEW_BLEND), 0); + assertEquals(0.0f, mModel.get(LayoutTab.SATURATION), 0); + } + + @Test + public void testTabSelection_SameTab() { + getTabModelSelectorTabModelObserverFromCaptor().didSelectTab( + mTab1, TabSelectionType.FROM_USER, TAB1_ID); + + assertFalse(mModel.get(LayoutTab.SHOULD_STALL)); + assertEquals(0.0f, mModel.get(LayoutTab.STATIC_TO_VIEW_BLEND), 0); + assertEquals(1.0f, mModel.get(LayoutTab.SATURATION), 0); + } + + @Test + public void testOnPageLoadFinished() { + doReturn(true).when(mTab2).isFrozen(); + getTabModelSelectorTabModelObserverFromCaptor().didSelectTab( + mTab2, TabSelectionType.FROM_USER, TAB1_ID); + assertTrue(mModel.get(LayoutTab.SHOULD_STALL)); + assertEquals(1.0f, mModel.get(LayoutTab.STATIC_TO_VIEW_BLEND), 0); + assertEquals(0.0f, mModel.get(LayoutTab.SATURATION), 0); + + // Index 1 is the TabObserver for mTab2. + mTabObserverCaptor.getAllValues().get(1).onPageLoadFinished(mTab2, TAB2_URL); + + assertFalse(mModel.get(LayoutTab.SHOULD_STALL)); + assertEquals(0.0f, mModel.get(LayoutTab.STATIC_TO_VIEW_BLEND), 0); + assertEquals(1.0f, mModel.get(LayoutTab.SATURATION), 0); + } + + @Test + public void testTabOnShown() { + assertNotEquals(TAB2_ID, mModel.get(LayoutTab.TAB_ID)); + + // Index 1 is the TabObserver for mTab2. + mTabObserverCaptor.getAllValues().get(1).onShown(mTab2, TabSelectionType.FROM_USER); + assertEquals(TAB2_ID, mModel.get(LayoutTab.TAB_ID)); + assertTrue(mModel.get(LayoutTab.CAN_USE_LIVE_TEXTURE)); + assertEquals(0.0f, mModel.get(LayoutTab.STATIC_TO_VIEW_BLEND), 0); + + LinkedList visibleIdList = new LinkedList<Integer>(Arrays.asList(TAB2_ID)); + verify(mTabContentManager).updateVisibleIds(eq(visibleIdList), eq(TAB2_ID)); + } + + @Test + public void testTabOnContentChanged() { + // Index 0 is the TabObserver for mTab1. + mTabObserverCaptor.getAllValues().get(0).onContentChanged(mTab1); + assertTrue(mModel.get(LayoutTab.CAN_USE_LIVE_TEXTURE)); + assertEquals(0.0f, mModel.get(LayoutTab.STATIC_TO_VIEW_BLEND), 0); + } + + @Test + public void testTabOnBackgroundColorChanged() { + mModel.set(LayoutTab.BACKGROUND_COLOR, Color.WHITE); + + // Index 0 is the TabObserver for mTab1. + doReturn(Color.RED).when(mTabThemeColorHelper).getBackgroundColor(); + mTabObserverCaptor.getAllValues().get(0).onBackgroundColorChanged(mTab1, Color.RED); + + assertEquals(Color.RED, mModel.get(LayoutTab.BACKGROUND_COLOR)); + } + + @Test + public void testUpdateLayout() { + mModel.set(LayoutTab.RENDER_X, 0.0f); + mModel.set(LayoutTab.RENDER_Y, 0.0f); + mModel.set(LayoutTab.X, 1.0f); + mModel.set(LayoutTab.Y, 1.0f); + + mStaticLayout.updateLayout(System.currentTimeMillis(), 1000); + + assertEquals(1.0f, mModel.get(LayoutTab.RENDER_X), 0); + assertEquals(1.0f, mModel.get(LayoutTab.RENDER_Y), 0); + + mModel.set(LayoutTab.X, 0.3f); + mModel.set(LayoutTab.Y, 0.3f); + + mStaticLayout.updateLayout(System.currentTimeMillis(), 1000); + + assertEquals(0.0f, mModel.get(LayoutTab.RENDER_X), 0); + assertEquals(0.0f, mModel.get(LayoutTab.RENDER_Y), 0); + } +} \ No newline at end of file
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java index 6b57660..df93196 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java
@@ -140,13 +140,13 @@ } // clang-format off - public CustomTabActivityTabController createTabController() { + public CustomTabActivityTabController createTabController(ProfileProvider profileProvider) { return new CustomTabActivityTabController(activity, () -> customTabDelegateFactory, connection, intentDataProvider, activityTabProvider, tabObserverRegistrar, () -> compositorViewHolder, lifecycleDispatcher, warmupManager, tabPersistencePolicy, tabFactory, () -> customTabObserver, webContentsFactory, navigationEventObserver, tabProvider, startupTabPreloader, reparentingTaskProvider, - () -> customTabIncognitoManager); + () -> customTabIncognitoManager, profileProvider); } // clang-format on
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerUnitTest.java index c00d689a..0435331 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerUnitTest.java
@@ -24,9 +24,12 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.embedder_support.util.ShadowUrlUtilities; @@ -49,9 +52,17 @@ private CustomTabActivityTabController mTabController; + @Mock + public ProfileProvider mProfileProvider; + + @Mock + private Profile mProfile; + @Before public void setUp() { - mTabController = env.createTabController(); + MockitoAnnotations.initMocks(this); + when(mProfileProvider.getLastUsedRegularProfile()).thenReturn(mProfile); + mTabController = env.createTabController(mProfileProvider); } @Test @@ -137,7 +148,7 @@ @Test public void usesWebContentsCreatedWithWarmRenderer_ByDefault() { WebContents webContents = mock(WebContents.class); - when(env.webContentsFactory.createWebContentsWithWarmRenderer(anyBoolean(), anyBoolean())) + when(env.webContentsFactory.createWebContentsWithWarmRenderer(any(), anyBoolean())) .thenReturn(webContents); env.reachNativeInit(mTabController); assertEquals(webContents, env.webContentsCaptor.getValue());
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityUrlLoadingTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityUrlLoadingTest.java index 09398abc..2985fe7 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityUrlLoadingTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityUrlLoadingTest.java
@@ -33,6 +33,7 @@ import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider; import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.embedder_support.util.UrlUtilities; @@ -55,6 +56,12 @@ @Rule public Features.JUnitProcessor processor = new Features.JUnitProcessor(); + @Mock + public ProfileProvider mProfileProvider; + + @Mock + private Profile mProfile; + private CustomTabActivityTabController mTabController; private CustomTabActivityNavigationController mNavigationController; private CustomTabIntentHandler mIntentHandler; @@ -69,7 +76,8 @@ public void setUp() { MockitoAnnotations.initMocks(this); mocker.mock(UrlUtilitiesJni.TEST_HOOKS, mUrlUtilitiesJniMock); - mTabController = env.createTabController(); + when(mProfileProvider.getLastUsedRegularProfile()).thenReturn(mProfile); + mTabController = env.createTabController(mProfileProvider); mNavigationController = env.createNavigationController(mTabController); mIntentHandler = env.createIntentHandler(mNavigationController); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java index 5f80cc00..f7654436 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmImportSyncDataDialogTest.java
@@ -3,6 +3,7 @@ // found in the LICENSE file. package org.chromium.chrome.browser.signin; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -24,6 +25,7 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.R; +import org.chromium.chrome.browser.profiles.Profile; /** Tests for {@link ConfirmImportSyncDataDialog}. */ @RunWith(BaseRobolectricTestRunner.class) @@ -37,6 +39,9 @@ @Mock private SigninManager mSigninManagerMock; + @Mock + private Profile mProfile; + private FragmentManager mFragmentManager; private ConfirmSyncDataStateMachineDelegate mStateMachineDelegate; @@ -45,7 +50,8 @@ public void setUp() { initMocks(this); IdentityServicesProvider.setInstanceForTests(mock(IdentityServicesProvider.class)); - when(IdentityServicesProvider.get().getSigninManager()).thenReturn(mSigninManagerMock); + Profile.setLastUsedProfileForTesting(mProfile); + when(IdentityServicesProvider.get().getSigninManager(any())).thenReturn(mSigninManagerMock); mFragmentManager = Robolectric.setupActivity(FragmentActivity.class).getSupportFragmentManager(); mStateMachineDelegate = new ConfirmSyncDataStateMachineDelegate(mFragmentManager);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachineTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachineTest.java index d51a395c..2ed7ad2 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachineTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachineTest.java
@@ -25,6 +25,7 @@ import org.chromium.base.Callback; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.JniMocker; +import org.chromium.chrome.browser.profiles.Profile; /** Tests for {@link ConfirmSyncDataStateMachine}. */ @RunWith(BaseRobolectricTestRunner.class) @@ -44,6 +45,9 @@ @Mock private SigninManager mSigninManagerMock; + @Mock + private Profile mProfile; + @Captor private ArgumentCaptor<Callback<Boolean>> mCallbackArgument; @@ -56,7 +60,8 @@ initMocks(this); mocker.mock(SigninManagerJni.TEST_HOOKS, mSigninManagerNativeMock); IdentityServicesProvider.setInstanceForTests(mock(IdentityServicesProvider.class)); - when(IdentityServicesProvider.get().getSigninManager()).thenReturn(mSigninManagerMock); + Profile.setLastUsedProfileForTesting(mProfile); + when(IdentityServicesProvider.get().getSigninManager(any())).thenReturn(mSigninManagerMock); } @Test(expected = AssertionError.class)
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SignOutDialogFragmentTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SignOutDialogFragmentTest.java index 8e052bf..7939716 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SignOutDialogFragmentTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SignOutDialogFragmentTest.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.signin; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -31,6 +32,7 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.R; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.ProfileAccountManagementMetrics; import org.chromium.components.signin.GAIAServiceType; @@ -55,6 +57,9 @@ @Mock private SigninManager mSigninManagerMock; + @Mock + private Profile mProfile; + @Spy private final DummySignOutTargetFragment mTargetFragment = new DummySignOutTargetFragment(); @@ -67,7 +72,8 @@ initMocks(this); mocker.mock(SigninUtilsJni.TEST_HOOKS, mSigninUtilsNativeMock); IdentityServicesProvider.setInstanceForTests(mock(IdentityServicesProvider.class)); - when(IdentityServicesProvider.get().getSigninManager()).thenReturn(mSigninManagerMock); + Profile.setLastUsedProfileForTesting(mProfile); + when(IdentityServicesProvider.get().getSigninManager(any())).thenReturn(mSigninManagerMock); setUpSignOutDialog(); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninUtilsStartActivityTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninUtilsStartActivityTest.java index 1633c34..d725c50 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninUtilsStartActivityTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninUtilsStartActivityTest.java
@@ -24,6 +24,7 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.R; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.components.signin.metrics.SigninAccessPoint; /** Tests for the method startSigninActivityIfAllowed {@link SigninUtils}. */ @@ -35,13 +36,17 @@ @Mock private SigninActivityLauncher mLauncherMock; + @Mock + private Profile mProfile; + private final Context mContext = RuntimeEnvironment.application.getApplicationContext(); @Before public void setUp() { initMocks(this); IdentityServicesProvider.setInstanceForTests(mock(IdentityServicesProvider.class)); - when(IdentityServicesProvider.get().getSigninManager()).thenReturn(mSigninManagerMock); + Profile.setLastUsedProfileForTesting(mProfile); + when(IdentityServicesProvider.get().getSigninManager(any())).thenReturn(mSigninManagerMock); SigninActivityLauncher.setLauncherForTest(mLauncherMock); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/site_settings/OWNERS b/chrome/android/junit/src/org/chromium/chrome/browser/site_settings/OWNERS new file mode 100644 index 0000000..72fb09a --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/site_settings/OWNERS
@@ -0,0 +1 @@ +file://components/browser_ui/site_settings/OWNERS \ No newline at end of file
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/site_settings/SingleWebsiteSettingsTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/site_settings/SingleWebsiteSettingsTest.java new file mode 100644 index 0000000..4a4d6e9 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/site_settings/SingleWebsiteSettingsTest.java
@@ -0,0 +1,81 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.site_settings; + +import androidx.test.filters.SmallTest; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.components.browser_ui.site_settings.SingleWebsiteSettings; +import org.chromium.components.content_settings.ContentSettingsType; + +/** + * Tests the functionality of the SingleWebsiteSettings.java page. + */ +@RunWith(BaseRobolectricTestRunner.class) +public class SingleWebsiteSettingsTest { + private @ContentSettingsType int getCorrectContentSettingsTypeForPreferenceKey( + String preferenceKey) { + switch (preferenceKey) { + case "ads_permission_list": + return ContentSettingsType.ADS; + case "automatic_downloads_permission_list": + return ContentSettingsType.AUTOMATIC_DOWNLOADS; + case "background_sync_permission_list": + return ContentSettingsType.BACKGROUND_SYNC; + case "bluetooth_scanning_permission_list": + return ContentSettingsType.BLUETOOTH_SCANNING; + case "cookies_permission_list": + return ContentSettingsType.COOKIES; + case "javascript_permission_list": + return ContentSettingsType.JAVASCRIPT; + case "popup_permission_list": + return ContentSettingsType.POPUPS; + case "sound_permission_list": + return ContentSettingsType.SOUND; + case "ar_permission_list": + return ContentSettingsType.AR; + case "camera_permission_list": + return ContentSettingsType.MEDIASTREAM_CAMERA; + case "clipboard_permission_list": + return ContentSettingsType.CLIPBOARD_READ_WRITE; + case "location_access_list": + return ContentSettingsType.GEOLOCATION; + case "microphone_permission_list": + return ContentSettingsType.MEDIASTREAM_MIC; + case "midi_sysex_permission_list": + return ContentSettingsType.MIDI_SYSEX; + case "nfc_permission_list": + return ContentSettingsType.NFC; + case "push_notifications_list": + return ContentSettingsType.NOTIFICATIONS; + case "protected_media_identifier_permission_list": + return ContentSettingsType.PROTECTED_MEDIA_IDENTIFIER; + case "sensors_permission_list": + return ContentSettingsType.SENSORS; + case "vr_permission_list": + return ContentSettingsType.VR; + default: + Assert.fail("Preference key not in list."); + return ContentSettingsType.DEFAULT; + } + } + + /** + * Tests that the order of SingleWebsiteSettings.PERMISSION_PREFERENCE_KEYS matches the enums it + * comes from. + */ + @Test + @SmallTest + public void testCorrectMapOfPreferenceKeyToContentSettingsType() { + for (String key : SingleWebsiteSettings.PERMISSION_PREFERENCE_KEYS) { + Assert.assertEquals(SingleWebsiteSettings.getContentSettingsTypeFromPreferenceKey(key), + getCorrectContentSettingsTypeForPreferenceKey(key)); + } + } +} \ No newline at end of file
diff --git a/chrome/android/modules/test_dummy/provider/BUILD.gn b/chrome/android/modules/test_dummy/provider/BUILD.gn index b35bd1e6..afc8f4a8 100644 --- a/chrome/android/modules/test_dummy/provider/BUILD.gn +++ b/chrome/android/modules/test_dummy/provider/BUILD.gn
@@ -10,6 +10,7 @@ "//base:jni_java", "//chrome/android/modules/test_dummy/public:java", "//chrome/browser/test_dummy:java", + "//components/module_installer/android:module_installer_java", ] sources = [ "java/src/org/chromium/chrome/modules/test_dummy/TestDummyModuleProvider.java" ] }
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index c487e4b..bd35f4c 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-86.0.4194.0_rc-r1-merged.afdo.bz2 +chromeos-chrome-amd64-86.0.4203.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/android/webapk/libs/runtime_library/BUILD.gn b/chrome/android/webapk/libs/runtime_library/BUILD.gn index eaba3a5..71bb30ae 100644 --- a/chrome/android/webapk/libs/runtime_library/BUILD.gn +++ b/chrome/android/webapk/libs/runtime_library/BUILD.gn
@@ -76,6 +76,7 @@ "//base:base_java_test_support", "//chrome/test/android:chrome_java_test_support", "//content/public/test/android:content_java_test_support", + "//third_party/android_deps:androidx_test_runner_java", "//third_party/android_support_test_runner:runner_java", "//third_party/junit", ]
diff --git a/chrome/android/webapk/shell_apk/BUILD.gn b/chrome/android/webapk/shell_apk/BUILD.gn index 075df97..c3bbeec 100644 --- a/chrome/android/webapk/shell_apk/BUILD.gn +++ b/chrome/android/webapk/shell_apk/BUILD.gn
@@ -71,6 +71,7 @@ "//chrome/android/webapk/libs/common:common_java", "//chrome/android/webapk/libs/common:splash_java", "//components/webapk/android/libs/common:java", + "//third_party/android_deps:androidx_annotation_annotation_java", ] } } @@ -341,6 +342,7 @@ "//base:base_java_test_support", "//chrome/android/webapk/libs/common:common_java", "//content/public/test/android:content_java_test_support", + "//third_party/android_deps:androidx_test_runner_java", "//third_party/android_support_test_runner:runner_java", "//third_party/junit", ] @@ -365,6 +367,7 @@ "//chrome/android/webapk/libs/runtime_library:runtime_library_for_tests_java", "//chrome/android/webapk/test:junit_test_support", "//components/webapk/android/libs/common:java", + "//third_party/android_deps:androidx_annotation_annotation_java", ] }
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index a73b7c8..c16ff790 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -4567,6 +4567,9 @@ <message name="IDS_CROSTINI_UPGRADER_RESTORE_MESSAGE" desc="Title of the Crostini upgrader when the container upgrade fails and restore of a backup is in progress."> Linux files and apps are being restored to their backed up state. </message> + <message name="IDS_CROSTINI_UPGRADER_NOT_NOW" desc="Text on the button to defer performing the upgrade"> + Not now + </message> <message name="IDS_CROSTINI_ANSIBLE_SOFTWARE_CONFIG_LABEL" desc="Label for dialog warning user of unavailable Linux container until software configurations are applied."> Configuring Linux </message>
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CROSTINI_UPGRADER_NOT_NOW.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CROSTINI_UPGRADER_NOT_NOW.png.sha1 new file mode 100644 index 0000000..a0eacbed --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CROSTINI_UPGRADER_NOT_NOW.png.sha1
@@ -0,0 +1 @@ +26e04e7c73a3943a4d16d99f51484cb6ec8d0486 \ No newline at end of file
diff --git a/chrome/app/theme/plugin_vm/plugin_vm_installer.png b/chrome/app/theme/plugin_vm/plugin_vm_installer.png index 3e95c0b..96a0460 100644 --- a/chrome/app/theme/plugin_vm/plugin_vm_installer.png +++ b/chrome/app/theme/plugin_vm/plugin_vm_installer.png Binary files differ
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index fa3a907a..bc40fca 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -966,8 +966,6 @@ "page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h", "page_load_metrics/observers/ad_metrics/frame_data.cc", "page_load_metrics/observers/ad_metrics/frame_data.h", - "page_load_metrics/observers/ad_metrics/page_ad_density_tracker.cc", - "page_load_metrics/observers/ad_metrics/page_ad_density_tracker.h", "page_load_metrics/observers/amp_page_load_metrics_observer.cc", "page_load_metrics/observers/amp_page_load_metrics_observer.h", "page_load_metrics/observers/data_saver_site_breakdown_metrics_observer.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index c532a1f..4c15e98 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -5881,7 +5881,15 @@ {"lite-video-force-override-decision", flag_descriptions::kLiteVideoForceOverrideDecisionName, flag_descriptions::kLiteVideoForceOverrideDecisionDescription, kOsAll, - SINGLE_VALUE_TYPE(lite_video::switches::kLiteVideoForceOverrideDecision)} + SINGLE_VALUE_TYPE(lite_video::switches::kLiteVideoForceOverrideDecision)}, + +#if !defined(OS_ANDROID) + {"edit-passwords-in-settings", + flag_descriptions::kEditPasswordsInDesktopSettingsName, + flag_descriptions::kEditPasswordsInDesktopSettingsDescription, kOsDesktop, + FEATURE_VALUE_TYPE( + password_manager::features::kEditPasswordsInDesktopSettings)} +#endif // !defined(OS_ANDROID) // 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/compositor/scene_layer/static_tab_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.cc index 6a25093..913a391 100644 --- a/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.cc +++ b/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.cc
@@ -20,6 +20,7 @@ StaticTabSceneLayer::StaticTabSceneLayer(JNIEnv* env, const JavaRef<jobject>& jobj) : SceneLayer(env, jobj), + tab_content_manager_(nullptr), last_set_tab_id_(-1), background_color_(SK_ColorWHITE), brightness_(1.f) {} @@ -39,7 +40,6 @@ void StaticTabSceneLayer::UpdateTabLayer( JNIEnv* env, const JavaParamRef<jobject>& jobj, - const JavaParamRef<jobject>& jtab_content_manager, jint id, jboolean can_use_live_layer, jint default_background_color, @@ -48,11 +48,12 @@ jfloat static_to_view_blend, jfloat saturation, jfloat brightness) { + DCHECK(tab_content_manager_) + << "TabContentManager must be set before updating the layer"; + background_color_ = default_background_color; if (!content_layer_.get()) { - android::TabContentManager* tab_content_manager = - android::TabContentManager::FromJavaObject(jtab_content_manager); - content_layer_ = android::ContentLayer::Create(tab_content_manager); + content_layer_ = android::ContentLayer::Create(tab_content_manager_); layer_->AddChild(content_layer_->layer()); } @@ -81,6 +82,16 @@ } } +void StaticTabSceneLayer::SetTabContentManager( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& jobj, + const base::android::JavaParamRef<jobject>& jtab_content_manager) { + if (!tab_content_manager_) { + tab_content_manager_ = + TabContentManager::FromJavaObject(jtab_content_manager); + } +} + static jlong JNI_StaticTabSceneLayer_Init(JNIEnv* env, const JavaParamRef<jobject>& jobj) { // This will automatically bind to the Java object and pass ownership there.
diff --git a/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.h b/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.h index 21e610c..b8acd7c 100644 --- a/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.h +++ b/chrome/browser/android/compositor/scene_layer/static_tab_scene_layer.h
@@ -22,6 +22,7 @@ namespace android { class ContentLayer; +class TabContentManager; // A SceneLayer to render a static tab. class StaticTabSceneLayer : public SceneLayer { @@ -36,7 +37,6 @@ void UpdateTabLayer( JNIEnv* env, const base::android::JavaParamRef<jobject>& jobj, - const base::android::JavaParamRef<jobject>& jtab_content_manager, jint id, jboolean can_use_live_layer, jint default_background_color, @@ -46,9 +46,15 @@ jfloat saturation, jfloat brightness); + void SetTabContentManager( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& jobj, + const base::android::JavaParamRef<jobject>& jtab_content_manager); + private: scoped_refptr<android::ContentLayer> content_layer_; + TabContentManager* tab_content_manager_; int last_set_tab_id_; int background_color_; float brightness_;
diff --git a/chrome/browser/android/compositor/scene_layer/tab_list_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/tab_list_scene_layer.cc index ee595fef..6d2c61e3 100644 --- a/chrome/browser/android/compositor/scene_layer/tab_list_scene_layer.cc +++ b/chrome/browser/android/compositor/scene_layer/tab_list_scene_layer.cc
@@ -68,22 +68,7 @@ jfloat viewport_x, jfloat viewport_y, jfloat viewport_width, - jfloat viewport_height, - const JavaParamRef<jobject>& jlayer_title_cache, - const JavaParamRef<jobject>& jtab_content_manager, - const JavaParamRef<jobject>& jresource_manager) { - // TODO(changwan): move these to constructor if possible - if (!resource_manager_) { - resource_manager_ = - ui::ResourceManagerImpl::FromJavaObject(jresource_manager); - } - if (!layer_title_cache_) - layer_title_cache_ = LayerTitleCache::FromJavaObject(jlayer_title_cache); - if (!tab_content_manager_) { - tab_content_manager_ = - TabContentManager::FromJavaObject(jtab_content_manager); - } - + jfloat viewport_height) { background_color_ = background_color; own_tree_->SetPosition(gfx::PointF(viewport_x, viewport_y)); own_tree_->SetBounds(gfx::Size(viewport_width, viewport_height)); @@ -145,6 +130,13 @@ jfloat content_offset, jfloat side_border_scale, jboolean inset_border) { + DCHECK(tab_content_manager_) + << "TabContentManager must be set before updating the TabLayer"; + DCHECK(layer_title_cache_) + << "LayerTitleCache must be set before updating the TabLayer"; + DCHECK(resource_manager_) + << "ResourceManager must be set before updating the TabLayer"; + scoped_refptr<TabLayer> layer; auto iter = tab_map_.find(id); if (iter != tab_map_.end()) { @@ -222,6 +214,25 @@ background_layer_->SetPosition(gfx::PointF(0, top_offset)); } +void TabListSceneLayer::SetDependencies( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& jobj, + const base::android::JavaParamRef<jobject>& jtab_content_manager, + const base::android::JavaParamRef<jobject>& jlayer_title_cache, + const base::android::JavaParamRef<jobject>& jresource_manager) { + if (!tab_content_manager_) { + tab_content_manager_ = + TabContentManager::FromJavaObject(jtab_content_manager); + } + if (!layer_title_cache_) { + layer_title_cache_ = LayerTitleCache::FromJavaObject(jlayer_title_cache); + } + if (!resource_manager_) { + resource_manager_ = + ui::ResourceManagerImpl::FromJavaObject(jresource_manager); + } +} + void TabListSceneLayer::OnDetach() { SceneLayer::OnDetach(); for (auto tab : tab_map_)
diff --git a/chrome/browser/android/compositor/scene_layer/tab_list_scene_layer.h b/chrome/browser/android/compositor/scene_layer/tab_list_scene_layer.h index 9c277fe..fd86840 100644 --- a/chrome/browser/android/compositor/scene_layer/tab_list_scene_layer.h +++ b/chrome/browser/android/compositor/scene_layer/tab_list_scene_layer.h
@@ -15,6 +15,7 @@ #include "cc/layers/ui_resource_layer.h" #include "chrome/browser/android/compositor/layer/layer.h" #include "chrome/browser/android/compositor/scene_layer/scene_layer.h" +#include "chrome/browser/android/compositor/tab_content_manager.h" #include "third_party/skia/include/core/SkColor.h" namespace ui { @@ -36,17 +37,13 @@ const base::android::JavaParamRef<jobject>& jobj); void FinishBuildingFrame(JNIEnv* env, const base::android::JavaParamRef<jobject>& jobj); - void UpdateLayer( - JNIEnv* env, - const base::android::JavaParamRef<jobject>& jobj, - jint background_color, - jfloat viewport_x, - jfloat viewport_y, - jfloat viewport_width, - jfloat viewport_height, - const base::android::JavaParamRef<jobject>& jlayer_title_cache, - const base::android::JavaParamRef<jobject>& jtab_content_manager, - const base::android::JavaParamRef<jobject>& jresource_manager); + void UpdateLayer(JNIEnv* env, + const base::android::JavaParamRef<jobject>& jobj, + jint background_color, + jfloat viewport_x, + jfloat viewport_y, + jfloat viewport_width, + jfloat viewport_height); // TODO(meiliang): This method needs another parameter, a resource that can be // used to indicate the currently selected tab for the TabLayer. // TODO(dtrainor): This method is ridiculous. Break this apart? @@ -112,6 +109,13 @@ jfloat alpha, jint top_offset); + void SetDependencies( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& jobj, + const base::android::JavaParamRef<jobject>& jtab_content_manager, + const base::android::JavaParamRef<jobject>& jlayer_title_cache, + const base::android::JavaParamRef<jobject>& jresource_manager); + void OnDetach() override; bool ShouldShowBackground() override; SkColor GetBackgroundColor() override;
diff --git a/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc b/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc index 274e2025f..79c166d 100644 --- a/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc +++ b/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc
@@ -34,7 +34,7 @@ #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" #include "extensions/common/constants.h" -#include "third_party/blink/public/mojom/referrer.mojom.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom.h" #include "ui/gfx/image/image.h" #include "url/origin.h"
diff --git a/chrome/browser/autofill/form_structure_browsertest.cc b/chrome/browser/autofill/form_structure_browsertest.cc index 6bb4a2a..854c8a2 100644 --- a/chrome/browser/autofill/form_structure_browsertest.cc +++ b/chrome/browser/autofill/form_structure_browsertest.cc
@@ -99,11 +99,11 @@ for (const auto& kv : forms) { const auto* form = kv.second.get(); for (const auto& field : *form) { - forms_string += field->Type().ToString(); - forms_string += " | " + base::UTF16ToUTF8(field->name); - forms_string += " | " + base::UTF16ToUTF8(field->label); - forms_string += " | " + base::UTF16ToUTF8(field->value); - forms_string += " | " + field->section; + forms_string += base::JoinString( + {field->Type().ToString(), base::UTF16ToUTF8(field->name), + base::UTF16ToUTF8(field->label), base::UTF16ToUTF8(field->value), + field->section}, + base::StringPiece(" | ")); forms_string += "\n"; } }
diff --git a/chrome/browser/chrome_security_exploit_browsertest.cc b/chrome/browser/chrome_security_exploit_browsertest.cc index f77a04e0..cb97e7c 100644 --- a/chrome/browser/chrome_security_exploit_browsertest.cc +++ b/chrome/browser/chrome_security_exploit_browsertest.cc
@@ -324,8 +324,8 @@ EXPECT_TRUE(content::ExecuteScriptAndExtractString(rfh, script, &body)); EXPECT_EQ( - "Your file was not found\n" - "It may have been moved or deleted.\n" + "Your file couldn’t be accessed\n" + "It may have been moved, edited, or deleted.\n" "ERR_FILE_NOT_FOUND", body); } @@ -402,8 +402,8 @@ EXPECT_TRUE(content::ExecuteScriptAndExtractString(rfh, script, &body)); EXPECT_EQ( - "Your file was not found\n" - "It may have been moved or deleted.\n" + "Your file couldn’t be accessed\n" + "It may have been moved, edited, or deleted.\n" "ERR_FILE_NOT_FOUND", body); }
diff --git a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc index 0b6f7e7..02ac56c1 100644 --- a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc +++ b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc
@@ -60,118 +60,9 @@ void AXTreeSourceArc::NotifyAccessibilityEvent(AXEventData* event_data) { root_id_.reset(); - tree_map_.clear(); - parent_map_.clear(); - computed_bounds_.clear(); + DCHECK(event_data); - window_id_ = event_data->window_id; - is_notification_ = event_data->notification_key.has_value(); - is_input_method_window_ = event_data->is_input_method_window; - - // Prepare the wrapper objects of mojom data from Android. - CHECK(event_data->window_data); - root_id_ = event_data->window_data->at(0)->window_id; - for (size_t i = 0; i < event_data->window_data->size(); ++i) { - int32_t window_id = event_data->window_data->at(i)->window_id; - int32_t root_node_id = event_data->window_data->at(i)->root_node_id; - AXWindowInfoData* window = event_data->window_data->at(i).get(); - if (root_node_id) - parent_map_[root_node_id] = window_id; - - tree_map_[window_id] = - std::make_unique<AccessibilityWindowInfoDataWrapper>(this, window); - - std::vector<int32_t> children; - if (GetProperty(window->int_list_properties, - AXWindowIntListProperty::CHILD_WINDOW_IDS, &children)) { - for (const int32_t child : children) { - DCHECK(child != root_id_); - parent_map_[child] = window_id; - } - } - } - - for (size_t i = 0; i < event_data->node_data.size(); ++i) { - int32_t node_id = event_data->node_data[i]->id; - AXNodeInfoData* node = event_data->node_data[i].get(); - tree_map_[node_id] = - std::make_unique<AccessibilityNodeInfoDataWrapper>(this, node); - - std::vector<int32_t> children; - if (GetProperty(event_data->node_data[i].get()->int_list_properties, - AXIntListProperty::CHILD_NODE_IDS, &children)) { - for (const int32_t child : children) - parent_map_[child] = node_id; - } - } - - // Compute each node's bounds, based on its descendants. - // Assuming |nodeData| is in pre-order, compute cached bounds in post-order to - // avoid an O(n^2) amount of work as the computed bounds uses descendant - // bounds. - for (int i = event_data->node_data.size() - 1; i >= 0; --i) { - int32_t id = event_data->node_data[i]->id; - computed_bounds_[id] = ComputeEnclosingBounds(tree_map_[id].get()); - } - for (int i = event_data->window_data->size() - 1; i >= 0; --i) { - int32_t id = event_data->window_data->at(i)->window_id; - computed_bounds_[id] = ComputeEnclosingBounds(tree_map_[id].get()); - } - - if (!UpdateAndroidFocusedId(*event_data)) { - // Exit this function if the focused node doesn't exist nor isn't visible. - return; - } - - if (event_data->event_type == AXEventType::WINDOW_STATE_CHANGED && - event_data->event_text) { - AccessibilityInfoDataWrapper* source_node = - GetFromId(event_data->source_id); - if (IsValid(source_node)) - UpdateAXNameCache(source_node, *event_data->event_text); - } - - ApplyCachedProperties(); - - ExtensionMsg_AccessibilityEventBundleParams event_bundle; - event_bundle.tree_id = ax_tree_id(); - - AccessibilityInfoDataWrapper* focused_node = - android_focused_id_.has_value() ? GetFromId(*android_focused_id_) - : nullptr; - event_bundle.events.emplace_back(); - ui::AXEvent& event = event_bundle.events.back(); - event.event_type = ToAXEvent( - event_data->event_type, - GetPropertyOrNull( - event_data->int_list_properties, - arc::mojom::AccessibilityEventIntListProperty::CONTENT_CHANGE_TYPES), - GetFromId(event_data->source_id), focused_node); - event.id = event_data->source_id; - - if (HasProperty(event_data->int_properties, - arc::mojom::AccessibilityEventIntProperty::ACTION)) { - event.event_from = ax::mojom::EventFrom::kAction; - } - - HandleLiveRegions(&event_bundle.events); - - event_bundle.updates.emplace_back(); - - // Force the tree, to update, so unignored fields get updated. - // On event type of WINDOW_STATE_CHANGED, update the entire tree so that - // window location is correctly calculated. - int32_t node_id_to_clear = - (event_data->event_type == AXEventType::WINDOW_STATE_CHANGED) - ? *root_id_ - : event_data->source_id; - event_bundle.updates[0].node_id_to_clear = node_id_to_clear; - current_tree_serializer_->InvalidateSubtree(GetFromId(node_id_to_clear)); - - current_tree_serializer_->SerializeChanges(GetFromId(node_id_to_clear), - &event_bundle.updates.back()); - - GetAutomationEventRouter()->DispatchAccessibilityEvents(event_bundle); + NotifyAccessibilityEventInternal(*event_data); // Clear maps in order to prevent invalid access from dead pointers. tree_map_.clear(); @@ -260,6 +151,117 @@ info_data->Serialize(out_data); } +void AXTreeSourceArc::NotifyAccessibilityEventInternal( + const AXEventData& event_data) { + window_id_ = event_data.window_id; + is_notification_ = event_data.notification_key.has_value(); + is_input_method_window_ = event_data.is_input_method_window; + + // Prepare the wrapper objects of mojom data from Android. + CHECK(event_data.window_data); + root_id_ = event_data.window_data->at(0)->window_id; + for (size_t i = 0; i < event_data.window_data->size(); ++i) { + int32_t window_id = event_data.window_data->at(i)->window_id; + int32_t root_node_id = event_data.window_data->at(i)->root_node_id; + AXWindowInfoData* window = event_data.window_data->at(i).get(); + if (root_node_id) + parent_map_[root_node_id] = window_id; + + tree_map_[window_id] = + std::make_unique<AccessibilityWindowInfoDataWrapper>(this, window); + + std::vector<int32_t> children; + if (GetProperty(window->int_list_properties, + AXWindowIntListProperty::CHILD_WINDOW_IDS, &children)) { + for (const int32_t child : children) { + DCHECK(child != root_id_); + parent_map_[child] = window_id; + } + } + } + + for (size_t i = 0; i < event_data.node_data.size(); ++i) { + int32_t node_id = event_data.node_data[i]->id; + AXNodeInfoData* node = event_data.node_data[i].get(); + tree_map_[node_id] = + std::make_unique<AccessibilityNodeInfoDataWrapper>(this, node); + + std::vector<int32_t> children; + if (GetProperty(event_data.node_data[i].get()->int_list_properties, + AXIntListProperty::CHILD_NODE_IDS, &children)) { + for (const int32_t child : children) + parent_map_[child] = node_id; + } + } + + // Compute each node's bounds, based on its descendants. + // Assuming |nodeData| is in pre-order, compute cached bounds in post-order to + // avoid an O(n^2) amount of work as the computed bounds uses descendant + // bounds. + for (int i = event_data.node_data.size() - 1; i >= 0; --i) { + int32_t id = event_data.node_data[i]->id; + computed_bounds_[id] = ComputeEnclosingBounds(tree_map_[id].get()); + } + for (int i = event_data.window_data->size() - 1; i >= 0; --i) { + int32_t id = event_data.window_data->at(i)->window_id; + computed_bounds_[id] = ComputeEnclosingBounds(tree_map_[id].get()); + } + + if (!UpdateAndroidFocusedId(event_data)) { + // Exit this function if the focused node doesn't exist nor isn't visible. + return; + } + + if (event_data.event_type == AXEventType::WINDOW_STATE_CHANGED && + event_data.event_text) { + AccessibilityInfoDataWrapper* source_node = GetFromId(event_data.source_id); + if (IsValid(source_node)) + UpdateAXNameCache(source_node, *event_data.event_text); + } + + ApplyCachedProperties(); + + ExtensionMsg_AccessibilityEventBundleParams event_bundle; + event_bundle.tree_id = ax_tree_id(); + + AccessibilityInfoDataWrapper* focused_node = + android_focused_id_.has_value() ? GetFromId(*android_focused_id_) + : nullptr; + event_bundle.events.emplace_back(); + ui::AXEvent& event = event_bundle.events.back(); + event.event_type = ToAXEvent( + event_data.event_type, + GetPropertyOrNull( + event_data.int_list_properties, + arc::mojom::AccessibilityEventIntListProperty::CONTENT_CHANGE_TYPES), + GetFromId(event_data.source_id), focused_node); + event.id = event_data.source_id; + + if (HasProperty(event_data.int_properties, + arc::mojom::AccessibilityEventIntProperty::ACTION)) { + event.event_from = ax::mojom::EventFrom::kAction; + } + + HandleLiveRegions(&event_bundle.events); + + event_bundle.updates.emplace_back(); + + // Force the tree, to update, so unignored fields get updated. + // On event type of WINDOW_STATE_CHANGED, update the entire tree so that + // window location is correctly calculated. + int32_t node_id_to_clear = + (event_data.event_type == AXEventType::WINDOW_STATE_CHANGED) + ? *root_id_ + : event_data.source_id; + event_bundle.updates[0].node_id_to_clear = node_id_to_clear; + current_tree_serializer_->InvalidateSubtree(GetFromId(node_id_to_clear)); + + current_tree_serializer_->SerializeChanges(GetFromId(node_id_to_clear), + &event_bundle.updates.back()); + + GetAutomationEventRouter()->DispatchAccessibilityEvents(event_bundle); +} + extensions::AutomationEventRouterInterface* AXTreeSourceArc::GetAutomationEventRouter() const { return extensions::AutomationEventRouter::GetInstance();
diff --git a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h index db2763b..61338ad 100644 --- a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h +++ b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h
@@ -96,6 +96,10 @@ private: friend class arc::AXTreeSourceArcTest; + // Actual implementation of NotifyAccessibilityEvent. + void NotifyAccessibilityEventInternal( + const mojom::AccessibilityEventData& event_data); + // virtual for testing. virtual extensions::AutomationEventRouterInterface* GetAutomationEventRouter() const;
diff --git a/chrome/browser/chromeos/arc/session/arc_service_launcher.cc b/chrome/browser/chromeos/arc/session/arc_service_launcher.cc index 6a4dedf..7055bc1 100644 --- a/chrome/browser/chromeos/arc/session/arc_service_launcher.cc +++ b/chrome/browser/chromeos/arc/session/arc_service_launcher.cc
@@ -73,6 +73,7 @@ #include "components/arc/power/arc_power_bridge.h" #include "components/arc/property/arc_property_bridge.h" #include "components/arc/rotation_lock/arc_rotation_lock_bridge.h" +#include "components/arc/sensor/arc_sensor_bridge.h" #include "components/arc/session/arc_session.h" #include "components/arc/session/arc_session_runner.h" #include "components/arc/storage_manager/arc_storage_manager.h" @@ -204,6 +205,7 @@ ArcProvisionNotificationService::GetForBrowserContext(profile); ArcRotationLockBridge::GetForBrowserContext(profile); ArcScreenCaptureBridge::GetForBrowserContext(profile); + ArcSensorBridge::GetForBrowserContext(profile); ArcSettingsService::GetForBrowserContext(profile); ArcSmartCardManagerBridge::GetForBrowserContext(profile); ArcTimerBridge::GetForBrowserContext(profile);
diff --git a/chrome/browser/chromeos/file_system_provider/notification_manager.cc b/chrome/browser/chromeos/file_system_provider/notification_manager.cc index cb94234..a045d1f 100644 --- a/chrome/browser/chromeos/file_system_provider/notification_manager.cc +++ b/chrome/browser/chromeos/file_system_provider/notification_manager.cc
@@ -44,8 +44,8 @@ void NotificationManager::ShowUnresponsiveNotification( int id, - const NotificationCallback& callback) { - callbacks_[id] = callback; + NotificationCallback callback) { + callbacks_[id] = std::move(callback); ShowNotification(); } @@ -119,9 +119,9 @@ CallbackMap::iterator it = callbacks_.begin(); while (it != callbacks_.end()) { CallbackMap::iterator current_it = it++; - NotificationCallback callback = current_it->second; + NotificationCallback callback = std::move(current_it->second); callbacks_.erase(current_it); - callback.Run(result); + std::move(callback).Run(result); } }
diff --git a/chrome/browser/chromeos/file_system_provider/notification_manager.h b/chrome/browser/chromeos/file_system_provider/notification_manager.h index 674a445..d2d6c48d 100644 --- a/chrome/browser/chromeos/file_system_provider/notification_manager.h +++ b/chrome/browser/chromeos/file_system_provider/notification_manager.h
@@ -40,9 +40,8 @@ ~NotificationManager() override; // NotificationManagerInterface overrides: - void ShowUnresponsiveNotification( - int id, - const NotificationCallback& callback) override; + void ShowUnresponsiveNotification(int id, + NotificationCallback callback) override; void HideUnresponsiveNotification(int id) override; // AppIconLoaderDelegate overrides:
diff --git a/chrome/browser/chromeos/file_system_provider/notification_manager_interface.h b/chrome/browser/chromeos/file_system_provider/notification_manager_interface.h index 648916a..ade108ed4 100644 --- a/chrome/browser/chromeos/file_system_provider/notification_manager_interface.h +++ b/chrome/browser/chromeos/file_system_provider/notification_manager_interface.h
@@ -18,16 +18,15 @@ enum NotificationResult { ABORT, CONTINUE }; // Callback for handling result of a notification. - typedef base::Callback<void(NotificationResult)> NotificationCallback; + typedef base::OnceCallback<void(NotificationResult)> NotificationCallback; NotificationManagerInterface() {} virtual ~NotificationManagerInterface() {} // Shows a notification about the request being unresponsive. The |callback| // is called when the notification is closed. - virtual void ShowUnresponsiveNotification( - int id, - const NotificationCallback& callback) = 0; + virtual void ShowUnresponsiveNotification(int id, + NotificationCallback callback) = 0; // Hides a notification previously shown with |id|. virtual void HideUnresponsiveNotification(int id) = 0;
diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc b/chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc index dd5b2b5..6bd7334 100644 --- a/chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc +++ b/chrome/browser/chromeos/file_system_provider/provided_file_system_unittest.cc
@@ -193,9 +193,8 @@ ~StubNotificationManager() override {} // NotificationManagerInterface overrides. - void ShowUnresponsiveNotification( - int id, - const NotificationCallback& callback) override {} + void ShowUnresponsiveNotification(int id, + NotificationCallback callback) override {} void HideUnresponsiveNotification(int id) override {} private:
diff --git a/chrome/browser/chromeos/file_system_provider/request_manager.cc b/chrome/browser/chromeos/file_system_provider/request_manager.cc index 7178562..c37f9e9 100644 --- a/chrome/browser/chromeos/file_system_provider/request_manager.cc +++ b/chrome/browser/chromeos/file_system_provider/request_manager.cc
@@ -171,8 +171,8 @@ if (!IsInteractingWithUser()) { notification_manager_->ShowUnresponsiveNotification( request_id, - base::Bind(&RequestManager::OnUnresponsiveNotificationResult, - weak_ptr_factory_.GetWeakPtr(), request_id)); + base::BindOnce(&RequestManager::OnUnresponsiveNotificationResult, + weak_ptr_factory_.GetWeakPtr(), request_id)); } else { ResetTimer(request_id); }
diff --git a/chrome/browser/chromeos/file_system_provider/request_manager_unittest.cc b/chrome/browser/chromeos/file_system_provider/request_manager_unittest.cc index 06b458d..155a7b67 100644 --- a/chrome/browser/chromeos/file_system_provider/request_manager_unittest.cc +++ b/chrome/browser/chromeos/file_system_provider/request_manager_unittest.cc
@@ -38,10 +38,9 @@ ~FakeNotificationManager() override {} // NotificationManagerInterface overrides: - void ShowUnresponsiveNotification( - int id, - const NotificationCallback& callback) override { - callbacks_[id] = callback; + void ShowUnresponsiveNotification(int id, + NotificationCallback callback) override { + callbacks_[id] = std::move(callback); } void HideUnresponsiveNotification(int id) override { callbacks_.erase(id); } @@ -64,9 +63,9 @@ CallbackMap::iterator it = callbacks_.begin(); while (it != callbacks_.end()) { CallbackMap::iterator current_it = it++; - NotificationCallback callback = current_it->second; + NotificationCallback callback = std::move(current_it->second); callbacks_.erase(current_it); - callback.Run(result); + std::move(callback).Run(result); } }
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc index b598396..cbb8f7f4 100644 --- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc +++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -1221,9 +1221,11 @@ LoginDisplayHost::default_host()->StartWizard( EnrollmentScreenView::kScreenId); WaitForGaiaPageBackButtonUpdate(); + auto flow_change_waiter = + OobeBaseTest::CreateGaiaPageEventWaiter("authFlowChange"); SigninFrameJS().TypeIntoPath(gaia_email, {"identifier"}); SigninFrameJS().TapOn("nextButton"); - OobeBaseTest::WaitForGaiaPageEvent("authFlowChange"); + flow_change_waiter->Wait(); } IN_PROC_BROWSER_TEST_F(SAMLEnrollmentTest, WithoutCredentialsPassingAPI) {
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.cc b/chrome/browser/chromeos/login/test/oobe_base_test.cc index a794cfa..db7e783 100644 --- a/chrome/browser/chromeos/login/test/oobe_base_test.cc +++ b/chrome/browser/chromeos/login/test/oobe_base_test.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/chromeos/login/session/user_session_manager_test_api.h" #include "chrome/browser/chromeos/login/test/https_forwarder.h" #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" +#include "chrome/browser/chromeos/login/test/test_condition_waiter.h" #include "chrome/browser/chromeos/login/ui/login_display_host_webui.h" #include "chrome/browser/chromeos/login/ui/webui_login_view.h" #include "chrome/browser/lifetime/application_lifetime.h" @@ -39,6 +40,46 @@ namespace chromeos { +namespace { + +class GaiaPageEventWaiter : public test::TestConditionWaiter { + public: + GaiaPageEventWaiter(const std::string& authenticator_id, + const std::string& event) { + std::string js = + R"((function() { + var authenticator = $AuthenticatorId; + var f = function() { + authenticator.removeEventListener('$Event', f); + window.domAutomationController.send('Done'); + }; + authenticator.addEventListener('$Event', f); + })();)"; + base::ReplaceSubstringsAfterOffset(&js, 0, "$AuthenticatorId", + authenticator_id); + base::ReplaceSubstringsAfterOffset(&js, 0, "$Event", event); + test::OobeJS().Evaluate(js); + } + + ~GaiaPageEventWaiter() override { EXPECT_TRUE(wait_called_); } + + // test::TestConditionWaiter: + void Wait() override { + ASSERT_FALSE(wait_called_) << "Wait should be called once"; + wait_called_ = true; + std::string message; + do { + ASSERT_TRUE(message_queue.WaitForMessage(&message)); + } while (message != "\"Done\""); + } + + private: + content::DOMMessageQueue message_queue; + bool wait_called_ = false; +}; + +} // namespace + OobeBaseTest::OobeBaseTest() { set_exit_when_last_browser_closes(false); } @@ -141,35 +182,16 @@ } void OobeBaseTest::WaitForGaiaPageReload() { - WaitForGaiaPageEvent("ready"); + CreateGaiaPageEventWaiter("ready")->Wait(); } void OobeBaseTest::WaitForGaiaPageBackButtonUpdate() { - WaitForGaiaPageEvent("backButton"); + CreateGaiaPageEventWaiter("backButton")->Wait(); } -void OobeBaseTest::WaitForGaiaPageEvent(const std::string& event) { - // Starts listening to message before executing the JS code that generates - // the message below. - content::DOMMessageQueue message_queue; - std::string js = - R"((function() { - var authenticator = $AuthenticatorId; - var f = function() { - authenticator.removeEventListener('$Event', f); - window.domAutomationController.send('Done'); - }; - authenticator.addEventListener('$Event', f); - })();)"; - base::ReplaceSubstringsAfterOffset(&js, 0, "$AuthenticatorId", - authenticator_id_); - base::ReplaceSubstringsAfterOffset(&js, 0, "$Event", event); - test::OobeJS().Evaluate(js); - - std::string message; - do { - ASSERT_TRUE(message_queue.WaitForMessage(&message)); - } while (message != "\"Done\""); +std::unique_ptr<test::TestConditionWaiter> +OobeBaseTest::CreateGaiaPageEventWaiter(const std::string& event) { + return std::make_unique<GaiaPageEventWaiter>(authenticator_id_, event); } void OobeBaseTest::WaitForSigninScreen() {
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.h b/chrome/browser/chromeos/login/test/oobe_base_test.h index 95bf4001..0b31385 100644 --- a/chrome/browser/chromeos/login/test/oobe_base_test.h +++ b/chrome/browser/chromeos/login/test/oobe_base_test.h
@@ -8,6 +8,7 @@ #include <memory> #include <string> +#include "base/compiler_specific.h" #include "base/macros.h" #include "chrome/browser/chromeos/login/test/embedded_test_server_mixin.h" #include "chrome/browser/chromeos/login/test/js_checker.h" @@ -57,7 +58,8 @@ void WaitForGaiaPageLoadAndPropertyUpdate(); void WaitForGaiaPageReload(); void WaitForGaiaPageBackButtonUpdate(); - void WaitForGaiaPageEvent(const std::string& event); + WARN_UNUSED_RESULT std::unique_ptr<test::TestConditionWaiter> + CreateGaiaPageEventWaiter(const std::string& event); void WaitForSigninScreen(); void CheckJsExceptionErrors(int number); test::JSChecker SigninFrameJS();
diff --git a/chrome/browser/chromeos/login/ui/simple_web_view_dialog.cc b/chrome/browser/chromeos/login/ui/simple_web_view_dialog.cc index ef0e87a..ca1c96a 100644 --- a/chrome/browser/chromeos/login/ui/simple_web_view_dialog.cc +++ b/chrome/browser/chromeos/login/ui/simple_web_view_dialog.cc
@@ -191,8 +191,7 @@ location_bar_ = location_bar.get(); // Reload button. - auto reload = std::make_unique<ReloadButton>( - command_updater_.get(), ReloadButton::IconStyle::kBrowser); + auto reload = std::make_unique<ReloadButton>(command_updater_.get()); reload->set_triggerable_event_flags(ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON); reload->set_tag(IDC_RELOAD);
diff --git a/chrome/browser/chromeos/login/webview_login_browsertest.cc b/chrome/browser/chromeos/login/webview_login_browsertest.cc index 0017a4c..1fd75fc1 100644 --- a/chrome/browser/chromeos/login/webview_login_browsertest.cc +++ b/chrome/browser/chromeos/login/webview_login_browsertest.cc
@@ -397,18 +397,22 @@ ExpectIdentifierPage(); // Move to password page. + auto back_button_waiter = CreateGaiaPageEventWaiter("backButton"); SigninFrameJS().TypeIntoPath(FakeGaiaMixin::kFakeUserEmail, {"identifier"}); test::OobeJS().ClickOnPath(kPrimaryButton); - WaitForGaiaPageBackButtonUpdate(); + back_button_waiter->Wait(); ExpectPasswordPage(); // Click back to identifier page. + back_button_waiter = CreateGaiaPageEventWaiter("backButton"); test::OobeJS().ClickOnPath({"gaia-signin", "signin-back-button"}); - WaitForGaiaPageBackButtonUpdate(); + back_button_waiter->Wait(); ExpectIdentifierPage(); + + back_button_waiter = CreateGaiaPageEventWaiter("backButton"); // Click next to password page, user id is remembered. test::OobeJS().ClickOnPath(kPrimaryButton); - WaitForGaiaPageBackButtonUpdate(); + back_button_waiter->Wait(); ExpectPasswordPage(); // Finish sign-up.
diff --git a/chrome/browser/download/android/intercept_oma_download_navigation_throttle.cc b/chrome/browser/download/android/intercept_oma_download_navigation_throttle.cc index d218ff0d..dffd9550 100644 --- a/chrome/browser/download/android/intercept_oma_download_navigation_throttle.cc +++ b/chrome/browser/download/android/intercept_oma_download_navigation_throttle.cc
@@ -13,7 +13,7 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" -#include "third_party/blink/public/mojom/referrer.mojom.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom.h" using content::BrowserThread;
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 20cfc30..e13957d 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1009,6 +1009,11 @@ "expiry_milestone": 90 }, { + "name": "edit-passwords-in-settings", + "owners": [ "irfedorova", "jdoerrie" ], + "expiry_milestone": 88 + }, + { "name": "elastic-overscroll-win", "owners": [ "arakeri@microsoft.com" ], "expiry_milestone": 90
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index b111934..3f72c12 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3025,6 +3025,10 @@ #else // !defined(OS_ANDROID) +const char kEditPasswordsInDesktopSettingsName[] = "Edit passwords in settings"; +const char kEditPasswordsInDesktopSettingsDescription[] = + "Enables password editing in settings."; + const char kEnableAccessibilityLiveCaptionsName[] = "Live Captions"; const char kEnableAccessibilityLiveCaptionsDescription[] = "Enables the live captions feature which generates captions for "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 64aa7cd3..d287a982 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1736,6 +1736,9 @@ #else // !defined(OS_ANDROID) +extern const char kEditPasswordsInDesktopSettingsName[]; +extern const char kEditPasswordsInDesktopSettingsDescription[]; + extern const char kEnableAccessibilityLiveCaptionsName[]; extern const char kEnableAccessibilityLiveCaptionsDescription[];
diff --git a/chrome/browser/history/history_tab_helper.cc b/chrome/browser/history/history_tab_helper.cc index a637974c..94af992 100644 --- a/chrome/browser/history/history_tab_helper.cc +++ b/chrome/browser/history/history_tab_helper.cc
@@ -24,7 +24,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/common/frame_navigate_params.h" -#include "third_party/blink/public/mojom/referrer.mojom.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom.h" #include "ui/base/page_transition_types.h" #if defined(OS_ANDROID)
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc index ab1569f..0417129f 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc
@@ -35,7 +35,7 @@ #include "components/url_formatter/spoof_checks/top_domains/top500_domains.h" #include "components/url_formatter/spoof_checks/top_domains/top_domain_util.h" #include "content/public/browser/navigation_handle.h" -#include "third_party/blink/public/mojom/referrer.mojom.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom.h" namespace {
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc index c4f985ba9..c6b695a 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc
@@ -47,8 +47,6 @@ #include "third_party/blink/public/mojom/devtools/inspector_issue.mojom-shared.h" #include "third_party/blink/public/mojom/web_feature/web_feature.mojom.h" #include "ui/base/page_transition_types.h" -#include "ui/gfx/geometry/point.h" -#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "url/gurl.h" @@ -335,7 +333,6 @@ if (should_ignore_detected_ad && (ad_id == previous_data->root_frame_tree_node_id())) { - page_ad_density_tracker_.RemoveRect(id_and_data->first); ad_frames_data_storage_.erase(id_and_data->second); ad_frames_data_.erase(id_and_data); @@ -556,35 +553,6 @@ ancestor_data->set_media_status(FrameData::MediaStatus::kPlayed); } -void AdsPageLoadMetricsObserver::OnFrameIntersectionUpdate( - content::RenderFrameHost* render_frame_host, - const page_load_metrics::mojom::FrameIntersectionUpdate& - intersection_update) { - if (!intersection_update.main_frame_intersection_rect) - return; - - int frame_tree_node_id = render_frame_host->GetFrameTreeNodeId(); - if (render_frame_host == GetDelegate().GetWebContents()->GetMainFrame()) { - page_ad_density_tracker_.UpdateMainFrameRect( - *intersection_update.main_frame_intersection_rect); - return; - } - - // If the frame whose size has changed is the root of the ad ancestry chain, - // then update it. - FrameData* ancestor_data = FindFrameData(frame_tree_node_id); - if (ancestor_data && - frame_tree_node_id == ancestor_data->root_frame_tree_node_id()) { - page_ad_density_tracker_.RemoveRect(frame_tree_node_id); - // Only add frames if they are visible. - if (!ancestor_data->is_display_none()) { - page_ad_density_tracker_.AddRect( - frame_tree_node_id, - *intersection_update.main_frame_intersection_rect); - } - } -} - void AdsPageLoadMetricsObserver::OnFrameDeleted( content::RenderFrameHost* render_frame_host) { if (!render_frame_host) @@ -610,7 +578,6 @@ ancestor_data->RecordAdFrameLoadUkmEvent(GetDelegate().GetSourceId()); DCHECK(id_and_data->second != ad_frames_data_storage_.end()); ad_frames_data_storage_.erase(id_and_data->second); - page_ad_density_tracker_.RemoveRect(id_and_data->first); } // Delete this frame's entry from the map now that the store is deleted. @@ -741,24 +708,6 @@ return; PAGE_BYTES_HISTOGRAM("PageLoad.Clients.Ads.Resources.Bytes.Ads2", aggregate_frame_data_->ad_network_bytes()); - - if (page_ad_density_tracker_.MaxPageAdDensityByArea() != -1) { - UMA_HISTOGRAM_PERCENTAGE("PageLoad.Clients.Ads.AdDensity.MaxPercentByArea", - page_ad_density_tracker_.MaxPageAdDensityByArea()); - } - - if (page_ad_density_tracker_.MaxPageAdDensityByHeight() != -1) { - UMA_HISTOGRAM_PERCENTAGE( - "PageLoad.Clients.Ads.AdDensity.MaxPercentByHeight", - page_ad_density_tracker_.MaxPageAdDensityByHeight()); - } - - // Records true if both of the density calculations succeeded on the page. - UMA_HISTOGRAM_BOOLEAN( - "PageLoad.Clients.Ads.AdDensity.Recorded", - page_ad_density_tracker_.MaxPageAdDensityByArea() != -1 && - page_ad_density_tracker_.MaxPageAdDensityByHeight() != -1); - auto* ukm_recorder = ukm::UkmRecorder::Get(); ukm::builders::AdPageLoad builder(source_id); builder.SetTotalBytes(aggregate_frame_data_->network_bytes() >> 10) @@ -770,10 +719,7 @@ FrameData::ResourceMimeType::kVideo) >> 10) .SetMainframeAdBytes(ukm::GetExponentialBucketMinForBytes( - main_frame_data_->ad_network_bytes())) - .SetMaxAdDensityByArea(page_ad_density_tracker_.MaxPageAdDensityByArea()) - .SetMaxAdDensityByHeight( - page_ad_density_tracker_.MaxPageAdDensityByHeight()); + main_frame_data_->ad_network_bytes())); // Record cpu metrics for the page. builder.SetAdCpuTime(
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h index 07483ca9..66c9785 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.h
@@ -14,7 +14,6 @@ #include "base/scoped_observer.h" #include "base/time/tick_clock.h" #include "chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.h" -#include "chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.h" #include "components/page_load_metrics/browser/page_load_metrics_observer.h" #include "components/page_load_metrics/common/page_load_metrics.mojom-forward.h" #include "components/subresource_filter/content/browser/subresource_filter_observer.h" @@ -121,10 +120,6 @@ void MediaStartedPlaying( const content::WebContentsObserver::MediaPlayerInfo& video_type, content::RenderFrameHost* render_frame_host) override; - void OnFrameIntersectionUpdate( - content::RenderFrameHost* render_frame_host, - const page_load_metrics::mojom::FrameIntersectionUpdate& - intersection_update) override; void OnFrameDeleted(content::RenderFrameHost* render_frame_host) override; void SetHeavyAdThresholdNoiseProviderForTesting( @@ -275,9 +270,6 @@ std::unique_ptr<HeavyAdThresholdNoiseProvider> heavy_ad_threshold_noise_provider_; - // The maximum ad density measurements for the page during it's lifecycle. - PageAdDensityTracker page_ad_density_tracker_; - DISALLOW_COPY_AND_ASSIGN(AdsPageLoadMetricsObserver); };
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc index 166fc78c..8231fe19 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc
@@ -83,15 +83,6 @@ const char kHeavyAdInterventionTypeHistogramId[] = "PageLoad.Clients.Ads.HeavyAds.InterventionType2"; -const char kMaxAdDensityByAreaHistogramId[] = - "PageLoad.Clients.Ads.AdDensity.MaxPercentByArea"; - -const char kMaxAdDensityByHeightHistogramId[] = - "PageLoad.Clients.Ads.AdDensity.MaxPercentByHeight"; - -const char kMaxAdDensityRecordedHistogramId[] = - "PageLoad.Clients.Ads.AdDensity.Recorded"; - const char kHttpOkResponseHeader[] = "HTTP/1.1 200 OK\r\n" "Content-Type: text/html; charset=utf-8\r\n" @@ -246,244 +237,6 @@ static_cast<int>(FrameData::OriginStatus::kCross)); } -// Verifies that the page ad density records the maximum value during -// a page's lifecycling by creating a large ad frame, destroying it, and -// creating a smaller iframe. The ad density recorded is the density with -// the first larger frame. -IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, - PageAdDensityRecordsPageMax) { - base::HistogramTester histogram_tester; - ukm::TestAutoSetUkmRecorder ukm_recorder; - auto waiter = CreatePageLoadMetricsTestWaiter(); - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - - // Evaluate the height and width of the page as the browser_test can - // vary the dimensions. - int document_height = - EvalJs(web_contents, "document.body.scrollHeight").ExtractInt(); - int document_width = - EvalJs(web_contents, "document.body.scrollWidth").ExtractInt(); - - // Expectation is before NavigateToUrl for this test as the expectation can be - // met after NavigateToUrl and before the Wait. - waiter->AddMainFrameIntersectionExpectation( - gfx::Rect(0, 0, document_width, - document_height)); // Initial main frame rect. - ui_test_utils::NavigateToURL( - browser(), embedded_test_server()->GetURL( - "a.com", "/ads_observer/blank_with_adiframe_writer.html")); - waiter->Wait(); - web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - - // Create a frame at 100,100 of size 200,200. - waiter->AddMainFrameIntersectionExpectation(gfx::Rect(100, 100, 200, 200)); - - // Create the frame with b.com as origin to not get caught by - // restricted ad tagging. - EXPECT_TRUE(ExecJs( - web_contents, - content::JsReplace( - "let frame = createAdIframeAtRect(100, 100, 200, 200); " - "frame.src = $1; ", - embedded_test_server()->GetURL("b.com", "/ads_observer/pixel.png")))); - waiter->Wait(); - - // Load should stop before we remove the frame. - EXPECT_TRUE(WaitForLoadStop(web_contents)); - EXPECT_TRUE(ExecJs(web_contents, - "let frames = document.getElementsByTagName('iframe'); " - "frames[0].remove(); ")); - waiter->AddMainFrameIntersectionExpectation(gfx::Rect(400, 400, 10, 10)); - - // Delete the frame and create a new frame at 400,400 of size 10x10. The - // ad density resulting from this frame is lower than the 200x200. - EXPECT_TRUE(ExecJs( - web_contents, - content::JsReplace("let frame = createAdIframeAtRect(400, 400, 10, 10); " - "frame.src = $1; ", - embedded_test_server() - ->GetURL("b.com", "/ads_observer/pixel.png") - .spec()))); - waiter->Wait(); - - // Evaluate the height and width of the page as the browser_test can - // vary the dimensions. - document_height = - EvalJs(web_contents, "document.body.scrollHeight").ExtractInt(); - document_width = - EvalJs(web_contents, "document.body.scrollWidth").ExtractInt(); - - int page_area = document_width * document_height; - int ad_area = 200 * 200; // The area of the first larger ad iframe. - int expected_page_density_area = ad_area * 100 / page_area; - int expected_page_density_height = 200 * 100 / document_height; - - ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); - - histogram_tester.ExpectUniqueSample(kMaxAdDensityByAreaHistogramId, - expected_page_density_area, 1); - histogram_tester.ExpectUniqueSample(kMaxAdDensityByHeightHistogramId, - expected_page_density_height, 1); - histogram_tester.ExpectUniqueSample(kMaxAdDensityRecordedHistogramId, true, - 1); - auto entries = - ukm_recorder.GetEntriesByName(ukm::builders::AdPageLoad::kEntryName); - EXPECT_EQ(1u, entries.size()); - ukm_recorder.ExpectEntryMetric( - entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByAreaName, - expected_page_density_area); - ukm_recorder.ExpectEntryMetric( - entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByHeightName, - expected_page_density_height); -} - -// Creates multiple overlapping frames and verifies the page ad density. -IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, - PageAdDensityMultipleFrames) { - base::HistogramTester histogram_tester; - ukm::TestAutoSetUkmRecorder ukm_recorder; - auto waiter = CreatePageLoadMetricsTestWaiter(); - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - - int document_height = - EvalJs(web_contents, "document.body.scrollHeight").ExtractInt(); - int document_width = - EvalJs(web_contents, "document.body.scrollWidth").ExtractInt(); - - // Expectation is before NavigateToUrl for this test as the expectation can be - // met after NavigateToUrl and before the Wait. - waiter->AddMainFrameIntersectionExpectation( - gfx::Rect(0, 0, document_width, - document_height)); // Initial main frame rect. - - ui_test_utils::NavigateToURL( - browser(), embedded_test_server()->GetURL( - "a.com", "/ads_observer/blank_with_adiframe_writer.html")); - waiter->Wait(); - web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - - // Create a frame of size 400,400 at 100,100. - waiter->AddMainFrameIntersectionExpectation(gfx::Rect(400, 400, 100, 100)); - - // Create the frame with b.com as origin to not get caught by - // restricted ad tagging. - EXPECT_TRUE(ExecJs( - web_contents, content::JsReplace( - "let frame = createAdIframeAtRect(400, 400, 100, 100); " - "frame.src = $1", - embedded_test_server() - ->GetURL("b.com", "/ads_observer/pixel.png") - .spec()))); - - waiter->Wait(); - - // Create a frame at of size 200,200 at 450,450. - waiter->AddMainFrameIntersectionExpectation(gfx::Rect(450, 450, 200, 200)); - EXPECT_TRUE(ExecJs( - web_contents, content::JsReplace( - "let frame = createAdIframeAtRect(450, 450, 200, 200); " - "frame.src = $1", - embedded_test_server() - ->GetURL("b.com", "/ads_observer/pixel.png") - .spec()))); - waiter->Wait(); - - // Evaluate the height and width of the page as the browser_test can - // vary the dimensions. - document_height = - EvalJs(web_contents, "document.body.scrollHeight").ExtractInt(); - document_width = - EvalJs(web_contents, "document.body.scrollWidth").ExtractInt(); - - ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); - - int page_area = document_width * document_height; - // The area of the two iframes minus the area of the overlapping section. - int ad_area = 100 * 100 + 200 * 200 - 50 * 50; - int expected_page_density_area = ad_area * 100 / page_area; - int expected_page_density_height = 250 * 100 / document_height; - - histogram_tester.ExpectUniqueSample(kMaxAdDensityByAreaHistogramId, - expected_page_density_area, 1); - histogram_tester.ExpectUniqueSample(kMaxAdDensityByHeightHistogramId, - expected_page_density_height, 1); - histogram_tester.ExpectUniqueSample(kMaxAdDensityRecordedHistogramId, true, - 1); - auto entries = - ukm_recorder.GetEntriesByName(ukm::builders::AdPageLoad::kEntryName); - EXPECT_EQ(1u, entries.size()); - ukm_recorder.ExpectEntryMetric( - entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByAreaName, - expected_page_density_area); - ukm_recorder.ExpectEntryMetric( - entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByHeightName, - expected_page_density_height); -} - -// Creates a frame with display:none styling and verifies that it has an -// empty intersection with the main frame. -IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, - PageAdDensityIgnoreDisplayNoneFrame) { - base::HistogramTester histogram_tester; - ukm::TestAutoSetUkmRecorder ukm_recorder; - auto waiter = CreatePageLoadMetricsTestWaiter(); - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - - // Evaluate the height and width of the page as the browser_test can - // vary the dimensions. - int document_height = - EvalJs(web_contents, "document.body.scrollHeight").ExtractInt(); - int document_width = - EvalJs(web_contents, "document.body.scrollWidth").ExtractInt(); - - // Expectation is before NavigateToUrl for this test as the expectation can be - // met after NavigateToUrl and before the Wait. - waiter->AddMainFrameIntersectionExpectation( - gfx::Rect(0, 0, document_width, - document_height)); // Initial main frame rect. - - ui_test_utils::NavigateToURL( - browser(), embedded_test_server()->GetURL( - "a.com", "/ads_observer/blank_with_adiframe_writer.html")); - waiter->Wait(); - web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - - // Create a frame at 100,100 of size 200,200. The expectation is an empty rect - // as the frame is display:none and as a result has no main frame - // intersection. - waiter->AddMainFrameIntersectionExpectation(gfx::Rect(0, 0, 0, 0)); - - // Create the frame with b.com as origin to not get caught by - // restricted ad tagging. - EXPECT_TRUE(ExecJs( - web_contents, content::JsReplace( - "let frame = createAdIframeAtRect(100, 100, 200, 200); " - "frame.src = $1; " - "frame.style.display = \"none\";", - embedded_test_server() - ->GetURL("b.com", "/ads_observer/pixel.png") - .spec()))); - - waiter->Wait(); - - ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); - - histogram_tester.ExpectUniqueSample(kMaxAdDensityByAreaHistogramId, 0, 1); - histogram_tester.ExpectUniqueSample(kMaxAdDensityByHeightHistogramId, 0, 1); - histogram_tester.ExpectUniqueSample(kMaxAdDensityRecordedHistogramId, true, - 1); - auto entries = - ukm_recorder.GetEntriesByName(ukm::builders::AdPageLoad::kEntryName); - EXPECT_EQ(1u, entries.size()); - ukm_recorder.ExpectEntryMetric( - entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByAreaName, 0); - ukm_recorder.ExpectEntryMetric( - entries.front(), ukm::builders::AdPageLoad::kMaxAdDensityByHeightName, 0); -} - // Each CreativeOriginStatus* browser test inputs a pointer to a frame object // representing the frame tree path of a website with with a (possibly null) // ad subframe, which itself may have linearly nested subframes.
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.h b/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.h index 8f1000e..4fd6937 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.h +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/frame_data.h
@@ -238,8 +238,6 @@ gfx::Size frame_size() const { return frame_size_; } - bool is_display_none() const { return is_display_none_; } - MediaStatus media_status() const { return media_status_; } void set_media_status(MediaStatus media_status) {
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.cc deleted file mode 100644 index 4daffc7..0000000 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.cc +++ /dev/null
@@ -1,297 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.h" -#include "base/metrics/histogram_macros.h" -#include "base/numerics/checked_math.h" -#include "base/optional.h" - -namespace { - -// Calculates the combined length of a set of line segments. This counts -// each overlapping area a single time and does not include areas where there -// is no line segment. -// -// TODO(https://crbug.com/1068586): Optimize segment length calculation. -// AddSegment and RemoveSegment are both logarithmic operations, making this -// linearithmic with the number of segments. However the expected number -// of segments at any given time in the density calculation is low. -class SegmentLength { - public: - // An event to process corresponding to the left or right point of each - // line segment. - struct SegmentEvent { - SegmentEvent(int segment_id, int pos, bool is_segment_start) - : segment_id(segment_id), - pos(pos), - is_segment_start(is_segment_start) {} - SegmentEvent(const SegmentEvent& other) = default; - - // Tiebreak with position with |is_segment_start| and |segment_id|. - bool operator<(const SegmentEvent& rhs) const { - if (pos == rhs.pos) { - if (segment_id == rhs.segment_id) { - return is_segment_start != rhs.is_segment_start; - } else { - return segment_id < rhs.segment_id; - } - } else { - return pos < rhs.pos; - } - } - - int segment_id; - int pos; - bool is_segment_start; - }; - - // Iterators into the set of segment events for efficient removal of - // segment events by segment_id. Maintained by |segment_event_iterators_|. - struct SegmentEventSetIterators { - SegmentEventSetIterators(std::set<SegmentEvent>::iterator start, - std::set<SegmentEvent>::iterator end) - : start_it(start), end_it(end) {} - - SegmentEventSetIterators(const SegmentEventSetIterators& other) = default; - - std::set<SegmentEvent>::const_iterator start_it; - std::set<SegmentEvent>::const_iterator end_it; - }; - - SegmentLength() = default; - ~SegmentLength() = default; - - // Add a line segment to the set of active line segments, the segment - // corresponds to the bottom or top of a rect. - void AddSegment(int segment_id, int start, int end) { - // Safe as insert will never return an invalid iterator, it will - // point to the existing element if already in the set. - auto start_it = - active_segments_ - .insert(SegmentEvent(segment_id, start, true /*is_segment_start*/)) - .first; - auto end_it = - active_segments_ - .insert(SegmentEvent(segment_id, end, false /*is_segment_start*/)) - .first; - - segment_event_iterators_.emplace( - segment_id, SegmentEventSetIterators(start_it, end_it)); - } - - // Remove a segment from the set of active line segmnets. - void RemoveSegment(int segment_id) { - auto it = segment_event_iterators_.find(segment_id); - DCHECK(it != segment_event_iterators_.end()); - - const SegmentEventSetIterators& set_its = it->second; - active_segments_.erase(set_its.start_it); - active_segments_.erase(set_its.end_it); - segment_event_iterators_.erase(segment_id); - } - - // Calculate the combined length of segments in the active set of segments by - // iterating over the the sorted set of segment events. - base::Optional<int> Length() { - base::CheckedNumeric<int> length = 0; - int last_event_pos = -1; - int num_active = 0; - for (const auto& segment_event : active_segments_) { - if (last_event_pos == -1) { - DCHECK(segment_event.is_segment_start); - last_event_pos = segment_event.pos; - } - - if (num_active > 0) - length += segment_event.pos - last_event_pos; - - last_event_pos = segment_event.pos; - if (segment_event.is_segment_start) { - num_active += 1; - } else { - num_active -= 1; - } - } - - base::Optional<int> total_length; - if (length.IsValid()) - total_length = length.ValueOrDie(); - - return total_length; - } - - private: - std::set<SegmentEvent> active_segments_; - - // Map from the segment_id passed by user to the Segment struct. - std::unordered_map<int, SegmentEventSetIterators> segment_event_iterators_; - - DISALLOW_COPY_AND_ASSIGN(SegmentLength); -}; - -} // namespace - -PageAdDensityTracker::RectEvent::RectEvent(int id, - bool is_bottom, - const gfx::Rect& rect) - : rect_id(id), is_bottom(is_bottom), rect(rect) {} - -PageAdDensityTracker::RectEvent::RectEvent(const RectEvent& other) = default; - -PageAdDensityTracker::RectEventSetIterators::RectEventSetIterators( - std::set<RectEvent>::iterator top, - std::set<RectEvent>::iterator bottom) - : top_it(top), bottom_it(bottom) {} - -PageAdDensityTracker::RectEventSetIterators::RectEventSetIterators( - const RectEventSetIterators& other) = default; - -PageAdDensityTracker::PageAdDensityTracker() = default; - -PageAdDensityTracker::~PageAdDensityTracker() = default; - -int PageAdDensityTracker::MaxPageAdDensityByHeight() { - return max_page_ad_density_by_height_; -} - -int PageAdDensityTracker::MaxPageAdDensityByArea() { - return max_page_ad_density_by_area_; -} - -void PageAdDensityTracker::AddRect(int rect_id, const gfx::Rect& rect) { - // Check that we do not already have rect events for the rect. - DCHECK(rect_events_iterators_.find(rect_id) == rect_events_iterators_.end()); - - // We do not track empty rects. - if (rect.IsEmpty()) - return; - - // Limit the maximum number of rects tracked to 50 due to poor worst - // case performance. - const int kMaxRectsTracked = 50; - if (rect_events_iterators_.size() > kMaxRectsTracked) - return; - - auto top_it = - rect_events_.insert(RectEvent(rect_id, true /*is_bottom*/, rect)).first; - auto bottom_it = - rect_events_.insert(RectEvent(rect_id, false /*is_bottom*/, rect)).first; - rect_events_iterators_.emplace(rect_id, - RectEventSetIterators(top_it, bottom_it)); - - // TODO(https://crbug.com/1068586): Improve performance by adding additional - // throttling to only calculate when max density can decrease (frame deleted - // or moved). - CalculateDensity(); -} - -void PageAdDensityTracker::RemoveRect(int rect_id) { - auto it = rect_events_iterators_.find(rect_id); - - if (it == rect_events_iterators_.end()) - return; - - const RectEventSetIterators& set_its = it->second; - rect_events_.erase(set_its.top_it); - rect_events_.erase(set_its.bottom_it); - rect_events_iterators_.erase(rect_id); -} - -void PageAdDensityTracker::UpdateMainFrameRect(const gfx::Rect& rect) { - if (!last_main_frame_size_ || rect != *last_main_frame_size_) { - last_main_frame_size_ = rect; - CalculateDensity(); - } -} - -// Ad density measurement uses a modified Bentley's Algorithm, the high level -// approach is described on: http://jeffe.cs.illinois.edu/open/klee.html. -void PageAdDensityTracker::CalculateDensity() { - // Cannot calculate density if there is no main frame rect. - if (!last_main_frame_size_) - return; - - SegmentLength segment_length_tracker; - - int last_y = -1; - base::CheckedNumeric<int> total_area = 0; - base::CheckedNumeric<int> total_height = 0; - for (const auto& rect_event : rect_events_) { - if (last_y == -1) { - DCHECK(rect_event.is_bottom); - segment_length_tracker.AddSegment( - rect_event.rect_id, rect_event.rect.x(), - rect_event.rect.x() + rect_event.rect.width()); - last_y = - rect_event.is_bottom ? rect_event.rect.bottom() : rect_event.rect.y(); - } - - int current_y = - rect_event.is_bottom ? rect_event.rect.bottom() : rect_event.rect.y(); - DCHECK_LE(current_y, last_y); - - // If the segment length value is invalid, skip this ad density calculation. - base::Optional<int> segment_length = segment_length_tracker.Length(); - if (!segment_length) - return; - - // Check that the segment length multiplied by the height of the block - // does not overflow an int. - base::CheckedNumeric<int> current_area = *segment_length; - current_area *= (last_y - current_y); - if (!current_area.IsValid()) - return; - - total_area += *segment_length * (last_y - current_y); - - if (*segment_length > 0) - total_height += (last_y - current_y); - - // As we are iterating from the bottom of the page to the top, add segments - // when we see the start (bottom) of a new rect. - if (rect_event.is_bottom) { - segment_length_tracker.AddSegment( - rect_event.rect_id, rect_event.rect.x(), - rect_event.rect.x() + rect_event.rect.width()); - } else { - segment_length_tracker.RemoveSegment(rect_event.rect_id); - } - last_y = current_y; - } - - // If the measured height or area is invalid, skip recording this ad density - // calculation. - if (!total_height.IsValid() || !total_area.IsValid()) - return; - - base::CheckedNumeric<int> ad_density_by_height = - total_height * 100 / last_main_frame_size_->height(); - if (ad_density_by_height.IsValid() && - ad_density_by_height.ValueOrDie() > max_page_ad_density_by_height_) - max_page_ad_density_by_height_ = ad_density_by_height.ValueOrDie(); - - // Invalidate the check numeric if the checked area is invalid. - base::CheckedNumeric<int> ad_density_by_area = - total_area * 100 / - (last_main_frame_size_->size().GetCheckedArea().ValueOrDefault(0)); - if (ad_density_by_area.IsValid() && - ad_density_by_area.ValueOrDie() > max_page_ad_density_by_area_) - max_page_ad_density_by_area_ = ad_density_by_area.ValueOrDie(); -} - -bool PageAdDensityTracker::RectEvent::operator<(const RectEvent& rhs) const { - int lhs_y = is_bottom ? rect.bottom() : rect.y(); - int rhs_y = rhs.is_bottom ? rhs.rect.bottom() : rhs.rect.y(); - - // Tiebreak with |rect_id| and |is_bottom|. - if (lhs_y == rhs_y) { - if (rect_id == rhs.rect_id) { - return is_bottom == rhs.is_bottom; - } else { - return rect_id < rhs.rect_id; - } - } else { - return lhs_y > rhs_y; - } -}
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.h b/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.h deleted file mode 100644 index b2f013d..0000000 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.h +++ /dev/null
@@ -1,96 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_AD_METRICS_PAGE_AD_DENSITY_TRACKER_H_ -#define CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_AD_METRICS_PAGE_AD_DENSITY_TRACKER_H_ - -#include <set> -#include <unordered_map> - -#include "base/optional.h" -#include "ui/gfx/geometry/rect.h" - -// Tracks the ad density of a page through the page's lifecycle. -// It has the following usage: -// 1. Set subframe and mainframe rects using subframe and mainframe rect -// operations (AddRect, RemoveRect, UpdateMainFrameRect). -// 2. Once a page has a main frame rect, get current density using -// DensityByHeight or DensityByArea. -class PageAdDensityTracker { - public: - PageAdDensityTracker(); - ~PageAdDensityTracker(); - - PageAdDensityTracker(const PageAdDensityTracker&) = delete; - PageAdDensityTracker& operator=(const PageAdDensityTracker&) = delete; - - // Operations to track sub frame rects in the page density calcluation. - void AddRect(int rect_id, const gfx::Rect& rect); - - // Removes a rect from the tracker if it is currently being tracked. - // Otherwise RemoveRect is a no op. - void RemoveRect(int rect_id); - - // Operations to track the main frame dimensions. The main frame rect has to - // be set to calculate density. - void UpdateMainFrameRect(const gfx::Rect& rect); - - // Returns the density by height, as a value from 0-100. If the density - // calculation fails (i.e. no main frame size), this returns -1. Percentage - // density by height is calculated as the the combined height of ads divided - // by the page's height. - int MaxPageAdDensityByHeight(); - - // Returns the density by area, as a value from 0-100. If the density - // calculation fails (i.e. no main frame size), this returns -1. - int MaxPageAdDensityByArea(); - - private: - // An event to process corresponding to the top or bottom of each rect. - struct RectEvent { - RectEvent(int id, bool is_bottom, const gfx::Rect& rect); - RectEvent(const RectEvent& other); - - // A unique identifier set when adding and removing rect events - // corresponding to a single rect. - int rect_id; - bool is_bottom; - gfx::Rect rect; - - // RectEvents are sorted by descending y value of the segment associated - // with the event. - bool operator<(const RectEvent& rhs) const; - }; - - // Iterators into the set of rect events for efficient removal of - // rect events by rect_id. Maintained by |rect_events_iterators_|. - struct RectEventSetIterators { - RectEventSetIterators(std::set<RectEvent>::iterator top, - std::set<RectEvent>::iterator bottom); - RectEventSetIterators(const RectEventSetIterators& other); - - std::set<RectEvent>::const_iterator top_it; - std::set<RectEvent>::const_iterator bottom_it; - }; - - // Calculates the combined area and height of the set of rects, this populates - // total_height_ and total_area_. - void CalculateDensity(); - - // Maintain a sorted set of rect events for use in calculating ad area. - std::set<RectEvent> rect_events_; - - // Map from rect_id to iterators of rect events in rect_events_. This allows - // efficient removal according to rect_id. - std::unordered_map<int, RectEventSetIterators> rect_events_iterators_; - - // Percentage of page ad density as a value from 0-100. These only have - // a value of -1 when ad density has not yet been calculated successfully. - int max_page_ad_density_by_area_ = -1; - int max_page_ad_density_by_height_ = -1; - - base::Optional<gfx::Rect> last_main_frame_size_; -}; - -#endif // CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_AD_METRICS_PAGE_AD_DENSITY_TRACKER_H_"
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker_unittest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker_unittest.cc deleted file mode 100644 index 65d92c7..0000000 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker_unittest.cc +++ /dev/null
@@ -1,98 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <limits> - -#include "chrome/browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/geometry/rect.h" - -TEST(PageAdDensityTrackerTest, MultipleRects_MaxPageDensityByAreaCalculated) { - PageAdDensityTracker tracker; - - // Page ad density is -1 before there is a main frame or subframes. - EXPECT_EQ(tracker.MaxPageAdDensityByArea(), -1); - - tracker.UpdateMainFrameRect(gfx::Rect(0, 0, 100, 100)); - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 100, 10)); - EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 10); - - tracker.AddRect(2 /* rect_id */, gfx::Rect(5, 5, 100, 10)); - EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 15); - - tracker.AddRect(3 /* rect_id */, gfx::Rect(50, 50, 50, 50)); - EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 40); - - // Removing a rect should not change the maximum ad density. - tracker.RemoveRect(3 /* rect_id */); - EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 40); -} - -TEST(PageAdDensityTrackerTest, MultipleRects_MaxPageDensityByHeightCalculated) { - PageAdDensityTracker tracker; - - // Page ad density is -1 before there is a main frame or subframes. - EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), -1); - - tracker.UpdateMainFrameRect(gfx::Rect(0, 0, 100, 100)); - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 100, 10)); - EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), 10); - - tracker.AddRect(2 /* rect_id */, gfx::Rect(5, 5, 100, 10)); - EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), 15); - - tracker.AddRect(3 /* rect_id */, gfx::Rect(50, 50, 50, 50)); - EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), 65); - - // Removing a rect should not change the maximum ad density. - tracker.RemoveRect(3 /* rect_id */); - EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), 65); -} - -// Remove a rect that was added twice, the second RemoveRect is -// ignored as it is no longer being tracked. -TEST(PageAdDensityTrackerTest, RemoveRectTwice_SecondRemoveIgnored) { - PageAdDensityTracker tracker; - - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 100, 10)); - tracker.RemoveRect(1 /* rect_id */); - tracker.RemoveRect(1 /* rect_id */); -} - -// Ensures that two rects with the same dimensions hash to different -// values in the density tracker's frame set. -TEST(PageAdDensityTrackerTest, SeperateRects_SameDimensions) { - PageAdDensityTracker tracker; - - tracker.UpdateMainFrameRect(gfx::Rect(0, 0, 100, 100)); - - tracker.AddRect(1 /* rect_id */, gfx::Rect(0, 0, 100, 10)); - tracker.AddRect(2 /* rect_id */, gfx::Rect(0, 0, 100, 10)); - EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 10); - - tracker.RemoveRect(1 /* rect_id */); - tracker.RemoveRect(2 /* rect_id */); - EXPECT_EQ(tracker.MaxPageAdDensityByArea(), 10); -} - -// Create 2 rects whose total area overflow an int. -TEST(PageAdDensityTrackerTest, OverflowTotalAreaAndHeight) { - PageAdDensityTracker tracker; - - tracker.AddRect(1 /* rect_id */, gfx::Rect(std::numeric_limits<int>::min(), 0, - std::numeric_limits<int>::max(), - std::numeric_limits<int>::max())); - tracker.AddRect(2 /* rect_id */, gfx::Rect(std::numeric_limits<int>::min(), - std::numeric_limits<int>::max(), - std::numeric_limits<int>::max(), - std::numeric_limits<int>::max())); - - // Update main frame rect to force a calculation. - tracker.UpdateMainFrameRect(gfx::Rect(0, 0, 100, 100)); - - // Density should not be updated as the sum of area - // or height overflows. - EXPECT_EQ(tracker.MaxPageAdDensityByArea(), -1); - EXPECT_EQ(tracker.MaxPageAdDensityByHeight(), -1); -}
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index ac02525..ef6eb82 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -70,9 +70,6 @@ #include "chrome/test/base/ui_test_utils.h" #include "components/browsing_data/content/browsing_data_helper.h" #include "components/content_settings/core/browser/host_content_settings_map.h" -#include "components/omnibox/browser/omnibox_edit_model.h" -#include "components/omnibox/browser/omnibox_popup_model.h" -#include "components/omnibox/browser/omnibox_view.h" #include "components/page_load_metrics/browser/metrics_web_contents_observer.h" #include "components/page_load_metrics/browser/page_load_tracker.h" #include "components/page_load_metrics/common/test/page_load_metrics_test_util.h" @@ -626,12 +623,6 @@ return display_test_result; } - std::unique_ptr<TestPrerender> ExpectPrerender( - FinalStatus expected_final_status) { - return prerender_contents_factory()->ExpectPrerenderContents( - expected_final_status); - } - void AddPrerender(const GURL& url, int index) { std::string javascript = base::StringPrintf("AddPrerender('%s', %d)", url.spec().c_str(), index); @@ -986,150 +977,6 @@ true)) /* Enable delayed warnings experiment */ ); -// Test interaction of the webNavigation and tabs API with prerender. -class PrerenderBrowserTestWithExtensions : public PrerenderBrowserTest, - public extensions::ExtensionApiTest { - public: - PrerenderBrowserTestWithExtensions() { - // The individual tests start the test server through ExtensionApiTest, so - // the port number can be passed through to the extension. - set_autostart_test_server(false); - } - - void SetUp() override { PrerenderBrowserTest::SetUp(); } - - void SetUpCommandLine(base::CommandLine* command_line) override { - extensions::ExtensionApiTest::SetUpCommandLine(command_line); - } - - void SetUpInProcessBrowserTestFixture() override { - PrerenderBrowserTest::SetUpInProcessBrowserTestFixture(); - extensions::ExtensionApiTest::SetUpInProcessBrowserTestFixture(); - } - - void TearDownInProcessBrowserTestFixture() override { - PrerenderBrowserTest::TearDownInProcessBrowserTestFixture(); - extensions::ExtensionApiTest::TearDownInProcessBrowserTestFixture(); - } - - void TearDownOnMainThread() override { - PrerenderBrowserTest::TearDownOnMainThread(); - extensions::ExtensionApiTest::TearDownOnMainThread(); - } - - void SetUpOnMainThread() override { - PrerenderBrowserTest::SetUpOnMainThread(); - extensions::ExtensionApiTest::SetUpOnMainThread(); - } -}; - -IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, WebNavigation) { - ASSERT_TRUE(StartEmbeddedTestServer()); - extensions::FrameNavigationState::set_allow_extension_scheme(true); - - // Wait for the extension to set itself up and return control to us. - ASSERT_TRUE(RunExtensionTest("webnavigation/prerender")) << message_; - - extensions::ResultCatcher catcher; - - PrerenderTestURL("/prerender/prerender_page.html", FINAL_STATUS_USED, 1); - - ChannelDestructionWatcher channel_close_watcher; - channel_close_watcher.WatchChannel(browser() - ->tab_strip_model() - ->GetActiveWebContents() - ->GetMainFrame() - ->GetProcess()); - NavigateToDestURL(); - channel_close_watcher.WaitForChannelClose(); - - ASSERT_TRUE(IsEmptyPrerenderLinkManager()); - ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); -} - -IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, TabsApi) { - ASSERT_TRUE(StartEmbeddedTestServer()); - extensions::FrameNavigationState::set_allow_extension_scheme(true); - - // Wait for the extension to set itself up and return control to us. - ASSERT_TRUE(RunExtensionTest("tabs/on_replaced")) << message_; - - extensions::ResultCatcher catcher; - - PrerenderTestURL("/prerender/prerender_page.html", FINAL_STATUS_USED, 1); - - ChannelDestructionWatcher channel_close_watcher; - channel_close_watcher.WatchChannel(browser() - ->tab_strip_model() - ->GetActiveWebContents() - ->GetMainFrame() - ->GetProcess()); - NavigateToDestURL(); - channel_close_watcher.WaitForChannelClose(); - - ASSERT_TRUE(IsEmptyPrerenderLinkManager()); - ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); -} - -// Checks that non-http/https/chrome-extension subresource cancels the -// prerender. -IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, - PrerenderCancelSubresourceUnsupportedScheme) { - GURL image_url = GURL("invalidscheme://www.google.com/test.jpg"); - base::StringPairs replacement_text; - replacement_text.push_back( - std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec())); - std::string replacement_path = net::test_server::GetFilePathWithReplacements( - "/prerender/prerender_with_image.html", replacement_text); - // Disable load event checks because they race with cancellation. - DisableLoadEventCheck(); - PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 0); -} - -// Attempt a swap-in in a new tab. The session storage doesn't match, so it -// should not swap. -IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTab) { - PrerenderTestURL("/prerender/prerender_page.html", - FINAL_STATUS_APP_TERMINATING, 1); - - // Open a new tab to navigate in. - ui_test_utils::NavigateToURLWithDisposition( - current_browser(), GURL(url::kAboutBlankURL), - WindowOpenDisposition::NEW_FOREGROUND_TAB, - ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); - - // Now navigate in the new tab. - NavigateToDestURLWithDisposition(WindowOpenDisposition::CURRENT_TAB, false); -} - -class PrerenderOmniboxBrowserTest : public PrerenderBrowserTest { - public: - LocationBar* GetLocationBar() { - return current_browser()->window()->GetLocationBar(); - } - - OmniboxView* GetOmniboxView() { return GetLocationBar()->GetOmniboxView(); } - - predictors::AutocompleteActionPredictor* GetAutocompleteActionPredictor() { - Profile* profile = current_browser()->profile(); - return predictors::AutocompleteActionPredictorFactory::GetForProfile( - profile); - } - - std::unique_ptr<TestPrerender> StartOmniboxPrerender( - const GURL& url, - FinalStatus expected_final_status) { - std::unique_ptr<TestPrerender> prerender = - ExpectPrerender(expected_final_status); - WebContents* web_contents = GetActiveWebContents(); - GetAutocompleteActionPredictor()->StartPrerendering( - url, web_contents->GetController().GetDefaultSessionStorageNamespace(), - gfx::Size(50, 50)); - prerender->WaitForStart(); - return prerender; - } -}; - } // namespace prerender #endif // !defined(OS_MACOSX) || !defined(ADDRESS_SANITIZER)
diff --git a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc index c6b6b96..a78df5e 100644 --- a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc +++ b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc
@@ -22,6 +22,8 @@ #include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/history/history_test_utils.h" +#include "chrome/browser/predictors/autocomplete_action_predictor.h" +#include "chrome/browser/predictors/autocomplete_action_predictor_factory.h" #include "chrome/browser/prerender/prerender_handle.h" #include "chrome/browser/prerender/prerender_manager.h" #include "chrome/browser/prerender/prerender_manager_factory.h" @@ -31,12 +33,16 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/location_bar/location_bar.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/ui_test_utils.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/common/pref_names.h" #include "components/embedder_support/switches.h" +#include "components/omnibox/browser/omnibox_edit_model.h" +#include "components/omnibox/browser/omnibox_view.h" #include "components/prefs/pref_service.h" #include "content/public/browser/appcache_service.h" #include "content/public/browser/browser_task_traits.h" @@ -1709,6 +1715,16 @@ WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 0); } +// Checks that prerenders are aborted when an incognito profile is closed. +// ToDo(crbug.com/994068): The test is crashing on multiple platforms. +IN_PROC_BROWSER_TEST_F(NoStatePrefetchIncognitoBrowserTest, + PrerenderIncognitoClosed) { + std::unique_ptr<TestPrerender> test_prerender = + PrefetchFromFile(kHungPrerenderPage, FINAL_STATUS_PROFILE_DESTROYED); + current_browser()->window()->Close(); + test_prerender->WaitForStop(); +} + // Checks that when the history is cleared, NoStatePrefetch history is cleared. IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, ClearHistory) { std::unique_ptr<TestPrerender> test_prerender = PrefetchFromFile( @@ -1802,4 +1818,50 @@ FINAL_STATUS_MEMORY_LIMIT_EXCEEDED); } +class NoStatePrefetchOmniboxBrowserTest : public NoStatePrefetchBrowserTest { + public: + LocationBar* GetLocationBar() { + return current_browser()->window()->GetLocationBar(); + } + + OmniboxView* GetOmniboxView() { return GetLocationBar()->GetOmniboxView(); } + + predictors::AutocompleteActionPredictor* GetAutocompleteActionPredictor() { + Profile* profile = current_browser()->profile(); + return predictors::AutocompleteActionPredictorFactory::GetForProfile( + profile); + } + + std::unique_ptr<TestPrerender> ExpectPrerender( + FinalStatus expected_final_status) { + return prerender_contents_factory()->ExpectPrerenderContents( + expected_final_status); + } + + std::unique_ptr<TestPrerender> StartOmniboxPrerender( + const GURL& url, + FinalStatus expected_final_status) { + std::unique_ptr<TestPrerender> prerender = + ExpectPrerender(expected_final_status); + content::WebContents* web_contents = GetActiveWebContents(); + GetAutocompleteActionPredictor()->StartPrerendering( + url, web_contents->GetController().GetDefaultSessionStorageNamespace(), + gfx::Size(50, 50)); + prerender->WaitForStart(); + return prerender; + } +}; + +// Checks that closing the omnibox popup cancels an omnibox prerender. +IN_PROC_BROWSER_TEST_F(NoStatePrefetchOmniboxBrowserTest, + PrerenderOmniboxCancel) { + // Fake an omnibox prerender. + std::unique_ptr<TestPrerender> prerender = StartOmniboxPrerender( + embedded_test_server()->GetURL("/empty.html"), FINAL_STATUS_CANCELLED); + + // Revert the location bar. This should cancel the prerender. + GetLocationBar()->Revert(); + prerender->WaitForStop(); +} + } // namespace prerender
diff --git a/chrome/browser/profiles/android/java/src/org/chromium/chrome/browser/profiles/Profile.java b/chrome/browser/profiles/android/java/src/org/chromium/chrome/browser/profiles/Profile.java index 9d15c62..9148a66 100644 --- a/chrome/browser/profiles/android/java/src/org/chromium/chrome/browser/profiles/Profile.java +++ b/chrome/browser/profiles/android/java/src/org/chromium/chrome/browser/profiles/Profile.java
@@ -141,6 +141,13 @@ return ProfileJni.get().hasPrimaryOTRProfile(mNativeProfileAndroid, Profile.this); } + /** + * Returns if the profile is a primary OTR Profile. + */ + public boolean isPrimaryOTRProfile() { + return ProfileJni.get().isPrimaryOTRProfile(mNativeProfileAndroid, Profile.this); + } + public ProfileKey getProfileKey() { return (ProfileKey) ProfileJni.get().getProfileKey(mNativeProfileAndroid, Profile.this); } @@ -219,6 +226,7 @@ long nativeProfileAndroid, Profile caller, OTRProfileID otrProfileID); boolean hasPrimaryOTRProfile(long nativeProfileAndroid, Profile caller); boolean isOffTheRecord(long nativeProfileAndroid, Profile caller); + boolean isPrimaryOTRProfile(long nativeProfileAndroid, Profile caller); boolean isChild(long nativeProfileAndroid, Profile caller); void wipe(long nativeProfileAndroid, Profile caller); Object getProfileKey(long nativeProfileAndroid, Profile caller);
diff --git a/chrome/browser/profiles/profile_android.cc b/chrome/browser/profiles/profile_android.cc index 065f714e..d01502f 100644 --- a/chrome/browser/profiles/profile_android.cc +++ b/chrome/browser/profiles/profile_android.cc
@@ -128,6 +128,11 @@ return profile_->HasPrimaryOTRProfile(); } +jboolean ProfileAndroid::IsPrimaryOTRProfile(JNIEnv* env, + const JavaParamRef<jobject>& obj) { + return profile_->IsPrimaryOTRProfile(); +} + base::android::ScopedJavaLocalRef<jobject> ProfileAndroid::GetProfileKey( JNIEnv* env, const JavaParamRef<jobject>& obj) {
diff --git a/chrome/browser/profiles/profile_android.h b/chrome/browser/profiles/profile_android.h index e7c11be..7d869cd 100644 --- a/chrome/browser/profiles/profile_android.h +++ b/chrome/browser/profiles/profile_android.h
@@ -72,6 +72,10 @@ jboolean IsOffTheRecord(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); + // Whether this profile is primary off the record profile. + jboolean IsPrimaryOTRProfile(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj); + // Whether this profile is signed in to a child account. jboolean IsChild(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
diff --git a/chrome/browser/resources/chromeos/crostini_upgrader/app.html b/chrome/browser/resources/chromeos/crostini_upgrader/app.html index b105134..919a85e 100644 --- a/chrome/browser/resources/chromeos/crostini_upgrader/app.html +++ b/chrome/browser/resources/chromeos/crostini_upgrader/app.html
@@ -14,7 +14,7 @@ } #icon { - fill: var(--cros-default-icon-color-prominent); + fill: var(--cros-icon-color-prominent); height: 32px; margin-top: 28px; width: 32px; @@ -31,7 +31,7 @@ } #main-title { - color: var(--cros-default-text-color); + color: var(--cros-text-color-primary); font-family: 'Google Sans'; font-size: 28px; line-height: 1; @@ -39,7 +39,7 @@ } #status-container { - color: var(--cros-default-text-color-secondary); + color: var(--cros-text-color-secondary); flex-grow: 1; font-family: Roboto; font-size: 13px; @@ -62,7 +62,7 @@ } paper-progress { - --paper-progress-active-color: var(--cros-default-icon-color-prominent); + --paper-progress-active-color: var(--cros-icon-color-prominent); --paper-progress-container-color: rgba(var(--google-blue-600-rgb), .24); margin-top: 36px; width: 100%;
diff --git a/chrome/browser/resources/chromeos/crostini_upgrader/app.js b/chrome/browser/resources/chromeos/crostini_upgrader/app.js index 7a2c4f4..dfa07b6 100644 --- a/chrome/browser/resources/chromeos/crostini_upgrader/app.js +++ b/chrome/browser/resources/chromeos/crostini_upgrader/app.js
@@ -428,6 +428,8 @@ case State.SUCCEEDED: case State.RESTORE_SUCCEEDED: return loadTimeData.getString('close'); + case State.PROMPT: + return loadTimeData.getString('notNow'); default: return loadTimeData.getString('cancel'); }
diff --git a/chrome/browser/resources/chromeos/zip_archiver/html/passphrase-dialog.html b/chrome/browser/resources/chromeos/zip_archiver/html/passphrase-dialog.html index a2a9a9e..9d69b17 100644 --- a/chrome/browser/resources/chromeos/zip_archiver/html/passphrase-dialog.html +++ b/chrome/browser/resources/chromeos/zip_archiver/html/passphrase-dialog.html
@@ -37,7 +37,7 @@ } #title { - color: var(--cros-default-text-color-rgb); + color: var(--cros-text-color-primary-rgb); font-size: 16px; overflow: hidden; padding-bottom: 16px;
diff --git a/chrome/browser/resources/nearby_share/BUILD.gn b/chrome/browser/resources/nearby_share/BUILD.gn index 2d59828..016739d 100644 --- a/chrome/browser/resources/nearby_share/BUILD.gn +++ b/chrome/browser/resources/nearby_share/BUILD.gn
@@ -10,6 +10,7 @@ deps = [ ":app", ":nearby_confirmation_page", + ":nearby_device", ":nearby_discovery_page", ":nearby_preview", ":nearby_progress", @@ -36,8 +37,15 @@ ] } +js_library("nearby_device") { + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + js_library("nearby_discovery_page") { deps = [ + ":nearby_device", ":nearby_preview", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_button:cr_button.m", @@ -62,6 +70,7 @@ "app.js", "icons.js", "nearby_confirmation_page.js", + "nearby_device.js", "nearby_discovery_page.js", "nearby_preview.js", "nearby_progress.js",
diff --git a/chrome/browser/resources/nearby_share/nearby_device.html b/chrome/browser/resources/nearby_share/nearby_device.html new file mode 100644 index 0000000..ea3a426 --- /dev/null +++ b/chrome/browser/resources/nearby_share/nearby_device.html
@@ -0,0 +1,25 @@ +<style> + :host { + align-items: center; + border: 1px solid rgba(216, 216, 216, 0.76); + border-radius: 8px; + box-sizing: border-box; + display: flex; + height: 40px; + margin-top: 6px; + } + + #name { + color: rgb(95, 99, 104); + flex-grow: 1; + font-size: 11px; + font-weight: 500; + letter-spacing: 0.3px; + overflow: hidden; + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; + } +</style> + +<div id="name">[[name]]</div>
diff --git a/chrome/browser/resources/nearby_share/nearby_device.js b/chrome/browser/resources/nearby_share/nearby_device.js new file mode 100644 index 0000000..22da70a --- /dev/null +++ b/chrome/browser/resources/nearby_share/nearby_device.js
@@ -0,0 +1,23 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview The 'nearby-device' component shows details of a remote device. + */ + +import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +Polymer({ + is: 'nearby-device', + + _template: html`{__html_template__}`, + + properties: { + /** The device name to show. */ + name: { + type: String, + value: '', + }, + }, +});
diff --git a/chrome/browser/resources/nearby_share/nearby_discovery_page.html b/chrome/browser/resources/nearby_share/nearby_discovery_page.html index 282b0f5b..585ccbd 100644 --- a/chrome/browser/resources/nearby_share/nearby_discovery_page.html +++ b/chrome/browser/resources/nearby_share/nearby_discovery_page.html
@@ -4,6 +4,11 @@ text-align: end; } + #device-list { + overflow: auto; + width: 191px; + } + nearby-preview { margin-inline-end: 10px; margin-inline-start: 10px; @@ -27,7 +32,9 @@ #process-row { display: flex; flex-grow: 1; + justify-content: space-between; margin-top: 48px; + overflow: hidden; } #subtitle { @@ -54,6 +61,21 @@ <div id="process-row"> <nearby-preview title="Doggo.jpg"></nearby-preview> + <div id="device-list"> + <nearby-device name="Alyssa's Pixel"></nearby-device> + <nearby-device name="Shangela's Pixel 2XL Name Is Looong"></nearby-device> + <nearby-device name="MirasChromebookIsAllInOneWord"></nearby-device> + <nearby-device name="One"></nearby-device> + <nearby-device name="Two"></nearby-device> + <nearby-device name="Three"></nearby-device> + <nearby-device name="Four"></nearby-device> + <nearby-device name="Five"></nearby-device> + <nearby-device name="Six"></nearby-device> + <nearby-device name="Seven"></nearby-device> + <nearby-device name="Eight"></nearby-device> + <nearby-device name="Nine"></nearby-device> + <nearby-device name="Ten"></nearby-device> + </div> </div> <div id="help">
diff --git a/chrome/browser/resources/nearby_share/nearby_discovery_page.js b/chrome/browser/resources/nearby_share/nearby_discovery_page.js index ce5bdd8..16a535e 100644 --- a/chrome/browser/resources/nearby_share/nearby_discovery_page.js +++ b/chrome/browser/resources/nearby_share/nearby_discovery_page.js
@@ -8,6 +8,7 @@ */ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; +import './nearby_device.js'; import './nearby_preview.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/browser/resources/nearby_share/nearby_share_dialog_resources.grd b/chrome/browser/resources/nearby_share/nearby_share_dialog_resources.grd index b615a14..52b17b3 100644 --- a/chrome/browser/resources/nearby_share/nearby_share_dialog_resources.grd +++ b/chrome/browser/resources/nearby_share/nearby_share_dialog_resources.grd
@@ -26,6 +26,9 @@ <include name="IDR_NEARBY_SHARE_NEARBY_CONFIRMATION_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/nearby_share/nearby_confirmation_page.js" use_base_dir="false" type="BINDATA"/> + <include name="IDR_NEARBY_SHARE_NEARBY_DEVICE_JS" + file="${root_gen_dir}/chrome/browser/resources/nearby_share/nearby_device.js" + use_base_dir="false" type="BINDATA"/> <include name="IDR_NEARBY_SHARE_NEARBY_DISCOVERY_PAGE_JS" file="${root_gen_dir}/chrome/browser/resources/nearby_share/nearby_discovery_page.js" use_base_dir="false" type="BINDATA"/>
diff --git a/chrome/browser/resources/pdf/pdf_viewer.js b/chrome/browser/resources/pdf/pdf_viewer.js index 6537583..cd024f5 100644 --- a/chrome/browser/resources/pdf/pdf_viewer.js +++ b/chrome/browser/resources/pdf/pdf_viewer.js
@@ -84,7 +84,7 @@ } } -class PDFViewerElement extends PDFViewerBaseElement { +export class PDFViewerElement extends PDFViewerBaseElement { static get is() { return 'pdf-viewer'; }
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html index babe5d2..0ee08db 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html +++ b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html
@@ -63,7 +63,7 @@ } iron-icon[icon='settings:check-circle'] { - fill: var(--cros-default-icon-color-prominent); + fill: var(--cros-icon-color-prominent); } iron-icon[icon='cr:error'] {
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.html index 4f329e0..025c88e 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.html +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/app_item.html
@@ -12,7 +12,7 @@ :host { align-items: center; border-bottom: var(--card-separator); - color: var(--cros-default-text-color); + color: var(--cros-text-color-primary); cursor: pointer; display: flex; flex-direction: row;
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/shared_style.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/shared_style.html index 856fc8a..f01d974 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/shared_style.html +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/shared_style.html
@@ -8,7 +8,7 @@ <template> <style include="cr-shared-style cros-color-overrides"> .card-container { - background-color: var(--cros-default-bg-color); + background-color: var(--cros-bg-color); border-radius: var(--cr-card-border-radius); box-shadow: var(--cr-card-shadow); display: flex;
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/shared_vars.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/shared_vars.html index c18182d..1f3102d 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/shared_vars.html +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/shared_vars.html
@@ -12,14 +12,14 @@ --card-separator: 1px solid var(--cros-separator-color); --expanded-permission-row-height: 48px; --header-font-weight: 500; - --header-text-color: var(--cros-default-text-color-secondary); + --header-text-color: var(--cros-text-color-secondary); --permission-icon-color: var(--cros-app-management-permission-icon-color); --permission-icon-padding: 20px; --permission-list-item-height: 48px; - --primary-text-color: var(--cros-default-text-color); + --primary-text-color: var(--cros-text-color-primary); --row-item-icon-padding: 12px; --secondary-font-weight: 400; - --secondary-text-color: var(--cros-default-text-color-secondary); + --secondary-text-color: var(--cros-text-color-secondary); --text-permission-list-row-height: 40px; } </style>
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.html b/chrome/browser/resources/settings/chromeos/os_settings.html index 1b27721d..5b3b0e1 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.html +++ b/chrome/browser/resources/settings/chromeos/os_settings.html
@@ -9,7 +9,7 @@ <link rel="stylesheet" href="chrome://resources/css/cros_colors.generated.css"> <style> html { - background-color: var(--cros-default-bg-color); + background-color: var(--cros-bg-color); overflow: hidden; /* Remove 300ms delay for 'click' event, when using touch interface. */ touch-action: manipulation;
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.html b/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.html index 986588f..d363af5 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.html +++ b/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.html
@@ -17,9 +17,9 @@ <template> <style include="settings-shared"> :host { - --menu-link-color: var(--cros-default-icon-color-prominent); - --menu-text-color: var(--cros-default-text-color-secondary); - --menu-icon-color: var(--cros-default-text-color-secondary); + --menu-link-color: var(--cros-icon-color-prominent); + --menu-text-color: var(--cros-text-color-secondary); + --menu-icon-color: var(--cros-text-color-secondary); /* The tap target extends slightly above each visible menu item. */ --tap-target-padding: 3px; /* Width of the keyboard focus border. */
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html index 0885cdb89..08e97f4e 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html +++ b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html
@@ -33,7 +33,7 @@ .banner { align-items: center; - background-color: var(--cros-default-bg-color); + background-color: var(--cros-bg-color); border: var(--cr-hairline); border-radius: var(--cr-card-border-radius); display: flex; @@ -77,7 +77,7 @@ #toggleContainer { align-items: center; - color: var(--cros-default-text-color); + color: var(--cros-text-color-primary); display: flex; font: inherit; justify-content: center;
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.html b/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.html index 9c19015e..fd18bba 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.html +++ b/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.html
@@ -47,7 +47,7 @@ cr-drawer { --cr-separator-line: none; - --cr-drawer-header-color: var(--cros-default-text-color-secondary); + --cr-drawer-header-color: var(--cros-text-color-secondary); --cr-drawer-header-font-weight: 500; --cr-drawer-header-padding: 20px; }
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_v3.html b/chrome/browser/resources/settings/chromeos/os_settings_v3.html index d97f6fa93..e3277b9 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_v3.html +++ b/chrome/browser/resources/settings/chromeos/os_settings_v3.html
@@ -7,7 +7,7 @@ <link rel="stylesheet" href="chrome://resources/css/cros_colors.generated.css"> <style> html { - background-color: var(--cros-default-bg-color); + background-color: var(--cros-bg-color); overflow: hidden; /* Remove 300ms delay for 'click' event, when using touch interface. */ touch-action: manipulation;
diff --git a/chrome/browser/resources/settings/chromeos/os_toolbar/os_toolbar.html b/chrome/browser/resources/settings/chromeos/os_toolbar/os_toolbar.html index ead73e5..fde85cc 100644 --- a/chrome/browser/resources/settings/chromeos/os_toolbar/os_toolbar.html +++ b/chrome/browser/resources/settings/chromeos/os_toolbar/os_toolbar.html
@@ -15,17 +15,17 @@ <style include="cr-icons cr-hidden-style"> :host { --cr-toolbar-search-field-background: - var(--cros-default-toolbar-search-bg-color); + var(--cros-toolbar-search-bg-color); --cr-toolbar-search-field-border-radius: 4px; --cr-toolbar-search-field-input-text-color: - var(--cros-default-text-color-secondary); + var(--cros-text-color-secondary); --cr-toolbar-search-field-input-icon-color: - var(--cros-default-text-color-secondary); + var(--cros-text-color-secondary); --cr-toolbar-search-field-input-bg-color: - var(--cros-default-toolbar-bg-color); + var(--cros-toolbar-bg-color); align-items: center; - background-color: var(--cros-default-toolbar-bg-color); - color: var(--cros-default-text-color-secondary); + background-color: var(--cros-toolbar-bg-color); + color: var(--cros-text-color-secondary); display: flex; height: var(--cr-toolbar-height); padding-top: 8px;
diff --git a/chrome/browser/safe_browsing/client_side_detection_host.cc b/chrome/browser/safe_browsing/client_side_detection_host.cc index 0e72a7cd..bcff2b9 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host.cc +++ b/chrome/browser/safe_browsing/client_side_detection_host.cc
@@ -48,7 +48,7 @@ #include "net/base/ip_endpoint.h" #include "net/http/http_response_headers.h" #include "services/service_manager/public/cpp/interface_provider.h" -#include "third_party/blink/public/mojom/referrer.mojom.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom.h" #include "url/gurl.h" using content::BrowserThread;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index b185871..377211c47 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -3791,8 +3791,6 @@ "views/toolbar/browser_actions_container.h", "views/toolbar/browser_app_menu_button.cc", "views/toolbar/browser_app_menu_button.h", - "views/toolbar/button_utils.cc", - "views/toolbar/button_utils.h", "views/toolbar/extension_toolbar_menu_view.cc", "views/toolbar/extension_toolbar_menu_view.h", "views/toolbar/home_button.cc",
diff --git a/chrome/browser/ui/app_list/app_list_notifier_impl.cc b/chrome/browser/ui/app_list/app_list_notifier_impl.cc index 0c98553..078d2710 100644 --- a/chrome/browser/ui/app_list/app_list_notifier_impl.cc +++ b/chrome/browser/ui/app_list/app_list_notifier_impl.cc
@@ -49,9 +49,18 @@ void AppListNotifierImpl::NotifySearchQueryChanged( const base::string16& query) { + // In some cases the query can change after the launcher is closed, in + // particular this happens when abandoning the launcher with a non-empty + // query. Only do a state transition if the launcher is open. + if (view_ != ash::AppListViewState::kClosed) { + DoStateTransition(Location::kList, State::kShown); + DoStateTransition(Location::kTile, State::kShown); + } + + // Update the stored |query_| after performing the state transitions, so that + // an abandon triggered by the query change correctly uses the pre-abandon + // query. query_ = query; - DoStateTransition(Location::kList, State::kShown); - DoStateTransition(Location::kTile, State::kShown); } void AppListNotifierImpl::NotifyUIStateChanged(ash::AppListViewState view) {
diff --git a/chrome/browser/ui/search_engines/search_engine_tab_helper.cc b/chrome/browser/ui/search_engines/search_engine_tab_helper.cc index b2fadd1..9e70ae2 100644 --- a/chrome/browser/ui/search_engines/search_engine_tab_helper.cc +++ b/chrome/browser/ui/search_engines/search_engine_tab_helper.cc
@@ -25,8 +25,8 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" #include "mojo/public/cpp/bindings/remote.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h" -#include "third_party/blink/public/mojom/referrer.mojom.h" using content::NavigationController; using content::NavigationEntry;
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc index 70706358..8ea2f5f 100644 --- a/chrome/browser/ui/views/download/download_item_view.cc +++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -260,14 +260,13 @@ status_label->GetViewAccessibility().OverrideIsIgnored(true); status_label_ = AddChildView(std::move(status_label)); - auto dangerous_download_label = std::make_unique<views::StyledLabel>( + auto warning_label = std::make_unique<views::StyledLabel>( base::string16(), /*listener=*/nullptr); - dangerous_download_label->SetTextContext(CONTEXT_DOWNLOAD_SHELF); - dangerous_download_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - dangerous_download_label->SetAutoColorReadabilityEnabled(false); - dangerous_download_label->set_can_process_events_within_subtree(false); - dangerous_download_label_ = AddChildView(std::move(dangerous_download_label)); - dangerous_download_label_->SetVisible(false); + warning_label->SetTextContext(CONTEXT_DOWNLOAD_SHELF); + warning_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + warning_label->SetAutoColorReadabilityEnabled(false); + warning_label->set_can_process_events_within_subtree(false); + warning_label_ = AddChildView(std::move(warning_label)); auto deep_scanning_label = std::make_unique<views::StyledLabel>( base::string16(), /*listener=*/nullptr); @@ -276,7 +275,6 @@ deep_scanning_label->SetAutoColorReadabilityEnabled(false); deep_scanning_label->set_can_process_events_within_subtree(false); deep_scanning_label_ = AddChildView(std::move(deep_scanning_label)); - deep_scanning_label_->SetVisible(false); auto open_now_button = views::MdTextButton::Create( this, l10n_util::GetStringUTF16(IDS_OPEN_DOWNLOAD_NOW)); @@ -303,8 +301,6 @@ // Further configure default state, e.g. child visibility. OnDownloadUpdated(); - - UpdateColorsFromTheme(); } DownloadItemView::~DownloadItemView() { @@ -316,17 +312,15 @@ void DownloadItemView::Layout() { View::Layout(); - UpdateColorsFromTheme(); - open_button_->SetBoundsRect(GetLocalBounds()); if (is_download_warning(mode_)) { gfx::Point child_origin( kStartPadding + GetWarningIconSize() + kStartPadding, - (height() - dangerous_download_label_->height()) / 2); - dangerous_download_label_->SetPosition(child_origin); + (height() - warning_label_->height()) / 2); + warning_label_->SetPosition(child_origin); - child_origin.Offset(dangerous_download_label_->width() + kLabelPadding, 0); + child_origin.Offset(warning_label_->width() + kLabelPadding, 0); gfx::Size button_size = GetButtonSize(); child_origin.set_y((height() - button_size.height()) / 2); if (save_button_->GetVisible()) { @@ -340,10 +334,10 @@ } else if (is_mixed_content(mode_)) { gfx::Point child_origin( kStartPadding + GetWarningIconSize() + kStartPadding, - (height() - dangerous_download_label_->height()) / 2); - dangerous_download_label_->SetPosition(child_origin); + (height() - warning_label_->height()) / 2); + warning_label_->SetPosition(child_origin); - child_origin.Offset(dangerous_download_label_->width() + kLabelPadding, 0); + child_origin.Offset(warning_label_->width() + kLabelPadding, 0); gfx::Size button_size = GetButtonSize(); child_origin.set_y((height() - button_size.height()) / 2); if (save_button_->GetVisible()) @@ -367,7 +361,11 @@ int mirrored_x = GetMirroredXWithWidthInView( kStartPadding + kProgressIndicatorSize + kProgressTextPadding, kTextWidth); - int file_name_y = GetYForFilenameText(); + + int text_height = font_list_.GetHeight(); + if (!status_label_->GetText().empty()) + text_height += status_font_list_.GetHeight(); + int file_name_y = (height() - text_height) / 2; file_name_label_->SetBoundsRect( gfx::Rect(mirrored_x, file_name_y, kTextWidth, font_list_.GetHeight())); @@ -557,6 +555,7 @@ } void DownloadItemView::OnDownloadOpened() { + file_name_label_->SetTextStyle(views::style::STYLE_DISABLED); // First, Calculate the download status opening string width. base::string16 status_string = l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_OPENING, base::string16()); @@ -607,7 +606,7 @@ if (has_warning_label(mode_)) { // Width. width = kStartPadding + GetWarningIconSize() + kStartPadding + - dangerous_download_label_->width() + kLabelPadding; + warning_label_->width() + kLabelPadding; gfx::Size button_size = GetButtonSize(); if (save_button_->GetVisible() && discard_button_->GetVisible()) width += button_size.width() + kSaveDiscardButtonPadding; @@ -696,36 +695,13 @@ } void DownloadItemView::UpdateMode(Mode mode) { - // TODO(pkasting): This function is currently enormous and has a lot of - // repeated and/or unnecessary code. Refactor further. - - if (mode_ != Mode::kNormal) { - file_name_label_->SetVisible(true); - status_label_->SetVisible(true); - if (is_mixed_content(mode_) || is_download_warning(mode_)) { - dangerous_download_label_->SetVisible(false); - } else if (mode_ == Mode::kDeepScanning) { - deep_scanning_label_->SetVisible(false); - } - } + // TODO(pkasting): Refactor further. mode_ = mode; + UpdateLabels(); UpdateButtons(); - if (is_mixed_content(mode_)) { - dangerous_download_label_->SetVisible(true); - const base::string16 filename = ElidedFilename(); - size_t filename_offset; - dangerous_download_label_->SetText( - model_->GetWarningText(filename, &filename_offset)); - StyleFilename(*dangerous_download_label_, filename_offset, - filename.length()); - dangerous_download_label_->SizeToFit( - GetLabelWidth(*dangerous_download_label_)); - - file_name_label_->SetVisible(false); - status_label_->SetVisible(false); - } else if (is_download_warning(mode_)) { + if (is_download_warning(mode_)) { time_download_warning_shown_ = base::Time::Now(); download::DownloadDangerType danger_type = model_->GetDangerType(); RecordDangerousDownloadWarningShown(danger_type); @@ -743,46 +719,13 @@ UpdateAccessibleAlert(model_->GetWarningText(unelided_filename, &ignore), true); } - - dangerous_download_label_->SetVisible(true); - const base::string16 filename = ElidedFilename(); - size_t filename_offset; - dangerous_download_label_->SetText( - model_->GetWarningText(filename, &filename_offset)); - StyleFilename(*dangerous_download_label_, filename_offset, - filename.length()); - dangerous_download_label_->SizeToFit( - GetLabelWidth(*dangerous_download_label_)); - - file_name_label_->SetVisible(false); - status_label_->SetVisible(false); } else if (mode_ == Mode::kDeepScanning) { - const int id = (model_->download() && - safe_browsing::DeepScanningRequest::ShouldUploadBinary( - model_->download())) - ? IDS_PROMPT_DEEP_SCANNING_DOWNLOAD - : IDS_PROMPT_DEEP_SCANNING_APP_DOWNLOAD; - deep_scanning_label_->SetVisible(true); - const base::string16 filename = ElidedFilename(); - size_t filename_offset; - deep_scanning_label_->SetText( - l10n_util::GetStringFUTF16(id, filename, &filename_offset)); - StyleFilename(*deep_scanning_label_, filename_offset, filename.length()); - deep_scanning_label_->SizeToFit(GetLabelWidth(*deep_scanning_label_)); - - file_name_label_->SetVisible(false); - status_label_->SetVisible(false); - UpdateAccessibleAlert( l10n_util::GetStringFUTF16( IDS_DEEP_SCANNING_ACCESSIBLE_ALERT, model_->GetFileNameToReportUser().LossyDisplayName()), false); - } else { - status_label_->SetText(GetStatusText()); - status_label_->GetViewAccessibility().OverrideIsIgnored( - status_label_->GetText().empty()); - file_name_label_->SetY(GetYForFilenameText()); + } else if (mode_ == Mode::kNormal) { switch (model_->GetState()) { case DownloadItem::IN_PROGRESS: // No need to send accessible alert for "paused", as the button ends @@ -844,6 +787,43 @@ shelf_->SchedulePaint(); } +void DownloadItemView::UpdateLabels() { + file_name_label_->SetVisible(mode_ == Mode::kNormal); + + status_label_->SetVisible(mode_ == Mode::kNormal); + if (status_label_->GetVisible()) { + const auto text_and_style = GetStatusTextAndStyle(); + status_label_->SetText(text_and_style.first); + status_label_->SetTextStyle(text_and_style.second); + status_label_->GetViewAccessibility().OverrideIsIgnored( + status_label_->GetText().empty()); + } + + warning_label_->SetVisible(has_warning_label(mode_)); + if (warning_label_->GetVisible()) { + const base::string16 filename = ElidedFilename(); + size_t filename_offset; + warning_label_->SetText(model_->GetWarningText(filename, &filename_offset)); + StyleFilename(*warning_label_, filename_offset, filename.length()); + warning_label_->SizeToFit(GetLabelWidth(*warning_label_)); + } + + deep_scanning_label_->SetVisible(mode_ == Mode::kDeepScanning); + if (deep_scanning_label_->GetVisible()) { + const int id = (model_->download() && + safe_browsing::DeepScanningRequest::ShouldUploadBinary( + model_->download())) + ? IDS_PROMPT_DEEP_SCANNING_DOWNLOAD + : IDS_PROMPT_DEEP_SCANNING_APP_DOWNLOAD; + const base::string16 filename = ElidedFilename(); + size_t filename_offset; + deep_scanning_label_->SetText( + l10n_util::GetStringFUTF16(id, filename, &filename_offset)); + StyleFilename(*deep_scanning_label_, filename_offset, filename.length()); + deep_scanning_label_->SizeToFit(GetLabelWidth(*deep_scanning_label_)); + } +} + void DownloadItemView::UpdateButtons() { bool prompt_to_scan = false, prompt_to_discard = false; if (is_download_warning(mode_)) { @@ -915,13 +895,6 @@ #endif } -int DownloadItemView::GetYForFilenameText() const { - int text_height = font_list_.GetHeight(); - if (!status_label_->GetText().empty()) - text_height += status_font_list_.GetHeight(); - return (height() - text_height) / 2; -} - void DownloadItemView::DrawIcon(gfx::Canvas* canvas) { bool use_new_warnings = base::FeatureList::IsEnabled(safe_browsing::kUseNewDownloadWarnings); @@ -1023,17 +996,6 @@ if (!GetThemeProvider()) return; - file_name_label_->SetTextStyle(GetEnabled() ? views::style::STYLE_PRIMARY - : views::style::STYLE_DISABLED); - if (model_->GetDangerType() == - download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_SAFE) { - status_label_->SetTextStyle(STYLE_GREEN); - } else if (model_->GetDangerType() == - download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_OPENED_DANGEROUS) { - status_label_->SetTextStyle(STYLE_RED); - } else { - status_label_->SetTextStyle(views::style::STYLE_PRIMARY); - } SkColor background_color = GetThemeProvider()->GetColor(ThemeProperties::COLOR_DOWNLOAD_SHELF); file_name_label_->SetBackgroundColor(background_color); @@ -1191,6 +1153,7 @@ } void DownloadItemView::Reenable() { + file_name_label_->SetTextStyle(views::style::STYLE_PRIMARY); file_name_label_->SetText(ElidedFilename()); SetEnabled(true); // Triggers a repaint. } @@ -1222,7 +1185,7 @@ void DownloadItemView::UpdateAccessibleName() { base::string16 new_name; if (has_warning_label(mode_)) { - new_name = dangerous_download_label_->GetText(); + new_name = warning_label_->GetText(); } else { new_name = status_label_->GetText() + base::char16(' ') + model_->GetFileNameToReportUser().LossyDisplayName(); @@ -1369,30 +1332,29 @@ SchedulePaint(); } -base::string16 DownloadItemView::GetStatusText() const { - if (model_->GetDangerType() == - download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_SAFE) { - return l10n_util::GetStringUTF16(IDS_PROMPT_DOWNLOAD_DEEP_SCANNED_SAFE); - } else if (model_->GetDangerType() == - download::DownloadDangerType:: - DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_OPENED_DANGEROUS) { - return l10n_util::GetStringUTF16( - IDS_PROMPT_DOWNLOAD_DEEP_SCANNED_OPENED_DANGEROUS); +std::pair<base::string16, int> DownloadItemView::GetStatusTextAndStyle() const { + using DangerType = download::DownloadDangerType; + const auto type = model_->GetDangerType(); + if (type == DangerType::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_SAFE) { + return {l10n_util::GetStringUTF16(IDS_PROMPT_DOWNLOAD_DEEP_SCANNED_SAFE), + STYLE_GREEN}; } + constexpr int kDangerous = IDS_PROMPT_DOWNLOAD_DEEP_SCANNED_OPENED_DANGEROUS; + if (type == DangerType::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_OPENED_DANGEROUS) + return {l10n_util::GetStringUTF16(kDangerous), STYLE_RED}; - if (!model_->ShouldPromoteOrigin() || - model_->GetOriginalURL().GetOrigin().is_empty()) { - // Use the default status text. - return model_->GetStatusText(); - } - -#if !defined(OS_ANDROID) - return url_formatter::ElideUrl(model_->GetOriginalURL().GetOrigin(), - status_font_list_, kTextWidth); + const GURL url = model_->GetOriginalURL().GetOrigin(); + const base::string16 text = + (!model_->ShouldPromoteOrigin() || url.is_empty()) + ? model_->GetStatusText() +#if defined(OS_ANDROID) + // url_formatter::ElideUrl() doesn't exist on Android. + : base::string16(); #else - NOTREACHED(); - return base::string16(); + : url_formatter::ElideUrl(url, status_label_->font_list(), + kTextWidth); #endif + return {text, views::style::STYLE_PRIMARY}; } base::string16 DownloadItemView::ElidedFilename() {
diff --git a/chrome/browser/ui/views/download/download_item_view.h b/chrome/browser/ui/views/download/download_item_view.h index 792386e7..18ea015 100644 --- a/chrome/browser/ui/views/download/download_item_view.h +++ b/chrome/browser/ui/views/download/download_item_view.h
@@ -134,6 +134,9 @@ // Sets the current mode to |mode| and updates UI appropriately. void UpdateMode(Mode mode); + // Updates the visibility, text, size, etc. of all labels. + void UpdateLabels(); + // Updates the visible and enabled state of all buttons. void UpdateButtons(); @@ -145,10 +148,6 @@ bool SubmitDownloadToFeedbackService( DownloadCommands::Command download_command); - // This function calculates the vertical coordinate to draw the file name text - // relative to local bounds. - int GetYForFilenameText() const; - void DrawIcon(gfx::Canvas* canvas); void LoadIcon(); @@ -228,8 +227,8 @@ // Callback for |progress_timer_|. void ProgressTimerFired(); - // Returns the status text to show in the notification. - base::string16 GetStatusText() const; + // Returns the text and style to use for the status label. + std::pair<base::string16, int> GetStatusTextAndStyle() const; // Returns the file name to report to user. It might be elided to fit into // the text width. @@ -307,7 +306,7 @@ views::Label* file_name_label_; views::Label* status_label_; - views::StyledLabel* dangerous_download_label_; + views::StyledLabel* warning_label_; views::StyledLabel* deep_scanning_label_; views::MdTextButton* open_now_button_;
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc index c4ea4fd9..c5f4e66 100644 --- a/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc +++ b/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc
@@ -43,12 +43,6 @@ CHECK(!IsInObserverList()); } -void ExtensionsToolbarButton::UpdateIcon() { - SetImage(views::Button::STATE_NORMAL, - gfx::CreateVectorIcon(vector_icons::kExtensionIcon, GetIconSize(), - extensions_container_->GetIconColor())); -} - gfx::Size ExtensionsToolbarButton::CalculatePreferredSize() const { return extensions_container_->GetToolbarActionSize(); } @@ -89,6 +83,13 @@ return "ExtensionsToolbarButton"; } +void ExtensionsToolbarButton::UpdateIcon() { + SetImageModel(views::Button::STATE_NORMAL, + ui::ImageModel::FromVectorIcon( + vector_icons::kExtensionIcon, + extensions_container_->GetIconColor(), GetIconSize())); +} + void ExtensionsToolbarButton::ButtonPressed(views::Button* sender, const ui::Event& event) { if (ExtensionsMenuView::IsShowing()) {
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_button.h b/chrome/browser/ui/views/extensions/extensions_toolbar_button.h index 86f7be1..a686432 100644 --- a/chrome/browser/ui/views/extensions/extensions_toolbar_button.h +++ b/chrome/browser/ui/views/extensions/extensions_toolbar_button.h
@@ -23,13 +23,12 @@ ExtensionsToolbarContainer* extensions_container); ~ExtensionsToolbarButton() override; - void UpdateIcon(); - // ToolbarButton: gfx::Size CalculatePreferredSize() const override; gfx::Size GetMinimumSize() const override; void OnBoundsChanged(const gfx::Rect& previous_bounds) override; const char* GetClassName() const override; + void UpdateIcon() override; // views::ButtonListener: void ButtonPressed(views::Button* sender, const ui::Event& event) override;
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc index 026c2a3..e835433 100644 --- a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc +++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc
@@ -105,8 +105,6 @@ } void ExtensionsToolbarContainer::UpdateAllIcons() { - extensions_button_->UpdateIcon(); - for (const auto& action : actions_) action->UpdateState(); }
diff --git a/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.h b/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.h index 62240028..0dc9b104 100644 --- a/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.h +++ b/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.h
@@ -37,11 +37,9 @@ // views::ButtonListener implementation. void ButtonPressed(views::Button* sender, const ui::Event& event) override; - // views::InkDropHostView implementation. + // ToolbarButton implementation. SkColor GetInkDropBaseColor() const override; - - // Updates the icon image. - void UpdateIcon(); + void UpdateIcon() override; void ShowPromo();
diff --git a/chrome/browser/ui/views/media_router/cast_toolbar_button.h b/chrome/browser/ui/views/media_router/cast_toolbar_button.h index a43b740..106594e 100644 --- a/chrome/browser/ui/views/media_router/cast_toolbar_button.h +++ b/chrome/browser/ui/views/media_router/cast_toolbar_button.h
@@ -38,9 +38,6 @@ std::unique_ptr<MediaRouterContextualMenu> context_menu); ~CastToolbarButton() override; - // Updates the icon image. - void UpdateIcon(); - // MediaRouterActionController::Observer: void ShowIcon() override; void HideIcon() override; @@ -60,6 +57,7 @@ bool OnMousePressed(const ui::MouseEvent& event) override; void OnMouseReleased(const ui::MouseEvent& event) override; void OnGestureEvent(ui::GestureEvent* event) override; + void UpdateIcon() override; // views::ButtonListener: void ButtonPressed(views::Button* sender, const ui::Event& event) override;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc index ecc038d91..a21c1c9 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -1546,6 +1546,46 @@ return Textfield::HandleAccessibleAction(action_data); } +void OmniboxViewViews::OnBoundsChanged(const gfx::Rect& previous_bounds) { + Textfield::OnBoundsChanged(previous_bounds); + + if (!OmniboxFieldTrial::ShouldRevealPathQueryRefOnHover() && + !OmniboxFieldTrial::ShouldHidePathQueryRefOnInteraction()) { + return; + } + + // When simplified domain display field trials are enabled, + // Textfield::OnBoundsChanged() may have undone the effect of any previous URL + // elisions, because it expands the Textfield's display rect to the local + // bounds, which may bring more of the URL into view than intended. Re-apply + // simplified domain elisions now. + + // Cancel any running animations. This could cause some abrupt transitions, + // but we can't adapt running animations to new bounds. + if (hover_elide_or_unelide_animation_) + hover_elide_or_unelide_animation_->Stop(); + if (elide_after_interaction_animation_) + elide_after_interaction_animation_->Stop(); + + // |elide_after_interaction_animation_| is created when the user interacts + // with the page, if hide-on-interaction is enabled. If hide-on-interaction is + // disabled or the user has already interacted with the page, the simplified + // domain should have been showing before the bounds changed (or we would have + // been in the process of animating to the simplified domain). + if (!OmniboxFieldTrial::ShouldHidePathQueryRefOnInteraction() || + elide_after_interaction_animation_) { + if (IsURLEligibleForSimplifiedDomainEliding() && + !model()->ShouldPreventElision()) { + ElideURL(); + } + } else { + // The user hasn't interacted with the page yet. This resets animation state + // and shows the partially elided URL with scheme and trivial subdomains + // hidden. + ResetToHideOnInteraction(); + } +} + void OmniboxViewViews::OnFocus() { views::Textfield::OnFocus(); // TODO(tommycli): This does not seem like it should be necessary.
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.h b/chrome/browser/ui/views/omnibox/omnibox_view_views.h index 6fbbf1cac..7052352b 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.h +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.h
@@ -175,6 +175,10 @@ UserInteractionAndHover); FRIEND_TEST_ALL_PREFIXES( OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest, + BoundsChanged); + FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsRevealOnHoverTest, BoundsChanged); + FRIEND_TEST_ALL_PREFIXES( + OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest, SchemeAndTrivialSubdomainElision); FRIEND_TEST_ALL_PREFIXES( OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest, @@ -367,6 +371,7 @@ bool SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; bool HandleAccessibleAction(const ui::AXActionData& action_data) override; + void OnBoundsChanged(const gfx::Rect& previous_bounds) override; void OnFocus() override; void OnBlur() override; base::string16 GetSelectionClipboardText() const override;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc index 2088e60..a83a4214 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
@@ -1738,6 +1738,94 @@ omnibox_view(), kSimplifiedDomainDisplayUrlSubdomainAndScheme)); } +// Tests that simplified domain elisions are re-applied when the omnibox's +// bounds change. +TEST_P(OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest, BoundsChanged) { + SetUpSimplifiedDomainTest(); + gfx::RenderText* render_text = omnibox_view()->GetRenderText(); + + content::MockNavigationHandle navigation; + navigation.set_is_same_document(false); + omnibox_view()->DidFinishNavigation(&navigation); + ASSERT_NO_FATAL_FAILURE(ExpectUnelidedFromSimplifiedDomain( + omnibox_view()->GetRenderText(), + gfx::Range(kSimplifiedDomainDisplayUrlScheme.size(), + kSimplifiedDomainDisplayUrl.size()))); + + // After the bounds change, the URL should remain unelided. + omnibox_view()->OnBoundsChanged(gfx::Rect()); + ASSERT_NO_FATAL_FAILURE(ExpectUnelidedFromSimplifiedDomain( + omnibox_view()->GetRenderText(), + gfx::Range(kSimplifiedDomainDisplayUrlScheme.size(), + kSimplifiedDomainDisplayUrl.size()))); + + // Hover over the omnibox and change the bounds during the animation. The + // animation should be cancelled and immediately transition back to the + // unelided URL. + omnibox_view()->OnMouseMoved(CreateMouseEvent(ui::ET_MOUSE_MOVED, {0, 0})); + OmniboxViewViews::ElideAnimation* unelide_animation = + omnibox_view()->GetHoverElideOrUnelideAnimationForTesting(); + ASSERT_TRUE(unelide_animation); + EXPECT_TRUE(unelide_animation->IsAnimating()); + omnibox_view()->OnBoundsChanged(gfx::Rect()); + ASSERT_NO_FATAL_FAILURE(ExpectUnelidedFromSimplifiedDomain( + omnibox_view()->GetRenderText(), + gfx::Range(kSimplifiedDomainDisplayUrlScheme.size(), + kSimplifiedDomainDisplayUrl.size()))); + + // Simulate a user interaction and change the bounds during the animation. The + // animation should be cancelled and immediately transition to the animation's + // end state (simplified domain). + omnibox_view()->DidGetUserInteraction( + blink::WebInputEvent::Type::kGestureScrollBegin); + OmniboxViewViews::ElideAnimation* elide_animation = + omnibox_view()->GetElideAfterInteractionAnimationForTesting(); + ASSERT_TRUE(elide_animation); + EXPECT_TRUE(elide_animation->IsAnimating()); + omnibox_view()->OnBoundsChanged(gfx::Rect()); + ASSERT_NO_FATAL_FAILURE(ExpectElidedToSimplifiedDomain( + render_text, kSimplifiedDomainDisplayUrlSubdomainAndScheme, + kSimplifiedDomainDisplayUrlSubdomain, + kSimplifiedDomainDisplayUrlHostnameAndScheme, + kSimplifiedDomainDisplayUrlPath, ShouldElideToRegistrableDomain())); +} + +// Tests that simplified domain elisions are re-applied when the omnibox's +// bounds change when only reveal-on-hover is enabled. +TEST_P(OmniboxViewViewsRevealOnHoverTest, BoundsChanged) { + SetUpSimplifiedDomainTest(); + gfx::RenderText* render_text = omnibox_view()->GetRenderText(); + + ASSERT_NO_FATAL_FAILURE(ExpectElidedToSimplifiedDomain( + render_text, kSimplifiedDomainDisplayUrlSubdomainAndScheme, + kSimplifiedDomainDisplayUrlSubdomain, + kSimplifiedDomainDisplayUrlHostnameAndScheme, + kSimplifiedDomainDisplayUrlPath, ShouldElideToRegistrableDomain())); + + // After the bounds change, the URL should remain elided. + omnibox_view()->OnBoundsChanged(gfx::Rect()); + ASSERT_NO_FATAL_FAILURE(ExpectElidedToSimplifiedDomain( + render_text, kSimplifiedDomainDisplayUrlSubdomainAndScheme, + kSimplifiedDomainDisplayUrlSubdomain, + kSimplifiedDomainDisplayUrlHostnameAndScheme, + kSimplifiedDomainDisplayUrlPath, ShouldElideToRegistrableDomain())); + + // Hover over the omnibox and change the bounds during the animation. The + // animation should be cancelled and immediately transition back to the + // simplified domain. + omnibox_view()->OnMouseMoved(CreateMouseEvent(ui::ET_MOUSE_MOVED, {0, 0})); + OmniboxViewViews::ElideAnimation* unelide_animation = + omnibox_view()->GetHoverElideOrUnelideAnimationForTesting(); + ASSERT_TRUE(unelide_animation); + EXPECT_TRUE(unelide_animation->IsAnimating()); + omnibox_view()->OnBoundsChanged(gfx::Rect()); + ASSERT_NO_FATAL_FAILURE(ExpectElidedToSimplifiedDomain( + render_text, kSimplifiedDomainDisplayUrlSubdomainAndScheme, + kSimplifiedDomainDisplayUrlSubdomain, + kSimplifiedDomainDisplayUrlHostnameAndScheme, + kSimplifiedDomainDisplayUrlPath, ShouldElideToRegistrableDomain())); +} + // Tests scheme and trivial subdomain elision when simplified domain field // trials are enabled. TEST_P(OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest,
diff --git a/chrome/browser/ui/views/passwords/move_to_account_store_bubble_view.cc b/chrome/browser/ui/views/passwords/move_to_account_store_bubble_view.cc index a2d734c..00a01402 100644 --- a/chrome/browser/ui/views/passwords/move_to_account_store_bubble_view.cc +++ b/chrome/browser/ui/views/passwords/move_to_account_store_bubble_view.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/strings/utf_string_conversions.h" #include "chrome/app/vector_icons/vector_icons.h" +#include "chrome/browser/profiles/profile_avatar_icon_util.h" #include "chrome/browser/ui/passwords/bubble_controllers/move_to_account_store_bubble_controller.h" #include "chrome/browser/ui/passwords/passwords_model_delegate.h" #include "chrome/browser/ui/views/accessibility/non_accessible_image_view.h" @@ -37,8 +38,7 @@ constexpr int kBadgeSpacing = 4; constexpr int kImageSize = BadgedProfilePhoto::kImageSize; // Width and Height of the badged icon. -constexpr int kBadgedProfilePhotoWidth = kImageSize + kBadgeSpacing; -constexpr int kBadgedProfilePhotoHeight = kImageSize; +constexpr int kBadgedProfilePhotoSize = kImageSize + kBadgeSpacing; // An image view that shows a vector icon and tracks changes in the theme. class VectorIconView : public views::ImageView { @@ -102,18 +102,20 @@ // Use a Globe icon as the default badge. auto badge_view = std::make_unique<VectorIconView>(kGlobeIcon, kBadgeIconSize); - badge_view->SetPosition( - gfx::Point(kBadgedProfilePhotoWidth - kBadgeIconSize, - kBadgedProfilePhotoHeight - kBadgeIconSize)); + badge_view->SetPosition(gfx::Point(kBadgedProfilePhotoSize - kBadgeIconSize, + kBadgedProfilePhotoSize - kBadgeIconSize)); badge_view->SizeToPreferredSize(); badge_view_ = AddChildView(std::move(badge_view)); - SetPreferredSize( - gfx::Size(kBadgedProfilePhotoWidth, kBadgedProfilePhotoHeight)); + SetPreferredSize(gfx::Size(kBadgedProfilePhotoSize, kBadgedProfilePhotoSize)); } void ImageWithBadge::UpdateBadge(const gfx::ImageSkia& badge_image) { - badge_view_->SetImage(badge_image); + gfx::Image rounded_badge = profiles::GetSizedAvatarIcon( + gfx::Image(badge_image), + /*is_rectangle=*/true, /*width=*/gfx::kFaviconSize, + /*height=*/gfx::kFaviconSize, profiles::SHAPE_CIRCLE); + badge_view_->SetImage(rounded_badge.ToImageSkia()); badge_view_->SizeToPreferredSize(); }
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc index 925ffe0..d492652a 100644 --- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
@@ -16,8 +16,11 @@ #include "chrome/browser/ui/views/payments/payment_request_views_util.h" #include "chrome/grit/generated_resources.h" #include "components/payments/content/icon/icon_size.h" +#include "components/payments/core/features.h" #include "components/payments/core/native_error_strings.h" +#include "components/payments/core/payments_experimental_features.h" #include "components/payments/core/url_util.h" +#include "components/vector_icons/vector_icons.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" #include "content/public/browser/navigation_handle.h" @@ -29,6 +32,7 @@ #include "ui/gfx/color_palette.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/image/image_skia.h" +#include "ui/gfx/paint_vector_icon.h" #include "ui/views/background.h" #include "ui/views/border.h" #include "ui/views/controls/image_view.h" @@ -90,8 +94,28 @@ title_label->SetEnabledColor(foreground); } - title_origin_layout->StartRow(views::GridLayout::kFixedSize, 0); - auto* origin_label = title_origin_layout->AddView( + auto origin_container = std::make_unique<views::View>(); + views::GridLayout* origin_layout = origin_container->SetLayoutManager( + std::make_unique<views::GridLayout>()); + + columns = origin_layout->AddColumnSet(0); + columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, + 1.0, views::GridLayout::ColumnSize::kUsePreferred, 0, 0); + columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING, + 1.0, views::GridLayout::ColumnSize::kUsePreferred, 0, 0); + origin_layout->StartRow(views::GridLayout::kFixedSize, 0); + if (PaymentsExperimentalFeatures::IsEnabled( + features::kPaymentHandlerLockIcon) && + origin.SchemeIs(url::kHttpsScheme)) { + // TODO(https://crbug.com/1052493): + // Selecting the correct icon based on the SSL certificate state + // and adding test coverage for this code path. + auto lock_icon = std::make_unique<views::ImageView>(); + lock_icon->SetImage(gfx::CreateVectorIcon(vector_icons::kLockIcon, 16, + gfx::kChromeIconGrey)); + origin_layout->AddView(std::move(lock_icon)); + } + auto* origin_label = origin_layout->AddView( std::make_unique<views::Label>(base::UTF8ToUTF16(origin.host()))); origin_label->SetElideBehavior(gfx::ELIDE_HEAD); if (!title_is_valid) { @@ -108,6 +132,8 @@ origin_label->SetAutoColorReadabilityEnabled(false); origin_label->SetEnabledColor(foreground); origin_label->SetBackgroundColor(background_color); + title_origin_layout->StartRow(views::GridLayout::kFixedSize, 0); + title_origin_layout->AddView(std::move(origin_container)); views::GridLayout* top_level_layout = SetLayoutManager(std::make_unique<views::GridLayout>());
diff --git a/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view.cc b/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view.cc index e63aadd..96a4a42 100644 --- a/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view.cc +++ b/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view.cc
@@ -30,6 +30,7 @@ #include "ui/base/resource/resource_bundle.h" #include "ui/base/text/bytes_formatting.h" #include "ui/chromeos/devicetype_utils.h" +#include "ui/gfx/geometry/insets.h" #include "ui/strings/grit/ui_strings.h" #include "ui/views/border.h" #include "ui/views/controls/image_view.h" @@ -94,9 +95,7 @@ plugin_vm::PluginVmInstallerFactory::GetForProfile(profile)) { // Layout constants from the spec. gfx::Insets kDialogInsets(60, 64, 0, 64); - constexpr gfx::Insets kLowerContainerInsets(12, 0, 52, 0); constexpr gfx::Size kLogoImageSize(32, 32); - constexpr gfx::Size kBigImageSize(264, 264); constexpr int kTitleFontSize = 28; const gfx::FontList kTitleFont({"Google Sans"}, gfx::Font::NORMAL, kTitleFontSize, gfx::Font::Weight::NORMAL); @@ -128,9 +127,9 @@ AddChildView(upper_container_view); views::View* lower_container_view = new views::View(); - views::BoxLayout* lower_container_layout = + lower_container_layout_ = lower_container_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical, kLowerContainerInsets)); + views::BoxLayout::Orientation::kVertical)); AddChildView(lower_container_view); views::ImageView* logo_image = new views::ImageView(); @@ -183,14 +182,10 @@ upper_container_view->AddChildView(download_progress_message_label_); big_image_ = new views::ImageView(); - big_image_->SetImageSize(kBigImageSize); - big_image_->SetImage( - ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - IDR_PLUGIN_VM_INSTALLER)); lower_container_view->AddChildView(big_image_); // Make sure the lower_container_view is pinned to the bottom of the dialog. - lower_container_layout->set_main_axis_alignment( + lower_container_layout_->set_main_axis_alignment( views::BoxLayout::MainAxisAlignment::kEnd); layout->SetFlexForView(lower_container_view, 1, true); } @@ -615,15 +610,26 @@ } void PluginVmInstallerView::SetBigImage() { - if (state_ == State::kError) { + constexpr gfx::Size kRegularImageSize(314, 191); + constexpr gfx::Size kErrorImageSize(264, 264); + constexpr int kRegularImageBottomInset = 52 + 57; + constexpr int kErrorImageBottomInset = 52; + + auto setImage = [this](int image_id, gfx::Size size, int bottom_inset) { + big_image_->SetImageSize(size); + lower_container_layout_->set_inside_border_insets( + gfx::Insets(0, 0, bottom_inset, 0)); big_image_->SetImage( - ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - IDR_PLUGIN_VM_INSTALLER_ERROR)); + ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(image_id)); + }; + + if (state_ == State::kError) { + setImage(IDR_PLUGIN_VM_INSTALLER_ERROR, kErrorImageSize, + kErrorImageBottomInset); return; } - big_image_->SetImage( - ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( - IDR_PLUGIN_VM_INSTALLER)); + setImage(IDR_PLUGIN_VM_INSTALLER, kRegularImageSize, + kRegularImageBottomInset); } void PluginVmInstallerView::StartInstallation() {
diff --git a/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view.h b/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view.h index 979d737f..f8abf2dd 100644 --- a/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view.h +++ b/chrome/browser/ui/views/plugin_vm/plugin_vm_installer_view.h
@@ -11,6 +11,7 @@ #include "ui/views/bubble/bubble_dialog_delegate_view.h" namespace views { +class BoxLayout; class ImageView; class Label; class Link; @@ -89,6 +90,7 @@ views::Label* message_label_ = nullptr; views::ProgressBar* progress_bar_ = nullptr; views::Label* download_progress_message_label_ = nullptr; + views::BoxLayout* lower_container_layout_ = nullptr; views::ImageView* big_image_ = nullptr; views::Link* learn_more_link_ = nullptr; base::TimeTicks setup_start_tick_;
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc b/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc index 243a8d6..c80f25fc 100644 --- a/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc +++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc
@@ -98,6 +98,8 @@ for (auto state : kButtonStates) SetImage(state, GetAvatarIcon(state, gaia_account_image)); delegate_->ShowIdentityAnimation(gaia_account_image); + + SetInsets(); } void AvatarToolbarButton::UpdateText() { @@ -197,7 +199,6 @@ void AvatarToolbarButton::OnThemeChanged() { ToolbarButton::OnThemeChanged(); - UpdateIcon(); UpdateText(); }
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button.h b/chrome/browser/ui/views/profiles/avatar_toolbar_button.h index dbe9c5069..33807b78 100644 --- a/chrome/browser/ui/views/profiles/avatar_toolbar_button.h +++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button.h
@@ -11,7 +11,6 @@ #include "base/scoped_observer.h" #include "chrome/browser/ui/views/toolbar/toolbar_button.h" #include "chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h" -#include "ui/base/pointer/touch_ui_controller.h" #include "ui/events/event.h" class AvatarToolbarButtonDelegate; @@ -45,7 +44,6 @@ AvatarToolbarButton(Browser* browser, ToolbarIconContainerView* parent); ~AvatarToolbarButton() override; - void UpdateIcon(); void UpdateText(); void ShowAvatarHighlightAnimation(); bool IsParentHighlighted() const; @@ -60,6 +58,7 @@ void OnMouseExited(const ui::MouseEvent& event) override; void OnBlur() override; void OnThemeChanged() override; + void UpdateIcon() override; // ToolbarIconContainerView::Observer: void OnHighlightChanged() override; @@ -80,18 +79,11 @@ void SetInsets(); - void OnTouchUiChanged(); - std::unique_ptr<AvatarToolbarButtonDelegate> delegate_; Browser* const browser_; ToolbarIconContainerView* const parent_; - std::unique_ptr<ui::TouchUiController::Subscription> subscription_ = - ui::TouchUiController::Get()->RegisterCallback( - base::BindRepeating(&AvatarToolbarButton::SetInsets, - base::Unretained(this))); - base::ObserverList<Observer>::Unchecked observer_list_; base::WeakPtrFactory<AvatarToolbarButton> weak_ptr_factory_{this};
diff --git a/chrome/browser/ui/views/toolbar/back_forward_button.cc b/chrome/browser/ui/views/toolbar/back_forward_button.cc index 33453880..1a1dee1 100644 --- a/chrome/browser/ui/views/toolbar/back_forward_button.cc +++ b/chrome/browser/ui/views/toolbar/back_forward_button.cc
@@ -44,3 +44,15 @@ } BackForwardButton::~BackForwardButton() = default; + +void BackForwardButton::UpdateIcon() { + const gfx::VectorIcon* image = nullptr; + const bool touch_ui = ui::TouchUiController::Get()->touch_ui(); + if (direction_ == Direction::kBack) { + image = touch_ui ? &kBackArrowTouchIcon : &vector_icons::kBackArrowIcon; + } else { + image = + touch_ui ? &kForwardArrowTouchIcon : &vector_icons::kForwardArrowIcon; + } + UpdateIconsWithStandardColors(*image); +}
diff --git a/chrome/browser/ui/views/toolbar/back_forward_button.h b/chrome/browser/ui/views/toolbar/back_forward_button.h index 8460c8b4..4323c2f 100644 --- a/chrome/browser/ui/views/toolbar/back_forward_button.h +++ b/chrome/browser/ui/views/toolbar/back_forward_button.h
@@ -20,6 +20,9 @@ BackForwardButton& operator=(const BackForwardButton&) = delete; ~BackForwardButton() override; + // ToolbarButton: + void UpdateIcon() override; + private: Direction direction_; };
diff --git a/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc b/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc index c0896ed..8554f6e 100644 --- a/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc +++ b/chrome/browser/ui/views/toolbar/browser_app_menu_button.cc
@@ -270,11 +270,6 @@ } } -void BrowserAppMenuButton::OnThemeChanged() { - AppMenuButton::OnThemeChanged(); - UpdateIcon(); -} - const char* BrowserAppMenuButton::GetClassName() const { return "BrowserAppMenuButton"; } @@ -368,7 +363,6 @@ } void BrowserAppMenuButton::OnTouchUiChanged() { - UpdateIcon(); UpdateColorsAndInsets(); PreferredSizeChanged(); }
diff --git a/chrome/browser/ui/views/toolbar/browser_app_menu_button.h b/chrome/browser/ui/views/toolbar/browser_app_menu_button.h index 5fe7b0e4..5169533 100644 --- a/chrome/browser/ui/views/toolbar/browser_app_menu_button.h +++ b/chrome/browser/ui/views/toolbar/browser_app_menu_button.h
@@ -14,7 +14,6 @@ #include "chrome/browser/ui/toolbar/app_menu_icon_controller.h" #include "chrome/browser/ui/views/frame/app_menu_button.h" #include "components/feature_engagement/buildflags.h" -#include "ui/base/pointer/touch_ui_controller.h" #include "ui/views/view.h" class ToolbarView; @@ -45,15 +44,11 @@ // noticeable color, and the menu item appearance may be affected. void SetPromoFeature(base::Optional<InProductHelpFeature> promo_feature); - // Updates the presentation according to |severity_| and the theme provider. - void UpdateIcon(); - // Opens the app menu immediately during a drag-and-drop operation. // Used only in testing. static bool g_open_app_immediately_for_testing; // AppMenuButton: - void OnThemeChanged() override; const char* GetClassName() const override; bool GetDropFormats(int* formats, std::set<ui::ClipboardFormatType>* format_types) override; @@ -68,6 +63,8 @@ std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override; SkColor GetInkDropBaseColor() const override; base::string16 GetTooltipText(const gfx::Point& p) const override; + // Updates the presentation according to |severity_| and the theme provider. + void UpdateIcon() override; protected: // If the button is being used as an anchor for a promo, returns the best
diff --git a/chrome/browser/ui/views/toolbar/button_utils.cc b/chrome/browser/ui/views/toolbar/button_utils.cc deleted file mode 100644 index 6d2543a7..0000000 --- a/chrome/browser/ui/views/toolbar/button_utils.cc +++ /dev/null
@@ -1,13 +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/ui/views/toolbar/button_utils.h" - -#if defined(OS_WIN) -#include "base/win/windows_version.h" - -bool UseWindowsIconsForMinimalUI() { - return base::win::GetVersion() >= base::win::Version::WIN10; -} -#endif
diff --git a/chrome/browser/ui/views/toolbar/button_utils.h b/chrome/browser/ui/views/toolbar/button_utils.h deleted file mode 100644 index 0523af79..0000000 --- a/chrome/browser/ui/views/toolbar/button_utils.h +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_VIEWS_TOOLBAR_BUTTON_UTILS_H_ -#define CHROME_BROWSER_UI_VIEWS_TOOLBAR_BUTTON_UTILS_H_ - -#include "build/build_config.h" - -#if defined(OS_WIN) -// For Windows 10 and later, we use custom icons for minimal-ui web app -// Back and Reload buttons, to conform to the native OS' appearance. -// https://w3c.github.io/manifest/#dom-displaymodetype-minimal-ui -bool UseWindowsIconsForMinimalUI(); -#endif - -#endif // CHROME_BROWSER_UI_VIEWS_TOOLBAR_BUTTON_UTILS_H_
diff --git a/chrome/browser/ui/views/toolbar/home_button.cc b/chrome/browser/ui/views/toolbar/home_button.cc index e5c18c5..b1fb3fad 100644 --- a/chrome/browser/ui/views/toolbar/home_button.cc +++ b/chrome/browser/ui/views/toolbar/home_button.cc
@@ -6,6 +6,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_dialogs.h" @@ -192,3 +193,10 @@ } return ui::DragDropTypes::DRAG_NONE; } + +void HomeButton::UpdateIcon() { + const gfx::VectorIcon& home_image = ui::TouchUiController::Get()->touch_ui() + ? kNavigateHomeTouchIcon + : kNavigateHomeIcon; + UpdateIconsWithStandardColors(home_image); +}
diff --git a/chrome/browser/ui/views/toolbar/home_button.h b/chrome/browser/ui/views/toolbar/home_button.h index c2e9e21a..b4dbce0 100644 --- a/chrome/browser/ui/views/toolbar/home_button.h +++ b/chrome/browser/ui/views/toolbar/home_button.h
@@ -24,6 +24,7 @@ bool CanDrop(const OSExchangeData& data) override; int OnDragUpdated(const ui::DropTargetEvent& event) override; int OnPerformDrop(const ui::DropTargetEvent& event) override; + void UpdateIcon() override; private: Browser* const browser_;
diff --git a/chrome/browser/ui/views/toolbar/reload_button.cc b/chrome/browser/ui/views/toolbar/reload_button.cc index 4dc1338..fd5ddcc 100644 --- a/chrome/browser/ui/views/toolbar/reload_button.cc +++ b/chrome/browser/ui/views/toolbar/reload_button.cc
@@ -14,7 +14,6 @@ #include "chrome/browser/command_updater.h" #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/ui/view_ids.h" -#include "chrome/browser/ui/views/toolbar/button_utils.h" #include "chrome/grit/generated_resources.h" #include "components/vector_icons/vector_icons.h" #include "ui/base/l10n/l10n_util.h" @@ -29,23 +28,8 @@ namespace { -const gfx::VectorIcon& GetIconForMode(ReloadButton::IconStyle icon_style, - bool is_reload) { - const bool touch_ui = ui::TouchUiController::Get()->touch_ui(); - -#if defined(OS_WIN) - if (icon_style == ReloadButton::IconStyle::kMinimalUi && - UseWindowsIconsForMinimalUI()) { - if (touch_ui) { - return is_reload ? kReloadWindowsTouchIcon - : kNavigateStopWindowsTouchIcon; - } - - return is_reload ? kReloadWindowsIcon : kNavigateStopWindowsIcon; - } -#endif - - if (touch_ui) +const gfx::VectorIcon& GetIconForMode(bool is_reload) { + if (ui::TouchUiController::Get()->touch_ui()) return is_reload ? kReloadTouchIcon : kNavigateStopTouchIcon; return is_reload ? vector_icons::kReloadIcon : kNavigateStopIcon; @@ -58,11 +42,9 @@ // static const char ReloadButton::kViewClassName[] = "ReloadButton"; -ReloadButton::ReloadButton(CommandUpdater* command_updater, - IconStyle icon_style) +ReloadButton::ReloadButton(CommandUpdater* command_updater) : ToolbarButton(this, CreateMenuModel(), nullptr), command_updater_(command_updater), - icon_style_(icon_style), double_click_timer_delay_( base::TimeDelta::FromMilliseconds(views::GetDoubleClickInterval())), mode_switch_timer_delay_(base::TimeDelta::FromMilliseconds(1350)) { @@ -106,12 +88,6 @@ } } -void ReloadButton::SetColors(SkColor normal_color, SkColor disabled_color) { - normal_color_ = normal_color; - disabled_color_ = disabled_color; - UpdateIcon(); -} - void ReloadButton::OnThemeChanged() { ToolbarButton::OnThemeChanged(); UpdateIcon(); @@ -123,15 +99,7 @@ if (!GetWidget()) return; - const gfx::VectorIcon& icon = - GetIconForMode(icon_style_, visible_mode_ == Mode::kReload); - DCHECK_EQ(normal_color_.has_value(), disabled_color_.has_value()); - if (normal_color_.has_value()) { - UpdateIconsWithColors(icon, normal_color_.value(), normal_color_.value(), - normal_color_.value(), disabled_color_.value()); - } else { - UpdateIconsWithStandardColors(icon); - } + UpdateIconsWithStandardColors(GetIconForMode(visible_mode_ == Mode::kReload)); } void ReloadButton::OnMouseExited(const ui::MouseEvent& event) {
diff --git a/chrome/browser/ui/views/toolbar/reload_button.h b/chrome/browser/ui/views/toolbar/reload_button.h index 8db1d0a..33aceebf 100644 --- a/chrome/browser/ui/views/toolbar/reload_button.h +++ b/chrome/browser/ui/views/toolbar/reload_button.h
@@ -26,13 +26,12 @@ public views::ButtonListener, public ui::SimpleMenuModel::Delegate { public: - enum class IconStyle { kBrowser, kMinimalUi }; enum class Mode { kReload = 0, kStop }; // The button's class name. static const char kViewClassName[]; - explicit ReloadButton(CommandUpdater* command_updater, IconStyle icon_style); + explicit ReloadButton(CommandUpdater* command_updater); ReloadButton(const ReloadButton&) = delete; ReloadButton& operator=(const ReloadButton&) = delete; ~ReloadButton() override; @@ -40,12 +39,11 @@ // Ask for a specified button state. If |force| is true this will be applied // immediately. void ChangeMode(Mode mode, bool force); + Mode visible_mode() const { return visible_mode_; } // Enable reload drop-down menu. void set_menu_enabled(bool enable) { menu_enabled_ = enable; } - void SetColors(SkColor normal_color, SkColor disabled_color); - // views::View: void OnThemeChanged() override; @@ -56,6 +54,7 @@ void GetAccessibleNodeData(ui::AXNodeData* node_data) override; bool ShouldShowMenu() override; void ShowDropDownMenu(ui::MenuSourceType source_type) override; + void UpdateIcon() override; // views::ButtonListener: void ButtonPressed(views::Button* /* button */, @@ -76,9 +75,6 @@ void ExecuteBrowserCommand(int command, int event_flags); - // Updates the icon images. - void UpdateIcon(); - void OnDoubleClickTimer(); void OnStopToReloadTimer(); void OnLongLoadTimer(); @@ -91,8 +87,6 @@ // This may be NULL when testing. CommandUpdater* command_updater_; - const IconStyle icon_style_; - // The mode we should be in assuming no timers are running. Mode intended_mode_ = Mode::kReload; @@ -104,10 +98,6 @@ base::TimeDelta double_click_timer_delay_; base::TimeDelta mode_switch_timer_delay_; - // The colors used for the icon if explicitly set by SetColors(). - base::Optional<SkColor> normal_color_; - base::Optional<SkColor> disabled_color_; - // Indicates if reload menu is enabled. bool menu_enabled_ = false;
diff --git a/chrome/browser/ui/views/toolbar/reload_button_unittest.cc b/chrome/browser/ui/views/toolbar/reload_button_unittest.cc index f3cca24..9a216ef 100644 --- a/chrome/browser/ui/views/toolbar/reload_button_unittest.cc +++ b/chrome/browser/ui/views/toolbar/reload_button_unittest.cc
@@ -38,8 +38,7 @@ ReloadButton reload_; }; -ReloadButtonTest::ReloadButtonTest() - : reload_(nullptr, ReloadButton::IconStyle::kBrowser) { +ReloadButtonTest::ReloadButtonTest() : reload_(nullptr) { // Set the timer delays to 0 so that timers will fire as soon as we tell the // message loop to run pending tasks. reload_.double_click_timer_delay_ = base::TimeDelta();
diff --git a/chrome/browser/ui/views/toolbar/sharesheet_button.h b/chrome/browser/ui/views/toolbar/sharesheet_button.h index 169fab8..5e4eefe 100644 --- a/chrome/browser/ui/views/toolbar/sharesheet_button.h +++ b/chrome/browser/ui/views/toolbar/sharesheet_button.h
@@ -16,7 +16,8 @@ SharesheetButton& operator=(const SharesheetButton&) = delete; ~SharesheetButton() override; - void UpdateIcon(); + // ToolbarButton: + void UpdateIcon() override; private: // views::ButtonListener:
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.cc b/chrome/browser/ui/views/toolbar/toolbar_button.cc index cc262c53..e473b08 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_button.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_button.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" +#include "ui/base/models/image_model.h" #include "ui/base/models/menu_model.h" #include "ui/display/display.h" #include "ui/display/screen.h" @@ -198,14 +199,14 @@ SkColor hovered_color, SkColor pressed_color, SkColor disabled_color) { - SetImage(ButtonState::STATE_NORMAL, - gfx::CreateVectorIcon(icon, normal_color)); - SetImage(ButtonState::STATE_HOVERED, - gfx::CreateVectorIcon(icon, hovered_color)); - SetImage(ButtonState::STATE_PRESSED, - gfx::CreateVectorIcon(icon, pressed_color)); - SetImage(views::Button::STATE_DISABLED, - gfx::CreateVectorIcon(icon, disabled_color)); + SetImageModel(ButtonState::STATE_NORMAL, + ui::ImageModel::FromVectorIcon(icon, normal_color)); + SetImageModel(ButtonState::STATE_HOVERED, + ui::ImageModel::FromVectorIcon(icon, hovered_color)); + SetImageModel(ButtonState::STATE_PRESSED, + ui::ImageModel::FromVectorIcon(icon, pressed_color)); + SetImageModel(Button::STATE_DISABLED, + ui::ImageModel::FromVectorIcon(icon, disabled_color)); } void ToolbarButton::UpdateIconsWithStandardColors(const gfx::VectorIcon& icon) { @@ -277,9 +278,12 @@ } void ToolbarButton::OnThemeChanged() { - LabelButton::OnThemeChanged(); if (installable_ink_drop_) installable_ink_drop_->SetConfig(GetToolbarInstallableInkDropConfig(this)); + UpdateIcon(); + + // Call this after UpdateIcon() to properly reset images. + LabelButton::OnThemeChanged(); } gfx::Rect ToolbarButton::GetAnchorBoundsInScreen() const {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.h b/chrome/browser/ui/views/toolbar/toolbar_button.h index 70fdc8d8..0066598 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_button.h +++ b/chrome/browser/ui/views/toolbar/toolbar_button.h
@@ -8,6 +8,7 @@ #include <memory> #include "base/optional.h" +#include "ui/base/pointer/touch_ui_controller.h" #include "ui/base/theme_provider.h" #include "ui/gfx/animation/animation_delegate.h" #include "ui/gfx/animation/slide_animation.h" @@ -78,6 +79,10 @@ // GetForegroundColor(). void UpdateIconsWithStandardColors(const gfx::VectorIcon& icon); + // Updates the icon images and colors as necessary. Should be called any time + // icon state changes, e.g. in response to theme or touch mode changes. + virtual void UpdateIcon() {} + // Sets |layout_insets_|, see comment there. void SetLayoutInsets(const gfx::Insets& insets); @@ -273,6 +278,11 @@ base::Optional<SkColor> last_border_color_; gfx::Insets last_paint_insets_; + std::unique_ptr<ui::TouchUiController::Subscription> subscription_ = + ui::TouchUiController::Get()->RegisterCallback( + base::BindRepeating(&ToolbarButton::UpdateIcon, + base::Unretained(this))); + // A factory for tasks that show the dropdown context menu for the button. base::WeakPtrFactory<ToolbarButton> show_menu_factory_{this}; };
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc index 84a8a67..31fec4e 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -17,7 +17,6 @@ #include "base/util/ranges/algorithm.h" #include "build/build_config.h" #include "chrome/app/chrome_command_ids.h" -#include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/command_updater.h" #include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/profiles/profile.h" @@ -68,7 +67,6 @@ #include "components/omnibox/browser/omnibox_view.h" #include "components/prefs/pref_service.h" #include "components/strings/grit/components_strings.h" -#include "components/vector_icons/vector_icons.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "media/base/media_switches.h" @@ -205,8 +203,8 @@ std::unique_ptr<ToolbarButton> forward = std::make_unique<BackForwardButton>( BackForwardButton::Direction::kForward, this, browser_); - std::unique_ptr<ReloadButton> reload = std::make_unique<ReloadButton>( - browser_->command_controller(), ReloadButton::IconStyle::kBrowser); + std::unique_ptr<ReloadButton> reload = + std::make_unique<ReloadButton>(browser_->command_controller()); std::unique_ptr<HomeButton> home = std::make_unique<HomeButton>(this, browser_); @@ -915,39 +913,11 @@ ThemeProperties::COLOR_TOOLBAR_VERTICAL_SEPARATOR)); } - const bool touch_ui = ui::TouchUiController::Get()->touch_ui(); - - const gfx::VectorIcon& back_image = - touch_ui ? kBackArrowTouchIcon : vector_icons::kBackArrowIcon; - back_->UpdateIconsWithStandardColors(back_image); - - const gfx::VectorIcon& forward_image = - touch_ui ? kForwardArrowTouchIcon : vector_icons::kForwardArrowIcon; - forward_->UpdateIconsWithStandardColors(forward_image); - - const gfx::VectorIcon& home_image = - touch_ui ? kNavigateHomeTouchIcon : kNavigateHomeIcon; - home_->UpdateIconsWithStandardColors(home_image); - if (extensions_container_) extensions_container_->UpdateAllIcons(); - if (cast_) - cast_->UpdateIcon(); - - if (media_button_) - media_button_->UpdateIcon(); - - if (sharesheet_button_) - sharesheet_button_->UpdateIcon(); - - if (avatar_) - avatar_->UpdateIcon(); - if (toolbar_account_icon_container_) toolbar_account_icon_container_->UpdateAllIcons(); - - app_menu_button_->UpdateIcon(); } void ToolbarView::ShowCriticalNotification() {
diff --git a/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.cc b/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.cc index 950e1b18..a53bddc 100644 --- a/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.cc +++ b/chrome/browser/ui/views/web_apps/web_app_frame_toolbar_view.cc
@@ -35,7 +35,6 @@ #include "chrome/browser/ui/views/page_action/page_action_icon_view.h" #include "chrome/browser/ui/views/toolbar/back_forward_button.h" #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" -#include "chrome/browser/ui/views/toolbar/button_utils.h" #include "chrome/browser/ui/views/toolbar/reload_button.h" #include "chrome/browser/ui/views/toolbar/toolbar_button.h" #include "chrome/browser/ui/views/web_apps/web_app_menu_button.h" @@ -75,6 +74,10 @@ #include "ui/views/window/custom_frame_view.h" #include "ui/views/window/hit_test_utils.h" +#if defined(OS_WIN) +#include "base/win/windows_version.h" +#endif + namespace { bool g_animation_disabled_for_testing = false; @@ -115,6 +118,109 @@ DISALLOW_COPY_AND_ASSIGN(WebAppToolbarActionsBar); }; +template <class BaseClass> +class WebAppToolbarButton : public BaseClass { + public: + using BaseClass::BaseClass; + WebAppToolbarButton(const WebAppToolbarButton&) = delete; + WebAppToolbarButton& operator=(const WebAppToolbarButton&) = delete; + ~WebAppToolbarButton() override = default; + +#if defined(OS_WIN) + bool ShouldUseWindowsIconsForMinimalUI() const { + return base::win::GetVersion() >= base::win::Version::WIN10; + } +#endif + + void SetIconColor(SkColor icon_color) { + if (icon_color_ == icon_color) + return; + + icon_color_ = icon_color; + UpdateIcon(); + } + + virtual const gfx::VectorIcon* GetAlternativeIcon() const { return nullptr; } + + // ToolbarButton: + void UpdateIcon() override { + if (const auto* icon = GetAlternativeIcon()) { + BaseClass::UpdateIconsWithStandardColors(*icon); + return; + } + + BaseClass::UpdateIcon(); + } + + protected: + // ToolbarButton: + SkColor GetForegroundColor(views::Button::ButtonState state) const override { + if (state == views::Button::STATE_DISABLED) + return SkColorSetA(icon_color_, gfx::kDisabledControlAlpha); + + return icon_color_; + } + + private: + SkColor icon_color_ = gfx::kPlaceholderColor; +}; + +class WebAppToolbarBackButton : public WebAppToolbarButton<BackForwardButton> { + public: + WebAppToolbarBackButton(views::ButtonListener* listener, Browser* browser); + WebAppToolbarBackButton(const WebAppToolbarBackButton&) = delete; + WebAppToolbarBackButton& operator=(const WebAppToolbarBackButton&) = delete; + ~WebAppToolbarBackButton() override = default; + + // WebAppToolbarButton: + const gfx::VectorIcon* GetAlternativeIcon() const override; +}; + +WebAppToolbarBackButton::WebAppToolbarBackButton( + views::ButtonListener* listener, + Browser* browser) + : WebAppToolbarButton<BackForwardButton>( + BackForwardButton::Direction::kBack, + listener, + browser) {} + +const gfx::VectorIcon* WebAppToolbarBackButton::GetAlternativeIcon() const { +#if defined(OS_WIN) + if (ShouldUseWindowsIconsForMinimalUI()) { + return ui::TouchUiController::Get()->touch_ui() + ? &kBackArrowWindowsTouchIcon + : &kBackArrowWindowsIcon; + } +#endif + return nullptr; +} + +class WebAppToolbarReloadButton : public WebAppToolbarButton<ReloadButton> { + public: + using WebAppToolbarButton<ReloadButton>::WebAppToolbarButton; + WebAppToolbarReloadButton(const WebAppToolbarReloadButton&) = delete; + WebAppToolbarReloadButton& operator=(const WebAppToolbarReloadButton&) = + delete; + ~WebAppToolbarReloadButton() override = default; + + // WebAppToolbarButton: + const gfx::VectorIcon* GetAlternativeIcon() const override; +}; + +const gfx::VectorIcon* WebAppToolbarReloadButton::GetAlternativeIcon() const { +#if defined(OS_WIN) + if (ShouldUseWindowsIconsForMinimalUI()) { + const bool is_reload = visible_mode() == ReloadButton::Mode::kReload; + if (ui::TouchUiController::Get()->touch_ui()) { + return is_reload ? &kReloadWindowsTouchIcon + : &kNavigateStopWindowsTouchIcon; + } + return is_reload ? &kReloadWindowsIcon : &kNavigateStopWindowsIcon; + } +#endif + return nullptr; +} + int HorizontalPaddingBetweenPageActionsAndAppMenuButtons() { return views::LayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_HORIZONTAL); @@ -136,15 +242,6 @@ toolbar_button->SetLayoutInsets(gfx::Insets(2)); } -const gfx::VectorIcon& GetBackImage(bool touch_ui) { -#if defined(OS_WIN) - if (UseWindowsIconsForMinimalUI()) - return touch_ui ? kBackArrowWindowsTouchIcon : kBackArrowWindowsIcon; -#endif - - return touch_ui ? kBackArrowTouchIcon : vector_icons::kBackArrowIcon; -} - } // namespace const char WebAppFrameToolbarView::kViewClassName[] = "WebAppFrameToolbarView"; @@ -258,27 +355,12 @@ explicit NavigationButtonContainer(BrowserView* browser_view); ~NavigationButtonContainer() override; - ToolbarButton* back_button() { return back_button_; } - - ReloadButton* reload_button() { return reload_button_; } + WebAppToolbarBackButton* back_button() { return back_button_; } + WebAppToolbarReloadButton* reload_button() { return reload_button_; } void SetIconColor(SkColor icon_color) { - icon_color_ = icon_color; - GenerateMinimalUIButtonImages(); - } - - void GenerateMinimalUIButtonImages() { - const SkColor disabled_color = - SkColorSetA(icon_color_, gfx::kDisabledControlAlpha); - - const bool touch_ui = ui::TouchUiController::Get()->touch_ui(); - const gfx::VectorIcon& back_image = GetBackImage(touch_ui); - back_button_->SetImage(views::Button::STATE_NORMAL, - gfx::CreateVectorIcon(back_image, icon_color_)); - back_button_->SetImage(views::Button::STATE_DISABLED, - gfx::CreateVectorIcon(back_image, disabled_color)); - - reload_button_->SetColors(icon_color_, disabled_color); + back_button_->SetIconColor(icon_color); + reload_button_->SetIconColor(icon_color); } protected: @@ -312,16 +394,9 @@ // The containing browser view. BrowserView* const browser_view_; - SkColor icon_color_ = gfx::kPlaceholderColor; - - std::unique_ptr<ui::TouchUiController::Subscription> subscription_ = - ui::TouchUiController::Get()->RegisterCallback(base::BindRepeating( - &NavigationButtonContainer::GenerateMinimalUIButtonImages, - base::Unretained(this))); - // These members are owned by the views hierarchy. - ToolbarButton* back_button_ = nullptr; - ReloadButton* reload_button_ = nullptr; + WebAppToolbarBackButton* back_button_ = nullptr; + WebAppToolbarReloadButton* reload_button_ = nullptr; }; WebAppFrameToolbarView::NavigationButtonContainer::NavigationButtonContainer( @@ -337,12 +412,11 @@ layout.set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kCenter); - back_button_ = AddChildView(std::make_unique<BackForwardButton>( - BackForwardButton::Direction::kBack, this, browser_view_->browser())); + back_button_ = AddChildView(std::make_unique<WebAppToolbarBackButton>( + this, browser_view_->browser())); back_button_->set_tag(IDC_BACK); - reload_button_ = AddChildView(std::make_unique<ReloadButton>( - browser_view_->browser()->command_controller(), - ReloadButton::IconStyle::kMinimalUi)); + reload_button_ = AddChildView(std::make_unique<WebAppToolbarReloadButton>( + browser_view_->browser()->command_controller())); reload_button_->set_tag(IDC_RELOAD); const bool is_browser_focus_mode = browser_view_->browser()->is_focus_mode();
diff --git a/chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_ui.cc b/chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_ui.cc index a9dbb7b64..58835da 100644 --- a/chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_ui.cc +++ b/chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_ui.cc
@@ -47,6 +47,7 @@ {"done", IDS_CROSTINI_UPGRADER_DONE_BUTTON}, {"restore", IDS_CROSTINI_UPGRADER_RESTORE_BUTTON}, {"learnMore", IDS_LEARN_MORE}, + {"notNow", IDS_CROSTINI_UPGRADER_NOT_NOW}, {"promptTitle", IDS_CROSTINI_UPGRADER_TITLE}, {"backingUpTitle", IDS_CROSTINI_UPGRADER_BACKING_UP_TITLE},
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 79f70be..b60d6d9 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1594857570-508aa514a52515f9e9dfbe5d476e51f86a549527.profdata +chrome-mac-master-1594878809-35ea1154d4590798f7d37522056e8d492cada716.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 76cb488..a89f192 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-master-1594771186-8c7f3834398f8caaba6f32c369440926161c5207.profdata +chrome-win64-master-1594814211-6e9c837aecb05743d0a6513baf4c13c15785a909.profdata
diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc index ec06f67..00aa1c2 100644 --- a/chrome/common/extensions/permissions/chrome_api_permissions.cc +++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc
@@ -44,7 +44,8 @@ {APIPermission::kExperimental, "experimental", APIPermissionInfo::kFlagCannotBeOptional}, {APIPermission::kGeolocation, "geolocation", - APIPermissionInfo::kFlagCannotBeOptional}, + APIPermissionInfo::kFlagCannotBeOptional | + APIPermissionInfo::kFlagRequiresManagementUIWarning}, {APIPermission::kNotifications, "notifications", APIPermissionInfo::kFlagDoesNotRequireManagedSessionFullLoginWarning}, {APIPermission::kGcm, "gcm",
diff --git a/chrome/services/sharing/nearby/nearby_connections.cc b/chrome/services/sharing/nearby/nearby_connections.cc index 13a1b76..7aa211a 100644 --- a/chrome/services/sharing/nearby/nearby_connections.cc +++ b/chrome/services/sharing/nearby/nearby_connections.cc
@@ -5,6 +5,7 @@ #include "chrome/services/sharing/nearby/nearby_connections.h" #include "base/run_loop.h" +#include "third_party/nearby/src/cpp/core_v2/core.h" namespace location { namespace nearby { @@ -41,11 +42,11 @@ // There should only be one instance of NearbyConnections in a process. DCHECK(!g_instance); g_instance = this; - // TODO(alexchau): Create Core here after g_instance is set. + core_ = std::make_unique<Core>(); } NearbyConnections::~NearbyConnections() { - // TODO(alexhcau): Destroy Core here before g_instance is reset. + core_.reset(); g_instance = nullptr; }
diff --git a/chrome/services/sharing/nearby/nearby_connections.h b/chrome/services/sharing/nearby/nearby_connections.h index e610775a..0b1c759a 100644 --- a/chrome/services/sharing/nearby/nearby_connections.h +++ b/chrome/services/sharing/nearby/nearby_connections.h
@@ -16,10 +16,14 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" +#include <memory> + namespace location { namespace nearby { namespace connections { +class Core; + // Implementation of the NearbyConnections mojo interface. // This class acts as a bridge to the NearbyConnections library which is pulled // in as a third_party dependency. It handles the translation from mojo calls to @@ -58,6 +62,8 @@ mojo::Remote<sharing::mojom::WebRtcSignalingMessenger> webrtc_signaling_messenger_; + std::unique_ptr<Core> core_; + base::WeakPtrFactory<NearbyConnections> weak_ptr_factory_{this}; };
diff --git a/chrome/services/sharing/sharing_impl_unittest.cc b/chrome/services/sharing/sharing_impl_unittest.cc index b3ea554..2ce37e3 100644 --- a/chrome/services/sharing/sharing_impl_unittest.cc +++ b/chrome/services/sharing/sharing_impl_unittest.cc
@@ -87,7 +87,7 @@ } protected: - base::test::SingleThreadTaskEnvironment task_environment_; + base::test::TaskEnvironment task_environment_; mojo::Remote<mojom::Sharing> remote_; std::unique_ptr<SharingImpl> service_; };
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index acdf97504..cafdf9e1 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -80,10 +80,13 @@ android_library("test_support_java") { testonly = true deps = [ + "//base:base_java", "//chrome/android:chrome_all_java", "//components/autofill/android:autofill_java", "//components/payments/content/android:java", "//components/payments/mojom:mojom_java", + "//content/public/android:content_java", + "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/blink/public/mojom:android_mojo_bindings_java", ] sources = [ "android/test_support/src/org/chromium/chrome/test_support/PaymentRequestTestBridge.java" ] @@ -481,8 +484,6 @@ "//testing/android/native_test:native_test_support", ] - data_deps = [ "//testing/buildbot/filters:android_browsertests_filters" ] - sources = [ "../browser/android/customtabs/custom_tabs_browsertest.cc", "../browser/android/webapk/webapk_icon_hasher_browsertest.cc", @@ -3264,7 +3265,6 @@ "../browser/page_load_metrics/metrics_web_contents_observer_unittest.cc", "../browser/page_load_metrics/observers/aborts_page_load_metrics_observer_unittest.cc", "../browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc", - "../browser/page_load_metrics/observers/ad_metrics/page_ad_density_tracker_unittest.cc", "../browser/page_load_metrics/observers/amp_page_load_metrics_observer_unittest.cc", "../browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_test_utils.cc", "../browser/page_load_metrics/observers/data_reduction_proxy_metrics_observer_test_utils.h",
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn index 839c4b5..66a5360e 100644 --- a/chrome/test/android/BUILD.gn +++ b/chrome/test/android/BUILD.gn
@@ -43,6 +43,7 @@ "//base:base_java_test_support", "//chrome/android:chrome_java", "//chrome/browser/ui/android/appmenu/test:test_support_java", + "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_drawerlayout_drawerlayout_java", "//third_party/android_deps:androidx_test_uiautomator_uiautomator_java", "//third_party/android_support_test_runner:runner_java", @@ -67,6 +68,7 @@ "//base:base_java_test_support", "//chrome/browser/flags:java", "//content/public/test/android:content_java_test_support", + "//third_party/android_deps:androidx_test_runner_java", "//third_party/hamcrest:hamcrest_java", "//third_party/junit", ] @@ -87,11 +89,13 @@ "//base:base_java", "//base:base_java_test_support", "//chrome/android:chrome_java", + "//chrome/browser/flags:java", "//chrome/browser/tab:java", "//chrome/browser/ui/android/native_page:java", "//components/embedder_support/android:util_java", "//content/public/test/android:content_java_test_support", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", + "//third_party/android_deps:androidx_test_runner_java", "//third_party/android_deps:com_android_support_drawerlayout_java", "//third_party/android_deps:com_android_support_recyclerview_v7_java", "//third_party/android_deps:espresso_java", @@ -119,6 +123,7 @@ "//chrome/android/webapk/libs/client:client_java", "//components/webapk/android/libs/client:java", "//content/public/test/android:content_java_test_support", + "//third_party/android_deps:androidx_test_runner_java", "//third_party/android_support_test_runner:runner_java", "//third_party/junit", ] @@ -139,6 +144,8 @@ sources = [ "javatests/src/org/chromium/chrome/test/pagecontroller/tests/codelab/SettingsForCodelabTest.java" ] deps = [ ":chrome_java_test_pagecontroller", + "//base:base_java_test_support", + "//third_party/android_deps:androidx_test_runner_java", "//third_party/junit", ] @@ -248,9 +255,11 @@ "//chrome/android/third_party/compositor_animator:compositor_animator_java", "//chrome/browser/flags:java", "//chrome/browser/preferences:java", + "//chrome/browser/profiles/android:java", "//chrome/browser/settings:test_support_java", "//chrome/browser/tab:java", "//chrome/browser/tabmodel:java", + "//chrome/browser/thumbnail/generator:java", "//chrome/browser/ui/android/appmenu:java", "//chrome/browser/ui/android/appmenu/test:test_support_java", "//chrome/browser/ui/android/favicon:java",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java index c0d08587..1a4e02d29 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/signin/SigninTestUtil.java
@@ -11,6 +11,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CallbackHelper; import org.chromium.chrome.browser.SyncFirstSetupCompleteSource; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.IdentityServicesProvider; import org.chromium.chrome.browser.signin.SigninManager; import org.chromium.chrome.browser.sync.ProfileSyncService; @@ -33,8 +34,9 @@ static Account getCurrentAccount() { return TestThreadUtils.runOnUiThreadBlockingNoException(() -> { return CoreAccountInfo.getAndroidAccountFrom( - IdentityServicesProvider.get().getIdentityManager().getPrimaryAccountInfo( - ConsentLevel.SYNC)); + IdentityServicesProvider.get() + .getIdentityManager(Profile.getLastUsedRegularProfile()) + .getPrimaryAccountInfo(ConsentLevel.SYNC)); }); } @@ -44,7 +46,8 @@ static void signIn(Account account) { CallbackHelper callbackHelper = new CallbackHelper(); TestThreadUtils.runOnUiThreadBlocking(() -> { - SigninManager signinManager = IdentityServicesProvider.get().getSigninManager(); + SigninManager signinManager = IdentityServicesProvider.get().getSigninManager( + Profile.getLastUsedRegularProfile()); signinManager.onFirstRunCheckDone(); // Allow sign-in signinManager.signIn( SigninAccessPoint.UNKNOWN, account, new SigninManager.SignInCallback() { @@ -69,7 +72,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { Assert.assertEquals(account.name, IdentityServicesProvider.get() - .getIdentityManager() + .getIdentityManager(Profile.getLastUsedRegularProfile()) .getPrimaryAccountInfo(ConsentLevel.SYNC) .getEmail()); }); @@ -83,7 +86,8 @@ CallbackHelper ch = new CallbackHelper(); TestThreadUtils.runOnUiThreadBlocking(() -> { AccountTrackerService accountTrackerService = - IdentityServicesProvider.get().getAccountTrackerService(); + IdentityServicesProvider.get().getAccountTrackerService( + Profile.getLastUsedRegularProfile()); if (accountTrackerService.checkAndSeedSystemAccounts()) { ch.notifyCalled(); } else { @@ -109,8 +113,9 @@ ThreadUtils.assertOnBackgroundThread(); CallbackHelper callbackHelper = new CallbackHelper(); TestThreadUtils.runOnUiThreadBlocking(() -> { - IdentityServicesProvider.get().getSigninManager().signOut( - SignoutReason.SIGNOUT_TEST, callbackHelper::notifyCalled, false); + IdentityServicesProvider.get() + .getSigninManager(Profile.getLastUsedRegularProfile()) + .signOut(SignoutReason.SIGNOUT_TEST, callbackHelper::notifyCalled, false); }); try { callbackHelper.waitForFirst();
diff --git a/chrome/test/android/test_trusted_web_activity/BUILD.gn b/chrome/test/android/test_trusted_web_activity/BUILD.gn index f8a3bc2..4911a9c 100644 --- a/chrome/test/android/test_trusted_web_activity/BUILD.gn +++ b/chrome/test/android/test_trusted_web_activity/BUILD.gn
@@ -13,5 +13,8 @@ "src/org/chromium/chrome/browser/browserservices/MessengerService.java", "src/org/chromium/chrome/browser/browserservices/TestTrustedWebActivityService.java", ] - deps = [ "//third_party/android_sdk/androidx_browser:androidx_browser_java" ] + deps = [ + "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_sdk/androidx_browser:androidx_browser_java", + ] }
diff --git a/chrome/test/data/ads_observer/ad_iframe_writer.js b/chrome/test/data/ads_observer/ad_iframe_writer.js index b49e3a29..547188d 100644 --- a/chrome/test/data/ads_observer/ad_iframe_writer.js +++ b/chrome/test/data/ads_observer/ad_iframe_writer.js
@@ -16,19 +16,3 @@ document.body.appendChild(frame); return frame; } - -function createAdIframeAtRect(x, y, width, height) { - let frame = document.createElement('iframe'); - frame.style.border = "0px none transparent"; - frame.style.overflow = "hidden"; - frame.style.position = "fixed"; - frame.style.left = x; - frame.style.top = y; - frame.scrolling = "no"; - frame.frameborder="0"; - frame.allowTransparency="true"; - frame.width = width; - frame.height = height; - document.body.appendChild(frame); - return frame; -}
diff --git a/chrome/test/data/pdf/BUILD.gn b/chrome/test/data/pdf/BUILD.gn index 9223d33..f4d49a4 100644 --- a/chrome/test/data/pdf/BUILD.gn +++ b/chrome/test/data/pdf/BUILD.gn
@@ -12,12 +12,44 @@ "js_module_root=./gen/chrome/test/data/webui/", ] deps = [ + #":annotations_feature_enabled_test", + #":basic_plugin_test", + ":basic_test", + + #":beep_test", + #":bookmarks_test", ":download_controls_test", ":gesture_detector_test", + + #":layout_test", + #":material_elements_test", + #":metrics_test", + #":navigator_test", + #":nobeep_test", + #":page_change_test", + #":params_parser_test", + #":printing_icon_test", + #":redirects_fail_test", ":test_util", + + #":title_test", + #":toolbar_manager_test", + #":touch_handling_test", + #":viewport_test", + #":whitespace_title_test", + #":zoom_manager_test", ] } +js_library("basic_test") { + deps = [ + "//chrome/browser/resources/pdf:pdf_viewer", + "//chrome/browser/resources/pdf/elements:viewer-pdf-toolbar", + "//chrome/browser/resources/pdf/elements:viewer-toolbar-dropdown", + ] + externs_list = [ "$externs_path/test.js" ] +} + js_library("gesture_detector_test") { deps = [ "//chrome/browser/resources/pdf:gesture_detector",
diff --git a/chrome/test/data/pdf/basic_test.js b/chrome/test/data/pdf/basic_test.js index 52667efb..e32b7ee 100644 --- a/chrome/test/data/pdf/basic_test.js +++ b/chrome/test/data/pdf/basic_test.js
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {getFilenameFromURL} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer.js'; +import {getFilenameFromURL, PDFViewerElement} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer.js'; import {shouldIgnoreKeyEvents} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_utils.js'; import {$} from 'chrome://resources/js/util.m.js'; import {pressAndReleaseKeyOn} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js'; @@ -13,7 +13,8 @@ * verifies that Polymer is working correctly. */ function testHasElements() { - const viewer = document.body.querySelector('pdf-viewer'); + const viewer = /** @type {!PDFViewerElement} */ ( + document.body.querySelector('pdf-viewer')); const elementNames = [ 'viewer-pdf-toolbar', 'viewer-zoom-toolbar', @@ -32,7 +33,8 @@ * Test that the plugin element exists and is navigated to the correct URL. */ function testPluginElement() { - const viewer = document.body.querySelector('pdf-viewer'); + const viewer = /** @type {!PDFViewerElement} */ ( + document.body.querySelector('pdf-viewer')); const plugin = viewer.shadowRoot.querySelector('#plugin'); chrome.test.assertEq('embed', plugin.localName); @@ -47,9 +49,11 @@ */ function testIgnoreKeyEvents() { // Test that the traversal through the shadow DOM works correctly. - const viewer = document.body.querySelector('pdf-viewer'); - const toolbar = viewer.shadowRoot.querySelector('#toolbar'); - toolbar.$.pageselector.pageSelector.focus(); + const viewer = /** @type {!PDFViewerElement} */ ( + document.body.querySelector('pdf-viewer')); + const toolbar = /** @type {!ViewerPdfToolbarElement} */ ( + viewer.shadowRoot.querySelector('#toolbar')); + toolbar.$$('#pageselector').pageSelector.focus(); chrome.test.assertTrue(shouldIgnoreKeyEvents(toolbar)); // Test case where the active element has a shadow root of its own. @@ -67,10 +71,13 @@ * pressing escape. */ function testOpenCloseBookmarks() { - const viewer = document.body.querySelector('pdf-viewer'); - const toolbar = viewer.shadowRoot.querySelector('#toolbar'); + const viewer = /** @type {!PDFViewerElement} */ ( + document.body.querySelector('pdf-viewer')); + const toolbar = /** @type {!ViewerPdfToolbarElement} */ ( + viewer.shadowRoot.querySelector('#toolbar')); toolbar.show(); - const dropdown = toolbar.$.bookmarks; + const dropdown = + /** @type {!ViewerToolbarDropdownElement} */ (toolbar.$$('#bookmarks')); const plugin = viewer.shadowRoot.querySelector('#plugin'); const ESC_KEY = 27;
diff --git a/chrome/test/data/webui/nearby_share/BUILD.gn b/chrome/test/data/webui/nearby_share/BUILD.gn index 137a156f..18130787 100644 --- a/chrome/test/data/webui/nearby_share/BUILD.gn +++ b/chrome/test/data/webui/nearby_share/BUILD.gn
@@ -13,11 +13,17 @@ ] deps = [ ":nearby_confirmation_page_test", + ":nearby_device_test", ":nearby_preview_test", ":nearby_progress_test", ] } +js_library("nearby_device_test") { + deps = [ "//chrome/browser/resources/nearby_share:nearby_device" ] + externs_list = [ "$externs_path/mocha-2.5.js" ] +} + js_library("nearby_confirmation_page_test") { deps = [ "//chrome/browser/resources/nearby_share:nearby_confirmation_page" ] externs_list = [ "$externs_path/mocha-2.5.js" ]
diff --git a/chrome/test/data/webui/nearby_share/nearby_browsertest.js b/chrome/test/data/webui/nearby_share/nearby_browsertest.js index 1c26c6e..7460ded9 100644 --- a/chrome/test/data/webui/nearby_share/nearby_browsertest.js +++ b/chrome/test/data/webui/nearby_share/nearby_browsertest.js
@@ -47,6 +47,7 @@ }; [['ConfirmationPage', 'nearby_confirmation_page_test.js'], + ['Device', 'nearby_device_test.js'], ['Preview', 'nearby_preview_test.js'], ['Progress', 'nearby_progress_test.js'], ].forEach(test => registerTest(...test));
diff --git a/chrome/test/data/webui/nearby_share/nearby_device_test.js b/chrome/test/data/webui/nearby_share/nearby_device_test.js new file mode 100644 index 0000000..dce051a --- /dev/null +++ b/chrome/test/data/webui/nearby_share/nearby_device_test.js
@@ -0,0 +1,37 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// So that mojo is defined. +import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; + +import 'chrome://nearby/nearby_device.js'; + +import {assertEquals} from '../chai_assert.js'; + +suite('DeviceTest', function() { + /** @type {!NearbyDeviceElement} */ + let deviceElement; + + setup(function() { + deviceElement = /** @type {!NearbyDeviceElement} */ ( + document.createElement('nearby-device')); + document.body.appendChild(deviceElement); + }); + + teardown(function() { + deviceElement.remove(); + }); + + test('renders component', function() { + assertEquals('NEARBY-DEVICE', deviceElement.tagName); + }); + + test('renders name', function() { + const name = 'Name'; + deviceElement.setAttribute('name', name); + + const renderedName = deviceElement.$$('#name').textContent; + assertEquals(name, renderedName); + }); +});
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 456a3054..78c109c 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -13349.0.0 \ No newline at end of file +13351.0.0 \ No newline at end of file
diff --git a/chromeos/components/media_app_ui/resources/js/web_app_file_handling.externs.js b/chromeos/components/media_app_ui/resources/js/web_app_file_handling.externs.js index 3a31ae0..022f59fd 100644 --- a/chromeos/components/media_app_ui/resources/js/web_app_file_handling.externs.js +++ b/chromeos/components/media_app_ui/resources/js/web_app_file_handling.externs.js
@@ -103,13 +103,6 @@ /** @interface */ class FileSystemFileHandle extends FileSystemHandle { /** - * @deprecated TODO(b/151564533): Remove when m82 is stable. - * @param {FileSystemCreateWriterOptions=} options - * @return {!Promise<!FileSystemWriter>} - */ - createWriter(options) {} - - /** * @param {FileSystemCreateWriterOptions=} options * @return {!Promise<!FileSystemWritableFileStream>} */
diff --git a/chromeos/components/media_app_ui/test/driver.js b/chromeos/components/media_app_ui/test/driver.js index 26cefd0..29e15dce 100644 --- a/chromeos/components/media_app_ui/test/driver.js +++ b/chromeos/components/media_app_ui/test/driver.js
@@ -146,10 +146,6 @@ this.nextCreateWritableError; } /** @override */ - createWriter(options) { - throw new Error('createWriter() deprecated.'); - } - /** @override */ async createWritable(options) { if (this.nextCreateWritableError) { throw this.nextCreateWritableError;
diff --git a/chromeos/components/print_management/resources/index.html b/chromeos/components/print_management/resources/index.html index eed681fc..c30bdef 100644 --- a/chromeos/components/print_management/resources/index.html +++ b/chromeos/components/print_management/resources/index.html
@@ -8,7 +8,7 @@ <title>Print Jobs</title> <style> html { - background-color: var(--cros-default-bg-color); + background-color: var(--cros-bg-color); } </style> </head>
diff --git a/chromeos/components/print_management/resources/print_management.html b/chromeos/components/print_management/resources/print_management.html index 2cd884bb..d22a4f8 100644 --- a/chromeos/components/print_management/resources/print_management.html +++ b/chromeos/components/print_management/resources/print_management.html
@@ -1,6 +1,6 @@ <style include="cr-shared-style print-management-shared print-management-fonts"> html { - background-color: var(--cros-default-bg-color); + background-color: var(--cros-bg-color); } .column-headers {
diff --git a/chromeos/components/print_management/resources/print_management_shared_css.html b/chromeos/components/print_management/resources/print_management_shared_css.html index 24052dd..e8ba704 100644 --- a/chromeos/components/print_management/resources/print_management_shared_css.html +++ b/chromeos/components/print_management/resources/print_management_shared_css.html
@@ -5,7 +5,7 @@ <template> <style include="cr-shared-style"> html { - background-color: var(--cros-default-bg-color); + background-color: var(--cros-bg-color); } .flex-center {
diff --git a/chromeos/profiles/airmont.afdo.newest.txt b/chromeos/profiles/airmont.afdo.newest.txt index 8b76862..766512b4 100644 --- a/chromeos/profiles/airmont.afdo.newest.txt +++ b/chromeos/profiles/airmont.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-airmont-86-4181.3-1594633354-benchmark-86.0.4194.0-r1-redacted.afdo.xz +chromeos-chrome-amd64-airmont-86-4181.3-1594633354-benchmark-86.0.4203.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/broadwell.afdo.newest.txt b/chromeos/profiles/broadwell.afdo.newest.txt index 65b7990..7a9d7ef3 100644 --- a/chromeos/profiles/broadwell.afdo.newest.txt +++ b/chromeos/profiles/broadwell.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-broadwell-86-4181.3-1594633791-benchmark-86.0.4194.0-r1-redacted.afdo.xz +chromeos-chrome-amd64-broadwell-86-4181.3-1594633791-benchmark-86.0.4203.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/silvermont.afdo.newest.txt b/chromeos/profiles/silvermont.afdo.newest.txt index 05aaef7f..0746fc5 100644 --- a/chromeos/profiles/silvermont.afdo.newest.txt +++ b/chromeos/profiles/silvermont.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-silvermont-86-4181.3-1594638142-benchmark-86.0.4194.0-r1-redacted.afdo.xz +chromeos-chrome-amd64-silvermont-86-4181.3-1594638142-benchmark-86.0.4203.0-r1-redacted.afdo.xz
diff --git a/chromeos/services/machine_learning/public/mojom/roll_mojoms.sh b/chromeos/services/machine_learning/public/mojom/roll_mojoms.sh index b7c912d..78c52e4d 100755 --- a/chromeos/services/machine_learning/public/mojom/roll_mojoms.sh +++ b/chromeos/services/machine_learning/public/mojom/roll_mojoms.sh
@@ -56,11 +56,6 @@ -e 's~^import "ml~import "chromeos/services/machine_learning/public~g' \ *.mojom -echo "Applying Mojo syntax changes ..." -sed --in-place --regexp-extended \ - -e 's/(GraphExecutor|Model|TextClassifier|HandwritingRecognizer)& request/pending_receiver<\1> receiver/g' \ - *.mojom - echo "OK. Now:" echo "1. Examine 'git diff' to double-check the results of this tool." echo "2. After submitting, also update any google3 files generated from these "
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index bab7b96..7503525 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -64,6 +64,8 @@ "property/arc_property_bridge.h", "rotation_lock/arc_rotation_lock_bridge.cc", "rotation_lock/arc_rotation_lock_bridge.h", + "sensor/arc_sensor_bridge.cc", + "sensor/arc_sensor_bridge.h", "storage_manager/arc_storage_manager.cc", "storage_manager/arc_storage_manager.h", "timer/arc_timer_bridge.cc",
diff --git a/components/arc/mojom/BUILD.gn b/components/arc/mojom/BUILD.gn index ebb973f53..7b784cd 100644 --- a/components/arc/mojom/BUILD.gn +++ b/components/arc/mojom/BUILD.gn
@@ -51,6 +51,8 @@ "rotation_lock.mojom", "scale_factor.mojom", "screen_capture.mojom", + "sensor.mojom", + "sensor_service.mojom", "storage_manager.mojom", "timer.mojom", "tracing.mojom",
diff --git a/components/arc/mojom/arc_bridge.mojom b/components/arc/mojom/arc_bridge.mojom index 127c819..aaa40070 100644 --- a/components/arc/mojom/arc_bridge.mojom +++ b/components/arc/mojom/arc_bridge.mojom
@@ -42,6 +42,7 @@ import "components/arc/mojom/property.mojom"; import "components/arc/mojom/rotation_lock.mojom"; import "components/arc/mojom/screen_capture.mojom"; +import "components/arc/mojom/sensor.mojom"; import "components/arc/mojom/storage_manager.mojom"; import "components/arc/mojom/timer.mojom"; import "components/arc/mojom/tracing.mojom"; @@ -54,9 +55,9 @@ import "components/arc/mojom/wake_lock.mojom"; import "components/arc/mojom/wallpaper.mojom"; -// Next MinVersion: 49 +// Next MinVersion: 50 // Deprecated method IDs: 101, 105, 121 -// Next method ID: 154 +// Next method ID: 155 interface ArcBridgeHost { // Keep the entries alphabetical. In order to do so without breaking // compatibility with the ARC instance, explicitly assign each interface a @@ -211,6 +212,10 @@ [MinVersion=35] OnScreenCaptureInstanceReady@140( pending_remote<ScreenCaptureInstance> instance_remote); + // Notifies Chrome that the SensorInstance interface is ready. + [MinVersion=49] OnSensorInstanceReady@154( + pending_remote<SensorInstance> instance_ptr); + // Notifies Chrome that the SmartCardManagerInstance interface is ready. [MinVersion=48] OnSmartCardManagerInstanceReady@153( pending_remote<SmartCardManagerInstance> instance_remote);
diff --git a/components/arc/mojom/sensor.mojom b/components/arc/mojom/sensor.mojom new file mode 100644 index 0000000..57733174 --- /dev/null +++ b/components/arc/mojom/sensor.mojom
@@ -0,0 +1,21 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module arc.mojom; + +import "components/arc/mojom/sensor_service.mojom"; + +// Chrome implements this interface to handle requests from ARC. +// Next method ID: 1 +interface SensorHost { + // Binds the request to the sensor service. + GetSensorService@0(pending_receiver<SensorService> request); +}; + +// ARC implements this interface to interact with chrome. +// Next method ID: 1 +interface SensorInstance { + // Establishes full-duplex communication with the host. + Init@0(pending_remote<SensorHost> host_ptr) => (); +}; \ No newline at end of file
diff --git a/components/arc/mojom/sensor_service.mojom b/components/arc/mojom/sensor_service.mojom new file mode 100644 index 0000000..414ef26 --- /dev/null +++ b/components/arc/mojom/sensor_service.mojom
@@ -0,0 +1,37 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module arc.mojom; + +enum AttributeIOResult { + SUCCESS = 0, + ERROR_CHANNEL_NOT_FOUND = 1, + ERROR_ATTRIBUTE_NOT_FOUND = 2, + ERROR_IO = 3, +}; + +// SensorService provides access to all sensor devices. +// arc-sensor-service runs in minijail to implement this interface to provide +// sensor data for ARC. +interface SensorService { + // Returns the list of device names. + GetDeviceNames@0() => (array<string> names); + + // Binds the request to the specified device. + GetDeviceByName@1(string name, SensorDevice& request); +}; + +// SensorDevice provides an interface to interact with a sensor device. +// arc-sensor-service runs in minijail to implement this interface to provide +// sensor data for ARC. +interface SensorDevice { + // Returns the value of the specified device attribute. + GetAttribute@0(string name) => (AttributeIOResult result, string value); + + // Sets the specified device attribute. + SetAttribute@1(string name, string value) => (AttributeIOResult result); + + // Opens the device buffer. + OpenBuffer@2() => (handle? fd); +};
diff --git a/components/arc/sensor/arc_sensor_bridge.cc b/components/arc/sensor/arc_sensor_bridge.cc new file mode 100644 index 0000000..812229f --- /dev/null +++ b/components/arc/sensor/arc_sensor_bridge.cc
@@ -0,0 +1,85 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/arc/sensor/arc_sensor_bridge.h" + +#include <utility> + +#include "base/bind.h" +#include "base/files/scoped_file.h" +#include "base/memory/singleton.h" +#include "base/rand_util.h" +#include "base/strings/string_number_conversions.h" +#include "chromeos/dbus/arc/arc_sensor_service_client.h" +#include "components/arc/arc_browser_context_keyed_service_factory_base.h" +#include "components/arc/session/arc_bridge_service.h" +#include "mojo/public/cpp/platform/platform_channel.h" +#include "mojo/public/cpp/system/invitation.h" +#include "mojo/public/cpp/system/platform_handle.h" + +namespace arc { + +namespace { + +// Singleton factory for ArcSensorBridge. +class ArcSensorBridgeFactory + : public internal::ArcBrowserContextKeyedServiceFactoryBase< + ArcSensorBridge, + ArcSensorBridgeFactory> { + public: + // Factory name used by ArcBrowserContextKeyedServiceFactoryBase. + static constexpr const char* kName = "ArcSensorBridgeFactory"; + + static ArcSensorBridgeFactory* GetInstance() { + return base::Singleton<ArcSensorBridgeFactory>::get(); + } + + private: + friend base::DefaultSingletonTraits<ArcSensorBridgeFactory>; + ArcSensorBridgeFactory() = default; + ~ArcSensorBridgeFactory() override = default; +}; + +} // namespace + +// static +ArcSensorBridge* ArcSensorBridge::GetForBrowserContext( + content::BrowserContext* context) { + return ArcSensorBridgeFactory::GetForBrowserContext(context); +} + +ArcSensorBridge::ArcSensorBridge(content::BrowserContext* context, + ArcBridgeService* bridge_service) + : arc_bridge_service_(bridge_service) { + arc_bridge_service_->sensor()->SetHost(this); +} + +ArcSensorBridge::~ArcSensorBridge() { + arc_bridge_service_->sensor()->SetHost(nullptr); +} + +void ArcSensorBridge::GetSensorService( + mojo::PendingReceiver<mojom::SensorService> receiver) { + auto token = base::NumberToString(base::RandUint64()); + mojo::OutgoingInvitation invitation; + mojo::PlatformChannel channel; + mojo::ScopedMessagePipeHandle pipe = invitation.AttachMessagePipe(token); + mojo::OutgoingInvitation::Send(std::move(invitation), + base::kNullProcessHandle, + channel.TakeLocalEndpoint()); + // Fuse the receiver with the attached pipe so that the requester's pipe will + // be connected to the sensor service. + MojoResult result = + mojo::FuseMessagePipes(receiver.PassPipe(), std::move(pipe)); + if (result != MOJO_RESULT_OK) { + LOG(ERROR) << "FuseMessagePipes() failed: " << result; + return; + } + base::ScopedFD fd = + channel.TakeRemoteEndpoint().TakePlatformHandle().TakeFD(); + chromeos::ArcSensorServiceClient::Get()->BootstrapMojoConnection( + fd.get(), token, base::BindOnce([](bool success) {})); +} + +} // namespace arc
diff --git a/components/arc/sensor/arc_sensor_bridge.h b/components/arc/sensor/arc_sensor_bridge.h new file mode 100644 index 0000000..77e0481 --- /dev/null +++ b/components/arc/sensor/arc_sensor_bridge.h
@@ -0,0 +1,43 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_ARC_SENSOR_ARC_SENSOR_BRIDGE_H_ +#define COMPONENTS_ARC_SENSOR_ARC_SENSOR_BRIDGE_H_ + +#include "components/arc/mojom/sensor.mojom.h" +#include "components/keyed_service/core/keyed_service.h" + +namespace content { +class BrowserContext; +} // namespace content + +namespace arc { + +class ArcBridgeService; + +// This class handles Sensor-related requests from the ARC container. +class ArcSensorBridge : public KeyedService, public mojom::SensorHost { + public: + // Returns singleton instance for the given BrowserContext, + // or nullptr if the browser |context| is not allowed to use ARC. + static ArcSensorBridge* GetForBrowserContext( + content::BrowserContext* context); + + ArcSensorBridge(content::BrowserContext* context, + ArcBridgeService* bridge_service); + ~ArcSensorBridge() override; + ArcSensorBridge(const ArcSensorBridge&) = delete; + ArcSensorBridge& operator=(const ArcSensorBridge&) = delete; + + // mojom::SensorHost overrides: + void GetSensorService( + mojo::PendingReceiver<mojom::SensorService> receiver) override; + + private: + ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager. +}; + +} // namespace arc + +#endif // COMPONENTS_ARC_SENSOR_ARC_SENSOR_BRIDGE_H_
diff --git a/components/arc/session/arc_bridge_host_impl.cc b/components/arc/session/arc_bridge_host_impl.cc index 4bd630b..548b749 100644 --- a/components/arc/session/arc_bridge_host_impl.cc +++ b/components/arc/session/arc_bridge_host_impl.cc
@@ -49,6 +49,7 @@ #include "components/arc/mojom/property.mojom.h" #include "components/arc/mojom/rotation_lock.mojom.h" #include "components/arc/mojom/screen_capture.mojom.h" +#include "components/arc/mojom/sensor.mojom.h" #include "components/arc/mojom/storage_manager.mojom.h" #include "components/arc/mojom/timer.mojom.h" #include "components/arc/mojom/tracing.mojom.h" @@ -307,6 +308,11 @@ std::move(screen_capture_remote)); } +void ArcBridgeHostImpl::OnSensorInstanceReady( + mojo::PendingRemote<mojom::SensorInstance> sensor_remote) { + OnInstanceReady(arc_bridge_service_->sensor(), std::move(sensor_remote)); +} + void ArcBridgeHostImpl::OnSmartCardManagerInstanceReady( mojo::PendingRemote<mojom::SmartCardManagerInstance> smart_card_manager_remote) {
diff --git a/components/arc/session/arc_bridge_host_impl.h b/components/arc/session/arc_bridge_host_impl.h index bbe1860f..d55d17d 100644 --- a/components/arc/session/arc_bridge_host_impl.h +++ b/components/arc/session/arc_bridge_host_impl.h
@@ -128,6 +128,8 @@ void OnScreenCaptureInstanceReady( mojo::PendingRemote<mojom::ScreenCaptureInstance> screen_capture_remote) override; + void OnSensorInstanceReady( + mojo::PendingRemote<mojom::SensorInstance> sensor_ptr) override; void OnSmartCardManagerInstanceReady( mojo::PendingRemote<mojom::SmartCardManagerInstance> smart_card_manager_remote) override;
diff --git a/components/arc/session/arc_bridge_service.cc b/components/arc/session/arc_bridge_service.cc index 5fae700..558cc0e 100644 --- a/components/arc/session/arc_bridge_service.cc +++ b/components/arc/session/arc_bridge_service.cc
@@ -43,6 +43,7 @@ #include "components/arc/mojom/property.mojom.h" #include "components/arc/mojom/rotation_lock.mojom.h" #include "components/arc/mojom/screen_capture.mojom.h" +#include "components/arc/mojom/sensor.mojom.h" #include "components/arc/mojom/storage_manager.mojom.h" #include "components/arc/mojom/timer.mojom.h" #include "components/arc/mojom/tracing.mojom.h"
diff --git a/components/arc/session/arc_bridge_service.h b/components/arc/session/arc_bridge_service.h index 93ed0c42..9cc494c 100644 --- a/components/arc/session/arc_bridge_service.h +++ b/components/arc/session/arc_bridge_service.h
@@ -81,6 +81,8 @@ class RotationLockInstance; class ScreenCaptureHost; class ScreenCaptureInstance; +class SensorHost; +class SensorInstance; class SmartCardManagerHost; class SmartCardManagerInstance; class StorageManagerInstance; @@ -249,6 +251,9 @@ screen_capture() { return &screen_capture_; } + ConnectionHolder<mojom::SensorInstance, mojom::SensorHost>* sensor() { + return &sensor_; + } ConnectionHolder<mojom::SmartCardManagerInstance, mojom::SmartCardManagerHost>* smart_card_manager() { @@ -334,6 +339,7 @@ ConnectionHolder<mojom::RotationLockInstance> rotation_lock_; ConnectionHolder<mojom::ScreenCaptureInstance, mojom::ScreenCaptureHost> screen_capture_; + ConnectionHolder<mojom::SensorInstance, mojom::SensorHost> sensor_; ConnectionHolder<mojom::SmartCardManagerInstance, mojom::SmartCardManagerHost> smart_card_manager_; ConnectionHolder<mojom::StorageManagerInstance> storage_manager_;
diff --git a/components/arc/session/arc_vm_client_adapter.cc b/components/arc/session/arc_vm_client_adapter.cc index f3091b0..dc224cb 100644 --- a/components/arc/session/arc_vm_client_adapter.cc +++ b/components/arc/session/arc_vm_client_adapter.cc
@@ -59,6 +59,7 @@ // ascii code in hex. So "arc_2dcreate_2ddata" becomes "arc-create-data". constexpr const char kArcCreateDataJobName[] = "arc_2dcreate_2ddata"; constexpr const char kArcKeymasterJobName[] = "arc_2dkeymasterd"; +constexpr const char kArcSensorServiceJobName[] = "arc_2dsensor_2dservice"; constexpr const char kArcVmServerProxyJobName[] = "arcvm_2dserver_2dproxy"; constexpr const char kArcVmPerBoardFeaturesJobName[] = "arcvm_2dper_2dboard_2dfeatures"; @@ -551,6 +552,33 @@ return; } + // Kill a stale arc-sensor-service job + chromeos::UpstartClient::Get()->StopJob( + kArcSensorServiceJobName, /*environment=*/{}, + base::BindOnce(&ArcVmClientAdapter::OnArcSensorServiceStopped, + weak_factory_.GetWeakPtr(), std::move(callback))); + } + + void OnArcSensorServiceStopped(chromeos::VoidDBusMethodCallback callback, + bool result) { + VLOG(1) << "OnArcSensorServiceStopped: job " + << (result ? "stopped" : "not running?"); + + VLOG(1) << "Starting arc-sensor-service"; + chromeos::UpstartClient::Get()->StartJob( + kArcSensorServiceJobName, /*environment=*/{}, + base::BindOnce(&ArcVmClientAdapter::OnArcSensorServiceStarted, + weak_factory_.GetWeakPtr(), std::move(callback))); + } + + void OnArcSensorServiceStarted(chromeos::VoidDBusMethodCallback callback, + bool result) { + if (!result) { + LOG(ERROR) << "Failed to start arc-sensor-service job"; + std::move(callback).Run(false); + return; + } + // Kill a stale arcvm-boot-notification-server job chromeos::UpstartClient::Get()->StopJob( kArcVmBootNotificationServerJobName, /*environment=*/{},
diff --git a/components/arc/session/arc_vm_client_adapter_unittest.cc b/components/arc/session/arc_vm_client_adapter_unittest.cc index eb8f849..b65a7c8 100644 --- a/components/arc/session/arc_vm_client_adapter_unittest.cc +++ b/components/arc/session/arc_vm_client_adapter_unittest.cc
@@ -43,6 +43,7 @@ constexpr const char kArcCreateDataJobName[] = "arc_2dcreate_2ddata"; constexpr const char kArcKeymasterJobName[] = "arc_2dkeymasterd"; +constexpr const char kArcSensorServiceJobName[] = "arc_2dsensor_2dservice"; constexpr const char kArcVmServerProxyJobName[] = "arcvm_2dserver_2dproxy"; constexpr const char kArcVmPerBoardFeaturesJobName[] = "arcvm_2dper_2dboard_2dfeatures"; @@ -523,6 +524,27 @@ EXPECT_FALSE(GetTestConciergeClient()->start_arc_vm_called()); } +// Tests that StartMiniArc() fails if Upstart fails to start arc-sensor-service. +TEST_F(ArcVmClientAdapterTest, StartMiniArc_StartArcSensorServiceJobFail) { + // Inject failure to FakeUpstartClient. + InjectUpstartStartJobFailure(kArcSensorServiceJobName); + + StartMiniArcWithParams(false, {}); + // Confirm that no VM is started. ARCVM doesn't support mini ARC yet. + EXPECT_FALSE(GetTestConciergeClient()->start_arc_vm_called()); +} + +// Tests that StartMiniArc() succeeds if Upstart fails to stop +// arc-sensor-service. +TEST_F(ArcVmClientAdapterTest, StartMiniArc_StopArcSensorServiceJobFail) { + // Inject failure to FakeUpstartClient. + InjectUpstartStopJobFailure(kArcSensorServiceJobName); + + StartMiniArc(); + // Confirm that no VM is started. ARCVM doesn't support mini ARC yet. + EXPECT_FALSE(GetTestConciergeClient()->start_arc_vm_called()); +} + // Tests that StartMiniArc() fails when Upstart fails to start the job. TEST_F(ArcVmClientAdapterTest, StartMiniArc_StartArcVmPerBoardFeaturesJobFail) { // Inject failure to FakeUpstartClient.
diff --git a/components/arc/test/fake_arc_bridge_host.cc b/components/arc/test/fake_arc_bridge_host.cc index c58e2088..861b6923 100644 --- a/components/arc/test/fake_arc_bridge_host.cc +++ b/components/arc/test/fake_arc_bridge_host.cc
@@ -43,6 +43,7 @@ #include "components/arc/mojom/property.mojom.h" #include "components/arc/mojom/rotation_lock.mojom.h" #include "components/arc/mojom/screen_capture.mojom.h" +#include "components/arc/mojom/sensor.mojom.h" #include "components/arc/mojom/storage_manager.mojom.h" #include "components/arc/mojom/timer.mojom.h" #include "components/arc/mojom/tracing.mojom.h" @@ -182,6 +183,9 @@ void FakeArcBridgeHost::OnScreenCaptureInstanceReady( mojo::PendingRemote<mojom::ScreenCaptureInstance> screen_capture_remote) {} +void FakeArcBridgeHost::OnSensorInstanceReady( + mojo::PendingRemote<mojom::SensorInstance> sensor_remote) {} + void FakeArcBridgeHost::OnSmartCardManagerInstanceReady( mojo::PendingRemote<mojom::SmartCardManagerInstance> smart_cardManager_remote) {}
diff --git a/components/arc/test/fake_arc_bridge_host.h b/components/arc/test/fake_arc_bridge_host.h index 46816c05..8ad93fe 100644 --- a/components/arc/test/fake_arc_bridge_host.h +++ b/components/arc/test/fake_arc_bridge_host.h
@@ -107,6 +107,8 @@ void OnScreenCaptureInstanceReady( mojo::PendingRemote<mojom::ScreenCaptureInstance> screen_capture_remote) override; + void OnSensorInstanceReady( + mojo::PendingRemote<mojom::SensorInstance> sensor_remote) override; void OnSmartCardManagerInstanceReady( mojo::PendingRemote<mojom::SmartCardManagerInstance> smart_card_manager_remote) override;
diff --git a/components/autofill/core/browser/autofill_type.cc b/components/autofill/core/browser/autofill_type.cc index 31428ca..b9a5ae2 100644 --- a/components/autofill/core/browser/autofill_type.cc +++ b/components/autofill/core/browser/autofill_type.cc
@@ -460,6 +460,7 @@ switch (html_type_) { case HTML_TYPE_UNSPECIFIED: + case HTML_TYPE_UNRECOGNIZED: NOTREACHED(); break; case HTML_TYPE_NAME: @@ -548,8 +549,6 @@ return "HTML_TRANSACTION_CURRENCY"; case HTML_TYPE_UPI_VPA: return "HTML_TYPE_UPI_VPA"; - case HTML_TYPE_UNRECOGNIZED: - return "HTML_TYPE_UNRECOGNIZED"; } NOTREACHED();
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingException.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingException.java index d6bdef3..f440edf7 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingException.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingException.java
@@ -21,21 +21,21 @@ * Exception information for a given origin. */ public class ContentSettingException implements Serializable { - @IntDef({Type.ADS, Type.AUTOMATIC_DOWNLOADS, Type.BACKGROUND_SYNC, Type.COOKIE, Type.JAVASCRIPT, - Type.POPUP, Type.SOUND, Type.BLUETOOTH_SCANNING}) + @IntDef({Type.ADS, Type.AUTOMATIC_DOWNLOADS, Type.BACKGROUND_SYNC, Type.BLUETOOTH_SCANNING, + Type.COOKIE, Type.JAVASCRIPT, Type.POPUP, Type.SOUND}) @Retention(RetentionPolicy.SOURCE) public @interface Type { // Values used to address array index - should be enumerated from 0 and can't have gaps. // All updates here must also be reflected in {@link #getContentSettingsType(int) // getContentSettingsType} and {@link SingleWebsiteSettings.PERMISSION_PREFERENCE_KEYS}. int ADS = 0; - int BACKGROUND_SYNC = 1; - int COOKIE = 2; - int JAVASCRIPT = 3; - int POPUP = 4; - int SOUND = 5; - int AUTOMATIC_DOWNLOADS = 6; - int BLUETOOTH_SCANNING = 7; + int AUTOMATIC_DOWNLOADS = 1; + int BACKGROUND_SYNC = 2; + int BLUETOOTH_SCANNING = 3; + int COOKIE = 4; + int JAVASCRIPT = 5; + int POPUP = 6; + int SOUND = 7; /** * Number of handled exceptions used for calculating array sizes. */
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java index 83a6645..94c2306 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
@@ -71,10 +71,9 @@ // Website permissions (if adding new, see hasPermissionsPreferences and resetSite below) // All permissions from the permissions preference category must be listed here. - private static final String[] PERMISSION_PREFERENCE_KEYS = { + public static final String[] PERMISSION_PREFERENCE_KEYS = { // Permission keys mapped for next {@link ContentSettingException.Type} values. "ads_permission_list", // ContentSettingException.Type.ADS - "ar_permission_list", // PermissionInfo.Type.AUGMENTED_REALITY "automatic_downloads_permission_list", // ContentSettingException.Type.AUTOMATIC_DOWNLOADS "background_sync_permission_list", // ContentSettingException.Type.BACKGROUND_SYNC @@ -84,6 +83,7 @@ "popup_permission_list", // ContentSettingException.Type.POPUP "sound_permission_list", // ContentSettingException.Type.SOUND // Permission keys mapped for next {@link PermissionInfo.Type} values. + "ar_permission_list", // PermissionInfo.Type.AUGMENTED_REALITY "camera_permission_list", // PermissionInfo.Type.CAMERA "clipboard_permission_list", // PermissionInfo.Type.CLIPBOARD "location_access_list", // PermissionInfo.Type.GEOLOCATION @@ -934,7 +934,7 @@ }); } - private int getContentSettingsTypeFromPreferenceKey(String preferenceKey) { + public static int getContentSettingsTypeFromPreferenceKey(String preferenceKey) { for (int i = 0; i < PERMISSION_PREFERENCE_KEYS.length; i++) { if (PERMISSION_PREFERENCE_KEYS[i].equals(preferenceKey)) { return i < ContentSettingException.Type.NUM_ENTRIES
diff --git a/components/error_page/common/localized_error.cc b/components/error_page/common/localized_error.cc index bfa1f13..51b723e 100644 --- a/components/error_page/common/localized_error.cc +++ b/components/error_page/common/localized_error.cc
@@ -168,6 +168,12 @@ SUGGEST_NONE, SHOW_NO_BUTTONS, }, + {net::ERR_UPLOAD_FILE_CHANGED, + IDS_ERRORPAGES_HEADING_FILE_NOT_FOUND, + IDS_ERRORPAGES_SUMMARY_FILE_NOT_FOUND, + SUGGEST_NONE, + SHOW_NO_BUTTONS, + }, {net::ERR_CACHE_MISS, IDS_ERRORPAGES_HEADING_CACHE_READ_FAILURE, IDS_ERRORPAGES_SUMMARY_CACHE_READ_FAILURE,
diff --git a/components/error_page_strings.grdp b/components/error_page_strings.grdp index 361b189..7c35948 100644 --- a/components/error_page_strings.grdp +++ b/components/error_page_strings.grdp
@@ -127,8 +127,8 @@ <message name="IDS_ERRORPAGES_HEADING_NOT_FOUND" desc="Heading in the error page when the server returns a 404 or 410."> This <ph name="HOST_NAME"><span jscontent="hostName"></span><ex>www.whatever.com</ex></ph> page can’t be found </message> - <message name="IDS_ERRORPAGES_HEADING_FILE_NOT_FOUND" desc="Heading in the error page when the local file was not found."> - Your file was not found + <message name="IDS_ERRORPAGES_HEADING_FILE_NOT_FOUND" desc="Heading in the error page when the local file could not be accessed."> + Your file couldn’t be accessed </message> <message name="IDS_ERRORPAGES_HEADING_BLOCKED" desc="Heading of the error page when a request is blocked by the administrator policy, extension or the browser itself."> <ph name="HOST_NAME"><span jscontent="hostName"></span><ex>www.example.com</ex></ph> is blocked @@ -190,8 +190,8 @@ <message name="IDS_ERRORPAGES_SUMMARY_NOT_FOUND" desc="Summary in the error page when the server returns a 404."> No webpage was found for the web address: <ph name="URL"><strong jscontent="failedUrl"></strong></ph> </message> - <message name="IDS_ERRORPAGES_SUMMARY_FILE_NOT_FOUND" desc="Summary in the error page when a local file is not found."> - It may have been moved or deleted. + <message name="IDS_ERRORPAGES_SUMMARY_FILE_NOT_FOUND" desc="Summary in the error page when a local file could not be accessed."> + It may have been moved, edited, or deleted. </message> <message name="IDS_ERRORPAGES_SUMMARY_TOO_MANY_REDIRECTS" desc="Summary in the error page when there are too many URL redirects."> <ph name="HOST_NAME"><strong jscontent="hostName"></strong><ex>www.whatever.com</ex></ph> redirected you too many times.
diff --git a/components/error_page_strings_grdp/IDS_ERRORPAGES_HEADING_FILE_NOT_FOUND.png.sha1 b/components/error_page_strings_grdp/IDS_ERRORPAGES_HEADING_FILE_NOT_FOUND.png.sha1 new file mode 100644 index 0000000..604ed90a --- /dev/null +++ b/components/error_page_strings_grdp/IDS_ERRORPAGES_HEADING_FILE_NOT_FOUND.png.sha1
@@ -0,0 +1 @@ +cf813c7007600a023efb077740640c1e03e952a3 \ No newline at end of file
diff --git a/components/error_page_strings_grdp/IDS_ERRORPAGES_SUMMARY_FILE_NOT_FOUND.png.sha1 b/components/error_page_strings_grdp/IDS_ERRORPAGES_SUMMARY_FILE_NOT_FOUND.png.sha1 new file mode 100644 index 0000000..604ed90a --- /dev/null +++ b/components/error_page_strings_grdp/IDS_ERRORPAGES_SUMMARY_FILE_NOT_FOUND.png.sha1
@@ -0,0 +1 @@ +cf813c7007600a023efb077740640c1e03e952a3 \ No newline at end of file
diff --git a/components/password_manager/core/browser/browser_save_password_progress_logger.cc b/components/password_manager/core/browser/browser_save_password_progress_logger.cc index 4452b7f..949e8a8 100644 --- a/components/password_manager/core/browser/browser_save_password_progress_logger.cc +++ b/components/password_manager/core/browser/browser_save_password_progress_logger.cc
@@ -209,14 +209,16 @@ ", autocomplete=" + ScrubElementID(field->autocomplete_attribute); if (field->server_type() != autofill::NO_SERVER_DATA) { - field_info += - ", SERVER_PREDICTION: " + - autofill::AutofillType::ServerFieldTypeToString(field->server_type()); + base::StrAppend(&field_info, + {", SERVER_PREDICTION: ", + autofill::AutofillType::ServerFieldTypeToString( + field->server_type())}); } for (ServerFieldType type : field->possible_types()) - field_info += - ", VOTE: " + autofill::AutofillType::ServerFieldTypeToString(type); + base::StrAppend( + &field_info, + {", VOTE: ", autofill::AutofillType::ServerFieldTypeToString(type)}); if (field->vote_type()) field_info += ", vote_type=" + VoteTypeToString(field->vote_type());
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc index d1892f1..371d371 100644 --- a/components/password_manager/core/browser/password_manager.cc +++ b/components/password_manager/core/browser/password_manager.cc
@@ -13,6 +13,7 @@ #include "base/metrics/field_trial.h" #include "base/metrics/histogram_macros.h" +#include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/platform_thread.h" @@ -180,12 +181,12 @@ field.type = NOT_USERNAME; } if (logger && local_prediction != UNKNOWN_TYPE) { - std::string message = - "form signature=" + - NumberToString(predictions->form_signature.value()) + - " , field signature=" + NumberToString(field.signature.value()) + - ", type=" + - autofill::AutofillType::ServerFieldTypeToString(local_prediction); + std::string message = base::StrCat( + {"form signature=", + NumberToString(predictions->form_signature.value()), + " , field signature=", NumberToString(field.signature.value()), + ", type=", + autofill::AutofillType::ServerFieldTypeToString(local_prediction)}); logger->LogString(Logger::STRING_LOCALLY_SAVED_PREDICTION, message); } }
diff --git a/components/payments/core/features.cc b/components/payments/core/features.cc index bc4b1a5..7b47a8b 100644 --- a/components/payments/core/features.cc +++ b/components/payments/core/features.cc
@@ -66,5 +66,8 @@ "AllowJITInstallationWhenAppIconIsMissing", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kPaymentHandlerLockIcon{"PaymentHandlerLockIcon", + base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace features } // namespace payments
diff --git a/components/payments/core/features.h b/components/payments/core/features.h index 273a692..ece0789 100644 --- a/components/payments/core/features.h +++ b/components/payments/core/features.h
@@ -75,6 +75,11 @@ // Used to test icon refetch for JIT installed apps with missing icons. extern const base::Feature kAllowJITInstallationWhenAppIconIsMissing; +// Desktop only, if enabled the lock icon would be showed next to the +// payment handler's URL bar. It indicate that only secure content is +// allowed inside the payment handler. +extern const base::Feature kPaymentHandlerLockIcon; + } // namespace features } // namespace payments
diff --git a/components/pdf/common/pdf.mojom b/components/pdf/common/pdf.mojom index e80e86f..99cad44 100644 --- a/components/pdf/common/pdf.mojom +++ b/components/pdf/common/pdf.mojom
@@ -4,7 +4,7 @@ module pdf.mojom; -import "third_party/blink/public/mojom/referrer.mojom"; +import "third_party/blink/public/mojom/loader/referrer.mojom"; import "ui/gfx/geometry/mojom/geometry.mojom"; import "url/mojom/url.mojom";
diff --git a/components/services/storage/public/mojom/service_worker_storage_control.mojom b/components/services/storage/public/mojom/service_worker_storage_control.mojom index 8d9b9b3..ee858a7 100644 --- a/components/services/storage/public/mojom/service_worker_storage_control.mojom +++ b/components/services/storage/public/mojom/service_worker_storage_control.mojom
@@ -247,6 +247,9 @@ ClearUserDataForAllRegistrationsByKeyPrefix(string key_prefix) => (ServiceWorkerDatabaseStatus status); + // Removes traces of deleted data on disk. + PerformStorageCleanup() => (); + // Applies changes to data retention policy which are relevant at shutdown. // This is analogous to LocalStorageControl::ApplyPolicyUpdates. ApplyPolicyUpdates(array<LocalStoragePolicyUpdate> policy_updates);
diff --git a/components/translate/content/renderer/BUILD.gn b/components/translate/content/renderer/BUILD.gn index bae4efd..b47398f 100644 --- a/components/translate/content/renderer/BUILD.gn +++ b/components/translate/content/renderer/BUILD.gn
@@ -6,6 +6,8 @@ static_library("renderer") { sources = [ + "isolated_world_util.cc", + "isolated_world_util.h", "per_frame_translate_agent.cc", "per_frame_translate_agent.h", "translate_agent.cc",
diff --git a/components/translate/content/renderer/isolated_world_util.cc b/components/translate/content/renderer/isolated_world_util.cc new file mode 100644 index 0000000..7e82bb3 --- /dev/null +++ b/components/translate/content/renderer/isolated_world_util.cc
@@ -0,0 +1,36 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/translate/content/renderer/isolated_world_util.h" + +#include "base/check_op.h" +#include "base/optional.h" +#include "components/translate/core/common/translate_util.h" +#include "third_party/blink/public/platform/web_isolated_world_info.h" +#include "third_party/blink/public/platform/web_url.h" + +namespace translate { + +void EnsureIsolatedWorldInitialized(int world_id) { + static base::Optional<int> last_used_world_id; + if (last_used_world_id) { + // Early return since the isolated world info. is already initialized. + DCHECK_EQ(*last_used_world_id, world_id) + << "EnsureIsolatedWorldInitialized should always be called with the " + "same |world_id|"; + return; + } + + last_used_world_id = world_id; + constexpr char kContentSecurityPolicy[] = "script-src 'self' 'unsafe-eval'"; + + blink::WebIsolatedWorldInfo info; + info.security_origin = + blink::WebSecurityOrigin::Create(GetTranslateSecurityOrigin()); + info.content_security_policy = + blink::WebString::FromUTF8(kContentSecurityPolicy); + blink::SetIsolatedWorldInfo(world_id, info); +} + +} // namespace translate
diff --git a/components/translate/content/renderer/isolated_world_util.h b/components/translate/content/renderer/isolated_world_util.h new file mode 100644 index 0000000..8e692f5 --- /dev/null +++ b/components/translate/content/renderer/isolated_world_util.h
@@ -0,0 +1,15 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_TRANSLATE_CONTENT_RENDERER_ISOLATED_WORLD_UTIL_H_ +#define COMPONENTS_TRANSLATE_CONTENT_RENDERER_ISOLATED_WORLD_UTIL_H_ + +namespace translate { + +// Ensures the isolated world information for |world_id| is initialized. +void EnsureIsolatedWorldInitialized(int world_id); + +} // namespace translate + +#endif // COMPONENTS_TRANSLATE_CONTENT_RENDERER_ISOLATED_WORLD_UTIL_H_
diff --git a/components/translate/content/renderer/per_frame_translate_agent.cc b/components/translate/content/renderer/per_frame_translate_agent.cc index 39dd1b94..ec2a727 100644 --- a/components/translate/content/renderer/per_frame_translate_agent.cc +++ b/components/translate/content/renderer/per_frame_translate_agent.cc
@@ -14,6 +14,7 @@ #include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "components/translate/content/renderer/isolated_world_util.h" #include "components/translate/core/common/translate_constants.h" #include "components/translate/core/common/translate_metrics.h" #include "components/translate/core/common/translate_util.h" @@ -23,7 +24,6 @@ #include "content/public/renderer/render_frame.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" -#include "third_party/blink/public/platform/web_isolated_world_info.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_language_detection_details.h" #include "third_party/blink/public/web/web_local_frame.h" @@ -35,7 +35,6 @@ using blink::WebLanguageDetectionDetails; using blink::WebLocalFrame; using blink::WebScriptSource; -using blink::WebSecurityOrigin; using blink::WebString; using blink::WebVector; @@ -61,9 +60,6 @@ // Language name passed to the Translate element for it to detect the language. const char kAutoDetectionLanguage[] = "auto"; -// Isolated world sets following content-security-policy. -const char kContentSecurityPolicy[] = "script-src 'self' 'unsafe-eval'"; - } // namespace namespace translate { @@ -131,16 +127,7 @@ GURL url(render_frame()->GetWebFrame()->GetDocument().Url()); ReportPageScheme(url.scheme()); - if (!isolated_world_initialized_) { - // Set up v8 isolated world with proper content-security-policy and - // security-origin. - blink::WebIsolatedWorldInfo info; - info.security_origin = - WebSecurityOrigin::Create(GetTranslateSecurityOrigin()); - info.content_security_policy = WebString::FromUTF8(kContentSecurityPolicy); - render_frame()->GetWebFrame()->SetIsolatedWorldInfo(world_id_, info); - isolated_world_initialized_ = true; - } + EnsureIsolatedWorldInitialized(world_id_); if (!IsTranslateLibAvailable()) { // Evaluate the script to add the translation related method to the global @@ -206,7 +193,7 @@ } void PerFrameTranslateAgent::ExecuteScript(const std::string& script) { - EnsureIsolatedWorldInitialized(); + EnsureIsolatedWorldInitialized(world_id_); WebLocalFrame* local_frame = render_frame()->GetWebFrame(); if (!local_frame) return; @@ -218,7 +205,7 @@ bool PerFrameTranslateAgent::ExecuteScriptAndGetBoolResult( const std::string& script, bool fallback) { - EnsureIsolatedWorldInitialized(); + EnsureIsolatedWorldInitialized(world_id_); WebLocalFrame* local_frame = render_frame()->GetWebFrame(); if (!local_frame) return fallback; @@ -235,7 +222,7 @@ std::string PerFrameTranslateAgent::ExecuteScriptAndGetStringResult( const std::string& script) { - EnsureIsolatedWorldInitialized(); + EnsureIsolatedWorldInitialized(world_id_); WebLocalFrame* local_frame = render_frame()->GetWebFrame(); if (!local_frame) return std::string(); @@ -257,7 +244,7 @@ double PerFrameTranslateAgent::ExecuteScriptAndGetDoubleResult( const std::string& script) { - EnsureIsolatedWorldInitialized(); + EnsureIsolatedWorldInitialized(world_id_); WebLocalFrame* local_frame = render_frame()->GetWebFrame(); if (!local_frame) return 0.0; @@ -274,7 +261,7 @@ int64_t PerFrameTranslateAgent::ExecuteScriptAndGetIntegerResult( const std::string& script) { - EnsureIsolatedWorldInitialized(); + EnsureIsolatedWorldInitialized(world_id_); WebLocalFrame* local_frame = render_frame()->GetWebFrame(); if (!local_frame) return 0; @@ -422,19 +409,6 @@ target_lang_.clear(); } -void PerFrameTranslateAgent::EnsureIsolatedWorldInitialized() { - if (!isolated_world_initialized_) { - // Set up v8 isolated world with proper content-security-policy and - // security-origin. - blink::WebIsolatedWorldInfo info; - info.security_origin = - WebSecurityOrigin::Create(GetTranslateSecurityOrigin()); - info.content_security_policy = WebString::FromUTF8(kContentSecurityPolicy); - render_frame()->GetWebFrame()->SetIsolatedWorldInfo(world_id_, info); - isolated_world_initialized_ = true; - } -} - void PerFrameTranslateAgent::BindReceiver( mojo::PendingAssociatedReceiver<mojom::TranslateAgent> receiver) { receiver_.Bind(std::move(receiver));
diff --git a/components/translate/content/renderer/per_frame_translate_agent.h b/components/translate/content/renderer/per_frame_translate_agent.h index b2d1e5e..d664f0d 100644 --- a/components/translate/content/renderer/per_frame_translate_agent.h +++ b/components/translate/content/renderer/per_frame_translate_agent.h
@@ -103,9 +103,6 @@ // Converts language code to the one used in server supporting list. static void ConvertLanguageCodeSynonym(std::string* code); - // Ensures that the isolated world for executing translation JS. - void EnsureIsolatedWorldInitialized(); - // Sets receiver for translate messages from browser process. void BindReceiver( mojo::PendingAssociatedReceiver<mojom::TranslateAgent> receiver); @@ -148,9 +145,6 @@ // The world ID to use for script execution. int world_id_; - // Whether the isolated world info has been initialized. - bool isolated_world_initialized_ = false; - mojo::AssociatedReceiver<mojom::TranslateAgent> receiver_{this}; // Method factory used to make calls to TranslateFrameImpl.
diff --git a/components/translate/content/renderer/translate_agent.cc b/components/translate/content/renderer/translate_agent.cc index c3b668fb..162c7c67 100644 --- a/components/translate/content/renderer/translate_agent.cc +++ b/components/translate/content/renderer/translate_agent.cc
@@ -17,6 +17,7 @@ #include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "components/translate/content/renderer/isolated_world_util.h" #include "components/translate/core/common/translate_constants.h" #include "components/translate/core/common/translate_metrics.h" #include "components/translate/core/common/translate_util.h" @@ -26,7 +27,6 @@ #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_thread.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" -#include "third_party/blink/public/platform/web_isolated_world_info.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_language_detection_details.h" #include "third_party/blink/public/web/web_local_frame.h" @@ -38,7 +38,6 @@ using blink::WebLanguageDetectionDetails; using blink::WebLocalFrame; using blink::WebScriptSource; -using blink::WebSecurityOrigin; using blink::WebString; using blink::WebVector; @@ -58,10 +57,6 @@ // Language name passed to the Translate element for it to detect the language. const char kAutoDetectionLanguage[] = "auto"; - -// Isolated world sets following content-security-policy. -const char kContentSecurityPolicy[] = "script-src 'self' 'unsafe-eval'"; - } // namespace namespace translate { @@ -320,13 +315,8 @@ GURL url(main_frame->GetDocument().Url()); ReportPageScheme(url.scheme()); - // Set up v8 isolated world with proper content-security-policy and - // security-origin. - blink::WebIsolatedWorldInfo info; - info.security_origin = - WebSecurityOrigin::Create(GetTranslateSecurityOrigin()); - info.content_security_policy = WebString::FromUTF8(kContentSecurityPolicy); - main_frame->SetIsolatedWorldInfo(world_id_, info); + // Set up v8 isolated world. + EnsureIsolatedWorldInitialized(world_id_); if (!IsTranslateLibAvailable()) { // Evaluate the script to add the translation related method to the global
diff --git a/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc b/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc index ff5eb68..61d2bc78 100644 --- a/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc +++ b/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc
@@ -54,8 +54,8 @@ #include "storage/browser/quota/quota_manager_proxy.h" #include "third_party/blink/public/common/cache_storage/cache_storage_utils.h" #include "third_party/blink/public/common/fetch/fetch_api_request_headers_map.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" -#include "third_party/blink/public/mojom/referrer.mojom.h" using blink::mojom::CacheStorageError; using blink::mojom::CacheStorageVerboseError;
diff --git a/content/browser/net/split_cache_browsertest.cc b/content/browser/net/split_cache_browsertest.cc index 3878728e..3a77415 100644 --- a/content/browser/net/split_cache_browsertest.cc +++ b/content/browser/net/split_cache_browsertest.cc
@@ -335,6 +335,7 @@ EXPECT_TRUE(ExecuteScript(host_to_load_resource, GetWorkerScript(worker))); observer.WaitForResourceCompletion(GenURL("3p.com", "/script")); + observer.WaitForResourceCompletion(worker); return (*observer.FindResource(worker))->was_cached; } @@ -613,14 +614,8 @@ GenURL("c.com", "/title1.html"))); } -// TODO(http://crbug.com/997808): Flaky on Linux ASAN. -#if defined(OS_LINUX) && (defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER)) -#define MAYBE_SplitCacheDedicatedWorkers DISABLED_SplitCacheDedicatedWorkers -#else -#define MAYBE_SplitCacheDedicatedWorkers SplitCacheDedicatedWorkers -#endif IN_PROC_BROWSER_TEST_F(SplitCacheWithFrameOriginContentBrowserTest, - MAYBE_SplitCacheDedicatedWorkers) { + SplitCacheDedicatedWorkers) { // Load 3p.com/script from a.com's worker. The first time it's loaded from the // network and the second it's cached. EXPECT_FALSE(TestResourceLoadFromDedicatedWorker( @@ -719,7 +714,7 @@ } IN_PROC_BROWSER_TEST_P(SplitCacheContentBrowserTestEnabled, - MAYBE_SplitCacheDedicatedWorkers) { + SplitCacheDedicatedWorkers) { // Load 3p.com/script from a.com's worker. The first time it's loaded from the // network and the second it's cached. EXPECT_FALSE(TestResourceLoadFromDedicatedWorker( @@ -762,15 +757,8 @@ GenURL("e.com", "/worker.js"))); } -// TODO(http://crbug.com/997732): Flaky on Linux and macOS. -#if defined(OS_LINUX) || defined(OS_MACOSX) -#define MAYBE_SplitCacheDedicatedWorkerScripts \ - DISABLED_SplitCacheDedicatedWorkersScripts -#else -#define MAYBE_SplitCacheDedicatedWorkerScripts SplitCacheDedicatedWorkersScripts -#endif IN_PROC_BROWSER_TEST_P(SplitCacheContentBrowserTestEnabled, - MAYBE_SplitCacheDedicatedWorkerScripts) { + SplitCacheDedicatedWorkersScripts) { // Load a.com's worker. The first time the worker script is loaded from the // network and the second it's cached. EXPECT_FALSE(DedicatedWorkerScriptCached( @@ -810,7 +798,7 @@ } IN_PROC_BROWSER_TEST_F(SplitCacheContentBrowserTestDisabled, - MAYBE_SplitCacheDedicatedWorkers) { + SplitCacheDedicatedWorkers) { // Load 3p.com/script from a.com's worker. The first time it's loaded from the // network and the second it's cached. EXPECT_FALSE(TestResourceLoadFromDedicatedWorker(
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc index a43d0126..c88e3eb3 100644 --- a/content/browser/service_worker/service_worker_browsertest.cc +++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -13,6 +13,7 @@ #include "base/bind_helpers.h" #include "base/callback.h" #include "base/command_line.h" +#include "base/guid.h" #include "base/json/json_reader.h" #include "base/memory/ref_counted.h" #include "base/metrics/statistics_recorder.h" @@ -40,6 +41,7 @@ #include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_context_core_observer.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" +#include "content/browser/service_worker/service_worker_fetch_dispatcher.h" #include "content/browser/service_worker/service_worker_registration.h" #include "content/browser/service_worker/service_worker_test_utils.h" #include "content/browser/service_worker/service_worker_version.h" @@ -962,6 +964,79 @@ run_loop.Run(); } +// Make sure that a fetch event is dispatched to a stopped worker in the task +// which calls ServiceWorkerFetchDispatcher::Run(). +IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, + DispatchFetchEventToStoppedWorkerSynchronously) { + // Setup the server so that the test doesn't crash when tearing down. + StartServerAndNavigateToSetup(); + // This test is meaningful only when ServiceWorkerOnUI is enabled. + if (!ServiceWorkerContext::IsServiceWorkerOnUIEnabled()) + return; + + WorkerRunningStatusObserver observer(public_context()); + EXPECT_TRUE(NavigateToURL(shell(), + embedded_test_server()->GetURL( + "/service_worker/create_service_worker.html"))); + EXPECT_EQ("DONE", EvalJs(shell(), "register('fetch_event.js');")); + observer.WaitUntilRunning(); + + ASSERT_TRUE( + BrowserThread::CurrentlyOn(ServiceWorkerContext::GetCoreThreadId())); + scoped_refptr<ServiceWorkerVersion> version = + wrapper()->GetLiveVersion(observer.version_id()); + EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version->running_status()); + + { + base::RunLoop loop; + version->StopWorker(loop.QuitClosure()); + loop.Run(); + EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version->running_status()); + } + + bool is_prepare_callback_called = false; + base::RunLoop fetch_loop; + blink::ServiceWorkerStatusCode fetch_status; + ServiceWorkerFetchDispatcher::FetchEventResult fetch_result; + blink::mojom::FetchAPIResponsePtr fetch_response; + + auto request = blink::mojom::FetchAPIRequest::New(); + request->url = embedded_test_server()->GetURL("/service_worker/in-scope"); + request->method = "GET"; + request->is_main_resource_load = true; + auto dispatcher = std::make_unique<ServiceWorkerFetchDispatcher>( + std::move(request), blink::mojom::ResourceType::kMainFrame, + /*client_id=*/base::GenerateGUID(), version, + base::BindLambdaForTesting([&]() { is_prepare_callback_called = true; }), + base::BindLambdaForTesting( + [&](blink::ServiceWorkerStatusCode status, + ServiceWorkerFetchDispatcher::FetchEventResult result, + blink::mojom::FetchAPIResponsePtr response, + blink::mojom::ServiceWorkerStreamHandlePtr, + blink::mojom::ServiceWorkerFetchEventTimingPtr, + scoped_refptr<ServiceWorkerVersion>) { + fetch_status = status; + fetch_result = result; + fetch_response = std::move(response); + fetch_loop.Quit(); + }), + /*is_offline_capability_check=*/false); + + // DispatchFetchEvent is called synchronously with dispatcher->Run() even if + // the worker is stopped. + dispatcher->Run(); + EXPECT_TRUE(is_prepare_callback_called); + EXPECT_FALSE(fetch_response); + + // Check if the fetch event is handled by fetch_event.js correctly. + fetch_loop.Run(); + ASSERT_TRUE(fetch_response); + EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, fetch_status); + EXPECT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse, + fetch_result); + EXPECT_EQ(301, fetch_response->status_code); +} + class ServiceWorkerEagerCacheStorageSetupTest : public ServiceWorkerBrowserTest { public:
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc index 8ece6cd..9ce8ecc 100644 --- a/content/browser/service_worker/service_worker_context_core.cc +++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -551,7 +551,7 @@ void ServiceWorkerContextCore::PerformStorageCleanup( base::OnceClosure callback) { DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); - storage()->PerformStorageCleanup(std::move(callback)); + GetStorageControl()->PerformStorageCleanup(std::move(callback)); } void ServiceWorkerContextCore::DidGetRegistrationsForDeleteForOrigin(
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc index ab1a589..c797a8e5 100644 --- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc +++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -532,6 +532,13 @@ GetEventType(), base::BindOnce(&ServiceWorkerFetchDispatcher::DidStartWorker, weak_factory_.GetWeakPtr())); + + if (ServiceWorkerContext::IsServiceWorkerOnUIEnabled() && + version_->is_endpoint_ready()) { + // For an active service worker, the endpoint becomes ready synchronously + // with StartWorker(). In that case, we can dispatch FetchEvent immediately. + DispatchFetchEvent(); + } } void ServiceWorkerFetchDispatcher::DidStartWorker( @@ -545,17 +552,19 @@ DidFail(status); return; } - DispatchFetchEvent(); + if (!IsEventDispatched()) { + DispatchFetchEvent(); + } } void ServiceWorkerFetchDispatcher::DispatchFetchEvent() { - DCHECK_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status()) + DCHECK(EmbeddedWorkerStatus::STARTING == version_->running_status() || + EmbeddedWorkerStatus::RUNNING == version_->running_status()) << "Worker stopped too soon after it was started."; TRACE_EVENT_WITH_FLOW0("ServiceWorker", "ServiceWorkerFetchDispatcher::DispatchFetchEvent", TRACE_ID_LOCAL(this), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); - // Grant the service worker's process access to files in the request body. if (request_->body) { GrantFileAccessToProcess(version_->embedded_worker()->process_id(), @@ -759,6 +768,10 @@ return ResourceTypeToEventType(resource_type_); } +bool ServiceWorkerFetchDispatcher::IsEventDispatched() const { + return request_.is_null(); +} + // static void ServiceWorkerFetchDispatcher::OnFetchEventFinished( ServiceWorkerVersion* version,
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.h b/content/browser/service_worker/service_worker_fetch_dispatcher.h index c24c6308..87ffce31 100644 --- a/content/browser/service_worker/service_worker_fetch_dispatcher.h +++ b/content/browser/service_worker/service_worker_fetch_dispatcher.h
@@ -109,6 +109,8 @@ ServiceWorkerMetrics::EventType GetEventType() const; + bool IsEventDispatched() const; + blink::mojom::FetchAPIRequestPtr request_; std::string client_id_; scoped_refptr<ServiceWorkerVersion> version_;
diff --git a/content/browser/service_worker/service_worker_script_cache_map.cc b/content/browser/service_worker/service_worker_script_cache_map.cc index 712c3f0..a93966d7 100644 --- a/content/browser/service_worker/service_worker_script_cache_map.cc +++ b/content/browser/service_worker/service_worker_script_cache_map.cc
@@ -10,10 +10,7 @@ #include "base/check_op.h" #include "content/browser/service_worker/service_worker_consts.h" #include "content/browser/service_worker/service_worker_context_core.h" -#include "content/browser/service_worker/service_worker_disk_cache.h" -#include "content/browser/service_worker/service_worker_storage.h" #include "content/browser/service_worker/service_worker_version.h" -#include "net/base/io_buffer.h" #include "net/base/net_errors.h" namespace content { @@ -112,16 +109,13 @@ return; } - scoped_refptr<net::IOBuffer> buffer = - base::MakeRefCounted<net::IOBuffer>(data.size()); - if (data.size()) - memmove(buffer->data(), &data[0], data.size()); - std::unique_ptr<ServiceWorkerResponseMetadataWriter> writer; - writer = context_->storage()->CreateResponseMetadataWriter( - found->second->resource_id); - ServiceWorkerResponseMetadataWriter* raw_writer = writer.get(); + mojo_base::BigBuffer buffer(base::as_bytes(data)); + mojo::Remote<storage::mojom::ServiceWorkerResourceMetadataWriter> writer; + context_->GetStorageControl()->CreateResourceMetadataWriter( + found->second->resource_id, writer.BindNewPipeAndPassReceiver()); + auto* raw_writer = writer.get(); raw_writer->WriteMetadata( - buffer.get(), data.size(), + std::move(buffer), base::BindOnce(&ServiceWorkerScriptCacheMap::OnMetadataWritten, weak_factory_.GetWeakPtr(), std::move(writer), std::move(callback))); @@ -134,7 +128,7 @@ } void ServiceWorkerScriptCacheMap::OnMetadataWritten( - std::unique_ptr<ServiceWorkerResponseMetadataWriter> writer, + mojo::Remote<storage::mojom::ServiceWorkerResourceMetadataWriter> writer, net::CompletionOnceCallback callback, int result) { std::move(callback).Run(result);
diff --git a/content/browser/service_worker/service_worker_script_cache_map.h b/content/browser/service_worker/service_worker_script_cache_map.h index ef8a55e..18a44c4 100644 --- a/content/browser/service_worker/service_worker_script_cache_map.h +++ b/content/browser/service_worker/service_worker_script_cache_map.h
@@ -13,8 +13,10 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "components/services/storage/public/mojom/service_worker_storage_control.mojom.h" #include "content/browser/service_worker/service_worker_database.h" #include "content/common/content_export.h" +#include "mojo/public/cpp/bindings/remote.h" #include "net/base/completion_once_callback.h" #include "net/base/net_errors.h" @@ -24,7 +26,6 @@ class ServiceWorkerContextCore; class ServiceWorkerVersion; -class ServiceWorkerResponseMetadataWriter; // Class that maintains the mapping between urls and a resource id // for a particular version's implicit script resources. @@ -80,7 +81,7 @@ ~ServiceWorkerScriptCacheMap(); void OnMetadataWritten( - std::unique_ptr<ServiceWorkerResponseMetadataWriter> writer, + mojo::Remote<storage::mojom::ServiceWorkerResourceMetadataWriter>, net::CompletionOnceCallback callback, int result);
diff --git a/content/browser/service_worker/service_worker_storage_control_impl.cc b/content/browser/service_worker/service_worker_storage_control_impl.cc index 7257c19..f83c0005 100644 --- a/content/browser/service_worker/service_worker_storage_control_impl.cc +++ b/content/browser/service_worker/service_worker_storage_control_impl.cc
@@ -353,6 +353,11 @@ std::move(callback)); } +void ServiceWorkerStorageControlImpl::PerformStorageCleanup( + PerformStorageCleanupCallback callback) { + storage_->PerformStorageCleanup(std::move(callback)); +} + void ServiceWorkerStorageControlImpl::ApplyPolicyUpdates( const std::vector<storage::mojom::LocalStoragePolicyUpdatePtr> policy_updates) {
diff --git a/content/browser/service_worker/service_worker_storage_control_impl.h b/content/browser/service_worker/service_worker_storage_control_impl.h index 5f350f2..b939948 100644 --- a/content/browser/service_worker/service_worker_storage_control_impl.h +++ b/content/browser/service_worker/service_worker_storage_control_impl.h
@@ -140,6 +140,7 @@ void ClearUserDataForAllRegistrationsByKeyPrefix( const std::string& key_prefix, ClearUserDataForAllRegistrationsByKeyPrefixCallback callback) override; + void PerformStorageCleanup(PerformStorageCleanupCallback callback) override; void ApplyPolicyUpdates( const std::vector<storage::mojom::LocalStoragePolicyUpdatePtr> policy_updates) override;
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index ca5ae8ca..1e01883 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -477,6 +477,12 @@ switch (running_status()) { case EmbeddedWorkerStatus::STARTING: case EmbeddedWorkerStatus::RUNNING: { + // Endpoint isn't available after calling StopWorker(). This needs to be + // set here without waiting until the worker is actually stopped because + // subsequent StartWorker() may read the flag to decide whether an event + // can be dispatched or not. + is_endpoint_ready_ = false; + // EmbeddedWorkerInstance::Stop() may synchronously call // ServiceWorkerVersion::OnStopped() and destroy |this|. This protection // avoids it. @@ -583,8 +589,9 @@ StatusCallback error_callback, const base::TimeDelta& timeout, TimeoutBehavior timeout_behavior) { - DCHECK_EQ(EmbeddedWorkerStatus::RUNNING, running_status()) - << "Can only start a request with a running worker."; + DCHECK(EmbeddedWorkerStatus::RUNNING == running_status() || + EmbeddedWorkerStatus::STARTING == running_status()) + << "Can only start a request with a running or starting worker."; DCHECK(event_type == ServiceWorkerMetrics::EventType::INSTALL || event_type == ServiceWorkerMetrics::EventType::ACTIVATE || event_type == ServiceWorkerMetrics::EventType::MESSAGE || @@ -1021,6 +1028,7 @@ } DCHECK(worker_host_); + DCHECK(service_worker_remote_); service_worker_remote_->InitializeGlobalScope( std::move(service_worker_host_), worker_host_->container_host()->CreateServiceWorkerRegistrationObjectInfo( @@ -1028,6 +1036,8 @@ worker_host_->container_host()->CreateServiceWorkerObjectInfoToSend(this), fetch_handler_existence_, std::move(subresource_loader_factories), std::move(reporting_observer_receiver_)); + + is_endpoint_ready_ = true; } void ServiceWorkerVersion::SetValidOriginTrialTokens( @@ -1868,11 +1878,13 @@ base::BindOnce(&OnConnectionError, embedded_worker_->AsWeakPtr())); receiver_.reset(); receiver_.Bind(service_worker_host_.InitWithNewEndpointAndPassReceiver()); + // Initialize the global scope now if the worker won't be paused. Otherwise, // delay initialization until the main script is loaded. - if (!initialize_global_scope_after_main_script_loaded_) + if (!initialize_global_scope_after_main_script_loaded_) { InitializeGlobalScope(/*script_loader_factories=*/nullptr, /*subresource_loader_factories=*/nullptr); + } if (!controller_receiver_.is_valid()) { controller_receiver_ = remote_controller_.BindNewPipeAndPassReceiver(); @@ -2230,6 +2242,7 @@ request_timeouts_.clear(); external_request_uuid_to_request_id_.clear(); service_worker_remote_.reset(); + is_endpoint_ready_ = false; remote_controller_.reset(); DCHECK(!controller_receiver_.is_valid()); installed_scripts_sender_.reset();
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index 7fa90b2..7be6c098 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h
@@ -339,7 +339,8 @@ // code and the dispatch time. See service_worker.mojom. SimpleEventCallback CreateSimpleEventCallback(int request_id); - // This must be called when the worker is running. + // This must be called when is_endpoint_ready() returns true, which is after + // InitializeGlobalScope() is called. blink::mojom::ServiceWorker* endpoint() { DCHECK(running_status() == EmbeddedWorkerStatus::STARTING || running_status() == EmbeddedWorkerStatus::RUNNING); @@ -347,6 +348,8 @@ return service_worker_remote_.get(); } + bool is_endpoint_ready() const { return is_endpoint_ready_; } + // Returns the 'controller' interface ptr of this worker. It is expected that // the worker is already starting or running, or is going to be started soon. // TODO(kinuko): Relying on the callsites to start the worker when it's @@ -910,6 +913,9 @@ Status status_ = NEW; std::unique_ptr<EmbeddedWorkerInstance> embedded_worker_; + // True if endpoint() is ready to dispatch events, which means + // InitializeGlobalScope() is already called. + bool is_endpoint_ready_ = false; std::vector<StatusCallback> start_callbacks_; std::vector<base::OnceClosure> stop_callbacks_; std::vector<base::OnceClosure> status_change_callbacks_;
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index 27cb3eeb..3c19196 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -2422,6 +2422,9 @@ EXPECT_CALL(delegate, RegisterProtocolHandler(contents(), "mailto", handler_url1, true)) .Times(1); + EXPECT_CALL(delegate, + RegisterProtocolHandler(contents(), "mailto", handler_url2, true)) + .Times(0); { contents()->RegisterProtocolHandler(main_test_rfh(), "mailto", handler_url1,
diff --git a/content/common/frame.mojom b/content/common/frame.mojom index d9817d5..a632d99 100644 --- a/content/common/frame.mojom +++ b/content/common/frame.mojom
@@ -41,7 +41,7 @@ import "third_party/blink/public/mojom/messaging/transferable_message.mojom"; import "third_party/blink/public/mojom/page/widget.mojom"; import "third_party/blink/public/mojom/portal/portal.mojom"; -import "third_party/blink/public/mojom/referrer.mojom"; +import "third_party/blink/public/mojom/loader/referrer.mojom"; import "third_party/blink/public/mojom/service_worker/controller_service_worker.mojom"; import "third_party/blink/public/mojom/service_worker/service_worker_container.mojom"; import "third_party/blink/public/mojom/window_features/window_features.mojom";
diff --git a/content/common/navigation_params.mojom b/content/common/navigation_params.mojom index 3e019dc1..fb9c824 100644 --- a/content/common/navigation_params.mojom +++ b/content/common/navigation_params.mojom
@@ -20,7 +20,7 @@ import "third_party/blink/public/mojom/feature_policy/feature_policy.mojom"; import "third_party/blink/public/mojom/fetch/fetch_api_request.mojom"; import "third_party/blink/public/mojom/frame/frame_policy.mojom"; -import "third_party/blink/public/mojom/referrer.mojom"; +import "third_party/blink/public/mojom/loader/referrer.mojom"; import "url/mojom/origin.mojom"; import "url/mojom/url.mojom";
diff --git a/content/public/common/referrer.cc b/content/public/common/referrer.cc index 4542c0f..2faa0972 100644 --- a/content/public/common/referrer.cc +++ b/content/public/common/referrer.cc
@@ -16,7 +16,7 @@ #include "services/network/public/cpp/features.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/mojom/referrer_policy.mojom-shared.h" -#include "third_party/blink/public/mojom/referrer.mojom.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom.h" namespace content {
diff --git a/content/public/common/referrer.h b/content/public/common/referrer.h index e895e42..a6ef571 100644 --- a/content/public/common/referrer.h +++ b/content/public/common/referrer.h
@@ -8,7 +8,7 @@ #include "content/common/content_export.h" #include "net/url_request/referrer_policy.h" #include "services/network/public/mojom/referrer_policy.mojom-shared.h" -#include "third_party/blink/public/mojom/referrer.mojom-forward.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom-forward.h" #include "url/gurl.h" #include "url/origin.h"
diff --git a/content/public/common/referrer_type_converters.h b/content/public/common/referrer_type_converters.h index cffd525..c7f355c25 100644 --- a/content/public/common/referrer_type_converters.h +++ b/content/public/common/referrer_type_converters.h
@@ -8,7 +8,7 @@ #include "content/common/content_export.h" #include "content/public/common/referrer.h" #include "mojo/public/cpp/bindings/type_converter.h" -#include "third_party/blink/public/mojom/referrer.mojom.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom.h" namespace mojo { // TODO(leonhsl): Remove these converters once we remove content::Referrer.
diff --git a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TestTouchUtils.java b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TestTouchUtils.java index 23fbf56..485b818 100644 --- a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TestTouchUtils.java +++ b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TestTouchUtils.java
@@ -203,7 +203,7 @@ * @param v The view to call performClick on. */ public static void performClickOnMainSync(Instrumentation instrumentation, final View v) { - TestThreadUtils.runOnUiThreadBlocking(() -> { v.performClick(); }); + instrumentation.runOnMainSync(() -> v.performClick()); } /**
diff --git a/content/public/test/mock_navigation_handle.h b/content/public/test/mock_navigation_handle.h index 498ab6a..c132ce6 100644 --- a/content/public/test/mock_navigation_handle.h +++ b/content/public/test/mock_navigation_handle.h
@@ -13,7 +13,7 @@ #include "net/base/ip_endpoint.h" #include "net/base/isolation_info.h" #include "testing/gmock/include/gmock/gmock.h" -#include "third_party/blink/public/mojom/referrer.mojom.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom.h" #include "url/gurl.h" namespace content {
diff --git a/content/public/test/navigation_simulator.h b/content/public/test/navigation_simulator.h index fcfc3a3..3ef5b96 100644 --- a/content/public/test/navigation_simulator.h +++ b/content/public/test/navigation_simulator.h
@@ -14,7 +14,7 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "net/dns/public/resolve_error_info.h" #include "services/service_manager/public/cpp/interface_provider.h" -#include "third_party/blink/public/mojom/referrer.mojom.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom.h" #include "ui/base/page_transition_types.h" class GURL;
diff --git a/content/renderer/performance_manager/v8_per_frame_memory_reporter_impl.cc b/content/renderer/performance_manager/v8_per_frame_memory_reporter_impl.cc index 2cd2b9d..3d350549 100644 --- a/content/renderer/performance_manager/v8_per_frame_memory_reporter_impl.cc +++ b/content/renderer/performance_manager/v8_per_frame_memory_reporter_impl.cc
@@ -7,6 +7,7 @@ #include "base/containers/flat_map.h" #include "content/public/common/isolated_world_ids.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" +#include "third_party/blink/public/platform/web_isolated_world_info.h" #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_local_frame_client.h" #include "v8/include/v8.h" @@ -87,9 +88,9 @@ if (world_id != content::ISOLATED_WORLD_ID_GLOBAL) { isolated_world_usage->stable_id = - frame->GetIsolatedWorldStableId(context).Utf8(); + blink::GetIsolatedWorldStableId(context).Utf8(); isolated_world_usage->human_readable_name = - frame->GetIsolatedWorldHumanReadableName(context).Utf8(); + blink::GetIsolatedWorldHumanReadableName(context).Utf8(); } DCHECK(
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 7f73a8952..2ead495 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -168,10 +168,10 @@ #include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #include "third_party/blink/public/mojom/input/focus_type.mojom.h" #include "third_party/blink/public/mojom/input/input_handler.mojom-shared.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom.h" #include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h" #include "third_party/blink/public/mojom/permissions/permission.mojom.h" -#include "third_party/blink/public/mojom/referrer.mojom.h" #include "third_party/blink/public/platform/file_path_conversion.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h" #include "third_party/blink/public/platform/url_conversion.h"
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 0b3a871..f16af9a 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -588,24 +588,6 @@ if (for_frame()) { SetZoomLevel(visual_properties.zoom_level); - if (root_widget_window_segments_ != - visual_properties.root_widget_window_segments) { - root_widget_window_segments_ = - visual_properties.root_widget_window_segments; - - blink::WebVector<blink::WebRect> web_segments; - web_segments.reserve(root_widget_window_segments_.size()); - for (const auto& segment : root_widget_window_segments_) - web_segments.emplace_back(segment); - - GetWebWidget()->SetWindowSegments(std::move(web_segments)); - - // Propagate changes down to child local root RenderWidgets in other frame - // trees/processes. - for (auto& observer : render_frame_proxies_) - observer.OnRootWindowSegmentsChanged(root_widget_window_segments_); - } - bool capture_sequence_number_changed = visual_properties.capture_sequence_number != last_capture_sequence_number_; @@ -655,8 +637,12 @@ // emulation. device_emulator_->OnSynchronizeVisualProperties( visual_properties.screen_info, visual_properties.new_size, - visual_properties.visible_viewport_size); + visual_properties.visible_viewport_size, + visual_properties.root_widget_window_segments); } else { + if (for_frame()) + SetRootWindowSegments(visual_properties.root_widget_window_segments); + // We can ignore browser-initialized resizing during synchronous // (renderer-controlled) mode, unless it is switching us to/from // fullsreen mode or changing the device scale factor. @@ -787,9 +773,6 @@ window_screen_rect_); } device_emulator_->ChangeEmulationParams(params); - // TODO: crbug.com/1099026 - // https://chromium-review.googlesource.com/c/chromium/src/+/2262193/1 - // Update root_widget_window_segments here. } void RenderWidget::OnDisableDeviceEmulation() { @@ -854,6 +837,25 @@ } } +void RenderWidget::SetRootWindowSegments( + const std::vector<gfx::Rect>& root_window_segments) { + if (root_widget_window_segments_ != root_window_segments) { + root_widget_window_segments_ = root_window_segments; + + blink::WebVector<blink::WebRect> web_segments; + web_segments.reserve(root_widget_window_segments_.size()); + for (const auto& segment : root_widget_window_segments_) + web_segments.emplace_back(segment); + + GetWebWidget()->SetWindowSegments(std::move(web_segments)); + + // Propagate changes down to child local root RenderWidgets in other frame + // trees/processes. + for (auto& observer : render_frame_proxies_) + observer.OnRootWindowSegmentsChanged(root_widget_window_segments_); + } +} + void RenderWidget::OnWasHidden() { // A provisional frame widget will never be hidden since that would require it // to be shown first. A frame must be attached to the frame tree before
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 5887954..8ed53f5 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -263,6 +263,8 @@ const gfx::Size& visible_viewport_size) override; void SetScreenRects(const gfx::Rect& widget_screen_rect, const gfx::Rect& window_screen_rect) override; + void SetRootWindowSegments( + const std::vector<gfx::Rect>& root_window_segments) override; // blink::WebWidgetClient void ScheduleAnimation() override;
diff --git a/content/renderer/render_widget_screen_metrics_emulator.cc b/content/renderer/render_widget_screen_metrics_emulator.cc index 7b25b6e..4d8b170d 100644 --- a/content/renderer/render_widget_screen_metrics_emulator.cc +++ b/content/renderer/render_widget_screen_metrics_emulator.cc
@@ -31,6 +31,7 @@ delegate_->SetScreenMetricsEmulationParameters(false, emulation_params_); delegate_->SetScreenRects(original_view_screen_rect_, original_window_screen_rect_); + delegate_->SetRootWindowSegments(original_root_window_segments_); delegate_->SetScreenInfoAndSize(original_screen_info_, original_widget_size_, original_visible_viewport_size_); } @@ -130,6 +131,14 @@ delegate_->SetScreenRects(gfx::Rect(widget_pos, widget_size), gfx::Rect(window_pos, window_size)); + // If there are no emulated window segments, use the original ones - when we + // switch from having them to having none, we need to fallback to the original + // value. If there never were any emulated segments this is a no-op. + bool emulated_window_segments = emulation_params_.window_segments.size(); + delegate_->SetRootWindowSegments(emulated_window_segments + ? emulation_params_.window_segments + : original_root_window_segments_); + blink::ScreenInfo screen_info = original_screen_info(); screen_info.device_scale_factor = device_scale_factor; screen_info.rect = screen_rect; @@ -143,10 +152,12 @@ void RenderWidgetScreenMetricsEmulator::OnSynchronizeVisualProperties( const blink::ScreenInfo& screen_info, const gfx::Size& widget_size, - const gfx::Size& visible_viewport_size) { + const gfx::Size& visible_viewport_size, + const std::vector<gfx::Rect>& root_window_segments) { original_screen_info_ = screen_info; original_widget_size_ = widget_size; original_visible_viewport_size_ = visible_viewport_size; + original_root_window_segments_ = root_window_segments; Apply(); }
diff --git a/content/renderer/render_widget_screen_metrics_emulator.h b/content/renderer/render_widget_screen_metrics_emulator.h index a5a32d1..d40108fa 100644 --- a/content/renderer/render_widget_screen_metrics_emulator.h +++ b/content/renderer/render_widget_screen_metrics_emulator.h
@@ -59,9 +59,12 @@ // Sets new parameters and applies them to the RenderWidget. void ChangeEmulationParams(const blink::WebDeviceEmulationParams& params); - void OnSynchronizeVisualProperties(const blink::ScreenInfo& screen_info, - const gfx::Size& widget_size, - const gfx::Size& visible_viewport_size); + void OnSynchronizeVisualProperties( + const blink::ScreenInfo& screen_info, + const gfx::Size& widget_size, + const gfx::Size& visible_viewport_size, + const std::vector<gfx::Rect>& root_window_segments); + void OnUpdateScreenRects(const gfx::Rect& view_screen_rect, const gfx::Rect& window_screen_rect); @@ -85,6 +88,7 @@ gfx::Size original_visible_viewport_size_; gfx::Rect original_view_screen_rect_; gfx::Rect original_window_screen_rect_; + std::vector<gfx::Rect> original_root_window_segments_; DISALLOW_COPY_AND_ASSIGN(RenderWidgetScreenMetricsEmulator); };
diff --git a/content/renderer/render_widget_screen_metrics_emulator_delegate.h b/content/renderer/render_widget_screen_metrics_emulator_delegate.h index 414323e9..1e12de88 100644 --- a/content/renderer/render_widget_screen_metrics_emulator_delegate.h +++ b/content/renderer/render_widget_screen_metrics_emulator_delegate.h
@@ -33,6 +33,9 @@ virtual void SetScreenRects(const gfx::Rect& view_screen_rect, const gfx::Rect& window_screen_rect) = 0; + virtual void SetRootWindowSegments( + const std::vector<gfx::Rect>& root_window_segments) = 0; + protected: virtual ~RenderWidgetScreenMetricsEmulatorDelegate() {} };
diff --git a/content/shell/renderer/web_test/test_runner.cc b/content/shell/renderer/web_test/test_runner.cc index 0cec169b..d17476c 100644 --- a/content/shell/renderer/web_test/test_runner.cc +++ b/content/shell/renderer/web_test/test_runner.cc
@@ -1108,7 +1108,7 @@ // Clear the document->isolated world CSP mapping. GetWebFrame()->ClearIsolatedWorldCSPForTesting(world_id); - GetWebFrame()->SetIsolatedWorldInfo(world_id, info); + blink::SetIsolatedWorldInfo(world_id, info); } void TestRunnerBindings::AddOriginAccessAllowListEntry(
diff --git a/content/test/navigation_simulator_impl.h b/content/test/navigation_simulator_impl.h index 86cee208..884e0eef 100644 --- a/content/test/navigation_simulator_impl.h +++ b/content/test/navigation_simulator_impl.h
@@ -23,7 +23,7 @@ #include "net/base/ip_endpoint.h" #include "net/dns/public/resolve_error_info.h" #include "services/service_manager/public/cpp/interface_provider.h" -#include "third_party/blink/public/mojom/referrer.mojom-forward.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom-forward.h" #include "url/gurl.h" struct FrameHostMsg_DidCommitProvisionalLoad_Params;
diff --git a/extensions/common/extension_api.cc b/extensions/common/extension_api.cc index a8828f93..d1575cd5 100644 --- a/extensions/common/extension_api.cc +++ b/extensions/common/extension_api.cc
@@ -224,18 +224,12 @@ base::StringPiece ExtensionAPI::GetSchemaStringPiece( const std::string& api_name) { DCHECK_EQ(api_name, GetAPINameFromFullName(api_name, nullptr)); - auto cached = schema_strings_.find(api_name); - if (cached != schema_strings_.end()) - return cached->second; - ExtensionsClient* client = ExtensionsClient::Get(); DCHECK(client); if (!default_configuration_initialized_) return base::StringPiece(); base::StringPiece schema = client->GetAPISchema(api_name); - if (!schema.empty()) - schema_strings_[api_name] = schema; return schema; }
diff --git a/extensions/common/extension_api.h b/extensions/common/extension_api.h index 01761a6..bdf05745 100644 --- a/extensions/common/extension_api.h +++ b/extensions/common/extension_api.h
@@ -172,9 +172,6 @@ std::map<std::string, std::unique_ptr<const base::DictionaryValue>>; SchemaMap schemas_; - using StringPieceMap = std::map<std::string, base::StringPiece>; - StringPieceMap schema_strings_; - // FeatureProviders used for resolving dependencies. typedef std::map<std::string, const FeatureProvider*> FeatureProviderMap; FeatureProviderMap dependency_providers_;
diff --git a/extensions/common/permissions/extensions_api_permissions.cc b/extensions/common/permissions/extensions_api_permissions.cc index 9bac9b019..4d82c54 100644 --- a/extensions/common/permissions/extensions_api_permissions.cc +++ b/extensions/common/permissions/extensions_api_permissions.cc
@@ -39,7 +39,8 @@ APIPermissionInfo::kFlagDoesNotRequireManagedSessionFullLoginWarning}, {APIPermission::kAudio, "audio", APIPermissionInfo::kFlagDoesNotRequireManagedSessionFullLoginWarning}, - {APIPermission::kAudioCapture, "audioCapture"}, + {APIPermission::kAudioCapture, "audioCapture", + APIPermissionInfo::kFlagRequiresManagementUIWarning}, {APIPermission::kBluetoothPrivate, "bluetoothPrivate", APIPermissionInfo::kFlagCannotBeOptional}, {APIPermission::kCecPrivate, "cecPrivate", @@ -144,7 +145,8 @@ {APIPermission::kUsbDevice, "usbDevices", extensions::APIPermissionInfo::kFlagNone, &CreateAPIPermission<UsbDevicePermission>}, - {APIPermission::kVideoCapture, "videoCapture"}, + {APIPermission::kVideoCapture, "videoCapture", + APIPermissionInfo::kFlagRequiresManagementUIWarning}, {APIPermission::kVirtualKeyboard, "virtualKeyboard"}, {APIPermission::kVpnProvider, "vpnProvider", APIPermissionInfo::kFlagCannotBeOptional |
diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc index 6245142..73d37aaf 100644 --- a/extensions/renderer/script_injection.cc +++ b/extensions/renderer/script_injection.cc
@@ -45,11 +45,10 @@ // The id of the next pending injection. int64_t g_next_pending_id = 0; -// Gets the isolated world ID to use for the given |injection_host| -// in the given |frame|. If no isolated world has been created for that -// |injection_host| one will be created and initialized. -int GetIsolatedWorldIdForInstance(const InjectionHost* injection_host, - blink::WebLocalFrame* frame) { +// Gets the isolated world ID to use for the given |injection_host|. If no +// isolated world has been created for that |injection_host| one will be created +// and initialized. +int GetIsolatedWorldIdForInstance(const InjectionHost* injection_host) { static int g_next_isolated_world_id = ExtensionsRendererClient::Get()->GetLowestIsolatedWorldId(); @@ -67,9 +66,6 @@ isolated_worlds[key] = id; } - // We need to set the isolated world origin and CSP even if it's not a new - // world since these are stored per frame, and we might not have used this - // isolated world in this frame before. blink::WebIsolatedWorldInfo info; info.security_origin = blink::WebSecurityOrigin::Create(injection_host->url()); @@ -80,7 +76,10 @@ if (csp) info.content_security_policy = blink::WebString::FromUTF8(*csp); - frame->SetIsolatedWorldInfo(id, info); + // Even though there may be an existing world for this |injection_host|'s key, + // the properties may have changed (e.g. due to an extension update). + // Overwrite any existing entries. + blink::SetIsolatedWorldInfo(id, info); return id; } @@ -285,12 +284,10 @@ void ScriptInjection::InjectJs(std::set<std::string>* executing_scripts, size_t* num_injected_js_scripts) { DCHECK(!did_inject_js_); - blink::WebLocalFrame* web_frame = render_frame_->GetWebFrame(); std::vector<blink::WebScriptSource> sources = injector_->GetJsSources( run_location_, executing_scripts, num_injected_js_scripts); DCHECK(!sources.empty()); - int world_id = - GetIsolatedWorldIdForInstance(injection_host_.get(), web_frame); + int world_id = GetIsolatedWorldIdForInstance(injection_host_.get()); bool is_user_gesture = injector_->IsUserGesture(); std::unique_ptr<blink::WebScriptExecutionCallback> callback( @@ -315,7 +312,8 @@ should_execute_asynchronously ? blink::WebLocalFrame::kAsynchronousBlockingOnload : blink::WebLocalFrame::kSynchronous; - web_frame->RequestExecuteScriptInIsolatedWorld( + + render_frame_->GetWebFrame()->RequestExecuteScriptInIsolatedWorld( world_id, &sources.front(), sources.size(), is_user_gesture, execution_option, callback.release()); }
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index 10cb002..13fa08f 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -17053,7 +17053,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17075,7 +17075,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17185,7 +17185,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17207,7 +17207,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17317,7 +17317,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17405,7 +17405,7 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" + properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\"}" execution_timeout_secs: 10800 build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -17427,11 +17427,11 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\",\"xcode_build_version\":\"11c29\"}" + properties: "{\"$build/goma\":{\"jobs\":80,\"rpc_extra_params\":\"?tot\",\"server_host\":\"staging-goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma\",\"recipe\":\"chromium\",\"xcode_build_version\":\"11e146\"}" execution_timeout_secs: 10800 caches { - name: "xcode_ios_11c29" - path: "xcode_ios_11c29.app" + name: "xcode_ios_11e146" + path: "xcode_ios_11e146.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18192,11 +18192,11 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\",\"xcode_build_version\":\"11c29\"}" + properties: "{\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\",\"xcode_build_version\":\"11e146\"}" execution_timeout_secs: 36000 caches { - name: "xcode_ios_11c29" - path: "xcode_ios_11c29.app" + name: "xcode_ios_11e146" + path: "xcode_ios_11e146.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18217,11 +18217,11 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\",\"xcode_build_version\":\"11c29\"}" + properties: "{\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\",\"xcode_build_version\":\"11e146\"}" execution_timeout_secs: 36000 caches { - name: "xcode_ios_11c29" - path: "xcode_ios_11c29.app" + name: "xcode_ios_11e146" + path: "xcode_ios_11e146.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18242,11 +18242,11 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\",\"xcode_build_version\":\"11c29\"}" + properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\",\"xcode_build_version\":\"11e146\"}" execution_timeout_secs: 36000 caches { - name: "xcode_ios_11c29" - path: "xcode_ios_11c29.app" + name: "xcode_ios_11e146" + path: "xcode_ios_11e146.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" @@ -18267,11 +18267,11 @@ cipd_version: "refs/heads/master" cmd: "recipes" } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\",\"xcode_build_version\":\"11c29\"}" + properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\"},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"mastername\":\"chromium.goma.fyi\",\"recipe\":\"chromium\",\"xcode_build_version\":\"11e146\"}" execution_timeout_secs: 36000 caches { - name: "xcode_ios_11c29" - path: "xcode_ios_11c29.app" + name: "xcode_ios_11e146" + path: "xcode_ios_11e146.app" } build_numbers: YES service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/infra/config/lib/builders.star b/infra/config/lib/builders.star index 1fa8ae9d..c84369f4 100644 --- a/infra/config/lib/builders.star +++ b/infra/config/lib/builders.star
@@ -162,7 +162,7 @@ return chromium_tests or None -def _goma_property(*, goma_backend, goma_debug, goma_enable_ats, goma_jobs, os): +def _goma_property(*, goma_backend, goma_debug, goma_enable_ats, goma_jobs, goma_use_luci_auth, os): goma_properties = {} goma_backend = defaults.get_value('goma_backend', goma_backend) @@ -187,6 +187,10 @@ if goma_jobs != None: goma_properties['jobs'] = goma_jobs + goma_use_luci_auth = defaults.get_value('goma_use_luci_auth', goma_use_luci_auth) + if goma_use_luci_auth: + goma_properties['use_luci_auth'] = True + return goma_properties or None @@ -239,6 +243,7 @@ goma_debug = False, goma_enable_ats = args.COMPUTE, goma_jobs = None, + goma_use_luci_auth = None, mastername = None, os = None, pool = None, @@ -279,6 +284,7 @@ goma_debug=args.DEFAULT, goma_enable_ats=args.DEFAULT, goma_jobs=args.DEFAULT, + goma_use_luci_auth=args.DEFAULT, use_clang_coverage=args.DEFAULT, use_java_coverage=args.DEFAULT, coverage_exclude_sources=args.DEFAULT, @@ -351,6 +357,9 @@ to be used by the builder. Sets the 'jobs' field of the '$build/goma' property will be set according to the enum member. By default, the 'jobs' considered None. + * goma_use_luci_auth - a boolean indicating whether luci_auth should be + used for accessing goma backend. If True, the 'use_luci_auth' field + will be set in the '$build/goma' property. By default, considered False. * use_clang_coverage - a boolean indicating whether clang coverage should be used. If True, the 'use_clang_coverage" field will be set in the '$build/code_coverage' property. By default, considered False. @@ -446,6 +455,7 @@ goma_debug = goma_debug, goma_enable_ats = goma_enable_ats, goma_jobs = goma_jobs, + goma_use_luci_auth = goma_use_luci_auth, os = os, ) if goma != None:
diff --git a/infra/config/subprojects/goma/goma.star b/infra/config/subprojects/goma/goma.star index f44522e3..3aaf83c 100644 --- a/infra/config/subprojects/goma/goma.star +++ b/infra/config/subprojects/goma/goma.star
@@ -111,11 +111,11 @@ fyi_goma_canary_builder( name = 'ios-device-goma-canary-clobber', - caches = [xcode_cache.x11c29], + caches = [xcode_cache.x11e146], cores = None, os = os.MAC_ANY, properties = { - 'xcode_build_version': '11c29' + 'xcode_build_version': '11e146' } ) @@ -187,11 +187,11 @@ fyi_goma_rbe_canary_builder( name = 'ios-device-goma-rbe-canary-clobber', - caches = [xcode_cache.x11c29], + caches = [xcode_cache.x11e146], cores = None, os = os.MAC_ANY, properties = { - 'xcode_build_version': '11c29' + 'xcode_build_version': '11e146' } ) @@ -273,11 +273,11 @@ fyi_goma_latest_client_builder( name = 'ios-device-goma-latest-clobber', - caches = [xcode_cache.x11c29], + caches = [xcode_cache.x11e146], cores = None, os = os.MAC_ANY, properties = { - 'xcode_build_version': '11c29' + 'xcode_build_version': '11e146' } ) @@ -363,11 +363,11 @@ fyi_goma_rbe_latest_client_builder( name = 'ios-device-goma-rbe-latest-clobber', - caches = [xcode_cache.x11c29], + caches = [xcode_cache.x11e146], cores = None, os = os.MAC_ANY, properties = { - 'xcode_build_version': '11c29' + 'xcode_build_version': '11e146' } ) @@ -406,12 +406,14 @@ name = 'Chromium Android ARM 32-bit Goma RBE ToT', goma_backend = goma.backend.RBE_TOT, goma_enable_ats = False, + goma_use_luci_auth = True, ) goma_builder( name = 'Chromium Android ARM 32-bit Goma RBE ToT (ATS)', goma_backend = goma.backend.RBE_TOT, goma_enable_ats = True, + goma_use_luci_auth = True, ) goma_builder( @@ -442,12 +444,14 @@ name = 'Chromium Linux Goma RBE ToT', goma_backend = goma.backend.RBE_TOT, goma_enable_ats = False, + goma_use_luci_auth = True, ) goma_builder( name = 'Chromium Linux Goma RBE ToT (ATS)', goma_backend = goma.backend.RBE_TOT, goma_enable_ats = True, + goma_use_luci_auth = True, ) @@ -462,11 +466,12 @@ goma_mac_builder( name = 'Chromium iOS Goma RBE ToT', - caches = [xcode_cache.x11c29], + caches = [xcode_cache.x11e146], goma_backend = goma.backend.RBE_TOT, + goma_use_luci_auth = True, os = os.MAC_10_14, properties = { - 'xcode_build_version': "11c29", + 'xcode_build_version': "11e146", } ) @@ -488,6 +493,7 @@ goma_mac_builder( name = 'Chromium Mac Goma RBE ToT', goma_backend = goma.backend.RBE_TOT, + goma_use_luci_auth = True, ) goma_mac_builder( @@ -517,6 +523,7 @@ goma_windows_builder( name = 'Chromium Win Goma RBE ToT', goma_backend = goma.backend.RBE_TOT, + goma_use_luci_auth = True, ) goma_windows_builder(
diff --git a/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-device.json b/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-device.json index a62ad82f..8af5c99 100644 --- a/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-device.json +++ b/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-device.json
@@ -3,7 +3,7 @@ "Builder for 64-bit devices.", "Build is performed with gn+ninja." ], - "xcode build version": "11c29", + "xcode build version": "11e146", "gn_args": [ "goma_dir=\"$(goma_dir)\"", "ios_enable_code_signing=false",
diff --git a/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-simulator.json b/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-simulator.json index c6c6849e..db2facc 100644 --- a/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-simulator.json +++ b/ios/build/bots/chromium.webrtc.fyi/WebRTC Chromium FYI ios-simulator.json
@@ -2,7 +2,7 @@ "comments": [ "Runs tests on @3x, @2x, 64-bit phone, tablet, iOS 12." ], - "xcode build version": "11c29", + "xcode build version": "11e146", "gn_args": [ "goma_dir=\"$(goma_dir)\"", "ios_enable_code_signing=false",
diff --git a/ios/chrome/browser/passwords/password_controller.mm b/ios/chrome/browser/passwords/password_controller.mm index 91046e2..d7952036 100644 --- a/ios/chrome/browser/passwords/password_controller.mm +++ b/ios/chrome/browser/passwords/password_controller.mm
@@ -14,7 +14,7 @@ #include "base/bind.h" #include "base/mac/foundation_util.h" -#include "base/metrics/histogram_macros.h" +#include "base/metrics/histogram_functions.h" #include "base/strings/string16.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -423,7 +423,7 @@ _lastTypedfieldIdentifier = formQuery.uniqueFieldID; _lastTypedValue = formQuery.typedValue; - if ([formQuery.type isEqual:@"text"]) { + if ([formQuery.type isEqual:@"input"]) { [self.formHelper updateFieldDataOnUserInput:formQuery.uniqueFieldID inputValue:formQuery.typedValue]; } @@ -799,7 +799,15 @@ delegate->set_handler(self.applicationCommandsHandler); if (IsInfobarUIRebootEnabled()) { + // Count only new infobar showings, not replacements. + if (![self findInfobarOfType:InfobarType::kInfobarTypePasswordSave + manual:manual]) { + base::UmaHistogramBoolean("PasswordManager.iOS.InfoBar.PasswordSave", + true); + } + std::unique_ptr<InfoBarIOS> infobar; + // If manual save, skip showing banner. bool skip_banner = manual; if (IsInfobarOverlayUIEnabled()) { @@ -827,6 +835,13 @@ } case PasswordInfoBarType::UPDATE: { if (IsInfobarUIRebootEnabled()) { + // Count only new infobar showings, not replacements. + if (![self findInfobarOfType:InfobarType::kInfobarTypePasswordUpdate + manual:manual]) { + base::UmaHistogramBoolean( + "PasswordManager.iOS.InfoBar.PasswordUpdate", true); + } + auto delegate = std::make_unique<IOSChromeSavePasswordInfoBarDelegate>( isSyncUser, /*password_update*/ true, std::move(form)); delegate->set_handler(self.applicationCommandsHandler);
diff --git a/ios/chrome/browser/passwords/password_controller_unittest.mm b/ios/chrome/browser/passwords/password_controller_unittest.mm index adecfbc9..40f34c6 100644 --- a/ios/chrome/browser/passwords/password_controller_unittest.mm +++ b/ios/chrome/browser/passwords/password_controller_unittest.mm
@@ -367,7 +367,7 @@ fieldIdentifier:SysUTF8ToNSString(field_identifier) uniqueFieldID:uniqueFieldID fieldType:@"not_important" - type:@"text" + type:@"input" typedValue:SysUTF8ToNSString(typed_value) frameID:SysUTF8ToNSString(main_frame_id)]; [passwordController_ checkIfSuggestionsAvailableForForm:form_query
diff --git a/ios/chrome/browser/ui/download/download_manager_coordinator.mm b/ios/chrome/browser/ui/download/download_manager_coordinator.mm index b74b4a2..fc4a276 100644 --- a/ios/chrome/browser/ui/download/download_manager_coordinator.mm +++ b/ios/chrome/browser/ui/download/download_manager_coordinator.mm
@@ -282,7 +282,7 @@ } })); - web::WebState* webState = self.downloadTask->GetWebState(); + web::WebState* webState = download->GetWebState(); OverlayRequestQueue::FromWebState(webState, OverlayModality::kWebContentArea) ->AddRequest(std::move(request)); }
diff --git a/ios/chrome/browser/ui/download/download_manager_coordinator_unittest.mm b/ios/chrome/browser/ui/download/download_manager_coordinator_unittest.mm index 920d2f1..a816cd9 100644 --- a/ios/chrome/browser/ui/download/download_manager_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/download/download_manager_coordinator_unittest.mm
@@ -669,6 +669,49 @@ EXPECT_EQ(0U, queue->size()); } +// Tests downloadManagerTabHelper:decidePolicyForDownload:completionHandler:. +// Coordinator should present the confirmation dialog. +TEST_F(DownloadManagerCoordinatorTest, + DecidePolicyForDownloadFromBackgroundTab) { + web::FakeDownloadTask task(GURL(kTestUrl), kTestMimeType); + task.SetWebState(&web_state_); + coordinator_.downloadTask = nullptr; // Current Tab does not have task. + + OverlayRequestQueue* queue = OverlayRequestQueue::FromWebState( + &web_state_, OverlayModality::kWebContentArea); + ASSERT_EQ(0U, queue->size()); + [coordinator_ downloadManagerTabHelper:&tab_helper_ + decidePolicyForDownload:&task + completionHandler:^(NewDownloadPolicy){ + }]; + + // Verify that confirm request was sent. + ASSERT_EQ(1U, queue->size()); + + alert_overlays::AlertRequest* config = + queue->front_request()->GetConfig<alert_overlays::AlertRequest>(); + ASSERT_TRUE(config); + EXPECT_NSEQ(@"Start New Download?", config->title()); + EXPECT_NSEQ(@"This will stop all progress for your current download.", + config->message()); + ASSERT_EQ(2U, config->button_configs().size()); + EXPECT_NSEQ(@"OK", config->button_configs()[0].title); + EXPECT_EQ(kDownloadReplaceActionName, + config->button_configs()[0].user_action_name); + EXPECT_NSEQ(@"Cancel", config->button_configs()[1].title); + EXPECT_EQ(kDownloadDoNotReplaceActionName, + config->button_configs()[1].user_action_name); + + queue->CancelAllRequests(); + @autoreleasepool { + // task_environment_ has to outlive the coordinator. Dismissing coordinator + // retains are autoreleases it. + [coordinator_ stop]; + } + + EXPECT_EQ(0U, queue->size()); +} + // Tests starting the download. Verifies that download task is started and its // file writer is configured to write into download directory. TEST_F(DownloadManagerCoordinatorTest, StartDownload) {
diff --git a/ios/chrome/browser/ui/settings/password/BUILD.gn b/ios/chrome/browser/ui/settings/password/BUILD.gn index ec93263..af4b44f0 100644 --- a/ios/chrome/browser/ui/settings/password/BUILD.gn +++ b/ios/chrome/browser/ui/settings/password/BUILD.gn
@@ -40,6 +40,7 @@ "//ios/chrome/browser/browser_state", "//ios/chrome/browser/passwords", "//ios/chrome/browser/signin", + "//ios/chrome/browser/sync", "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/coordinators:chrome_coordinators", @@ -47,11 +48,14 @@ "//ios/chrome/browser/ui/settings/cells", "//ios/chrome/browser/ui/settings/cells:public", "//ios/chrome/browser/ui/settings/elements:enterprise_info_popover_view_controller", + "//ios/chrome/browser/ui/settings/password/password_details", "//ios/chrome/browser/ui/settings/utils", "//ios/chrome/browser/ui/table_view", "//ios/chrome/browser/ui/table_view/cells:cells_constants", "//ios/chrome/browser/ui/util", + "//ios/chrome/common", "//ios/chrome/common/ui/colors", + "//ios/chrome/common/ui/elements:popover_label_view_controller", "//ios/chrome/common/ui/reauthentication", "//ios/chrome/common/ui/util", "//ios/third_party/material_components_ios", @@ -75,6 +79,7 @@ ] deps = [ "//base", + "//components/autofill/core/common", "//components/password_manager/core/browser", "//components/password_manager/core/common", "//components/prefs", @@ -83,6 +88,7 @@ "//ios/chrome/app/strings:ios_strings_grit", "//ios/chrome/browser", "//ios/chrome/browser/ui/settings:settings_root", + "//ios/chrome/browser/ui/settings/autofill", "//ios/chrome/browser/ui/table_view/cells", "//ios/chrome/browser/ui/util", "//ios/chrome/common/ui/util",
diff --git a/ios/chrome/browser/ui/settings/password/password_details/BUILD.gn b/ios/chrome/browser/ui/settings/password/password_details/BUILD.gn new file mode 100644 index 0000000..4719b99 --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/password_details/BUILD.gn
@@ -0,0 +1,59 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("password_details") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "password_details_coordinator.h", + "password_details_coordinator.mm", + "password_details_coordinator_delegate.h", + "password_details_mediator.h", + "password_details_mediator.mm", + ] + deps = [ + ":password_details_ui", + "//base", + "//components/autofill/core/common", + "//components/strings", + "//components/url_formatter", + "//ios/chrome/app/strings", + "//ios/chrome/browser", + "//ios/chrome/browser/passwords", + "//ios/chrome/browser/ui:feature_flags", + "//ios/chrome/browser/ui/commands", + "//ios/chrome/browser/ui/coordinators:chrome_coordinators", + "//ios/chrome/browser/ui/table_view", + "//ios/chrome/common/ui/colors", + "//ios/chrome/common/ui/util", + "//ui/base", + ] +} + +source_set("password_details_ui") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "password_details.h", + "password_details.mm", + "password_details_consumer.h", + "password_details_handler.h", + "password_details_table_view_constants.h", + "password_details_table_view_constants.mm", + "password_details_view_controller.h", + "password_details_view_controller.mm", + "password_details_view_controller_delegate.h", + ] + deps = [ + "//base", + "//components/autofill/core/common", + "//components/password_manager/core/browser:browser", + "//components/strings", + "//ios/chrome/browser", + "//ios/chrome/browser/ui/settings:settings_root", + "//ios/chrome/browser/ui/settings/autofill", + "//ios/chrome/browser/ui/table_view/cells", + "//ios/chrome/browser/ui/util", + "//ios/chrome/common/ui/util", + "//ui/base", + ] +}
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details.h b/ios/chrome/browser/ui/settings/password/password_details/password_details.h new file mode 100644 index 0000000..092f213 --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details.h
@@ -0,0 +1,37 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_H_ + +#import <Foundation/Foundation.h> + +namespace autofill { +struct PasswordForm; +} + +// Object which is used by |PasswordDetailsViewController| to show +// information about password. +@interface PasswordDetails : NSObject + +// Short version of website. +@property(nonatomic, strong, readonly) NSString* origin; + +// Associated website. +@property(nonatomic, strong, readonly) NSString* website; + +// Associated username. +@property(nonatomic, strong, readonly) NSString* username; + +// Associated password. +@property(nonatomic, strong) NSString* password; + +- (instancetype)initWithPasswordForm:(const autofill::PasswordForm&)form + NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_H_
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details.mm new file mode 100644 index 0000000..3e6855e --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details.mm
@@ -0,0 +1,29 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/settings/password/password_details/password_details.h" + +#include "base/strings/sys_string_conversions.h" +#include "components/autofill/core/common/password_form.h" +#include "components/password_manager/core/browser/password_ui_utils.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@implementation PasswordDetails + +- (instancetype)initWithPasswordForm:(const autofill::PasswordForm&)form { + self = [super init]; + if (self) { + auto nameWithLink = password_manager::GetShownOriginAndLinkUrl(form); + _origin = base::SysUTF8ToNSString(nameWithLink.first); + _website = base::SysUTF8ToNSString(nameWithLink.second.spec()); + _username = base::SysUTF16ToNSString(form.username_value); + _password = base::SysUTF16ToNSString(form.password_value); + } + return self; +} + +@end
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_consumer.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_consumer.h new file mode 100644 index 0000000..9486313 --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_consumer.h
@@ -0,0 +1,20 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_CONSUMER_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_CONSUMER_H_ + +#import <Foundation/Foundation.h> + +@class PasswordDetails; + +// Sets the Password details for consumer. +@protocol PasswordDetailsConsumer <NSObject> + +// Displays provided password details. +- (void)setPassword:(PasswordDetails*)password; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_CONSUMER_H_
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.h new file mode 100644 index 0000000..ab51f26 --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.h
@@ -0,0 +1,33 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_COORDINATOR_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_COORDINATOR_H_ + +#import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h" + +@protocol PasswordDetailsCoordinatorDelegate; + +namespace autofill { +struct PasswordForm; +} + +// This coordinator presents a password details for the user. +@interface PasswordDetailsCoordinator : ChromeCoordinator + +- (instancetype)initWithBaseNavigationController: + (UINavigationController*)navigationController + password:(const autofill::PasswordForm&) + password + NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithBaseViewController:(UIViewController*)viewController + browser:(Browser*)browser NS_UNAVAILABLE; + +// Delegate. +@property(nonatomic, weak) id<PasswordDetailsCoordinatorDelegate> delegate; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm new file mode 100644 index 0000000..517b6ee --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.mm
@@ -0,0 +1,76 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.h" + +#include "base/mac/foundation_util.h" +#include "components/autofill/core/common/password_form.h" +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_consumer.h" +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h" +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_handler.h" +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h" +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller.h" +#include "ios/chrome/browser/ui/ui_feature_flags.h" +#include "ui/base/l10n/l10n_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface PasswordDetailsCoordinator () <PasswordDetailsHandler> { + autofill::PasswordForm _password; +} + +// Main view controller for this coordinator. +@property(nonatomic, strong) PasswordDetailsViewController* viewController; + +// Main mediator for this coordinator. +@property(nonatomic, strong) PasswordDetailsMediator* mediator; + +@end + +@implementation PasswordDetailsCoordinator + +@synthesize baseNavigationController = _baseNavigationController; + +- (instancetype)initWithBaseNavigationController: + (UINavigationController*)navigationController + password:(const autofill::PasswordForm&) + password { + self = [super initWithBaseViewController:navigationController browser:nil]; + if (self) { + _password = password; + _baseNavigationController = navigationController; + } + return self; +} + +- (void)start { + UITableViewStyle style = base::FeatureList::IsEnabled(kSettingsRefresh) + ? UITableViewStylePlain + : UITableViewStyleGrouped; + + self.viewController = + [[PasswordDetailsViewController alloc] initWithStyle:style]; + + self.mediator = [[PasswordDetailsMediator alloc] initWithPassword:_password]; + self.mediator.consumer = self.viewController; + self.viewController.handler = self; + + [self.baseNavigationController pushViewController:self.viewController + animated:YES]; +} + +- (void)stop { + self.mediator = nil; + self.viewController = nil; +} + +#pragma mark - PasswordDetailsHandler + +- (void)passwordDetailsViewControllerDidDisappear { + [self.delegate passwordDetailsCoordinatorDidRemove:self]; +} + +@end
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h new file mode 100644 index 0000000..56e1c44a --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator_delegate.h
@@ -0,0 +1,28 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_COORDINATOR_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_COORDINATOR_DELEGATE_H_ + +@class PasswordDetailsCoordinator; + +namespace autofill { +struct PasswordForm; +} + +// Delegate for PasswordIssuesCoordinator. +@protocol PasswordDetailsCoordinatorDelegate + +// Called when the view controller was removed from navigation controller. +- (void)passwordDetailsCoordinatorDidRemove: + (PasswordDetailsCoordinator*)coordinator; + +// Called when user deleted password. This action should be handled +// outside to update the list of passwords immediately. +- (void)passwordDetailsCoordinator:(PasswordDetailsCoordinator*)coordinator + deletePassword:(const autofill::PasswordForm&)password; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_COORDINATOR_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_handler.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_handler.h new file mode 100644 index 0000000..619395a --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_handler.h
@@ -0,0 +1,16 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_HANDLER_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_HANDLER_H_ + +// Presenter which handles commands from |PasswordDetailsViewController|. +@protocol PasswordDetailsHandler + +// Called when the view controller was dismissed. +- (void)passwordDetailsViewControllerDidDisappear; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_HANDLER_H_
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h new file mode 100644 index 0000000..7419f17 --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h
@@ -0,0 +1,30 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_MEDIATOR_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_MEDIATOR_H_ + +#import <Foundation/Foundation.h> + +@protocol PasswordDetailsConsumer; + +namespace autofill { +struct PasswordForm; +} + +// This mediator fetches and organises the credentials for its consumer. +@interface PasswordDetailsMediator : NSObject + +// PasswordForm is converted to the PasswordDetails and passed to a consumer. +- (instancetype)initWithPassword:(const autofill::PasswordForm&)passwordForm + NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +// Consumer of this mediator. +@property(nonatomic, weak) id<PasswordDetailsConsumer> consumer; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm new file mode 100644 index 0000000..4af31a37 --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm
@@ -0,0 +1,54 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.h" + +#include "components/autofill/core/common/password_form.h" +#import "ios/chrome/browser/ui/settings/password/password_details/password_details.h" +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_consumer.h" +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller_delegate.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace autofill { +struct PasswordForm; +} + +@interface PasswordDetailsMediator () <PasswordDetailsViewControllerDelegate> { + autofill::PasswordForm _password; +} + +@end + +@implementation PasswordDetailsMediator + +- (instancetype)initWithPassword:(const autofill::PasswordForm&)passwordForm { + self = [super init]; + if (self) { + _password = passwordForm; + } + return self; +} + +- (void)setConsumer:(id<PasswordDetailsConsumer>)consumer { + if (_consumer == consumer) + return; + _consumer = consumer; + + PasswordDetails* password = + [[PasswordDetails alloc] initWithPasswordForm:_password]; + + [self.consumer setPassword:password]; +} + +#pragma mark - PasswordDetailsViewControllerDelegate +- (void)passwordDetailsViewController: + (PasswordDetailsViewController*)viewController + didEditPasswordDetails:(PasswordDetails*)password { + // TODO:(crbug.com/1075494) - Edit password accordingly. +} + +@end
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_constants.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_constants.h new file mode 100644 index 0000000..ac54ac66 --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_constants.h
@@ -0,0 +1,13 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_TABLE_VIEW_CONSTANTS_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_TABLE_VIEW_CONSTANTS_H_ + +#import <Foundation/Foundation.h> + +// The accessibility identifier of the password details table view. +extern NSString* const kPasswordDetailsViewControllerId; + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_TABLE_VIEW_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_constants.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_constants.mm new file mode 100644 index 0000000..c74c413 --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_constants.mm
@@ -0,0 +1,12 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_constants.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +NSString* const kPasswordDetailsViewControllerId = + @"kPasswordDetailsViewControllerId";
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller.h new file mode 100644 index 0000000..ebbab60 --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller.h
@@ -0,0 +1,26 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_VIEW_CONTROLLER_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_VIEW_CONTROLLER_H_ + +#import "ios/chrome/browser/ui/settings/autofill/autofill_edit_table_view_controller.h" +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_consumer.h" + +@protocol PasswordDetailsHandler; +@protocol PasswordDetailsViewControllerDelegate; + +// Screen which shows password details and allows to edit it. +@interface PasswordDetailsViewController + : AutofillEditTableViewController <PasswordDetailsConsumer> + +// Handler for PasswordDetails related actions. +@property(nonatomic, weak) id<PasswordDetailsHandler> handler; + +// Delegate for PasswordDetails related actions e.g. Password editing. +@property(nonatomic, weak) id<PasswordDetailsViewControllerDelegate> delegate; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller.mm new file mode 100644 index 0000000..464d031 --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller.mm
@@ -0,0 +1,48 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller.h" + +#include "base/mac/foundation_util.h" +#import "ios/chrome/browser/ui/settings/password/password_details/password_details.h" +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_consumer.h" +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_constants.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface PasswordDetailsViewController () + +// Password which is shown on the screen. +@property(nonatomic, strong) PasswordDetails* password; + +@end + +@implementation PasswordDetailsViewController + +#pragma mark - UIViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + self.tableView.accessibilityIdentifier = kPasswordDetailsViewControllerId; + self.tableView.allowsSelectionDuringEditing = YES; + + [self loadModel]; +} + +#pragma mark - ChromeTableViewController + +- (void)loadModel { + [super loadModel]; +} + +#pragma mark - PasswordDetailsConsumer + +- (void)setPassword:(PasswordDetails*)password { + _password = password; + [self reloadData]; +} + +@end
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller_delegate.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller_delegate.h new file mode 100644 index 0000000..85e8a17 --- /dev/null +++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_view_controller_delegate.h
@@ -0,0 +1,20 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_VIEW_CONTROLLER_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_VIEW_CONTROLLER_DELEGATE_H_ + +@class PasswordDetails; +@class PasswordDetailsViewController; + +@protocol PasswordDetailsViewControllerDelegate + +// Called when user finished editing a password. +- (void)passwordDetailsViewController: + (PasswordDetailsViewController*)viewController + didEditPasswordDetails:(PasswordDetails*)password; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_VIEW_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/settings/password/password_issues_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_issues_coordinator.mm index e05a4b6..c2b33f4 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues_coordinator.mm +++ b/ios/chrome/browser/ui/settings/password/password_issues_coordinator.mm
@@ -5,6 +5,8 @@ #import "ios/chrome/browser/ui/settings/password/password_issues_coordinator.h" #include "base/mac/foundation_util.h" +#import "ios/chrome/browser/ui/settings/password/password_details/password_details_coordinator.h" +#import "ios/chrome/browser/ui/settings/password/password_issue_with_form.h" #import "ios/chrome/browser/ui/settings/password/password_issues_consumer.h" #import "ios/chrome/browser/ui/settings/password/password_issues_mediator.h" #import "ios/chrome/browser/ui/settings/password/password_issues_presenter.h" @@ -78,7 +80,15 @@ } - (void)presentPasswordIssueDetails:(id<PasswordIssue>)password { - // TODO(crbug.com/1075494) - Show Password details page + autofill::PasswordForm form = + base::mac::ObjCCastStrict<PasswordIssueWithForm>(password).form; + + PasswordDetailsCoordinator* passwordDetails = + [[PasswordDetailsCoordinator alloc] + initWithBaseNavigationController:self.baseNavigationController + password:form]; + // TODO:(crbug.com/1075494) - Add self as delegate for coordinator. + [passwordDetails start]; } @end
diff --git a/ios/chrome/browser/ui/settings/password/passwords_consumer.h b/ios/chrome/browser/ui/settings/password/passwords_consumer.h index a5d83ab..4435559 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_consumer.h +++ b/ios/chrome/browser/ui/settings/password/passwords_consumer.h
@@ -19,6 +19,8 @@ PasswordCheckStateRunning, // When user has no passwords and check can't be performed. PasswordCheckStateDisabled, + // When password check failed due to network issues, quota limit or others. + PasswordCheckStateError, }; // Consumer for the Passwords Screen.
diff --git a/ios/chrome/browser/ui/settings/password/passwords_mediator.h b/ios/chrome/browser/ui/settings/password/passwords_mediator.h index b7d21c6..46f2c34 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_mediator.h +++ b/ios/chrome/browser/ui/settings/password/passwords_mediator.h
@@ -9,8 +9,10 @@ #include "base/memory/scoped_refptr.h" +class AuthenticationService; class IOSChromePasswordCheckManager; @protocol PasswordsConsumer; +class SyncSetupService; namespace password_manager { class PasswordStore; @@ -19,16 +21,22 @@ // This mediator fetches and organises the passwords for its consumer. @interface PasswordsMediator : NSObject -- (instancetype)initWithPasswordStore: - (scoped_refptr<password_manager::PasswordStore>) - passwordStore - passwordCheckManager:(IOSChromePasswordCheckManager*)manager +- (instancetype) + initWithPasswordStore: + (scoped_refptr<password_manager::PasswordStore>)passwordStore + passwordCheckManager: + (scoped_refptr<IOSChromePasswordCheckManager>)passwordCheckManager + authService:(AuthenticationService*)authService + syncService:(SyncSetupService*)syncService NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; @property(nonatomic, weak) id<PasswordsConsumer> consumer; +// Returns detailed information about error if applicable. +- (NSAttributedString*)passwordCheckErrorInfo; + @end #endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORDS_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/settings/password/passwords_mediator.mm b/ios/chrome/browser/ui/settings/password/passwords_mediator.mm index 80b3861..d9e9a04 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_mediator.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_mediator.mm
@@ -4,13 +4,24 @@ #import "ios/chrome/browser/ui/settings/password/passwords_mediator.h" +#include "components/password_manager/core/browser/leak_detection_dialog_utils.h" #include "components/password_manager/core/browser/password_store.h" #include "components/password_manager/core/common/password_manager_features.h" #include "ios/chrome/browser/passwords/password_check_observer_bridge.h" #include "ios/chrome/browser/passwords/password_store_observer_bridge.h" #import "ios/chrome/browser/passwords/save_passwords_consumer.h" +#import "ios/chrome/browser/signin/authentication_service.h" +#include "ios/chrome/browser/sync/sync_setup_service.h" #import "ios/chrome/browser/ui/settings/password/passwords_consumer.h" +#import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h" #include "ios/chrome/browser/ui/ui_feature_flags.h" +#import "ios/chrome/browser/ui/util/uikit_ui_util.h" +#import "ios/chrome/common/string_util.h" +#import "ios/chrome/common/ui/colors/semantic_color_names.h" +#include "ios/chrome/grit/ios_chromium_strings.h" +#import "net/base/mac/url_conversions.h" +#include "ui/base/l10n/l10n_util_mac.h" +#include "url/gurl.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -20,11 +31,17 @@ PasswordStoreObserver, SavePasswordsConsumerDelegate> { // The service responsible for password check feature. - IOSChromePasswordCheckManager* _manager; + scoped_refptr<IOSChromePasswordCheckManager> _passwordCheckManager; // The interface for getting and manipulating a user's saved passwords. scoped_refptr<password_manager::PasswordStore> _passwordStore; + // Service used to check if user is signed in. + AuthenticationService* _authService; + + // Service to check if passwords are synced. + SyncSetupService* _syncService; + // A helper object for passing data about changes in password check status // and changes to compromised credentials list. std::unique_ptr<PasswordCheckObserverBridge> _passwordCheckObserver; @@ -44,21 +61,26 @@ @implementation PasswordsMediator -- (instancetype)initWithPasswordStore: - (scoped_refptr<password_manager::PasswordStore>) - passwordStore - passwordCheckManager:(IOSChromePasswordCheckManager*)manager { +- (instancetype) + initWithPasswordStore: + (scoped_refptr<password_manager::PasswordStore>)passwordStore + passwordCheckManager: + (scoped_refptr<IOSChromePasswordCheckManager>)passwordCheckManager + authService:(AuthenticationService*)authService + syncService:(SyncSetupService*)syncService { self = [super init]; if (self) { - _manager = manager; _passwordStore = passwordStore; + _authService = authService; + _syncService = syncService; _savedPasswordsConsumer = std::make_unique<ios::SavePasswordsConsumer>(self); if (base::FeatureList::IsEnabled( password_manager::features::kPasswordCheck)) { - _passwordCheckObserver = - std::make_unique<PasswordCheckObserverBridge>(self, manager); + _passwordCheckManager = passwordCheckManager; + _passwordCheckObserver = std::make_unique<PasswordCheckObserverBridge>( + self, _passwordCheckManager.get()); _passwordStoreObserver = std::make_unique<PasswordStoreObserverBridge>(self); _passwordStore->AddObserver(_passwordStoreObserver.get()); @@ -78,8 +100,50 @@ return; _consumer = consumer; [self loginsDidChange]; - [self.consumer setPasswordCheckUIState: - [self computePasswordCheckUIStateWithChangedState:NO]]; + + if (base::FeatureList::IsEnabled( + password_manager::features::kPasswordCheck)) { + _currentState = _passwordCheckManager->GetPasswordCheckState(); + [self.consumer setPasswordCheckUIState: + [self computePasswordCheckUIStateWith:_currentState]]; + } +} + +- (NSAttributedString*)passwordCheckErrorInfo { + if (!_passwordCheckManager->GetCompromisedCredentials().empty()) + return nil; + + NSString* message; + GURL linkURL; + + switch (_currentState) { + case PasswordCheckState::kRunning: + case PasswordCheckState::kNoPasswords: + case PasswordCheckState::kCanceled: + case PasswordCheckState::kIdle: + return nil; + case PasswordCheckState::kSignedOut: + message = l10n_util::GetNSString(IDS_IOS_PASSWORD_CHECK_ERROR_SIGNED_OUT); + break; + case PasswordCheckState::kOffline: + message = l10n_util::GetNSString(IDS_IOS_PASSWORD_CHECK_ERROR_OFFLINE); + break; + case PasswordCheckState::kQuotaLimit: + if ([self canUseAccountPasswordCheckup]) { + message = l10n_util::GetNSString( + IDS_IOS_PASSWORD_CHECK_ERROR_QUOTA_LIMIT_VISIT_GOOGLE); + linkURL = password_manager::GetPasswordCheckupURL( + password_manager::PasswordCheckupReferrer::kPasswordCheck); + } else { + message = + l10n_util::GetNSString(IDS_IOS_PASSWORD_CHECK_ERROR_QUOTA_LIMIT); + } + break; + case PasswordCheckState::kOther: + message = l10n_util::GetNSString(IDS_IOS_PASSWORD_CHECK_ERROR_OTHER); + break; + } + return [self configureTextWithLink:message link:linkURL]; } #pragma mark - PasswordCheckObserver @@ -88,10 +152,9 @@ if (state == _currentState) return; - _currentState = state; DCHECK(self.consumer); - [self.consumer setPasswordCheckUIState: - [self computePasswordCheckUIStateWithChangedState:YES]]; + [self.consumer + setPasswordCheckUIState:[self computePasswordCheckUIStateWith:state]]; } - (void)compromisedCredentialsDidChange: @@ -99,40 +162,80 @@ credentials { DCHECK(self.consumer); [self.consumer setPasswordCheckUIState: - [self computePasswordCheckUIStateWithChangedState:NO]]; + [self computePasswordCheckUIStateWith:_currentState]]; } #pragma mark - Private Methods // Returns PasswordCheckUIState based on PasswordCheckState. -// Parameter indicates whether function called when |_currentState| changed as -// safe status is only possible if state changed from kRunning to kIdle. -- (PasswordCheckUIState)computePasswordCheckUIStateWithChangedState: - (BOOL)stateChanged { +- (PasswordCheckUIState)computePasswordCheckUIStateWith: + (PasswordCheckState)newState { + BOOL wasRunning = _currentState == PasswordCheckState::kRunning; + _currentState = newState; + switch (_currentState) { - case PasswordCheckState::kRunning: { + case PasswordCheckState::kRunning: return PasswordCheckStateRunning; - } - case PasswordCheckState::kNoPasswords: { + case PasswordCheckState::kNoPasswords: return PasswordCheckStateDisabled; - } - case PasswordCheckState::kIdle: case PasswordCheckState::kSignedOut: case PasswordCheckState::kOffline: case PasswordCheckState::kQuotaLimit: + case PasswordCheckState::kOther: + return _passwordCheckManager->GetCompromisedCredentials().empty() + ? PasswordCheckStateError + : PasswordCheckStateUnSafe; case PasswordCheckState::kCanceled: - case PasswordCheckState::kOther: { - if (!_manager->GetCompromisedCredentials().empty()) { + case PasswordCheckState::kIdle: { + if (!_passwordCheckManager->GetCompromisedCredentials().empty()) { return PasswordCheckStateUnSafe; } else if (_currentState == PasswordCheckState::kIdle) { - return stateChanged ? PasswordCheckStateSafe - : PasswordCheckStateDefault; + // Safe state is only possible after the state transitioned from + // kRunning to kIdle. + return wasRunning ? PasswordCheckStateSafe : PasswordCheckStateDefault; } return PasswordCheckStateDefault; } } } +// Compute whether user is capable to run password check in Google Account. +- (BOOL)canUseAccountPasswordCheckup { + return (_authService->IsAuthenticated() && + _authService->GetAuthenticatedIdentity()) && + (_syncService->IsSyncEnabled() && + !_syncService->IsEncryptEverythingEnabled()); +} + +// Configures text for Error Info Popover. +- (NSAttributedString*)configureTextWithLink:(NSString*)text link:(GURL)link { + NSRange range; + + NSString* strippedText = ParseStringWithLink(text, &range); + + NSRange fullRange = NSMakeRange(0, strippedText.length); + NSMutableAttributedString* attributedText = + [[NSMutableAttributedString alloc] initWithString:strippedText]; + [attributedText addAttribute:NSForegroundColorAttributeName + value:[UIColor colorNamed:kTextSecondaryColor] + range:fullRange]; + + [attributedText + addAttribute:NSFontAttributeName + value:[UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] + range:fullRange]; + + if (range.location != NSNotFound && range.length != 0) { + NSURL* URL = net::NSURLWithGURL(link); + id linkValue = URL ? URL : @""; + [attributedText addAttribute:NSLinkAttributeName + value:linkValue + range:range]; + } + + return attributedText; +} + #pragma mark - PasswordStoreObserver - (void)loginsDidChange {
diff --git a/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm b/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm index 51262114..9510a1b 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm
@@ -39,6 +39,7 @@ #import "ios/chrome/browser/signin/authentication_service.h" #include "ios/chrome/browser/signin/authentication_service_factory.h" #import "ios/chrome/browser/signin/chrome_identity_service_observer_bridge.h" +#include "ios/chrome/browser/sync/sync_setup_service_factory.h" #include "ios/chrome/browser/system_flags.h" #import "ios/chrome/browser/ui/settings/cells/settings_cells_constants.h" #import "ios/chrome/browser/ui/settings/cells/settings_check_cell.h" @@ -68,9 +69,12 @@ #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" +#import "ios/chrome/common/ui/elements/popover_label_view_controller.h" #import "ios/chrome/common/ui/reauthentication/reauthentication_module.h" #import "ios/chrome/common/ui/util/constraints_ui_util.h" +#include "ios/chrome/grit/ios_chromium_strings.h" #include "ios/chrome/grit/ios_strings.h" +#import "net/base/mac/url_conversions.h" #include "ui/base/l10n/l10n_util_mac.h" #include "url/gurl.h" @@ -175,6 +179,7 @@ PasswordExportActivityViewControllerDelegate, PasswordsConsumer, PasswordIssuesCoordinatorDelegate, + PopoverLabelViewControllerDelegate, UISearchControllerDelegate, UISearchBarDelegate, SuccessfulReauthTimeAccessor> { @@ -268,9 +273,13 @@ DCHECK(_passwordStore); _passwordCheck = IOSChromePasswordCheckManagerFactory::GetForBrowserState(_browserState); - _mediator = - [[PasswordsMediator alloc] initWithPasswordStore:_passwordStore - passwordCheckManager:_passwordCheck.get()]; + _mediator = [[PasswordsMediator alloc] + initWithPasswordStore:_passwordStore + passwordCheckManager:_passwordCheck + authService:AuthenticationServiceFactory::GetForBrowserState( + _browserState) + syncService:SyncSetupServiceFactory::GetForBrowserState( + _browserState)]; _mediator.consumer = self; _passwordManagerEnabled = [[PrefBackedBoolean alloc] initWithPrefService:_browserState->GetPrefs() @@ -576,6 +585,13 @@ return passwordItem; } +#pragma mark - PopoverLabelViewControllerDelegate + +- (void)didTapLinkURL:(NSURL*)URL { + GURL convertedURL = net::GURLWithNSURL(URL); + [self view:nil didTapLinkURL:convertedURL]; +} + #pragma mark - BooleanObserver - (void)booleanDidChange:(id<ObservableBoolean>)observableBoolean { @@ -629,6 +645,28 @@ UIPopoverArrowDirectionAny; } +// Called when user tapped on the information button of the password check +// item. Shows popover with detailed description of an error. +- (void)didTapPasswordCheckInfoButton:(UIButton*)buttonView { + NSAttributedString* info = [_mediator passwordCheckErrorInfo]; + // If no info returned by mediator handle this tap as tap on a cell. + if (!info) { + [self showPasswordIssuesPage]; + return; + } + + PopoverLabelViewController* errorInfoPopover = + [[PopoverLabelViewController alloc] initWithPrimaryAttributedString:info + secondaryAttributedString:nil]; + errorInfoPopover.delegate = self; + + errorInfoPopover.popoverPresentationController.sourceView = buttonView; + errorInfoPopover.popoverPresentationController.sourceRect = buttonView.bounds; + errorInfoPopover.popoverPresentationController.permittedArrowDirections = + UIPopoverArrowDirectionAny; + [self presentViewController:errorInfoPopover animated:YES completion:nil]; +} + #pragma mark - PasswordsConsumer - (void)setPasswordCheckUIState:(PasswordCheckUIState)state { @@ -884,6 +922,7 @@ case PasswordCheckStateSafe: case PasswordCheckStateUnSafe: case PasswordCheckStateDefault: + case PasswordCheckStateError: _checkForProblemsItem.textColor = [UIColor colorNamed:kBlueColor]; _checkForProblemsItem.accessibilityTraits &= ~UIAccessibilityTraitNotEnabled; @@ -916,6 +955,7 @@ _passwordProblemsItem.trailingImage = nil; _passwordProblemsItem.enabled = YES; _passwordProblemsItem.indicatorHidden = YES; + _passwordProblemsItem.infoButtonHidden = YES; _passwordProblemsItem.accessoryType = UITableViewCellAccessoryNone; _passwordProblemsItem.detailText = l10n_util::GetNSString(IDS_IOS_CHECK_PASSWORDS_DESCRIPTION); @@ -952,7 +992,12 @@ [UIColor colorNamed:kGreenColor]; break; } - case PasswordCheckStateDefault: { + case PasswordCheckStateDefault: + break; + case PasswordCheckStateError: { + _passwordProblemsItem.detailText = + l10n_util::GetNSString(IDS_IOS_PASSWORD_CHECK_ERROR); + _passwordProblemsItem.infoButtonHidden = NO; break; } } @@ -1276,6 +1321,15 @@ forControlEvents:UIControlEventTouchUpInside]; break; } + case ItemTypePasswordCheckStatus: { + SettingsCheckCell* passwordCheckCell = + base::mac::ObjCCastStrict<SettingsCheckCell>(cell); + [passwordCheckCell.infoButton + addTarget:self + action:@selector(didTapPasswordCheckInfoButton:) + forControlEvents:UIControlEventTouchUpInside]; + break; + } } return cell; }
diff --git a/ios/chrome/browser/ui/settings/password/passwords_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/password/passwords_table_view_controller_unittest.mm index 9bbba3af..3b67139 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_table_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_table_view_controller_unittest.mm
@@ -31,6 +31,7 @@ #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" +#include "ios/chrome/grit/ios_chromium_strings.h" #include "ios/chrome/grit/ios_strings.h" #include "ios/web/public/test/web_task_environment.h" #include "testing/gmock/include/gmock/gmock.h" @@ -590,6 +591,26 @@ EXPECT_FALSE(checkPassword.trailingImage); } +// Test verifies error state of password check cell. +TEST_P(PasswordsTableViewControllerTest, PasswordCheckStateError) { + if (!GetParam().password_check_enabled) + return; + + ChangePasswordCheckState(PasswordCheckStateError); + + CheckTextCellTextWithId(IDS_IOS_CHECK_PASSWORDS_NOW_BUTTON, + GetSectionIndex(PasswordCheck), 1); + CheckDetailItemTextWithIds(IDS_IOS_CHECK_PASSWORDS, + IDS_IOS_PASSWORD_CHECK_ERROR, + GetSectionIndex(PasswordCheck), 0); + SettingsCheckItem* checkPassword = + GetTableViewItem(GetSectionIndex(PasswordCheck), 0); + EXPECT_TRUE(checkPassword.enabled); + EXPECT_TRUE(checkPassword.indicatorHidden); + EXPECT_FALSE(checkPassword.trailingImage); + EXPECT_FALSE(checkPassword.infoButtonHidden); +} + // Test verifies tapping start with no saved passwords has no effect. TEST_P(PasswordsTableViewControllerTest, DisabledPasswordCheck) { if (!GetParam().password_check_enabled)
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn index 38d520b..144ba5ac 100644 --- a/ios/chrome/browser/web/BUILD.gn +++ b/ios/chrome/browser/web/BUILD.gn
@@ -347,6 +347,14 @@ ] } +source_set("constants") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "lookalike_url_constants.h", + "lookalike_url_constants.mm", + ] +} + source_set("eg_test_support+eg2") { defines = [ "CHROME_EARL_GREY_2" ] configs += [ @@ -355,7 +363,10 @@ ] testonly = true - sources = [ "progress_indicator_app_interface.h" ] + sources = [ + "lookalike_url_app_interface.h", + "progress_indicator_app_interface.h", + ] deps = [ "//ios/chrome/test/earl_grey:eg_test_support+eg2", @@ -372,15 +383,23 @@ defines = [ "CHROME_EARL_GREY_2" ] sources = [ + "lookalike_url_app_interface.h", + "lookalike_url_app_interface.mm", "progress_indicator_app_interface.h", "progress_indicator_app_interface.mm", ] deps = [ + ":constants", "//base", + "//components/lookalikes/core", + "//ios/chrome/test/app:test_support", + "//ios/components/security_interstitials/lookalikes", "//ios/testing/earl_grey:eg_app_support+eg2", "//ios/third_party/earl_grey2:app_framework+link", "//ios/third_party/material_components_ios", + "//ios/web/public", + "//net", ] } @@ -402,6 +421,7 @@ "forms_egtest.mm", "http_auth_egtest.mm", "js_print_egtest.mm", + "lookalike_url_egtest.mm", "navigation_egtest.mm", "progress_indicator_egtest.mm", "push_and_replace_state_navigation_egtest.mm", @@ -414,6 +434,7 @@ ] deps = [ + ":constants", ":eg_test_support+eg2", "//components/content_settings/core/common", "//components/strings",
diff --git a/ios/chrome/browser/web/lookalike_url_app_interface.h b/ios/chrome/browser/web/lookalike_url_app_interface.h new file mode 100644 index 0000000..a4f864c --- /dev/null +++ b/ios/chrome/browser/web/lookalike_url_app_interface.h
@@ -0,0 +1,28 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_WEB_LOOKALIKE_URL_APP_INTERFACE_H_ +#define IOS_CHROME_BROWSER_WEB_LOOKALIKE_URL_APP_INTERFACE_H_ + +#import <Foundation/Foundation.h> + +// The app interface for lookalike URL blocking page tests. It sets +// up LookalikeUrlDecider, which does the following: +// - Lets a navigation proceed if the domain is explicitly allowed +// - Cancels the navigation and shows error page with a suggested URL +// for the /lookalike.html path +// - Cancels the navigation and shows error page with no suggested URL +// for the /lookalike-empty.html path +// - Allows other navigations to proceed +@interface LookalikeUrlAppInterface : NSObject + +// Sets up lookalike policy decider. Used for testing. ++ (void)setUpLookalikeUrlDeciderForWebState; + +// Tear down lookalike policy decider. Used for testing. ++ (void)tearDownLookalikeUrlDeciderForWebState; + +@end + +#endif // IOS_CHROME_BROWSER_WEB_LOOKALIKE_URL_APP_INTERFACE_H_
diff --git a/ios/chrome/browser/web/lookalike_url_app_interface.mm b/ios/chrome/browser/web/lookalike_url_app_interface.mm new file mode 100644 index 0000000..b2ec43e --- /dev/null +++ b/ios/chrome/browser/web/lookalike_url_app_interface.mm
@@ -0,0 +1,90 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/web/lookalike_url_app_interface.h" + +#include "components/lookalikes/core/lookalike_url_util.h" +#import "ios/chrome/browser/web/lookalike_url_constants.h" +#import "ios/chrome/test/app/chrome_test_util.h" +#import "ios/chrome/test/app/tab_test_util.h" +#include "ios/components/security_interstitials/lookalikes/lookalike_url_container.h" +#include "ios/components/security_interstitials/lookalikes/lookalike_url_error.h" +#include "ios/components/security_interstitials/lookalikes/lookalike_url_tab_allow_list.h" +#import "ios/web/public/navigation/web_state_policy_decider.h" +#import "ios/web/public/web_state_user_data.h" +#import "net/base/mac/url_conversions.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { + +// This decider determines whether a URL is a lookalike. If so, it cancels +// navigation and shows an error. +class LookalikeUrlDecider : public web::WebStatePolicyDecider, + public web::WebStateUserData<LookalikeUrlDecider> { + public: + LookalikeUrlDecider(web::WebState* web_state) + : web::WebStatePolicyDecider(web_state), web_state_(web_state) {} + + void ShouldAllowResponse( + NSURLResponse* response, + bool for_main_frame, + web::WebStatePolicyDecider::PolicyDecisionCallback callback) override { + LookalikeUrlContainer* lookalike_container = + LookalikeUrlContainer::FromWebState(web_state_); + LookalikeUrlTabAllowList* allow_list = + LookalikeUrlTabAllowList::FromWebState(web_state_); + + GURL response_url = net::GURLWithNSURL(response.URL); + if (allow_list->IsDomainAllowed(response_url.host())) { + return std::move(callback).Run( + web::WebStatePolicyDecider::PolicyDecision::Allow()); + } + if (response_url.path() == kLookalikePagePathForTesting) { + GURL::Replacements safeReplacements; + safeReplacements.SetPathStr("echo"); + lookalike_container->SetLookalikeUrlInfo( + response_url.ReplaceComponents(safeReplacements), response_url, + LookalikeUrlMatchType::kSkeletonMatchTop5k); + std::move(callback).Run(CreateLookalikeErrorDecision()); + return; + } + if (response_url.path() == kLookalikePageEmptyUrlPathForTesting) { + lookalike_container->SetLookalikeUrlInfo( + GURL::EmptyGURL(), response_url, + LookalikeUrlMatchType::kSkeletonMatchTop5k); + std::move(callback).Run(CreateLookalikeErrorDecision()); + return; + } + return std::move(callback).Run( + web::WebStatePolicyDecider::PolicyDecision::Allow()); + } + + WEB_STATE_USER_DATA_KEY_DECL(); + + private: + web::WebState* web_state_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(LookalikeUrlDecider); +}; + +WEB_STATE_USER_DATA_KEY_IMPL(LookalikeUrlDecider) + +} // namespace + +@implementation LookalikeUrlAppInterface + ++ (void)setUpLookalikeUrlDeciderForWebState { + LookalikeUrlDecider::CreateForWebState( + chrome_test_util::GetCurrentWebState()); +} + ++ (void)tearDownLookalikeUrlDeciderForWebState { + LookalikeUrlDecider::RemoveFromWebState( + chrome_test_util::GetCurrentWebState()); +} + +@end
diff --git a/ios/chrome/browser/web/lookalike_url_constants.h b/ios/chrome/browser/web/lookalike_url_constants.h new file mode 100644 index 0000000..c8b88d4 --- /dev/null +++ b/ios/chrome/browser/web/lookalike_url_constants.h
@@ -0,0 +1,14 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_WEB_LOOKALIKE_URL_CONSTANTS_H_ +#define IOS_CHROME_BROWSER_WEB_LOOKALIKE_URL_CONSTANTS_H_ + +// Constant used for testing a lookalike URL interstitial. +extern const char kLookalikePagePathForTesting[]; + +// Constant used for testing a lookalike URL interstitial with no suggested URL. +extern const char kLookalikePageEmptyUrlPathForTesting[]; + +#endif // IOS_CHROME_BROWSER_WEB_LOOKALIKE_URL_CONSTANTS_H_
diff --git a/ios/chrome/browser/web/lookalike_url_constants.mm b/ios/chrome/browser/web/lookalike_url_constants.mm new file mode 100644 index 0000000..eec1f20d --- /dev/null +++ b/ios/chrome/browser/web/lookalike_url_constants.mm
@@ -0,0 +1,12 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/web/lookalike_url_constants.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +const char kLookalikePagePathForTesting[] = "/lookalike.html"; +const char kLookalikePageEmptyUrlPathForTesting[] = "/lookalike-empty.html";
diff --git a/ios/chrome/browser/web/lookalike_url_egtest.mm b/ios/chrome/browser/web/lookalike_url_egtest.mm new file mode 100644 index 0000000..ef0147cc --- /dev/null +++ b/ios/chrome/browser/web/lookalike_url_egtest.mm
@@ -0,0 +1,300 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <string> + +#include "base/bind.h" +#include "base/strings/stringprintf.h" +#include "components/strings/grit/components_strings.h" +#import "ios/chrome/browser/web/lookalike_url_app_interface.h" +#import "ios/chrome/browser/web/lookalike_url_constants.h" +#import "ios/chrome/test/earl_grey/chrome_earl_grey.h" +#import "ios/chrome/test/earl_grey/chrome_matchers.h" +#import "ios/chrome/test/earl_grey/chrome_test_case.h" +#import "ios/testing/earl_grey/earl_grey_test.h" +#include "ios/testing/embedded_test_server_handlers.h" +#include "ios/web/common/features.h" +#include "ios/web/public/test/element_selector.h" +#include "net/test/embedded_test_server/default_handlers.h" +#include "net/test/embedded_test_server/http_request.h" +#include "net/test/embedded_test_server/http_response.h" +#include "net/test/embedded_test_server/request_handler_util.h" +#include "ui/base/l10n/l10n_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +#if defined(CHROME_EARL_GREY_2) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++98-compat-extra-semi" +GREY_STUB_CLASS_IN_APP_MAIN_QUEUE(LookalikeUrlAppInterface); +#pragma clang diagnostic pop +#endif // defined(CHROME_EARL_GREY_2) + +using chrome_test_util::BackButton; +using chrome_test_util::ForwardButton; + +namespace { +// Relative paths used for a page that opens a lookalike in a new tab. +const char kLookalikeInNewTab[] = "/lookalike-newtab.html"; + +// Text that is found on the lookalike page. +const char kLookalikeContent[] = "Lookalike - Safety warning bypassed"; +// Text that is found on a page that opens a lookalike in a new tab. +const char kLookalikeInNewTabContent[] = "New tab"; +} // namespace + +// Tests lookalike URL blocking. +@interface LookalikeUrlTestCase : ChromeTestCase { + // A URL that is treated as a lookalike. + GURL _lookalikeURL; + // A URL that is treated as a safe page. + GURL _safeURL; + // Text that is found on the safe page. + std::string _safeContent; + // Text that is found on the lookalike interstitial. + std::string _lookalikeBlockingPageContent; +} +@end + +@implementation LookalikeUrlTestCase + +- (AppLaunchConfiguration)appConfigurationForTestCase { + AppLaunchConfiguration config; + config.features_enabled.push_back( + web::features::kIOSLookalikeUrlNavigationSuggestionsUI); + config.features_enabled.push_back(web::features::kSSLCommittedInterstitials); + config.relaunch_policy = NoForceRelaunchAndResetState; + return config; +} + +- (void)setUp { + [super setUp]; + [LookalikeUrlAppInterface setUpLookalikeUrlDeciderForWebState]; + std::string lookalikeHTML = + base::StringPrintf("<html><body>%s</body></html>", kLookalikeContent); + self.testServer->RegisterRequestHandler(base::BindRepeating( + &net::test_server::HandlePrefixedRequest, kLookalikePagePathForTesting, + base::BindRepeating(&testing::HandlePageWithHtml, lookalikeHTML))); + self.testServer->RegisterRequestHandler(base::BindRepeating( + &net::test_server::HandlePrefixedRequest, + kLookalikePageEmptyUrlPathForTesting, + base::BindRepeating(&testing::HandlePageWithHtml, lookalikeHTML))); + std::string lookalikeNewTabHTML = base::StringPrintf( + "<html><body><a target=\"_blank\" href=\"%s\" " + "id=\"lookalike-newtab\">%s</a></body></html>", + kLookalikePageEmptyUrlPathForTesting, kLookalikeInNewTabContent); + self.testServer->RegisterRequestHandler(base::BindRepeating( + &net::test_server::HandlePrefixedRequest, kLookalikeInNewTab, + base::BindRepeating(&testing::HandlePageWithHtml, lookalikeNewTabHTML))); + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); + _safeURL = self.testServer->GetURL("/echo"); + _safeContent = "Echo"; + _lookalikeURL = self.testServer->GetURL(kLookalikePagePathForTesting); + _lookalikeBlockingPageContent = + l10n_util::GetStringUTF8(IDS_LOOKALIKE_URL_PRIMARY_PARAGRAPH); +} + +- (void)tearDown { + [LookalikeUrlAppInterface tearDownLookalikeUrlDeciderForWebState]; + [super tearDown]; +} + +// Tests that non-lookalike URLs are not blocked. +- (void)testSafePage { + [ChromeEarlGrey loadURL:_safeURL]; + [ChromeEarlGrey waitForWebStateContainingText:_safeContent]; +} + +// Tests that a lookalike URL navigation is blocked, and the Go to suggested +// site button works. Also tests that navigating back to the site shows the +// interstitial and that navigating forward again works. +- (void)testLookalikeUrlPage { + // Load the lookalike page and verify a warning is shown. + [ChromeEarlGrey loadURL:_lookalikeURL]; + [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + + // Tap on the "Go to" button and verify that the suggested page + // contents are loaded. + [ChromeEarlGrey tapWebStateElementWithID:@"primary-button"]; + [ChromeEarlGrey waitForWebStateContainingText:_safeContent]; + + // Verify that the warning is shown when navigating back and that safe + // content is shown when navigating forward again. + [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()]; + [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + [[EarlGrey selectElementWithMatcher:ForwardButton()] + performAction:grey_tap()]; + [ChromeEarlGrey waitForWebStateContainingText:_safeContent]; +} + +// Tests that a lookalike URL navigation is blocked, and the text link for +// suggested site works. Also tests that navigating back to the site shows +// the interstitial and that navigating forward again works. +- (void)testLookalikeUrlPageSiteLink { + // Load the lookalike page and verify a warning is shown. + [ChromeEarlGrey loadURL:_lookalikeURL]; + [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + + // Tap on the site suggestion link and verify that the suggested page + // contents are loaded. + [ChromeEarlGrey tapWebStateElementWithID:@"dont-proceed-link"]; + [ChromeEarlGrey waitForWebStateContainingText:_safeContent]; + + // Verify that the warning is shown when navigating back and that safe + // content is shown when navigating forward again. + [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()]; + [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + [[EarlGrey selectElementWithMatcher:ForwardButton()] + performAction:grey_tap()]; + [ChromeEarlGrey waitForWebStateContainingText:_safeContent]; +} + +// Tests that Back to safety works when there is no suggested URL. Also tests +// that navigating forward to the site shows the interstitial and that +// navigating back again works. +- (void)testLookalikeUrlPageNoSuggestion { + // Navigate to safe page first to enable later verification of + // back/forward navigation. + [ChromeEarlGrey loadURL:_safeURL]; + [ChromeEarlGrey waitForWebStateContainingText:_safeContent]; + + // Navigate to a lookalike page with no suggestion and verify that a warning + // and the correct button is shown. + [ChromeEarlGrey + loadURL:self.testServer->GetURL(kLookalikePageEmptyUrlPathForTesting)]; + [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + [ChromeEarlGrey + waitForWebStateContainingText:l10n_util::GetStringUTF8( + IDS_LOOKALIKE_URL_BACK_TO_SAFETY)]; + + // Tap on the "Back to safety" button and verify that the safe content + // is loaded. + [ChromeEarlGrey tapWebStateElementWithID:@"primary-button"]; + [ChromeEarlGrey waitForWebStateContainingText:_safeContent]; + + // Verify that the warning is shown when navigating forward and that safe + // content is shown when navigating back again. + [[EarlGrey selectElementWithMatcher:ForwardButton()] + performAction:grey_tap()]; + [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()]; + [ChromeEarlGrey waitForWebStateContainingText:_safeContent]; +} + +// Tests that Close page works when there is no suggested URL and unable +// to go back. +- (void)testLookalikeUrlPageNoSuggestionClosePage { + // First navigate to a page that will open the lookalike URL in a new tab, + // then open the lookalike page. + [ChromeEarlGrey loadURL:self.testServer->GetURL(kLookalikeInNewTab)]; + [ChromeEarlGrey tapWebStateElementWithID:@"lookalike-newtab"]; + + // Verify that the new tab has loaded before setting up the policy decider + // for the new web state. Then reload to make sure the interstitial is + // displayed. + [ChromeEarlGrey waitForWebStateContainingText:kLookalikeContent]; + [LookalikeUrlAppInterface setUpLookalikeUrlDeciderForWebState]; + [ChromeEarlGrey reload]; + + // Verify that a warning and the correct button is shown. + [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + [ChromeEarlGrey + waitForWebStateContainingText:l10n_util::GetStringUTF8( + IDS_LOOKALIKE_URL_CLOSE_PAGE)]; + + // Tap on the "Close" button and verify that the page closes. + [ChromeEarlGrey tapWebStateElementWithID:@"primary-button"]; + [ChromeEarlGrey waitForWebStateContainingText:kLookalikeInNewTabContent]; +} + +// Tests proceeding past the lookalike warning and that opening the page in +// a new tab will bypass the warning. +- (void)testProceedingPastLookalikeUrlWarning { + // Load the lookalike page and verify a warning is shown. + [ChromeEarlGrey loadURL:_lookalikeURL]; + [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + + // Tap on the link to ignore the warning, and verify that the page is loaded. + [ChromeEarlGrey tapWebStateElementWithID:@"proceed-button"]; + [ChromeEarlGrey waitForWebStateContainingText:kLookalikeContent]; + + // In a new tab, the warning should not be shown. + [ChromeEarlGrey openNewTab]; + [ChromeEarlGrey loadURL:_lookalikeURL]; + [ChromeEarlGrey waitForWebStateContainingText:kLookalikeContent]; +} + +// Tests displaying a warning for an lookalike URL, proceeding past the warning, +// and navigating back/forward, in incognito. +- (void)testProceedingPastLookalikeWarningInIncognito { + [ChromeEarlGrey openNewIncognitoTab]; + [LookalikeUrlAppInterface setUpLookalikeUrlDeciderForWebState]; + + // Navigate to safe page first to enable later verification of + // back/forward navigation. + [ChromeEarlGrey loadURL:_safeURL]; + [ChromeEarlGrey waitForWebStateContainingText:_safeContent]; + + // Load the lookalike page and verify a warning is shown. + [ChromeEarlGrey loadURL:_lookalikeURL]; + [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + + // Tap on the link to ignore the warning, and verify that the page is loaded. + [ChromeEarlGrey tapWebStateElementWithID:@"proceed-button"]; + [ChromeEarlGrey waitForWebStateContainingText:kLookalikeContent]; + + // Verify that no warning is shown when navigating back and then forward to + // the unsafe page. + [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()]; + [ChromeEarlGrey waitForWebStateContainingText:_safeContent]; + [[EarlGrey selectElementWithMatcher:ForwardButton()] + performAction:grey_tap()]; + [ChromeEarlGrey waitForWebStateContainingText:kLookalikeContent]; +} + +// Tests that performing session restoration to a lookalike URL warning page +// preserves navigation history. +- (void)testRestoreToWarningPagePreservesHistory { + // Build up navigation history that consists of a safe URL, a warning page, + // and the suggested safe URL. + [ChromeEarlGrey loadURL:self.testServer->GetURL("/echoall")]; + std::string safeContent2 = "Request Body"; + [ChromeEarlGrey waitForWebStateContainingText:safeContent2]; + + // Load the lookalike URL page and verify a warning is shown. + [ChromeEarlGrey loadURL:_lookalikeURL]; + [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + + // Tap on the "Go to" button and verify that the suggested page contents + // are loaded. + [ChromeEarlGrey tapWebStateElementWithID:@"primary-button"]; + [ChromeEarlGrey waitForWebStateContainingText:_safeContent]; + + // Navigate back to the interstitial. Now both the back list and the forward + // list are non-empty. + [ChromeEarlGrey goBack]; + [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + + // Do a session restoration and verify that all navigation history is + // preserved. For this test, the policy decider doesn't get installed for + // the first page load, so expect the page content instead of the warning. + [ChromeEarlGrey triggerRestoreViaTabGridRemoveAllUndo]; + [ChromeEarlGrey waitForWebStateContainingText:kLookalikeContent]; + [LookalikeUrlAppInterface setUpLookalikeUrlDeciderForWebState]; + + [ChromeEarlGrey goBack]; + [ChromeEarlGrey waitForWebStateContainingText:safeContent2]; + + // The policy decider will trigger at this point, so the warning should + // be shown. + [ChromeEarlGrey goForward]; + [ChromeEarlGrey waitForWebStateContainingText:_lookalikeBlockingPageContent]; + + [ChromeEarlGrey goForward]; + [ChromeEarlGrey waitForWebStateContainingText:_safeContent]; +} + +@end
diff --git a/ios/components/security_interstitials/lookalikes/lookalike_url_controller_client.mm b/ios/components/security_interstitials/lookalikes/lookalike_url_controller_client.mm index a11b3eb..769ff52a 100644 --- a/ios/components/security_interstitials/lookalikes/lookalike_url_controller_client.mm +++ b/ios/components/security_interstitials/lookalikes/lookalike_url_controller_client.mm
@@ -46,9 +46,10 @@ if (!safe_url_.is_valid()) { IOSBlockingPageControllerClient::GoBack(); } else { - // TODO(crbug.com/1058898): Replace the last committed navigation - // (the interstitial) with the safe URL navigation to prevent the - // back button from returning to the bad site. + // For simplicity and because replacement doesn't always work, the + // navigation to the safe URL does not replace the navigation to + // the interstitial. However, this is acceptable since if a user + // navigates back to the lookalike, the interstitial will be shown. OpenUrlInCurrentTab(safe_url_); } }
diff --git a/ios/components/security_interstitials/lookalikes/lookalike_url_error.h b/ios/components/security_interstitials/lookalikes/lookalike_url_error.h index 5183cf70..e8606a0f 100644 --- a/ios/components/security_interstitials/lookalikes/lookalike_url_error.h +++ b/ios/components/security_interstitials/lookalikes/lookalike_url_error.h
@@ -7,10 +7,16 @@ #import <Foundation/Foundation.h> +#import "ios/web/public/navigation/web_state_policy_decider.h" + // The error domain for lookalike URL errors. extern const NSErrorDomain kLookalikeUrlErrorDomain; // Error code for navigations to lookalike URLs. extern const NSInteger kLookalikeUrlErrorCode; +// Creates a PolicyDecision that cancels a navigation to show a lookalike +// error. +web::WebStatePolicyDecider::PolicyDecision CreateLookalikeErrorDecision(); + #endif // IOS_COMPONENTS_SECURITY_INTERSTITIALS_LOOKALIKES_LOOKALIKE_URL_ERROR_H_
diff --git a/ios/components/security_interstitials/lookalikes/lookalike_url_error.mm b/ios/components/security_interstitials/lookalikes/lookalike_url_error.mm index fffae48..00e19439 100644 --- a/ios/components/security_interstitials/lookalikes/lookalike_url_error.mm +++ b/ios/components/security_interstitials/lookalikes/lookalike_url_error.mm
@@ -11,3 +11,10 @@ const NSErrorDomain kLookalikeUrlErrorDomain = @"com.google.chrome.lookalike_url"; const NSInteger kLookalikeUrlErrorCode = -1003; + +web::WebStatePolicyDecider::PolicyDecision CreateLookalikeErrorDecision() { + return web::WebStatePolicyDecider::PolicyDecision::CancelAndDisplayError( + [NSError errorWithDomain:kLookalikeUrlErrorDomain + code:kLookalikeUrlErrorCode + userInfo:nil]); +}
diff --git a/ios/components/security_interstitials/lookalikes/lookalike_url_tab_helper.mm b/ios/components/security_interstitials/lookalikes/lookalike_url_tab_helper.mm index 555ed74e..371c01e 100644 --- a/ios/components/security_interstitials/lookalikes/lookalike_url_tab_helper.mm +++ b/ios/components/security_interstitials/lookalikes/lookalike_url_tab_helper.mm
@@ -19,15 +19,6 @@ #endif namespace { -// Creates a PolicyDecision that cancels a navigation to show a lookalike -// error. -web::WebStatePolicyDecider::PolicyDecision CreateLookalikeErrorDecision() { - return web::WebStatePolicyDecider::PolicyDecision::CancelAndDisplayError( - [NSError errorWithDomain:kLookalikeUrlErrorDomain - code:kLookalikeUrlErrorCode - userInfo:nil]); -} - // Creates a PolicyDecision that allows the navigation. web::WebStatePolicyDecider::PolicyDecision CreateAllowDecision() { return web::WebStatePolicyDecider::PolicyDecision::Allow(); @@ -50,7 +41,7 @@ return; } - // TODO(crbug.com/1058898): Create container and ReleaseInterstitialParams. + // TODO(crbug.com/1104386): Create container and ReleaseInterstitialParams. // Get stored interstitial parameters early. Doing so ensures that a // navigation to an irrelevant (for this interstitial's purposes) URL such as // chrome://settings while the lookalike interstitial is being shown clears @@ -78,7 +69,7 @@ return; } - // TODO(crbug.com/1058898): If this is a reload and if the current + // TODO(crbug.com/1104386): If this is a reload and if the current // URL is the last URL of the stored redirect chain, the interstitial // was probably reloaded. Stop the reload and navigate back to the // original lookalike URL so that the full checks are exercised again. @@ -91,7 +82,7 @@ return; } - // TODO(crbug.com/1058898): After site engagement has been componentized, + // TODO(crbug.com/1104384): After site engagement has been componentized, // fetch and set |engaged_sites| here so that an interstitial won't be // shown on engaged sites, and so that the interstitial will be shown on // lookalikes of engaged sites.
diff --git a/ios/web/web_state/js/resources/all_frames_context_menu.js b/ios/web/web_state/js/resources/all_frames_context_menu.js index 27b78bb44..ae5c39f 100644 --- a/ios/web/web_state/js/resources/all_frames_context_menu.js +++ b/ios/web/web_state/js/resources/all_frames_context_menu.js
@@ -247,20 +247,7 @@ if (currentElement.tagName.toLowerCase() === 'iframe' || currentElement.tagName.toLowerCase() === 'frame') { - // Check if the frame is in a different domain using only information - // visible to the current frame (i.e. currentElement.src) to avoid - // triggering a SecurityError in the console. - if (!__gCrWeb.common.isSameOrigin( - window.location.href, currentElement.src)) { - return currentElement; - } - var framePosition = getPositionInWindow(currentElement); - coordinates.viewPortX -= framePosition.x - coordinates.window.pageXOffset; - coordinates.viewPortY -= framePosition.y - coordinates.window.pageYOffset; - coordinates.window = currentElement.contentWindow; - coordinates.x -= framePosition.x + coordinates.window.pageXOffset; - coordinates.y -= framePosition.y + coordinates.window.pageYOffset; - return elementsFromCoordinates(coordinates.window.document, coordinates); + return currentElement; } if (currentElement.shadowRoot) { @@ -366,9 +353,10 @@ var payload = message.data; if (payload.hasOwnProperty('type') && payload.type == 'org.chromium.contextMenuMessage') { - __gCrWeb.findElementAtPointInPageCoordinates(payload.requestId, - payload.x, - payload.y); + __gCrWeb.findElementAtPointInPageCoordinates( + payload.requestId, + payload.x + window.pageXOffset, + payload.y + window.pageYOffset); } });
diff --git a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py index c88392e..25af94a4 100644 --- a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py +++ b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -689,8 +689,11 @@ value_name_cppname = (value, parameter_name, cpp_parameter_name) # TODO(crbug.com/1103623): Support more involved types. if mojom.IsEnumKind(kind): - # TODO(crbug.com/1103623): Pretty-print enums. - yield '%s->SetInteger("%s", static_cast<int>(%s));' % value_name_cppname + if self._IsTypemappedKind(kind) or IsNativeOnlyKind(kind): + yield '%s->SetInteger("%s", static_cast<int>(%s));' % value_name_cppname + else: + yield '%s->SetString("%s", base::trace_event::'\ + 'TracedValue::ValueToString(%s));' % value_name_cppname return if mojom.IsStringKind(kind): if self.for_blink:
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index a1828087..3a65c23 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -521,7 +521,6 @@ { "args": [ "--enable-features=BackForwardCache,BackForwardCacheNoTimeEviction,ServiceWorkerOnUI,ProactivelySwapBrowsingInstance", - "--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.android_browsertests.filter", "--gs-results-bucket=chromium-result-details", "--recover-devices" ], @@ -676,7 +675,6 @@ { "args": [ "--enable-features=BackForwardCache,BackForwardCacheNoTimeEviction,ServiceWorkerOnUI,ProactivelySwapBrowsingInstance", - "--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.content_shell_test_apk.filter", "--gs-results-bucket=chromium-result-details", "--recover-devices" ],
diff --git a/testing/buildbot/chromium.ci.json b/testing/buildbot/chromium.ci.json index 93402f2a..d7a114e 100644 --- a/testing/buildbot/chromium.ci.json +++ b/testing/buildbot/chromium.ci.json
@@ -166345,7 +166345,6 @@ { "args": [ "--enable-features=BackForwardCache,BackForwardCacheNoTimeEviction,ServiceWorkerOnUI,ProactivelySwapBrowsingInstance", - "--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.android_browsertests.filter", "--gs-results-bucket=chromium-result-details", "--recover-devices" ], @@ -166500,7 +166499,6 @@ { "args": [ "--enable-features=BackForwardCache,BackForwardCacheNoTimeEviction,ServiceWorkerOnUI,ProactivelySwapBrowsingInstance", - "--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.content_shell_test_apk.filter", "--gs-results-bucket=chromium-result-details", "--recover-devices" ],
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index a3900d8..c6ca12b 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -16,12 +16,6 @@ # $ for i in $(ls -1 testing/buildbot/filters/*.browser_tests.*filter ); \ # do echo " \"//$i\","; done | sort -source_set("android_browsertests_filters") { - testonly = true - - data = [ "//testing/buildbot/filters/bfcache.android_browsertests.filter" ] -} - source_set("cc_unittests_filters") { testonly = true @@ -111,10 +105,7 @@ source_set("content_shell_test_apk_filters") { testonly = true - data = [ - "//testing/buildbot/filters/bfcache.content_shell_test_apk.filter", - "//testing/buildbot/filters/android.emulator_m.content_shell_test_apk.filter", - ] + data = [ "//testing/buildbot/filters/android.emulator_m.content_shell_test_apk.filter" ] } source_set("content_unittests_filters") {
diff --git a/testing/buildbot/filters/bfcache.android_browsertests.filter b/testing/buildbot/filters/bfcache.android_browsertests.filter deleted file mode 100644 index 2d8f82a..0000000 --- a/testing/buildbot/filters/bfcache.android_browsertests.filter +++ /dev/null
@@ -1 +0,0 @@ -# These tests currently fail when run with --enable-features=BackForwardCache
diff --git a/testing/buildbot/filters/bfcache.content_shell_test_apk.filter b/testing/buildbot/filters/bfcache.content_shell_test_apk.filter deleted file mode 100644 index 2d8f82a..0000000 --- a/testing/buildbot/filters/bfcache.content_shell_test_apk.filter +++ /dev/null
@@ -1 +0,0 @@ -# These tests currently fail when run with --enable-features=BackForwardCache
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index ae642cdd..62ed4a3 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -294,7 +294,6 @@ 'bf_cache_android_browsertests': { 'args': [ '--enable-features=BackForwardCache,BackForwardCacheNoTimeEviction,ServiceWorkerOnUI,ProactivelySwapBrowsingInstance', - '--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.android_browsertests.filter' ], 'test': 'android_browsertests', }, @@ -315,7 +314,6 @@ 'bf_cache_content_shell_test_apk': { 'args': [ '--enable-features=BackForwardCache,BackForwardCacheNoTimeEviction,ServiceWorkerOnUI,ProactivelySwapBrowsingInstance', - '--test-launcher-filter-file=../../testing/buildbot/filters/bfcache.content_shell_test_apk.filter' ], 'swarming': { 'shards': 5,
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 745d31c..76f7b2a 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -5328,6 +5328,21 @@ ] } ], + "PrivacyElevatedAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PrivacyElevatedAndroid" + ] + } + ] + } + ], "ProactivelySwapBrowsingInstance": [ { "platforms": [
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index 7bfdbb57..23bb354 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -81,6 +81,7 @@ "loader/navigation_predictor.mojom", "loader/pause_subresource_loading_handle.mojom", "loader/previews_resource_loading_hints.mojom", + "loader/referrer.mojom", "loader/request_context_frame_type.mojom", "loader/resource_load_info.mojom", "loader/resource_load_info_notifier.mojom", @@ -123,7 +124,6 @@ "push_messaging/push_messaging_status.mojom", "quota/quota_manager_host.mojom", "quota/quota_types.mojom", - "referrer.mojom", "renderer_preference_watcher.mojom", "renderer_preferences.mojom", "reporting/reporting.mojom",
diff --git a/third_party/blink/public/mojom/fetch/fetch_api_request.mojom b/third_party/blink/public/mojom/fetch/fetch_api_request.mojom index 175bbf6..f1431686 100644 --- a/third_party/blink/public/mojom/fetch/fetch_api_request.mojom +++ b/third_party/blink/public/mojom/fetch/fetch_api_request.mojom
@@ -14,7 +14,7 @@ import "services/network/public/mojom/url_loader.mojom"; import "third_party/blink/public/mojom/blob/serialized_blob.mojom"; import "third_party/blink/public/mojom/loader/request_context_frame_type.mojom"; -import "third_party/blink/public/mojom/referrer.mojom"; +import "third_party/blink/public/mojom/loader/referrer.mojom"; import "url/mojom/url.mojom";
diff --git a/third_party/blink/public/mojom/frame/frame.mojom b/third_party/blink/public/mojom/frame/frame.mojom index 994e24b..b8fce51 100644 --- a/third_party/blink/public/mojom/frame/frame.mojom +++ b/third_party/blink/public/mojom/frame/frame.mojom
@@ -37,7 +37,7 @@ import "third_party/blink/public/mojom/input/focus_type.mojom"; import "third_party/blink/public/mojom/input/scroll_direction.mojom"; import "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom"; -import "third_party/blink/public/mojom/referrer.mojom"; +import "third_party/blink/public/mojom/loader/referrer.mojom"; import "third_party/blink/public/mojom/timing/resource_timing.mojom"; import "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom"; import "third_party/blink/public/mojom/web_feature/web_feature.mojom";
diff --git a/third_party/blink/public/mojom/referrer.mojom b/third_party/blink/public/mojom/loader/referrer.mojom similarity index 100% rename from third_party/blink/public/mojom/referrer.mojom rename to third_party/blink/public/mojom/loader/referrer.mojom
diff --git a/third_party/blink/public/mojom/portal/portal.mojom b/third_party/blink/public/mojom/portal/portal.mojom index 731da40..9b6a7279 100644 --- a/third_party/blink/public/mojom/portal/portal.mojom +++ b/third_party/blink/public/mojom/portal/portal.mojom
@@ -7,7 +7,7 @@ import "mojo/public/mojom/base/time.mojom"; import "mojo/public/mojom/base/unguessable_token.mojom"; import "third_party/blink/public/mojom/messaging/transferable_message.mojom"; -import "third_party/blink/public/mojom/referrer.mojom"; +import "third_party/blink/public/mojom/loader/referrer.mojom"; import "url/mojom/origin.mojom"; import "url/mojom/url.mojom"; import "url/mojom/origin.mojom";
diff --git a/third_party/blink/public/mojom/prerender/prerender.mojom b/third_party/blink/public/mojom/prerender/prerender.mojom index 6b1564e..1ff74e8 100644 --- a/third_party/blink/public/mojom/prerender/prerender.mojom +++ b/third_party/blink/public/mojom/prerender/prerender.mojom
@@ -4,7 +4,7 @@ module blink.mojom; -import "third_party/blink/public/mojom/referrer.mojom"; +import "third_party/blink/public/mojom/loader/referrer.mojom"; import "ui/gfx/geometry/mojom/geometry.mojom"; import "url/mojom/origin.mojom"; import "url/mojom/url.mojom";
diff --git a/third_party/blink/public/platform/web_isolated_world_info.h b/third_party/blink/public/platform/web_isolated_world_info.h index 71c66ec..1f1ba5f6 100644 --- a/third_party/blink/public/platform/web_isolated_world_info.h +++ b/third_party/blink/public/platform/web_isolated_world_info.h
@@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "third_party/blink/public/platform/web_common.h" #include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/public/platform/web_string.h" +#include "v8/include/v8.h" #ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_ISOLATED_WORLD_INFO_H_ #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_ISOLATED_WORLD_INFO_H_ @@ -49,6 +51,19 @@ WebString stable_id; }; +// Sets up an isolated world by associating a |world_id| with |info|. +// worldID must be > 0 (as 0 represents the main world). +// worldID must be < kEmbedderWorldIdLimit, high number used internally. +BLINK_EXPORT void SetIsolatedWorldInfo(int32_t world_id, + const WebIsolatedWorldInfo& info); + +// Returns the stable ID that was set with SetIsolatedWorldInfo. +BLINK_EXPORT WebString GetIsolatedWorldStableId(v8::Local<v8::Context>); + +// Returns the human readable name that was set with SetIsolatedWorldInfo. +BLINK_EXPORT WebString + GetIsolatedWorldHumanReadableName(v8::Local<v8::Context>); + } // namespace blink #endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_ISOLATED_WORLD_INFO_H_
diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h index 179221fb..a6b33cc 100644 --- a/third_party/blink/public/web/web_local_frame.h +++ b/third_party/blink/public/web/web_local_frame.h
@@ -316,21 +316,6 @@ // Document. virtual void ClearIsolatedWorldCSPForTesting(int32_t world_id) = 0; - // Sets up an isolated world by associating a |world_id| with |info|. - // worldID must be > 0 (as 0 represents the main world). - // worldID must be < kEmbedderWorldIdLimit, high number used internally. - // TODO(karandeepb): This modifies the global isolated world info and hence - // should ideally be moved out of WebLocalFrame. - virtual void SetIsolatedWorldInfo(int32_t world_id, - const WebIsolatedWorldInfo& info) = 0; - - // Returns the stable ID that was set with SetIsolatedWorldInfo. - virtual WebString GetIsolatedWorldStableId(v8::Local<v8::Context>) const = 0; - - // Returns the human readable name that was set with SetIsolatedWorldInfo. - virtual WebString GetIsolatedWorldHumanReadableName( - v8::Local<v8::Context>) const = 0; - // Executes script in the context of the current page and returns the value // that the script evaluated to. // DEPRECATED: Use WebLocalFrame::requestExecuteScriptAndReturnValue.
diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc index 17ebe5e..4e2f84be 100644 --- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc +++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
@@ -31,6 +31,7 @@ #include "third_party/blink/renderer/bindings/core/v8/local_window_proxy.h" #include "base/debug/dump_without_crashing.h" +#include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h" #include "third_party/blink/renderer/bindings/core/v8/script_controller.h" #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h" @@ -181,22 +182,23 @@ V8String(GetIsolate(), csp->EvalDisabledErrorMessage())); } - const SecurityOrigin* origin = nullptr; + scoped_refptr<const SecurityOrigin> origin; if (world_->IsMainWorld()) { // ActivityLogger for main world is updated within updateDocumentInternal(). UpdateDocumentInternal(); origin = GetFrame()->DomWindow()->GetSecurityOrigin(); } else { UpdateActivityLogger(); - origin = world_->IsolatedWorldSecurityOrigin(); - SetSecurityToken(origin); + origin = world_->IsolatedWorldSecurityOrigin( + GetFrame()->DomWindow()->GetAgentClusterID()); + SetSecurityToken(origin.get()); } { TRACE_EVENT1("v8", "ContextCreatedNotification", "IsMainFrame", GetFrame()->IsMainFrame()); MainThreadDebugger::Instance()->ContextCreated(script_state_, GetFrame(), - origin); + origin.get()); GetFrame()->Client()->DidCreateScriptContext(context, world_->GetWorldId()); }
diff --git a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc index b302d33b..90083d1f 100644 --- a/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc +++ b/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc
@@ -113,9 +113,10 @@ for (auto& entry : isolated_worlds_) { auto* isolated_window_proxy = static_cast<LocalWindowProxy*>(entry.value.Get()); - const SecurityOrigin* isolated_security_origin = - isolated_window_proxy->World().IsolatedWorldSecurityOrigin(); - isolated_window_proxy->UpdateSecurityOrigin(isolated_security_origin); + scoped_refptr<SecurityOrigin> isolated_security_origin = + isolated_window_proxy->World().IsolatedWorldSecurityOrigin( + security_origin->AgentClusterId()); + isolated_window_proxy->UpdateSecurityOrigin(isolated_security_origin.get()); } }
diff --git a/third_party/blink/renderer/core/clipboard/system_clipboard.cc b/third_party/blink/renderer/core/clipboard/system_clipboard.cc index 3f61e32..d272728 100644 --- a/third_party/blink/renderer/core/clipboard/system_clipboard.cc +++ b/third_party/blink/renderer/core/clipboard/system_clipboard.cc
@@ -49,7 +49,7 @@ } bool SystemClipboard::CanSmartReplace() { - if (!IsValidBufferType(buffer_)) + if (!IsValidBufferType(buffer_) || !clipboard_.is_bound()) return false; bool result = false; clipboard_->IsFormatAvailable(mojom::ClipboardFormat::kSmartPaste, buffer_, @@ -58,7 +58,7 @@ } bool SystemClipboard::IsHTMLAvailable() { - if (!IsValidBufferType(buffer_)) + if (!IsValidBufferType(buffer_) || !clipboard_.is_bound()) return false; bool result = false; clipboard_->IsFormatAvailable(mojom::ClipboardFormat::kHtml, buffer_, @@ -67,7 +67,7 @@ } uint64_t SystemClipboard::SequenceNumber() { - if (!IsValidBufferType(buffer_)) + if (!IsValidBufferType(buffer_) || !clipboard_.is_bound()) return 0; uint64_t result = 0; clipboard_->GetSequenceNumber(buffer_, &result); @@ -75,7 +75,7 @@ } Vector<String> SystemClipboard::ReadAvailableTypes() { - if (!IsValidBufferType(buffer_)) + if (!IsValidBufferType(buffer_) || !clipboard_.is_bound()) return {}; Vector<String> types; clipboard_->ReadAvailableTypes(buffer_, &types); @@ -87,7 +87,7 @@ } String SystemClipboard::ReadPlainText(mojom::ClipboardBuffer buffer) { - if (!IsValidBufferType(buffer)) + if (!IsValidBufferType(buffer) || !clipboard_.is_bound()) return String(); String text; clipboard_->ReadText(buffer, &text); @@ -131,7 +131,7 @@ } String SystemClipboard::ReadRTF() { - if (!IsValidBufferType(buffer_)) + if (!IsValidBufferType(buffer_) || !clipboard_.is_bound()) return String(); String rtf; clipboard_->ReadRtf(buffer_, &rtf); @@ -139,7 +139,7 @@ } SkBitmap SystemClipboard::ReadImage(mojom::ClipboardBuffer buffer) { - if (!IsValidBufferType(buffer)) + if (!IsValidBufferType(buffer) || !clipboard_.is_bound()) return SkBitmap(); SkBitmap image; clipboard_->ReadImage(buffer, &image); @@ -185,7 +185,7 @@ } String SystemClipboard::ReadCustomData(const String& type) { - if (!IsValidBufferType(buffer_)) + if (!IsValidBufferType(buffer_) || !clipboard_.is_bound()) return String(); String data; clipboard_->ReadCustomData(buffer_, NonNullString(type), &data);
diff --git a/third_party/blink/renderer/core/clipboard/system_clipboard.h b/third_party/blink/renderer/core/clipboard/system_clipboard.h index 1fdda23..8f4979d 100644 --- a/third_party/blink/renderer/core/clipboard/system_clipboard.h +++ b/third_party/blink/renderer/core/clipboard/system_clipboard.h
@@ -9,7 +9,6 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" -#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -22,7 +21,7 @@ class LocalFrame; // SystemClipboard: -// - is a singleton. +// - is a LocalFrame bounded object. // - provides sanitized, platform-neutral read/write access to the clipboard. // - mediates between core classes and mojom::ClipboardHost. // @@ -79,9 +78,7 @@ private: bool IsValidBufferType(mojom::ClipboardBuffer); - HeapMojoRemote<mojom::blink::ClipboardHost, - HeapMojoWrapperMode::kForceWithoutContextObserver> - clipboard_; + HeapMojoRemote<mojom::blink::ClipboardHost> clipboard_; // In X11, |buffer_| may equal ClipboardBuffer::kStandard or kSelection. // Outside X11, |buffer_| always equals ClipboardBuffer::kStandard. mojom::ClipboardBuffer buffer_ = mojom::ClipboardBuffer::kStandard;
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc b/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc index 48d17cbde..440fbdef 100644 --- a/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc +++ b/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc
@@ -343,11 +343,13 @@ if (!src_markers) return; - if (!markers_.Contains(&dst_node)) { - markers_.insert(&dst_node, MakeGarbageCollected<MarkerLists>( - DocumentMarker::kMarkerTypeIndexesCount)); + auto& dst_marker_entry = + markers_.insert(&dst_node, nullptr).stored_value->value; + if (!dst_marker_entry) { + dst_marker_entry = MakeGarbageCollected<MarkerLists>( + DocumentMarker::kMarkerTypeIndexesCount); } - MarkerLists* const dst_markers = markers_.at(&dst_node); + MarkerLists* const dst_markers = dst_marker_entry; bool doc_dirty = false; for (DocumentMarker::MarkerType type : DocumentMarker::MarkerTypes::All()) {
diff --git a/third_party/blink/renderer/core/exported/BUILD.gn b/third_party/blink/renderer/core/exported/BUILD.gn index e597f82..3181148 100644 --- a/third_party/blink/renderer/core/exported/BUILD.gn +++ b/third_party/blink/renderer/core/exported/BUILD.gn
@@ -42,6 +42,7 @@ "web_input_element.cc", "web_input_method_controller_impl.cc", "web_input_method_controller_impl.h", + "web_isolated_world_info.cc", "web_label_element.cc", "web_language_detection_details.cc", "web_local_frame_client.cc",
diff --git a/third_party/blink/renderer/core/exported/web_isolated_world_info.cc b/third_party/blink/renderer/core/exported/web_isolated_world_info.cc new file mode 100644 index 0000000..d47897d --- /dev/null +++ b/third_party/blink/renderer/core/exported/web_isolated_world_info.cc
@@ -0,0 +1,42 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/public/platform/web_isolated_world_info.h" + +#include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h" +#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h" + +namespace blink { + +void SetIsolatedWorldInfo(int32_t world_id, const WebIsolatedWorldInfo& info) { + CHECK_GT(world_id, DOMWrapperWorld::kMainWorldId); + CHECK_LT(world_id, DOMWrapperWorld::kDOMWrapperWorldEmbedderWorldIdLimit); + + scoped_refptr<SecurityOrigin> security_origin = + info.security_origin.Get() ? info.security_origin.Get()->IsolatedCopy() + : nullptr; + + CHECK(info.content_security_policy.IsNull() || security_origin); + + DOMWrapperWorld::SetIsolatedWorldSecurityOrigin(world_id, security_origin); + DOMWrapperWorld::SetNonMainWorldStableId(world_id, info.stable_id); + DOMWrapperWorld::SetNonMainWorldHumanReadableName(world_id, + info.human_readable_name); + IsolatedWorldCSP::Get().SetContentSecurityPolicy( + world_id, info.content_security_policy, security_origin); +} + +WebString GetIsolatedWorldStableId(v8::Local<v8::Context> context) { + const DOMWrapperWorld& world = DOMWrapperWorld::World(context); + DCHECK(!world.IsMainWorld()); + return world.NonMainWorldStableId(); +} + +WebString GetIsolatedWorldHumanReadableName(v8::Local<v8::Context> context) { + const DOMWrapperWorld& world = DOMWrapperWorld::World(context); + DCHECK(!world.IsMainWorld()); + return world.NonMainWorldHumanReadableName(); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/fetch/request.cc b/third_party/blink/renderer/core/fetch/request.cc index 9fdf4da..82e0ac0 100644 --- a/third_party/blink/renderer/core/fetch/request.cc +++ b/third_party/blink/renderer/core/fetch/request.cc
@@ -66,16 +66,18 @@ FetchRequestData* CreateCopyOfFetchRequestDataForFetch( ScriptState* script_state, const FetchRequestData* original) { - auto* request = MakeGarbageCollected<FetchRequestData>( - ExecutionContext::From(script_state)); + ExecutionContext* context = ExecutionContext::From(script_state); + auto* request = MakeGarbageCollected<FetchRequestData>(context); request->SetURL(original->Url()); request->SetMethod(original->Method()); request->SetHeaderList(original->HeaderList()->Clone()); - request->SetOrigin(ExecutionContext::From(script_state)->GetSecurityOrigin()); + request->SetOrigin(context->GetSecurityOrigin()); // FIXME: Set client. DOMWrapperWorld& world = script_state->World(); - if (world.IsIsolatedWorld()) - request->SetIsolatedWorldOrigin(world.IsolatedWorldSecurityOrigin()); + if (world.IsIsolatedWorld()) { + request->SetIsolatedWorldOrigin( + world.IsolatedWorldSecurityOrigin(context->GetAgentClusterID())); + } // FIXME: Set ForceOriginHeaderFlag. request->SetReferrerString(original->ReferrerString()); request->SetReferrerPolicy(original->GetReferrerPolicy());
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 4b62d4f..971224f 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -720,8 +720,16 @@ void LocalFrame::SetDOMWindow(LocalDOMWindow* dom_window) { DCHECK(dom_window); - if (this->DomWindow()) + if (this->DomWindow()) { this->DomWindow()->Reset(); + // SystemClipboard and RawSystemClipboard uses HeapMojo wrappers. HeapMojo + // wrappers uses LocalDOMWindow (ExecutionContext) to reset the mojo + // objects when the ExecutionContext was destroyed. So when new + // LocalDOMWindow was set, we need to create new SystemClipboard and + // RawSystemClipboard. + system_clipboard_ = nullptr; + raw_system_clipboard_ = nullptr; + } GetScriptController().ClearWindowProxy(); dom_window_ = dom_window; }
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 3b9a026..5f49317 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -813,47 +813,6 @@ GetFrame()->DomWindow()->ClearIsolatedWorldCSPForTesting(world_id); } -void WebLocalFrameImpl::SetIsolatedWorldInfo(int32_t world_id, - const WebIsolatedWorldInfo& info) { - DCHECK(GetFrame()); - CHECK_GT(world_id, DOMWrapperWorld::kMainWorldId); - CHECK_LT(world_id, DOMWrapperWorld::kDOMWrapperWorldEmbedderWorldIdLimit); - - // The security origin received via IPC doesn't contain the agent cluster - // ID so we need to make sure it contains the cluster agent ID from - // the current document. - scoped_refptr<SecurityOrigin> security_origin = - info.security_origin.Get() - ? info.security_origin.Get() - ->IsolatedCopy() - ->GetOriginForAgentCluster( - GetFrame()->DomWindow()->GetAgentClusterID()) - : nullptr; - - CHECK(info.content_security_policy.IsNull() || security_origin); - - DOMWrapperWorld::SetIsolatedWorldSecurityOrigin(world_id, security_origin); - DOMWrapperWorld::SetNonMainWorldStableId(world_id, info.stable_id); - DOMWrapperWorld::SetNonMainWorldHumanReadableName(world_id, - info.human_readable_name); - IsolatedWorldCSP::Get().SetContentSecurityPolicy( - world_id, info.content_security_policy, security_origin); -} - -WebString WebLocalFrameImpl::GetIsolatedWorldStableId( - v8::Local<v8::Context> context) const { - const DOMWrapperWorld& world = DOMWrapperWorld::World(context); - DCHECK(!world.IsMainWorld()); - return world.NonMainWorldStableId(); -} - -WebString WebLocalFrameImpl::GetIsolatedWorldHumanReadableName( - v8::Local<v8::Context> context) const { - const DOMWrapperWorld& world = DOMWrapperWorld::World(context); - DCHECK(!world.IsMainWorld()); - return world.NonMainWorldHumanReadableName(); -} - void WebLocalFrameImpl::Alert(const WebString& message) { DCHECK(GetFrame()); ScriptState* script_state = ToScriptStateForMainWorld(GetFrame());
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h index 670dff25..93dacfa 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -150,12 +150,6 @@ ExecuteScriptInIsolatedWorldAndReturnValue(int32_t world_id, const WebScriptSource&) override; void ClearIsolatedWorldCSPForTesting(int32_t world_id) override; - void SetIsolatedWorldInfo(int32_t world_id, - const WebIsolatedWorldInfo&) override; - WebString GetIsolatedWorldStableId( - v8::Local<v8::Context> context) const override; - WebString GetIsolatedWorldHumanReadableName( - v8::Local<v8::Context> context) const override; v8::Local<v8::Value> ExecuteScriptAndReturnValue( const WebScriptSource&) override; v8::MaybeLocal<v8::Value> CallFunctionEvenIfScriptDisabled(
diff --git a/third_party/blink/renderer/core/html/portal/html_portal_element.cc b/third_party/blink/renderer/core/html/portal/html_portal_element.cc index 01ebb86d..fa4d18a 100644 --- a/third_party/blink/renderer/core/html/portal/html_portal_element.cc +++ b/third_party/blink/renderer/core/html/portal/html_portal_element.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/html/portal/html_portal_element.h" #include <utility> -#include "third_party/blink/public/mojom/referrer.mojom-blink.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom-blink.h" #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_event_listener.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
diff --git a/third_party/blink/renderer/core/html/portal/portal_contents.cc b/third_party/blink/renderer/core/html/portal/portal_contents.cc index d38cbc0..31402e1 100644 --- a/third_party/blink/renderer/core/html/portal/portal_contents.cc +++ b/third_party/blink/renderer/core/html/portal/portal_contents.cc
@@ -6,8 +6,8 @@ #include "base/compiler_specific.h" #include "base/time/time.h" +#include "third_party/blink/public/mojom/loader/referrer.mojom-blink.h" #include "third_party/blink/public/mojom/portal/portal.mojom-blink-forward.h" -#include "third_party/blink/public/mojom/referrer.mojom-blink.h" #include "third_party/blink/renderer/core/dom/increment_load_event_delay_count.h" #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" #include "third_party/blink/renderer/core/frame/remote_frame.h"
diff --git a/third_party/blink/renderer/core/layout/BUILD.gn b/third_party/blink/renderer/core/layout/BUILD.gn index 238744e..63c40273 100644 --- a/third_party/blink/renderer/core/layout/BUILD.gn +++ b/third_party/blink/renderer/core/layout/BUILD.gn
@@ -314,6 +314,8 @@ "ng/exclusions/ng_layout_opportunity.h", "ng/exclusions/ng_line_layout_opportunity.h", "ng/exclusions/ng_shape_exclusions.h", + "ng/flex/layout_ng_button.cc", + "ng/flex/layout_ng_button.h", "ng/flex/layout_ng_flexible_box.cc", "ng/flex/layout_ng_flexible_box.h", "ng/flex/ng_flex_child_iterator.cc",
diff --git a/third_party/blink/renderer/core/layout/layout_button.cc b/third_party/blink/renderer/core/layout/layout_button.cc index 29ddba1..59118813 100644 --- a/third_party/blink/renderer/core/layout/layout_button.cc +++ b/third_party/blink/renderer/core/layout/layout_button.cc
@@ -59,6 +59,12 @@ void LayoutButton::UpdateAnonymousChildStyle(const LayoutObject* child, ComputedStyle& child_style) const { DCHECK_EQ(inner_, child); + UpdateAnonymousChildStyle(StyleRef(), child_style); +} + +// This function is shared with LayoutNGButton. +void LayoutButton::UpdateAnonymousChildStyle(const ComputedStyle& parent_style, + ComputedStyle& child_style) { child_style.SetFlexGrow(1.0f); // min-width: 0; is needed for correct shrinking. child_style.SetMinWidth(Length::Fixed(0)); @@ -66,13 +72,13 @@ // when the content overflows, treat it the same as align-items: flex-start. child_style.SetMarginTop(Length()); child_style.SetMarginBottom(Length()); - child_style.SetFlexDirection(StyleRef().FlexDirection()); - child_style.SetJustifyContent(StyleRef().JustifyContent()); - child_style.SetFlexWrap(StyleRef().FlexWrap()); + child_style.SetFlexDirection(parent_style.FlexDirection()); + child_style.SetJustifyContent(parent_style.JustifyContent()); + child_style.SetFlexWrap(parent_style.FlexWrap()); // TODO (lajava): An anonymous box must not be used to resolve children's auto // values. - child_style.SetAlignItems(StyleRef().AlignItems()); - child_style.SetAlignContent(StyleRef().AlignContent()); + child_style.SetAlignItems(parent_style.AlignItems()); + child_style.SetAlignContent(parent_style.AlignContent()); } LayoutUnit LayoutButton::BaselinePosition(
diff --git a/third_party/blink/renderer/core/layout/layout_button.h b/third_party/blink/renderer/core/layout/layout_button.h index 60ce95b..e0f91004 100644 --- a/third_party/blink/renderer/core/layout/layout_button.h +++ b/third_party/blink/renderer/core/layout/layout_button.h
@@ -53,6 +53,9 @@ LineDirectionMode, LinePositionMode) const override; + static void UpdateAnonymousChildStyle(const ComputedStyle& parent_sytle, + ComputedStyle& child_style); + private: void UpdateAnonymousChildStyle(const LayoutObject* child, ComputedStyle& child_style) const override; @@ -60,8 +63,6 @@ LayoutBlock* inner_; }; -DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutButton, IsLayoutButton()); - } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_BUTTON_H_
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index 870ec24..b0cba3c 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -717,6 +717,7 @@ bool IsProgress() const { return IsOfType(kLayoutObjectProgress); } bool IsQuote() const { return IsOfType(kLayoutObjectQuote); } bool IsLayoutButton() const { return IsOfType(kLayoutObjectLayoutButton); } + bool IsLayoutNGButton() const { return IsOfType(kLayoutObjectNGButton); } bool IsLayoutNGCustom() const { return IsOfType(kLayoutObjectLayoutNGCustom); } @@ -2653,6 +2654,7 @@ kLayoutObjectMathMLRoot, kLayoutObjectMedia, kLayoutObjectNGBlockFlow, + kLayoutObjectNGButton, kLayoutObjectNGFieldset, kLayoutObjectNGFlexibleBox, kLayoutObjectNGGrid,
diff --git a/third_party/blink/renderer/core/layout/ng/flex/layout_ng_button.cc b/third_party/blink/renderer/core/layout/ng/flex/layout_ng_button.cc new file mode 100644 index 0000000..dad1b953 --- /dev/null +++ b/third_party/blink/renderer/core/layout/ng/flex/layout_ng_button.cc
@@ -0,0 +1,50 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/layout/ng/flex/layout_ng_button.h" + +#include "third_party/blink/renderer/core/layout/layout_button.h" + +namespace blink { + +LayoutNGButton::LayoutNGButton(Element* element) + : LayoutNGFlexibleBox(element), inner_(nullptr) {} + +LayoutNGButton::~LayoutNGButton() = default; + +void LayoutNGButton::AddChild(LayoutObject* new_child, + LayoutObject* before_child) { + if (!inner_) { + // Create an anonymous block. + DCHECK(!FirstChild()); + inner_ = CreateAnonymousBlock(StyleRef().Display()); + LayoutNGFlexibleBox::AddChild(inner_); + } + + inner_->AddChild(new_child, before_child); +} + +void LayoutNGButton::RemoveChild(LayoutObject* old_child) { + if (old_child == inner_ || !inner_) { + LayoutNGFlexibleBox::RemoveChild(old_child); + inner_ = nullptr; + + } else if (old_child->Parent() == this) { + // We aren't the inner node, but we're getting removed from the button, this + // can happen with things like scrollable area resizer's. + LayoutNGFlexibleBox::RemoveChild(old_child); + + } else { + inner_->RemoveChild(old_child); + } +} + +void LayoutNGButton::UpdateAnonymousChildStyle( + const LayoutObject* child, + ComputedStyle& child_style) const { + DCHECK_EQ(inner_, child); + LayoutButton::UpdateAnonymousChildStyle(StyleRef(), child_style); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/flex/layout_ng_button.h b/third_party/blink/renderer/core/layout/ng/flex/layout_ng_button.h new file mode 100644 index 0000000..080b502 --- /dev/null +++ b/third_party/blink/renderer/core/layout/ng/flex/layout_ng_button.h
@@ -0,0 +1,37 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_FLEX_LAYOUT_NG_BUTTON_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_FLEX_LAYOUT_NG_BUTTON_H_ + +#include "third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.h" + +namespace blink { + +class LayoutNGButton final : public LayoutNGFlexibleBox { + public: + explicit LayoutNGButton(Element*); + ~LayoutNGButton() override; + + const char* GetName() const override { return "LayoutNGButton"; } + void AddChild(LayoutObject* new_child, + LayoutObject* before_child = nullptr) override; + void RemoveChild(LayoutObject*) override; + void RemoveLeftoverAnonymousBlock(LayoutBlock*) override {} + bool CreatesAnonymousWrapper() const override { return true; } + + private: + void UpdateAnonymousChildStyle(const LayoutObject* child, + ComputedStyle& child_style) const override; + + bool IsOfType(LayoutObjectType type) const override { + return type == kLayoutObjectNGButton || LayoutNGFlexibleBox::IsOfType(type); + } + + LayoutBlock* inner_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_FLEX_LAYOUT_NG_BUTTON_H_
diff --git a/third_party/blink/renderer/core/paint/file_upload_control_painter.cc b/third_party/blink/renderer/core/paint/file_upload_control_painter.cc index 45080722..1f5cb0a0 100644 --- a/third_party/blink/renderer/core/paint/file_upload_control_painter.cc +++ b/third_party/blink/renderer/core/paint/file_upload_control_painter.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/paint/file_upload_control_painter.h" #include "base/optional.h" -#include "third_party/blink/renderer/core/layout/layout_button.h" +#include "third_party/blink/renderer/core/html/forms/html_input_element.h" #include "third_party/blink/renderer/core/layout/layout_file_upload_control.h" #include "third_party/blink/renderer/core/layout/text_run_constructor.h" #include "third_party/blink/renderer/core/paint/paint_info.h" @@ -57,8 +57,7 @@ LayoutUnit text_y; // We want to match the button's baseline // FIXME: Make this work with transforms. - if (LayoutButton* button_layout_object = - ToLayoutButton(button->GetLayoutObject())) + if (LayoutBox* button_layout_object = button->GetLayoutBox()) text_y = paint_offset.top + layout_file_upload_control_.BorderTop() + layout_file_upload_control_.PaddingTop() + button_layout_object->BaselinePosition(
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc index ffcf5c5..260fc6f 100644 --- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc +++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
@@ -276,11 +276,12 @@ DOMWrapperWorld& world = script_state->World(); v8::Isolate* isolate = script_state->GetIsolate(); - return world.IsIsolatedWorld() - ? MakeGarbageCollected<XMLHttpRequest>( - context, isolate, true, world.IsolatedWorldSecurityOrigin()) - : MakeGarbageCollected<XMLHttpRequest>(context, isolate, false, - nullptr); + return world.IsIsolatedWorld() ? MakeGarbageCollected<XMLHttpRequest>( + context, isolate, true, + world.IsolatedWorldSecurityOrigin( + context->GetAgentClusterID())) + : MakeGarbageCollected<XMLHttpRequest>( + context, isolate, false, nullptr); } XMLHttpRequest* XMLHttpRequest::Create(ExecutionContext* context) {
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc index d36fc78..cf74e1aa 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc
@@ -20,17 +20,14 @@ mojom::blink::WebBluetoothRemoteGATTServicePtr remote_gatt_service, bool is_primary, const String& device_instance_id) { - String service_instance_id = remote_gatt_service->instance_id; - BluetoothRemoteGATTService* service = - service_id_to_object_.at(service_instance_id); - + auto& service = + service_id_to_object_.insert(remote_gatt_service->instance_id, nullptr) + .stored_value->value; if (!service) { service = MakeGarbageCollected<BluetoothRemoteGATTService>( std::move(remote_gatt_service), is_primary, device_instance_id, device_); - service_id_to_object_.insert(service_instance_id, service); } - return service; } @@ -45,16 +42,14 @@ mojom::blink::WebBluetoothRemoteGATTCharacteristicPtr remote_gatt_characteristic, BluetoothRemoteGATTService* service) { - String instance_id = remote_gatt_characteristic->instance_id; - BluetoothRemoteGATTCharacteristic* characteristic = - characteristic_id_to_object_.at(instance_id); - + auto& characteristic = + characteristic_id_to_object_ + .insert(remote_gatt_characteristic->instance_id, nullptr) + .stored_value->value; if (!characteristic) { characteristic = MakeGarbageCollected<BluetoothRemoteGATTCharacteristic>( context, std::move(remote_gatt_characteristic), service, device_); - characteristic_id_to_object_.insert(instance_id, characteristic); } - return characteristic; } @@ -65,19 +60,16 @@ BluetoothRemoteGATTDescriptor* BluetoothAttributeInstanceMap::GetOrCreateBluetoothRemoteGATTDescriptor( - mojom::blink::WebBluetoothRemoteGATTDescriptorPtr descriptor, + mojom::blink::WebBluetoothRemoteGATTDescriptorPtr remote_gatt_descriptor, BluetoothRemoteGATTCharacteristic* characteristic) { - String instance_id = descriptor->instance_id; - BluetoothRemoteGATTDescriptor* result = - descriptor_id_to_object_.at(instance_id); - - if (result) - return result; - - result = MakeGarbageCollected<BluetoothRemoteGATTDescriptor>( - std::move(descriptor), characteristic); - descriptor_id_to_object_.insert(instance_id, result); - return result; + auto& descriptor = descriptor_id_to_object_ + .insert(remote_gatt_descriptor->instance_id, nullptr) + .stored_value->value; + if (!descriptor) { + descriptor = MakeGarbageCollected<BluetoothRemoteGATTDescriptor>( + std::move(remote_gatt_descriptor), characteristic); + } + return descriptor; } bool BluetoothAttributeInstanceMap::ContainsDescriptor(
diff --git a/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converter.cc b/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converter.cc index 403eaca2b..21c85a9e 100644 --- a/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converter.cc +++ b/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converter.cc
@@ -28,13 +28,4 @@ input->userVisibleOnly(), std::move(application_server_key)); } -// TODO(viviy): implement conversion -// static -blink::PushSubscription* -TypeConverter<blink::PushSubscription*, - blink::mojom::blink::PushSubscriptionPtr>:: - Convert(const blink::mojom::blink::PushSubscriptionPtr& input) { - return nullptr; -} - } // namespace mojo
diff --git a/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converter.h b/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converter.h index 2c5f79aa..f155f25 100644 --- a/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converter.h +++ b/third_party/blink/renderer/modules/push_messaging/push_messaging_type_converter.h
@@ -29,15 +29,6 @@ const blink::PushSubscriptionOptions* input); }; -// Converts a {blink::mojom::blink::PushSubscriptionPtr} object into a -// {blink::PushSubscription*}, currently returning nullptr -template <> -struct TypeConverter<blink::PushSubscription*, - blink::mojom::blink::PushSubscriptionPtr> { - static blink::PushSubscription* Convert( - const blink::mojom::blink::PushSubscriptionPtr& input); -}; - } // namespace mojo #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_MESSAGING_TYPE_CONVERTER_H_
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc index 4d060db..32f07e0 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -96,7 +96,6 @@ #include "third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h" #include "third_party/blink/renderer/modules/push_messaging/push_event.h" #include "third_party/blink/renderer/modules/push_messaging/push_message_data.h" -#include "third_party/blink/renderer/modules/push_messaging/push_messaging_type_converter.h" #include "third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.h" #include "third_party/blink/renderer/modules/service_worker/cross_origin_resource_policy_checker.h" #include "third_party/blink/renderer/modules/service_worker/extendable_event.h" @@ -2063,8 +2062,9 @@ this, WaitUntilObserver::kPushSubscriptionChange, event_id); Event* event = PushSubscriptionChangeEvent::Create( event_type_names::kPushsubscriptionchange, - new_subscription.To<blink::PushSubscription*>(), - old_subscription.To<blink::PushSubscription*>(), observer); + PushSubscription::Create(std::move(new_subscription), registration_), + PushSubscription::Create(std::move(old_subscription), registration_), + observer); DispatchExtendableEvent(event, observer); }
diff --git a/third_party/blink/renderer/modules/speech/speech_synthesis.h b/third_party/blink/renderer/modules/speech/speech_synthesis.h index 83f91cfb..2a14b0c 100644 --- a/third_party/blink/renderer/modules/speech/speech_synthesis.h +++ b/third_party/blink/renderer/modules/speech/speech_synthesis.h
@@ -35,7 +35,6 @@ #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" -#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" #include "third_party/blink/renderer/platform/supplementable.h" namespace blink { @@ -130,12 +129,9 @@ void InitializeMojomSynthesisIfNeeded(); HeapMojoReceiver<mojom::blink::SpeechSynthesisVoiceListObserver, - SpeechSynthesis, - HeapMojoWrapperMode::kForceWithoutContextObserver> + SpeechSynthesis> receiver_; - HeapMojoRemote<mojom::blink::SpeechSynthesis, - HeapMojoWrapperMode::kForceWithoutContextObserver> - mojom_synthesis_; + HeapMojoRemote<mojom::blink::SpeechSynthesis> mojom_synthesis_; HeapVector<Member<SpeechSynthesisVoice>> voice_list_; HeapDeque<Member<SpeechSynthesisUtterance>> utterance_queue_; bool is_paused_ = false;
diff --git a/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc b/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc index bd63794..99693ac 100644 --- a/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc +++ b/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc
@@ -156,11 +156,15 @@ return map; } -SecurityOrigin* DOMWrapperWorld::IsolatedWorldSecurityOrigin() { +scoped_refptr<SecurityOrigin> DOMWrapperWorld::IsolatedWorldSecurityOrigin( + const base::UnguessableToken& cluster_id) { DCHECK(this->IsIsolatedWorld()); IsolatedWorldSecurityOriginMap& origins = IsolatedWorldSecurityOrigins(); IsolatedWorldSecurityOriginMap::iterator it = origins.find(GetWorldId()); - return it == origins.end() ? nullptr : it->value.get(); + if (it == origins.end()) + return nullptr; + + return it->value->GetOriginForAgentCluster(cluster_id); } void DOMWrapperWorld::SetIsolatedWorldSecurityOrigin(
diff --git a/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h b/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h index 571e3f6..0cfb818 100644 --- a/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h +++ b/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h
@@ -44,6 +44,10 @@ #include "third_party/blink/renderer/platform/wtf/ref_counted.h" #include "v8/include/v8.h" +namespace base { +class UnguessableToken; +} // namespace base + namespace blink { class DOMDataStore; @@ -129,7 +133,11 @@ static void SetIsolatedWorldSecurityOrigin( int32_t world_id, scoped_refptr<SecurityOrigin> security_origin); - SecurityOrigin* IsolatedWorldSecurityOrigin(); + + // Returns the security origin for the given world with the given + // |cluster_id|. + scoped_refptr<SecurityOrigin> IsolatedWorldSecurityOrigin( + const base::UnguessableToken& cluster_id); static bool HasWrapperInAnyWorldInMainThread(ScriptWrappable*);
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-features=OutOfBlinkCors b/third_party/blink/web_tests/FlagExpectations/disable-features=OutOfBlinkCors index c2d1369..4e6e2076 100644 --- a/third_party/blink/web_tests/FlagExpectations/disable-features=OutOfBlinkCors +++ b/third_party/blink/web_tests/FlagExpectations/disable-features=OutOfBlinkCors
@@ -98,3 +98,5 @@ crbug.com/688906 virtual/omt-worker-fetch/external/wpt/fetch/api/basic/request-upload.any.worker.html [ Failure ] crbug.com/688906 external/wpt/service-workers/service-worker/fetch-event.https.html [ Failure ] +# Subresource WBN is only supported with OOR-CORS. +crbug.com/1082020 virtual/subresource-web-bundles/external/wpt/web-bundle/subresource-loading/subresource-loading-from-web-bundle.tentative.html [ Failure ]
diff --git a/third_party/blink/web_tests/css3/selectors3/html/css3-modsel-23.html b/third_party/blink/web_tests/css3/selectors3/html/css3-modsel-23.html deleted file mode 100644 index 62ce1946..0000000 --- a/third_party/blink/web_tests/css3/selectors3/html/css3-modsel-23.html +++ /dev/null
@@ -1,23 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> -<html> - <head> - <title>:enabled pseudo-class</title> - <style type="text/css">button { background-color : red } -input { background-color : red } -button:enabled { background-color : lime } -input:enabled { background-color : lime }</style> - <link rel="first" href="css3-modsel-1.html" title="Groups of selectors"> - <link rel="prev" href="css3-modsel-22.html" title=":lang() pseudo-class"> - <link rel="next" href="css3-modsel-24.html" title=":disabled pseudo-class"> - <link rel="last" href="css3-modsel-d4.html" title="Dynamic updating of :first-child and :last-child"> - <link rel="up" href="./index.html"> - <link rel="top" href="../../index.html"> - </head> - <body> -<p> - <button>A button (enabled) with green background</button> - <br> - <input type="text" size="36" value="a text area (enabled) with green background"> -</p> -</body> -</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/css3/selectors3/html/css3-modsel-24.html b/third_party/blink/web_tests/css3/selectors3/html/css3-modsel-24.html deleted file mode 100644 index 67420fc0..0000000 --- a/third_party/blink/web_tests/css3/selectors3/html/css3-modsel-24.html +++ /dev/null
@@ -1,23 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> -<html> - <head> - <title>:disabled pseudo-class</title> - <style type="text/css">button { background-color : red } -input { background-color : red } -button:disabled { background-color : lime } -input:disabled { background-color : lime }</style> - <link rel="first" href="css3-modsel-1.html" title="Groups of selectors"> - <link rel="prev" href="css3-modsel-23.html" title=":enabled pseudo-class"> - <link rel="next" href="css3-modsel-25.html" title=":checked pseudo-class"> - <link rel="last" href="css3-modsel-d4.html" title="Dynamic updating of :first-child and :last-child"> - <link rel="up" href="./index.html"> - <link rel="top" href="../../index.html"> - </head> - <body> -<p> - <button disabled="disabled">A button (disabled) with green background</button> - <br> - <input disabled="disabled" type="text" size="36" value="a text area (disabled) with green background"> -</p> -</body> -</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/css3/selectors3/html/css3-modsel-68.html b/third_party/blink/web_tests/css3/selectors3/html/css3-modsel-68.html deleted file mode 100644 index 70118fa..0000000 --- a/third_party/blink/web_tests/css3/selectors3/html/css3-modsel-68.html +++ /dev/null
@@ -1,23 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> -<html> - <head> - <title>NEGATED :enabled pseudo-class</title> - <style type="text/css">button { background-color : red } -input { background-color : red } -button:not(:enabled) { background-color : lime } -input:not(:enabled) { background-color : lime }</style> - <link rel="first" href="css3-modsel-1.html" title="Groups of selectors"> - <link rel="prev" href="css3-modsel-67.html" title="NEGATED :lang() pseudo-class"> - <link rel="next" href="css3-modsel-69.html" title="NEGATED :disabled pseudo-class"> - <link rel="last" href="css3-modsel-d4.html" title="Dynamic updating of :first-child and :last-child"> - <link rel="up" href="./index.html"> - <link rel="top" href="../../index.html"> - </head> - <body> -<p> - <button disabled="disabled">A button (disabled) with green background</button> - <br> - <input disabled="disabled" type="text" size="36" value="a text area (disabled) with green background"> -</p> -</body> -</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/css3/selectors3/html/css3-modsel-69.html b/third_party/blink/web_tests/css3/selectors3/html/css3-modsel-69.html deleted file mode 100644 index 1760324a..0000000 --- a/third_party/blink/web_tests/css3/selectors3/html/css3-modsel-69.html +++ /dev/null
@@ -1,23 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> -<html> - <head> - <title>NEGATED :disabled pseudo-class</title> - <style type="text/css">button { background-color : red } -input { background-color : red } -button:not(:disabled) { background-color : lime } -input:not(:disabled) { background-color : lime }</style> - <link rel="first" href="css3-modsel-1.html" title="Groups of selectors"> - <link rel="prev" href="css3-modsel-68.html" title="NEGATED :enabled pseudo-class"> - <link rel="next" href="css3-modsel-70.html" title="NEGATED :checked pseudo-class"> - <link rel="last" href="css3-modsel-d4.html" title="Dynamic updating of :first-child and :last-child"> - <link rel="up" href="./index.html"> - <link rel="top" href="../../index.html"> - </head> - <body> -<p> - <button>A button (enabled) with green background</button> - <br> - <input type="text" size="36" value="a text area (enabled) with green background"> -</p> -</body> -</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/css3/selectors3/xhtml/css3-modsel-23.xml b/third_party/blink/web_tests/css3/selectors3/xhtml/css3-modsel-23.xml deleted file mode 100644 index 14ce6ee..0000000 --- a/third_party/blink/web_tests/css3/selectors3/xhtml/css3-modsel-23.xml +++ /dev/null
@@ -1,23 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>:enabled pseudo-class</title> - <style type="text/css"><![CDATA[button { background-color : red } -input { background-color : red } -button:enabled { background-color : lime } -input:enabled { background-color : lime }]]></style> - <link rel="first" href="css3-modsel-1.xml" title="Groups of selectors"/> - <link rel="prev" href="css3-modsel-22.xml" title=":lang() pseudo-class"/> - <link rel="next" href="css3-modsel-24.xml" title=":disabled pseudo-class"/> - <link rel="last" href="css3-modsel-d4.xml" title="Dynamic updating of :first-child and :last-child"/> - <link rel="up" href="./index.html"/> - <link rel="top" href="../../index.html"/> - </head> - <body> -<p> - <button>A button (enabled) with green background</button> - <br></br> - <input type="text" size="36" value="a text area (enabled) with green background"></input> -</p> -</body> -</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/css3/selectors3/xhtml/css3-modsel-24.xml b/third_party/blink/web_tests/css3/selectors3/xhtml/css3-modsel-24.xml deleted file mode 100644 index 226517e..0000000 --- a/third_party/blink/web_tests/css3/selectors3/xhtml/css3-modsel-24.xml +++ /dev/null
@@ -1,23 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>:disabled pseudo-class</title> - <style type="text/css"><![CDATA[button { background-color : red } -input { background-color : red } -button:disabled { background-color : lime } -input:disabled { background-color : lime }]]></style> - <link rel="first" href="css3-modsel-1.xml" title="Groups of selectors"/> - <link rel="prev" href="css3-modsel-23.xml" title=":enabled pseudo-class"/> - <link rel="next" href="css3-modsel-25.xml" title=":checked pseudo-class"/> - <link rel="last" href="css3-modsel-d4.xml" title="Dynamic updating of :first-child and :last-child"/> - <link rel="up" href="./index.html"/> - <link rel="top" href="../../index.html"/> - </head> - <body> -<p> - <button disabled="disabled">A button (disabled) with green background</button> - <br></br> - <input disabled="disabled" type="text" size="36" value="a text area (disabled) with green background"></input> -</p> -</body> -</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/css3/selectors3/xhtml/css3-modsel-68.xml b/third_party/blink/web_tests/css3/selectors3/xhtml/css3-modsel-68.xml deleted file mode 100644 index 45741ceb..0000000 --- a/third_party/blink/web_tests/css3/selectors3/xhtml/css3-modsel-68.xml +++ /dev/null
@@ -1,23 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>NEGATED :enabled pseudo-class</title> - <style type="text/css"><![CDATA[button { background-color : red } -input { background-color : red } -button:not(:enabled) { background-color : lime } -input:not(:enabled) { background-color : lime }]]></style> - <link rel="first" href="css3-modsel-1.xml" title="Groups of selectors"/> - <link rel="prev" href="css3-modsel-67.xml" title="NEGATED :lang() pseudo-class"/> - <link rel="next" href="css3-modsel-69.xml" title="NEGATED :disabled pseudo-class"/> - <link rel="last" href="css3-modsel-d4.xml" title="Dynamic updating of :first-child and :last-child"/> - <link rel="up" href="./index.html"/> - <link rel="top" href="../../index.html"/> - </head> - <body> -<p> - <button disabled="disabled">A button (disabled) with green background</button> - <br></br> - <input disabled="disabled" type="text" size="36" value="a text area (disabled) with green background"></input> -</p> -</body> -</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/css3/selectors3/xhtml/css3-modsel-69.xml b/third_party/blink/web_tests/css3/selectors3/xhtml/css3-modsel-69.xml deleted file mode 100644 index 92d7116..0000000 --- a/third_party/blink/web_tests/css3/selectors3/xhtml/css3-modsel-69.xml +++ /dev/null
@@ -1,23 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>NEGATED :disabled pseudo-class</title> - <style type="text/css"><![CDATA[button { background-color : red } -input { background-color : red } -button:not(:disabled) { background-color : lime } -input:not(:disabled) { background-color : lime }]]></style> - <link rel="first" href="css3-modsel-1.xml" title="Groups of selectors"/> - <link rel="prev" href="css3-modsel-68.xml" title="NEGATED :enabled pseudo-class"/> - <link rel="next" href="css3-modsel-70.xml" title="NEGATED :checked pseudo-class"/> - <link rel="last" href="css3-modsel-d4.xml" title="Dynamic updating of :first-child and :last-child"/> - <link rel="up" href="./index.html"/> - <link rel="top" href="../../index.html"/> - </head> - <body> -<p> - <button>A button (enabled) with green background</button> - <br></br> - <input type="text" size="36" value="a text area (enabled) with green background"></input> -</p> -</body> -</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-23.css b/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-23.css deleted file mode 100644 index ebf9dd1..0000000 --- a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-23.css +++ /dev/null
@@ -1,4 +0,0 @@ -button { background-color : red } -input { background-color : red } -button:enabled { background-color : lime } -input:enabled { background-color : lime } \ No newline at end of file
diff --git a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-23.xml b/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-23.xml deleted file mode 100644 index 55fdffb..0000000 --- a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-23.xml +++ /dev/null
@@ -1,8 +0,0 @@ -<?xml-stylesheet href="css3-modsel-23.css" type="text/css"?> -<test> -<p xmlns="http://www.w3.org/1999/xhtml"> - <button>A button (enabled) with green background</button> - <br></br> - <input type="text" size="36" value="a text area (enabled) with green background"></input> -</p> -</test> \ No newline at end of file
diff --git a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-24.css b/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-24.css deleted file mode 100644 index 9a0d1f5..0000000 --- a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-24.css +++ /dev/null
@@ -1,4 +0,0 @@ -button { background-color : red } -input { background-color : red } -button:disabled { background-color : lime } -input:disabled { background-color : lime } \ No newline at end of file
diff --git a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-24.xml b/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-24.xml deleted file mode 100644 index f276f4e..0000000 --- a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-24.xml +++ /dev/null
@@ -1,8 +0,0 @@ -<?xml-stylesheet href="css3-modsel-24.css" type="text/css"?> -<test> -<p xmlns="http://www.w3.org/1999/xhtml"> - <button disabled="disabled">A button (disabled) with green background</button> - <br></br> - <input disabled="disabled" type="text" size="36" value="a text area (disabled) with green background"></input> -</p> -</test> \ No newline at end of file
diff --git a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-68.css b/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-68.css deleted file mode 100644 index 7ab9632..0000000 --- a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-68.css +++ /dev/null
@@ -1,4 +0,0 @@ -button { background-color : red } -input { background-color : red } -button:not(:enabled) { background-color : lime } -input:not(:enabled) { background-color : lime } \ No newline at end of file
diff --git a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-68.xml b/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-68.xml deleted file mode 100644 index 442d39612..0000000 --- a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-68.xml +++ /dev/null
@@ -1,8 +0,0 @@ -<?xml-stylesheet href="css3-modsel-68.css" type="text/css"?> -<test> -<p xmlns="http://www.w3.org/1999/xhtml"> - <button disabled="disabled">A button (disabled) with green background</button> - <br></br> - <input disabled="disabled" type="text" size="36" value="a text area (disabled) with green background"></input> -</p> -</test> \ No newline at end of file
diff --git a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-69.css b/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-69.css deleted file mode 100644 index 39108ae..0000000 --- a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-69.css +++ /dev/null
@@ -1,4 +0,0 @@ -button { background-color : red } -input { background-color : red } -button:not(:disabled) { background-color : lime } -input:not(:disabled) { background-color : lime } \ No newline at end of file
diff --git a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-69.xml b/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-69.xml deleted file mode 100644 index 9a5fcd05..0000000 --- a/third_party/blink/web_tests/css3/selectors3/xml/css3-modsel-69.xml +++ /dev/null
@@ -1,8 +0,0 @@ -<?xml-stylesheet href="css3-modsel-69.css" type="text/css"?> -<test> -<p xmlns="http://www.w3.org/1999/xhtml"> - <button>A button (enabled) with green background</button> - <br></br> - <input type="text" size="36" value="a text area (enabled) with green background"></input> -</p> -</test> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/old-tests/css3-modsel-23.xml b/third_party/blink/web_tests/external/wpt/css/selectors/old-tests/css3-modsel-23.xml deleted file mode 100644 index 663ec09e..0000000 --- a/third_party/blink/web_tests/external/wpt/css/selectors/old-tests/css3-modsel-23.xml +++ /dev/null
@@ -1,21 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>:enabled pseudo-class</title> - <style type="text/css"><![CDATA[button { background-color : red } -input { background-color : red } -button:enabled { background-color : lime } -input:enabled { background-color : lime }]]></style> - <link rel="author" title="Daniel Glazman" href="http://glazman.org/"/> - <link rel="author" title="Ian Hickson" href="mailto:ian@hixie.ch"/> - <link rel="help" href="https://www.w3.org/TR/css3-selectors/#selectors"/> <!-- bogus link to make sure it gets found --> - <meta name="flags" content="" /> - </head> - <body> -<p> - <button>A button (enabled) with green background</button> - <br></br> - <input type="text" size="36" value="a text area (enabled) with green background"></input> -</p> -</body> -</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/old-tests/css3-modsel-24.xml b/third_party/blink/web_tests/external/wpt/css/selectors/old-tests/css3-modsel-24.xml deleted file mode 100644 index d20a011..0000000 --- a/third_party/blink/web_tests/external/wpt/css/selectors/old-tests/css3-modsel-24.xml +++ /dev/null
@@ -1,21 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>:disabled pseudo-class</title> - <style type="text/css"><![CDATA[button { background-color : red } -input { background-color : red } -button:disabled { background-color : lime } -input:disabled { background-color : lime }]]></style> - <link rel="author" title="Daniel Glazman" href="http://glazman.org/"/> - <link rel="author" title="Ian Hickson" href="mailto:ian@hixie.ch"/> - <link rel="help" href="https://www.w3.org/TR/css3-selectors/#selectors"/> <!-- bogus link to make sure it gets found --> - <meta name="flags" content="" /> - </head> - <body> -<p> - <button disabled="disabled">A button (disabled) with green background</button> - <br></br> - <input disabled="disabled" type="text" size="36" value="a text area (disabled) with green background"></input> -</p> -</body> -</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/old-tests/css3-modsel-68.xml b/third_party/blink/web_tests/external/wpt/css/selectors/old-tests/css3-modsel-68.xml deleted file mode 100644 index 99c28261..0000000 --- a/third_party/blink/web_tests/external/wpt/css/selectors/old-tests/css3-modsel-68.xml +++ /dev/null
@@ -1,20 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>NEGATED :enabled pseudo-class</title> - <style type="text/css"><![CDATA[button { background-color : red } -input { background-color : red } -button:not(:enabled) { background-color : lime } -input:not(:enabled) { background-color : lime }]]></style> - <link rel="author" title="Daniel Glazman" href="http://glazman.org/"/> - <link rel="help" href="https://www.w3.org/TR/css3-selectors/#selectors"/> <!-- bogus link to make sure it gets found --> - <meta name="flags" content="" /> - </head> - <body> -<p> - <button disabled="disabled">A button (disabled) with green background</button> - <br></br> - <input disabled="disabled" type="text" size="36" value="a text area (disabled) with green background"></input> -</p> -</body> -</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/old-tests/css3-modsel-69.xml b/third_party/blink/web_tests/external/wpt/css/selectors/old-tests/css3-modsel-69.xml deleted file mode 100644 index 3da2a7f4..0000000 --- a/third_party/blink/web_tests/external/wpt/css/selectors/old-tests/css3-modsel-69.xml +++ /dev/null
@@ -1,20 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>NEGATED :disabled pseudo-class</title> - <style type="text/css"><![CDATA[button { background-color : red } -input { background-color : red } -button:not(:disabled) { background-color : lime } -input:not(:disabled) { background-color : lime }]]></style> - <link rel="author" title="Daniel Glazman" href="http://glazman.org/"/> - <link rel="help" href="https://www.w3.org/TR/css3-selectors/#selectors"/> <!-- bogus link to make sure it gets found --> - <meta name="flags" content="" /> - </head> - <body> -<p> - <button>A button (enabled) with green background</button> - <br></br> - <input type="text" size="36" value="a text area (enabled) with green background"></input> -</p> -</body> -</html> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/pseudo-enabled-disabled.html b/third_party/blink/web_tests/external/wpt/css/selectors/pseudo-enabled-disabled.html new file mode 100644 index 0000000..521767d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/selectors/pseudo-enabled-disabled.html
@@ -0,0 +1,51 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/selectors-4/#enableddisabled"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<div id="container"> +<button id="button_enabled"></button> +<button id="button_disabled" disabled></button> +<input id="input_enabled"> +<input id="input_disabled" disabled> +<select id="select_enabled"></select> +<select id="select_disabled" disabled></select> +<textarea id="textarea_enabled"></textarea> +<textarea id="textarea_disabled" disabled></textarea> +<span id="incapable"></span> +</div> + +<script> +test(() => { + const container = document.querySelector('#container'); + const matched = container.querySelectorAll(':enabled'); + for (let element of matched) { + assert_true(element.id.endsWith('_enabled'), element.id); + } +}, ':enabeld should match to enabled controls'); + +test(() => { + const container = document.querySelector('#container'); + const matched = container.querySelectorAll(':disabled'); + for (let element of matched) { + assert_true(element.id.endsWith('_disabled'), element.id); + } +}, ':disabled should match to enabled controls'); + +test(() => { + const container = document.querySelector('#container'); + const matched = container.querySelectorAll(':not(:enabled)'); + for (let element of matched) { + assert_true(element.id.endsWith('_disabled') || element.id == 'incapable', element.id); + } +}, ':not(:enabeld) should match to disabled controls and non-controls'); + +test(() => { + const container = document.querySelector('#container'); + const matched = container.querySelectorAll(':not(:disabled)'); + for (let element of matched) { + assert_true(element.id.endsWith('_enabled') || element.id == 'incapable', element.id); + } +}, ':not(:disabled) should match to enabled controls and non-controls'); +</script> +</body>
diff --git a/third_party/blink/web_tests/inspector-protocol/emulation/device-emulation-window-segments-expected.txt b/third_party/blink/web_tests/inspector-protocol/emulation/device-emulation-window-segments-expected.txt new file mode 100644 index 0000000..f33d0450 --- /dev/null +++ b/third_party/blink/web_tests/inspector-protocol/emulation/device-emulation-window-segments-expected.txt
@@ -0,0 +1,41 @@ +Tests that device emulation of window segments is propagated and powers getWindowSegments API. +No segments: +Main frame segments: +1 +0 0 800 600 +Iframe segments: +1 +0 0 800 600 +Side-by-side segments +Main frame segments: +2 +0 0 390 600 +410 0 390 600 +Iframe segments: +2 +0 0 390 600 +410 0 390 600 +Unspecified display feature +Main frame segments: +1 +0 0 800 600 +Iframe segments: +1 +0 0 800 600 +Stacked segments +Main frame segments: +2 +0 0 800 290 +0 310 800 290 +Iframe segments: +2 +0 0 800 290 +0 310 800 290 +Emulation disabled +Main frame segments: +1 +0 0 800 600 +Iframe segments: +1 +0 0 800 600 +
diff --git a/third_party/blink/web_tests/inspector-protocol/emulation/device-emulation-window-segments.js b/third_party/blink/web_tests/inspector-protocol/emulation/device-emulation-window-segments.js new file mode 100644 index 0000000..a7903af --- /dev/null +++ b/third_party/blink/web_tests/inspector-protocol/emulation/device-emulation-window-segments.js
@@ -0,0 +1,52 @@ +(async function(testRunner) { + let {page, session, dp} = await testRunner.startBlank('Tests that device emulation of window segments is propagated and powers getWindowSegments API.'); + + let deviceMetrics = { + width: 800, + height: 600, + deviceScaleFactor: 2, + mobile: false, + fitWindow: false, + scale: 2, + screenWidth: 1200, + screenHeight: 1000, + positionX: 110, + positionY: 120, + }; + + await session.protocol.Emulation.setDeviceMetricsOverride(deviceMetrics); + + await session.navigate('../resources/device-emulation.html'); + + testRunner.log("No segments:"); + testRunner.log(await session.evaluate(`dumpWindowSegments()`)); + + testRunner.log("Side-by-side segments"); + deviceMetrics.displayFeature = { + orientation: "vertical", + offset: 390, + maskLength: 20 + }; + await session.protocol.Emulation.setDeviceMetricsOverride(deviceMetrics); + testRunner.log(await session.evaluate(`dumpWindowSegments()`)); + + testRunner.log("Unspecified display feature"); + delete deviceMetrics.displayFeature; + await session.protocol.Emulation.setDeviceMetricsOverride(deviceMetrics); + testRunner.log(await session.evaluate(`dumpWindowSegments()`)); + + testRunner.log("Stacked segments"); + deviceMetrics.displayFeature = { + orientation: "horizontal", + offset: 290, + maskLength: 20 + }; + await session.protocol.Emulation.setDeviceMetricsOverride(deviceMetrics); + testRunner.log(await session.evaluate(`dumpWindowSegments()`)); + + testRunner.log("Emulation disabled"); + await dp.Emulation.clearDeviceMetricsOverride(); + testRunner.log(await session.evaluate(`dumpWindowSegments()`)); + + testRunner.completeTest(); +})
diff --git a/third_party/blink/web_tests/inspector-protocol/resources/device-emulation.html b/third_party/blink/web_tests/inspector-protocol/resources/device-emulation.html index d36e0b8..f01cd3a4 100644 --- a/third_party/blink/web_tests/inspector-protocol/resources/device-emulation.html +++ b/third_party/blink/web_tests/inspector-protocol/resources/device-emulation.html
@@ -111,6 +111,25 @@ return results.join("\n"); } +function dumpWindowSegments() { + let output = []; + output.push("Main frame segments:"); + output = output.concat(dumpWindowSegmentsForWindow(this)); + output.push("Iframe segments:"); + output = output.concat(dumpWindowSegmentsForWindow(window.frames[0])); + return output.join("\n"); +} + +function dumpWindowSegmentsForWindow(window_object) { + let output = []; + output.push(window_object.getWindowSegments().length); + window_object.getWindowSegments().forEach((segment) => { + let segmentString = `${segment.x} ${segment.y} ${segment.width} ${segment.height}`; + output.push(segmentString); + }); + return output; +} + function testJS(expr, unit) { if (unit === undefined) @@ -209,5 +228,6 @@ </head> <body> +<iframe src="about:blank"></iframe> </body> </html>
diff --git a/third_party/blink/web_tests/platform/linux/css3/selectors3/html/css3-modsel-23-expected.png b/third_party/blink/web_tests/platform/linux/css3/selectors3/html/css3-modsel-23-expected.png deleted file mode 100644 index ee296bb..0000000 --- a/third_party/blink/web_tests/platform/linux/css3/selectors3/html/css3-modsel-23-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/selectors3/html/css3-modsel-24-expected.png b/third_party/blink/web_tests/platform/linux/css3/selectors3/html/css3-modsel-24-expected.png deleted file mode 100644 index f6e4663a..0000000 --- a/third_party/blink/web_tests/platform/linux/css3/selectors3/html/css3-modsel-24-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/selectors3/html/css3-modsel-68-expected.png b/third_party/blink/web_tests/platform/linux/css3/selectors3/html/css3-modsel-68-expected.png deleted file mode 100644 index f6e4663a..0000000 --- a/third_party/blink/web_tests/platform/linux/css3/selectors3/html/css3-modsel-68-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/selectors3/html/css3-modsel-69-expected.png b/third_party/blink/web_tests/platform/linux/css3/selectors3/html/css3-modsel-69-expected.png deleted file mode 100644 index ee296bb..0000000 --- a/third_party/blink/web_tests/platform/linux/css3/selectors3/html/css3-modsel-69-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/selectors3/xhtml/css3-modsel-23-expected.png b/third_party/blink/web_tests/platform/linux/css3/selectors3/xhtml/css3-modsel-23-expected.png deleted file mode 100644 index ee296bb..0000000 --- a/third_party/blink/web_tests/platform/linux/css3/selectors3/xhtml/css3-modsel-23-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/selectors3/xhtml/css3-modsel-24-expected.png b/third_party/blink/web_tests/platform/linux/css3/selectors3/xhtml/css3-modsel-24-expected.png deleted file mode 100644 index f6e4663a..0000000 --- a/third_party/blink/web_tests/platform/linux/css3/selectors3/xhtml/css3-modsel-24-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/selectors3/xhtml/css3-modsel-68-expected.png b/third_party/blink/web_tests/platform/linux/css3/selectors3/xhtml/css3-modsel-68-expected.png deleted file mode 100644 index f6e4663a..0000000 --- a/third_party/blink/web_tests/platform/linux/css3/selectors3/xhtml/css3-modsel-68-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/selectors3/xhtml/css3-modsel-69-expected.png b/third_party/blink/web_tests/platform/linux/css3/selectors3/xhtml/css3-modsel-69-expected.png deleted file mode 100644 index ee296bb..0000000 --- a/third_party/blink/web_tests/platform/linux/css3/selectors3/xhtml/css3-modsel-69-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/selectors3/xml/css3-modsel-23-expected.png b/third_party/blink/web_tests/platform/linux/css3/selectors3/xml/css3-modsel-23-expected.png deleted file mode 100644 index f1aa8ed..0000000 --- a/third_party/blink/web_tests/platform/linux/css3/selectors3/xml/css3-modsel-23-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/selectors3/xml/css3-modsel-24-expected.png b/third_party/blink/web_tests/platform/linux/css3/selectors3/xml/css3-modsel-24-expected.png deleted file mode 100644 index 4b1f534a..0000000 --- a/third_party/blink/web_tests/platform/linux/css3/selectors3/xml/css3-modsel-24-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/selectors3/xml/css3-modsel-68-expected.png b/third_party/blink/web_tests/platform/linux/css3/selectors3/xml/css3-modsel-68-expected.png deleted file mode 100644 index 4b1f534a..0000000 --- a/third_party/blink/web_tests/platform/linux/css3/selectors3/xml/css3-modsel-68-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/css3/selectors3/xml/css3-modsel-69-expected.png b/third_party/blink/web_tests/platform/linux/css3/selectors3/xml/css3-modsel-69-expected.png deleted file mode 100644 index f1aa8ed..0000000 --- a/third_party/blink/web_tests/platform/linux/css3/selectors3/xml/css3-modsel-69-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/selectors3/html/css3-modsel-23-expected.png b/third_party/blink/web_tests/platform/mac/css3/selectors3/html/css3-modsel-23-expected.png deleted file mode 100644 index 066b2e4..0000000 --- a/third_party/blink/web_tests/platform/mac/css3/selectors3/html/css3-modsel-23-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/selectors3/html/css3-modsel-24-expected.png b/third_party/blink/web_tests/platform/mac/css3/selectors3/html/css3-modsel-24-expected.png deleted file mode 100644 index c1f904d..0000000 --- a/third_party/blink/web_tests/platform/mac/css3/selectors3/html/css3-modsel-24-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/selectors3/html/css3-modsel-68-expected.png b/third_party/blink/web_tests/platform/mac/css3/selectors3/html/css3-modsel-68-expected.png deleted file mode 100644 index c1f904d..0000000 --- a/third_party/blink/web_tests/platform/mac/css3/selectors3/html/css3-modsel-68-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/selectors3/html/css3-modsel-69-expected.png b/third_party/blink/web_tests/platform/mac/css3/selectors3/html/css3-modsel-69-expected.png deleted file mode 100644 index 066b2e4..0000000 --- a/third_party/blink/web_tests/platform/mac/css3/selectors3/html/css3-modsel-69-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/selectors3/xhtml/css3-modsel-23-expected.png b/third_party/blink/web_tests/platform/mac/css3/selectors3/xhtml/css3-modsel-23-expected.png deleted file mode 100644 index 066b2e4..0000000 --- a/third_party/blink/web_tests/platform/mac/css3/selectors3/xhtml/css3-modsel-23-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/selectors3/xhtml/css3-modsel-24-expected.png b/third_party/blink/web_tests/platform/mac/css3/selectors3/xhtml/css3-modsel-24-expected.png deleted file mode 100644 index c1f904d..0000000 --- a/third_party/blink/web_tests/platform/mac/css3/selectors3/xhtml/css3-modsel-24-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/selectors3/xhtml/css3-modsel-68-expected.png b/third_party/blink/web_tests/platform/mac/css3/selectors3/xhtml/css3-modsel-68-expected.png deleted file mode 100644 index c1f904d..0000000 --- a/third_party/blink/web_tests/platform/mac/css3/selectors3/xhtml/css3-modsel-68-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/selectors3/xhtml/css3-modsel-69-expected.png b/third_party/blink/web_tests/platform/mac/css3/selectors3/xhtml/css3-modsel-69-expected.png deleted file mode 100644 index 066b2e4..0000000 --- a/third_party/blink/web_tests/platform/mac/css3/selectors3/xhtml/css3-modsel-69-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/selectors3/xml/css3-modsel-23-expected.png b/third_party/blink/web_tests/platform/mac/css3/selectors3/xml/css3-modsel-23-expected.png deleted file mode 100644 index bb58fd1..0000000 --- a/third_party/blink/web_tests/platform/mac/css3/selectors3/xml/css3-modsel-23-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/selectors3/xml/css3-modsel-24-expected.png b/third_party/blink/web_tests/platform/mac/css3/selectors3/xml/css3-modsel-24-expected.png deleted file mode 100644 index b1423c3..0000000 --- a/third_party/blink/web_tests/platform/mac/css3/selectors3/xml/css3-modsel-24-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/selectors3/xml/css3-modsel-68-expected.png b/third_party/blink/web_tests/platform/mac/css3/selectors3/xml/css3-modsel-68-expected.png deleted file mode 100644 index b1423c3..0000000 --- a/third_party/blink/web_tests/platform/mac/css3/selectors3/xml/css3-modsel-68-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css3/selectors3/xml/css3-modsel-69-expected.png b/third_party/blink/web_tests/platform/mac/css3/selectors3/xml/css3-modsel-69-expected.png deleted file mode 100644 index bb58fd1..0000000 --- a/third_party/blink/web_tests/platform/mac/css3/selectors3/xml/css3-modsel-69-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/css3/selectors3/html/css3-modsel-23-expected.png b/third_party/blink/web_tests/platform/win/css3/selectors3/html/css3-modsel-23-expected.png deleted file mode 100644 index 9feeef77..0000000 --- a/third_party/blink/web_tests/platform/win/css3/selectors3/html/css3-modsel-23-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/css3/selectors3/html/css3-modsel-24-expected.png b/third_party/blink/web_tests/platform/win/css3/selectors3/html/css3-modsel-24-expected.png deleted file mode 100644 index 1040346..0000000 --- a/third_party/blink/web_tests/platform/win/css3/selectors3/html/css3-modsel-24-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/css3/selectors3/html/css3-modsel-68-expected.png b/third_party/blink/web_tests/platform/win/css3/selectors3/html/css3-modsel-68-expected.png deleted file mode 100644 index 1040346..0000000 --- a/third_party/blink/web_tests/platform/win/css3/selectors3/html/css3-modsel-68-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/css3/selectors3/html/css3-modsel-69-expected.png b/third_party/blink/web_tests/platform/win/css3/selectors3/html/css3-modsel-69-expected.png deleted file mode 100644 index 9feeef77..0000000 --- a/third_party/blink/web_tests/platform/win/css3/selectors3/html/css3-modsel-69-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/css3/selectors3/xhtml/css3-modsel-23-expected.png b/third_party/blink/web_tests/platform/win/css3/selectors3/xhtml/css3-modsel-23-expected.png deleted file mode 100644 index 9feeef77..0000000 --- a/third_party/blink/web_tests/platform/win/css3/selectors3/xhtml/css3-modsel-23-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/css3/selectors3/xhtml/css3-modsel-24-expected.png b/third_party/blink/web_tests/platform/win/css3/selectors3/xhtml/css3-modsel-24-expected.png deleted file mode 100644 index 1040346..0000000 --- a/third_party/blink/web_tests/platform/win/css3/selectors3/xhtml/css3-modsel-24-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/css3/selectors3/xhtml/css3-modsel-68-expected.png b/third_party/blink/web_tests/platform/win/css3/selectors3/xhtml/css3-modsel-68-expected.png deleted file mode 100644 index 1040346..0000000 --- a/third_party/blink/web_tests/platform/win/css3/selectors3/xhtml/css3-modsel-68-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/css3/selectors3/xhtml/css3-modsel-69-expected.png b/third_party/blink/web_tests/platform/win/css3/selectors3/xhtml/css3-modsel-69-expected.png deleted file mode 100644 index 9feeef77..0000000 --- a/third_party/blink/web_tests/platform/win/css3/selectors3/xhtml/css3-modsel-69-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/css3/selectors3/xml/css3-modsel-23-expected.png b/third_party/blink/web_tests/platform/win/css3/selectors3/xml/css3-modsel-23-expected.png deleted file mode 100644 index 0b56648b..0000000 --- a/third_party/blink/web_tests/platform/win/css3/selectors3/xml/css3-modsel-23-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/css3/selectors3/xml/css3-modsel-24-expected.png b/third_party/blink/web_tests/platform/win/css3/selectors3/xml/css3-modsel-24-expected.png deleted file mode 100644 index f2210a10..0000000 --- a/third_party/blink/web_tests/platform/win/css3/selectors3/xml/css3-modsel-24-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/css3/selectors3/xml/css3-modsel-68-expected.png b/third_party/blink/web_tests/platform/win/css3/selectors3/xml/css3-modsel-68-expected.png deleted file mode 100644 index f2210a10..0000000 --- a/third_party/blink/web_tests/platform/win/css3/selectors3/xml/css3-modsel-68-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/css3/selectors3/xml/css3-modsel-69-expected.png b/third_party/blink/web_tests/platform/win/css3/selectors3/xml/css3-modsel-69-expected.png deleted file mode 100644 index 0b56648b..0000000 --- a/third_party/blink/web_tests/platform/win/css3/selectors3/xml/css3-modsel-69-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/libgav1/README.chromium b/third_party/libgav1/README.chromium index a24df95..dd7aca0c 100644 --- a/third_party/libgav1/README.chromium +++ b/third_party/libgav1/README.chromium
@@ -2,9 +2,9 @@ Short Name: libgav1 URL: https://chromium.googlesource.com/codecs/libgav1/ Version: 0 -Date: Friday June 26 2020 +Date: Tuesday July 14 2020 Branch: master -Commit: ba8dd2919fcaf65646858a6d7fd5e75ed4946cb1 +Commit: e46493b9148e0d1e63f55b5890bff503822616e5 License: Apache 2.0 License File: libgav1/LICENSE Security Critical: yes
diff --git a/third_party/nearby/BUILD.gn b/third_party/nearby/BUILD.gn index 4b30d8c..5b08764e 100644 --- a/third_party/nearby/BUILD.gn +++ b/third_party/nearby/BUILD.gn
@@ -360,7 +360,6 @@ } # src/cpp/core_v2/internal/mediums -# TODO(himanshujaju) - Add bloom filter after resolving smhasher dependency. source_set("core_v2_internal_mediums") { public_configs = [ ":nearby_include_config" ] sources = [ @@ -368,6 +367,7 @@ "src/cpp/core_v2/internal/mediums/ble_advertisement.cc", "src/cpp/core_v2/internal/mediums/ble_advertisement_header.cc", "src/cpp/core_v2/internal/mediums/ble_packet.cc", + "src/cpp/core_v2/internal/mediums/bloom_filter.cc", "src/cpp/core_v2/internal/mediums/bluetooth_classic.cc", "src/cpp/core_v2/internal/mediums/bluetooth_radio.cc", "src/cpp/core_v2/internal/mediums/mediums.cc", @@ -381,6 +381,7 @@ "src/cpp/core_v2/internal/mediums/ble_advertisement_header.h", "src/cpp/core_v2/internal/mediums/ble_packet.h", "src/cpp/core_v2/internal/mediums/ble_peripheral.h", + "src/cpp/core_v2/internal/mediums/bloom_filter.h", "src/cpp/core_v2/internal/mediums/bluetooth_classic.h", "src/cpp/core_v2/internal/mediums/bluetooth_radio.h", "src/cpp/core_v2/internal/mediums/lost_entity_tracker.h",
diff --git a/third_party/nearby/README.chromium b/third_party/nearby/README.chromium index f72f227..610e1ba 100644 --- a/third_party/nearby/README.chromium +++ b/third_party/nearby/README.chromium
@@ -1,7 +1,7 @@ Name: Nearby Connections Library Short Name: Nearby URL: https://github.com/google/nearby-connections -Version: 31ab07b5d7183572a4250be2e0ff26a03f920e77 +Version: ae277748ce068ef1730d5104002d4324fc4ed89e License: Apache 2.0 License File: LICENSE Security Critical: yes
diff --git a/tools/json_schema_compiler/cpp_bundle_generator.py b/tools/json_schema_compiler/cpp_bundle_generator.py index 9d77888..9d2c0f2 100644 --- a/tools/json_schema_compiler/cpp_bundle_generator.py +++ b/tools/json_schema_compiler/cpp_bundle_generator.py
@@ -334,6 +334,11 @@ c.Append('#include "%s"' % (os.path.join(self._bundle._source_file_dir, 'generated_schemas.h'))) c.Append() + c.Append('#include <algorithm>') + c.Append('#include <iterator>') + c.Append() + c.Append('#include "base/stl_util.h"') + c.Append() c.Append('namespace {') for api in self._bundle._api_defs: namespace = self._bundle._model.namespaces[api.get('namespace')] @@ -348,8 +353,9 @@ json_content[i:i + max_length] for i in range(0, len(json_content), max_length) ] - c.Append('const char %s[] = R"R(%s)R";' % (_FormatNameAsConstant( - namespace.name), ')R" R"R('.join(segments))) + c.Append( + 'constexpr char %s[] = R"R(%s)R";' % + (_FormatNameAsConstant(namespace.name), ')R" R"R('.join(segments))) c.Append('} // namespace') c.Append() c.Concat(cpp_util.OpenNamespace(self._bundle._cpp_namespace)) @@ -363,9 +369,13 @@ c.Append('// static') c.Sblock('base::StringPiece %s::Get(base::StringPiece name) {' % self._bundle._GenerateBundleClass('GeneratedSchemas')) - c.Append('static const struct {') - c.Append(' base::StringPiece name;') - c.Append(' base::StringPiece schema;') + c.Sblock('static constexpr struct kSchemaMapping {') + c.Append('const base::StringPiece name;') + c.Append('const base::StringPiece schema;') + c.Sblock('constexpr bool operator<(const kSchemaMapping& that) const {') + c.Append('return name < that.name;') + c.Eblock('}') + c.Eblock() c.Sblock('} kSchemas[] = {') namespaces = [self._bundle._model.namespaces[api.get('namespace')].name for api in self._bundle._api_defs] @@ -373,11 +383,18 @@ schema_constant_name = _FormatNameAsConstant(namespace) c.Append('{"%s", %s},' % (namespace, schema_constant_name)) c.Eblock('};') - c.Sblock('for (const auto& schema : kSchemas) {') - c.Sblock('if (schema.name == name)') - c.Append('return schema.schema;') + c.Append('static_assert(base::STLIsSorted(kSchemas), "|kSchemas| should be ' + 'sorted.");') + + c.Sblock('auto it = std::lower_bound(std::begin(kSchemas), ' + 'std::end(kSchemas),') + c.Append('kSchemaMapping{name, base::StringPiece()});') c.Eblock() - c.Eblock('}') + + c.Sblock('if (it != std::end(kSchemas) && it->name == name)') + c.Append('return it->schema;') + c.Eblock() + c.Append('return base::StringPiece();') c.Eblock('}') c.Append()
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index da7b584..6b5a7a8 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -41608,6 +41608,7 @@ <int value="64942701" label="OfflinePagesSvelteConcurrentLoading:disabled"/> <int value="66897259" label="ModalPermissionDialogView:enabled"/> <int value="67639499" label="stop-loading-in-background:disabled"/> + <int value="73436710" label="EditPasswordsInDesktopSettings:disabled"/> <int value="73929836" label="VrBrowsingInCustomTab:enabled"/> <int value="75207621" label="enable-stylus-virtual-keyboard:enabled"/> <int value="75237697" label="ash-enable-new-overview-ui"/> @@ -43285,6 +43286,7 @@ <int value="1933376478" label="IsolatePrerenders:enabled"/> <int value="1935405622" label="AppServiceInstanceRegistry:disabled"/> <int value="1936810062" label="WebVrVsyncAlign:enabled"/> + <int value="1936816247" label="EditPasswordsInDesktopSettings:enabled"/> <int value="1938279796" label="PromosOnLocalNtp:disabled"/> <int value="1939413645" label="enable-invalid-cert-collection"/> <int value="1939884866" label="web-otp-backend"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index f6f7173..0f7e54e6 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -118566,42 +118566,6 @@ </summary> </histogram> -<histogram name="PageLoad.Clients.Ads.AdDensity.MaxPercentByArea" units="%" - expires_after="2020-10-08"> - <owner>justinmron@chromium.org</owner> - <owner>johnidel@chromium.org</owner> - <summary> - The page's maximum ad density by area over its lifecycle as a percent from - 0-100. The density measurement is throttled in page load metrics propagation - from renderer to browser and in the ads page load metrics observer, this may - lead to inaccurate maximum density. Recorded at the time a page is - destroyed. - </summary> -</histogram> - -<histogram name="PageLoad.Clients.Ads.AdDensity.MaxPercentByHeight" units="%" - expires_after="2020-10-08"> - <owner>justinmron@chromium.org</owner> - <owner>johnidel@chromium.org</owner> - <summary> - The page's maximum ad density by height over its lifecycle as a percent from - 0-100. The density measurement is throttled in page load metrics propagation - from renderer to browser and in the ads page load metrics observer, this may - lead to inaccurate maximum density. Recorded at the time a page is - destroyed. - </summary> -</histogram> - -<histogram name="PageLoad.Clients.Ads.AdDensity.Recorded" units="Boolean" - expires_after="2020-10-08"> - <owner>justinmron@chromium.org</owner> - <owner>johnidel@chromium.org</owner> - <summary> - Whether the ad density was recorded on the page for both density by area and - density by height. Recorded at the time a page is destroyed. - </summary> -</histogram> - <histogram name="PageLoad.Clients.Ads.All.Navigations.AdFrameRenavigatedToAd" enum="DidNavigateToAd" expires_after="2018-07-13"> <obsolete> @@ -124296,7 +124260,7 @@ </histogram> <histogram name="PasswordManager.BulkCheck.CanceledCredentials" - units="credentials" expires_after="M86"> + units="credentials" expires_after="2021-02-01"> <owner>vasilii@chromium.org</owner> <owner>jdoerrie@chromium.org</owner> <summary> @@ -124306,7 +124270,7 @@ </histogram> <histogram name="PasswordManager.BulkCheck.CanceledTime" units="ms" - expires_after="M86"> + expires_after="2021-02-01"> <owner>vasilii@chromium.org</owner> <owner>jdoerrie@chromium.org</owner> <summary> @@ -124315,7 +124279,7 @@ </histogram> <histogram name="PasswordManager.BulkCheck.CheckedCredentials" - units="credentials" expires_after="M86"> + units="credentials" expires_after="2021-02-01"> <owner>vasilii@chromium.org</owner> <owner>jdoerrie@chromium.org</owner> <summary> @@ -124325,14 +124289,14 @@ </histogram> <histogram name="PasswordManager.BulkCheck.Error" - enum="PasswordLeakDetectionError" expires_after="M86"> + enum="PasswordLeakDetectionError" expires_after="2021-02-01"> <owner>vasilii@chromium.org</owner> <owner>jdoerrie@chromium.org</owner> <summary>Error encountered during the password bulk check.</summary> </histogram> <histogram name="PasswordManager.BulkCheck.LeaksFound" units="credentials" - expires_after="M86"> + expires_after="2021-02-01"> <owner>vasilii@chromium.org</owner> <owner>jdoerrie@chromium.org</owner> <summary> @@ -124350,7 +124314,8 @@ </summary> </histogram> -<histogram name="PasswordManager.BulkCheck.Time" units="ms" expires_after="M86"> +<histogram name="PasswordManager.BulkCheck.Time" units="ms" + expires_after="2021-02-01"> <owner>vasilii@chromium.org</owner> <owner>jdoerrie@chromium.org</owner> <summary> @@ -124359,7 +124324,7 @@ </histogram> <histogram name="PasswordManager.BulkCheck.TimePerCredential" units="ms" - expires_after="M86"> + expires_after="2021-02-01"> <owner>vasilii@chromium.org</owner> <owner>jdoerrie@chromium.org</owner> <summary> @@ -124369,7 +124334,7 @@ </histogram> <histogram name="PasswordManager.BulkCheck.UserAction" - enum="PasswordCheckInteraction" expires_after="M86"> + enum="PasswordCheckInteraction" expires_after="2021-02-01"> <owner>jdoerrie@chromium.org</owner> <owner>vasilii@chromium.org</owner> <summary>User actions performed on the Password Check settings page.</summary> @@ -125017,6 +124982,24 @@ </summary> </histogram> +<histogram name="PasswordManager.iOS.InfoBar.PasswordSave" enum="Boolean" + expires_after="2021-07-01"> + <owner>djean@chromium.org</owner> + <owner>sczs@google.com</owner> + <summary> + This metric counts how many times the Save Password infobar is shown. + </summary> +</histogram> + +<histogram name="PasswordManager.iOS.InfoBar.PasswordUpdate" enum="Boolean" + expires_after="2021-07-01"> + <owner>djean@chromium.org</owner> + <owner>sczs@google.com</owner> + <summary> + This metric counts how many times the Update Password infobar is shown. + </summary> +</histogram> + <histogram name="PasswordManager.IsSyncPasswordHashSaved" enum="IsSyncPasswordHashSaved" expires_after="2021-02-01"> <owner>vakh@chromium.org</owner> @@ -126571,7 +126554,7 @@ </histogram> <histogram base="true" name="PasswordManager.TotalAccountsHiRes.ByType" - units="units" expires_after="M86"> + units="units" expires_after="2020-12-12"> <owner>battre@chromium.org</owner> <owner>vasilii@chromium.org</owner> <summary> @@ -126583,7 +126566,7 @@ </histogram> <histogram base="true" name="PasswordManager.TotalAccountsHiRes.WithScheme" - units="accounts" expires_after="M86"> + units="accounts" expires_after="2020-12-12"> <owner>battre@chromium.org</owner> <owner>vasilii@chromium.org</owner> <summary>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index ac51054..7b78668 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -345,22 +345,6 @@ bucket (with a bucket ratio of 1.3). </summary> </metric> - <metric name="MaxAdDensityByArea"> - <summary> - The estimated maximum density of ads on a page by area. Calculated as the - area of ads on the page * 100 / page area. This counts each overlapping - area once, it may be inaccurate due to updates and calculations being - throttled. - </summary> - </metric> - <metric name="MaxAdDensityByHeight"> - <summary> - The estimated maximum density of ads on a page by height. Calculated as - the combined height of ads on the page * 100 / page height. This counts - each overlapping area once, it may be inaccurate due to updates and - calculations being throttled. - </summary> - </metric> <metric name="TotalBytes"> <summary> Amount of network bytes used to load resources on the page. Includes
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 4fa13b74..9b7e8fc 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -2,15 +2,15 @@ "trace_processor_shell": { "win": { "hash": "011aacdd55d1deab186a4c37b06f11ccc04a5e97", - "remote_path": "perfetto_binaries/trace_processor_shell/win/1a82e68482aacc6cdeeeab15c4d95185b49a05ac/trace_processor_shell.exe" + "remote_path": "perfetto_binaries/trace_processor_shell/win/c63cdce64c9e4dc5fb9fa4f820b39bac1de8553b/trace_processor_shell.exe" }, "mac": { "hash": "dca76ba55b453f63fac42fc51946fc3d8a076b92", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/1a82e68482aacc6cdeeeab15c4d95185b49a05ac/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/mac/c63cdce64c9e4dc5fb9fa4f820b39bac1de8553b/trace_processor_shell" }, "linux": { "hash": "066f8c275b0c6b23b36eb933b42a1e2070176a30", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/ddc86ef759d8e5f1c46324aab820427a4a9e444d/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/linux/c63cdce64c9e4dc5fb9fa4f820b39bac1de8553b/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/style_variable_generator/base_generator.py b/tools/style_variable_generator/base_generator.py index f3bcd80..2090ace 100644 --- a/tools/style_variable_generator/base_generator.py +++ b/tools/style_variable_generator/base_generator.py
@@ -75,7 +75,10 @@ def __init__(self): self.out_file_path = None - self.in_files = [] + # A map of input filepaths to their context object. + self.in_file_to_context = dict() + + # If specified, only generates the given mode. self.generate_single_mode = None # The mode that colors will fallback to when not specified in a @@ -117,19 +120,28 @@ raise ValueError('Error parsing color "%s": %s' % (value_obj, err)) def AddJSONFileToModel(self, path): - self.in_files.append(path) try: with open(path, 'r') as f: - self.AddJSONToModel(f.read(), self.GetName()) + return self.AddJSONToModel(f.read(), self.GetName(), path) except ValueError as err: raise ValueError('\n%s:\n %s' % (path, err)) - def AddJSONToModel(self, json_string, generator_name=None): + def AddJSONToModel(self, json_string, generator_name=None, in_file=None): + '''Adds a |json_string| with variable definitions to the model. + + See *test.json5 files for a defacto format reference. + + |generator_name| is used to get the generator-specific context from the + 'options' object. + |in_file| is used to populate a file-to-context map. + ''' # TODO(calamity): Add allow_duplicate_keys=False once pyjson5 is # rolled. data = json5.loads(json_string, object_pairs_hook=collections.OrderedDict) generator_context = data.get('options', {}).get(generator_name, None) + self.in_file_to_context[in_file] = generator_context + for name, value in data['colors'].items(): if not re.match('^[a-z0-9_]+$', name): raise ValueError( @@ -138,6 +150,7 @@ self.AddColor(name, value, generator_context) + return generator_context def ApplyTemplate(self, style_generator, path_to_template, params): loader_root_dir = path_overrides.GetFileSystemLoaderRootDirectory()
diff --git a/tools/style_variable_generator/colors_test.json5 b/tools/style_variable_generator/colors_test.json5 index 5021c97..948ac1e 100644 --- a/tools/style_variable_generator/colors_test.json5 +++ b/tools/style_variable_generator/colors_test.json5
@@ -5,12 +5,12 @@ } }, colors: { - default_text_color: { + text_color_primary: { light: "$google_grey_900", dark: "rgb(255, 255, 255)", }, toggle_color: { - light: "rgba($default_text_color_rgb, 0.1)" + light: "rgba($text_color_primary_rgb, 0.1)" } }, }
diff --git a/tools/style_variable_generator/colors_test_dark_only_expected.css b/tools/style_variable_generator/colors_test_dark_only_expected.css index 18cc27e..cac2df9 100644 --- a/tools/style_variable_generator/colors_test_dark_only_expected.css +++ b/tools/style_variable_generator/colors_test_dark_only_expected.css
@@ -11,10 +11,10 @@ --google-grey-900-rgb: 32, 33, 36; --google-grey-900: rgb(var(--google-grey-900-rgb)); - --cros-default-text-color-rgb: 255, 255, 255; - --cros-default-text-color: rgb(var(--cros-default-text-color-rgb)); + --cros-text-color-primary-rgb: 255, 255, 255; + --cros-text-color-primary: rgb(var(--cros-text-color-primary-rgb)); - --cros-toggle-color-rgb: var(--cros-default-text-color-rgb); + --cros-toggle-color-rgb: var(--cros-text-color-primary-rgb); --cros-toggle-color: rgba(var(--cros-toggle-color-rgb), 0.1); }
diff --git a/tools/style_variable_generator/colors_test_expected.css b/tools/style_variable_generator/colors_test_expected.css index bbab0956..bf4867a 100644 --- a/tools/style_variable_generator/colors_test_expected.css +++ b/tools/style_variable_generator/colors_test_expected.css
@@ -11,18 +11,18 @@ --google-grey-900-rgb: 32, 33, 36; --google-grey-900: rgb(var(--google-grey-900-rgb)); - --cros-default-text-color-rgb: var(--google-grey-900-rgb); - --cros-default-text-color: rgb(var(--cros-default-text-color-rgb)); + --cros-text-color-primary-rgb: var(--google-grey-900-rgb); + --cros-text-color-primary: rgb(var(--cros-text-color-primary-rgb)); - --cros-toggle-color-rgb: var(--cros-default-text-color-rgb); + --cros-toggle-color-rgb: var(--cros-text-color-primary-rgb); --cros-toggle-color: rgba(var(--cros-toggle-color-rgb), 0.1); } @media (prefers-color-scheme: dark) { html:not(body) { - --cros-default-text-color-rgb: 255, 255, 255; - --cros-default-text-color: rgb(var(--cros-default-text-color-rgb)); + --cros-text-color-primary-rgb: 255, 255, 255; + --cros-text-color-primary: rgb(var(--cros-text-color-primary-rgb)); } }
diff --git a/tools/style_variable_generator/colors_test_expected.h b/tools/style_variable_generator/colors_test_expected.h index 3b823634..f703fdb5 100644 --- a/tools/style_variable_generator/colors_test_expected.h +++ b/tools/style_variable_generator/colors_test_expected.h
@@ -17,7 +17,7 @@ enum class ColorName { kGoogleGrey900, - kDefaultTextColor, + kTextColorPrimary, kToggleColor, }; @@ -25,14 +25,14 @@ switch (color_name) { case ColorName::kGoogleGrey900: return SkColorSetRGB(0x20, 0x21, 0x24); - case ColorName::kDefaultTextColor: + case ColorName::kTextColorPrimary: if (color_mode == AshColorMode::kLight) { return ResolveColor(ColorName::kGoogleGrey900, color_mode); } else { return SkColorSetRGB(0xFF, 0xFF, 0xFF); } case ColorName::kToggleColor: - return SkColorSetA(ResolveColor(ColorName::kDefaultTextColor, color_mode), 0x19); + return SkColorSetA(ResolveColor(ColorName::kTextColorPrimary, color_mode), 0x19); } }
diff --git a/tools/style_variable_generator/css_generator.py b/tools/style_variable_generator/css_generator.py index 1c40a3a..587f4ca 100644 --- a/tools/style_variable_generator/css_generator.py +++ b/tools/style_variable_generator/css_generator.py
@@ -55,9 +55,17 @@ def GetGlobals(self): return { 'css_color_from_rgb_var': self._CssColorFromRGBVar, - 'in_files': self.in_files, + 'in_files': self.in_file_to_context.keys(), } + def GetCSSVarNames(self): + '''Returns generated CSS variable names (excluding the rgb versions)''' + names = set() + for name in self.model[VariableType.COLOR].keys(): + names.add(self._ToCSSVarName(name)) + + return names + def _GetCSSVarPrefix(self, model_name): prefix = self.context_map[model_name].get('prefix') return prefix + '-' if prefix else ''
diff --git a/tools/style_variable_generator/find_invalid_css_variables.py b/tools/style_variable_generator/find_invalid_css_variables.py new file mode 100644 index 0000000..439ce42e --- /dev/null +++ b/tools/style_variable_generator/find_invalid_css_variables.py
@@ -0,0 +1,80 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from __future__ import print_function + +import argparse +import os +import subprocess +import sys +from css_generator import CSSStyleGenerator + + +def RunGit(command): + """Run a git subcommand, returning its output.""" + command = ['git'] + command + proc = subprocess.Popen(command, stdout=subprocess.PIPE) + out = proc.communicate()[0].strip() + return out + + +# TODO(calamity): extend this checker to find unused C++ variables +def FindInvalidCSSVariables(json_string, input_file, git_runner=RunGit): + style_generator = CSSStyleGenerator() + style_generator.AddJSONToModel(json_string, style_generator.GetName(), + input_file) + + context = style_generator.in_file_to_context[input_file] + if (not context or 'prefix' not in context): + raise KeyError('This tool only works on files with a CSS prefix.') + + css_prefix = '--' + context['prefix'] + '-' + + valid_names = style_generator.GetCSSVarNames() + + found_names_list = git_runner([ + 'grep', '-ho', + '\\%s[a-z-]*' % css_prefix, '--', '*.css', '*.html', '*.js' + ]).splitlines() + found_names = set() + for name in found_names_list: + rgb_suffix = '-rgb' + if name.endswith(rgb_suffix): + name = name[:-len(rgb_suffix)] + found_names.add(name) + return { + 'unspecified': found_names.difference(valid_names), + 'unused': valid_names.difference(found_names), + 'css_prefix': css_prefix, + } + + +def main(): + parser = argparse.ArgumentParser( + description='''Finds CSS variables in the codebase that are prefixed + with |input_file|'s CSS prefix but aren't specified in |input_file|.''' + ) + # TODO(calamity): support multiple files if multiple json5 files have the + # same prefix. + parser.add_argument('target', help='source json5 color file') + args = parser.parse_args() + + input_file = args.target + + with open(input_file, 'r') as f: + result = FindInvalidCSSVariables(f.read(), input_file) + + print('Has prefix %s but not in %s:' % (result['css_prefix'], input_file)) + for name in sorted(result['unspecified']): + print(name) + + print('\nGenerated by %s but not used in codebase:' % input_file) + for name in sorted(result['unused']): + print(name) + + return 0 + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/tools/style_variable_generator/find_invalid_css_variables_test.py b/tools/style_variable_generator/find_invalid_css_variables_test.py new file mode 100644 index 0000000..0a411d7b --- /dev/null +++ b/tools/style_variable_generator/find_invalid_css_variables_test.py
@@ -0,0 +1,83 @@ +# Copyright 2020 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from find_invalid_css_variables import FindInvalidCSSVariables +import unittest + + +class FindInvalidCSSVariablesTest(unittest.TestCase): + def testUnspecified(self): + def GitResult(command): + return '''--test-not-specified +--test-only-rgb-used-rgb +--test-toolbar''' + + json_string = ''' +{ + options: { + CSS: { + prefix: 'test' + } + }, + colors: { + toolbar: "rgb(255, 255, 255)", + only_rgb_used: "rgb(255, 255, 255)", + } +} + ''' + + result = FindInvalidCSSVariables(json_string, + 'test', + git_runner=GitResult) + unused = set() + self.assertEqual(result['unused'], unused) + unspecified = set(['--test-not-specified']) + self.assertEqual(result['unspecified'], unspecified) + + def testUnused(self): + def GitResult(command): + return '''--test-toolbar''' + + json_string = ''' +{ + options: { + CSS: { + prefix: 'test' + } + }, + colors: { + toolbar: "rgb(255, 255, 255)", + unused: "rgb(255, 255, 255)", + } +} + ''' + + result = FindInvalidCSSVariables(json_string, + 'test', + git_runner=GitResult) + unused = set(['--test-unused']) + self.assertEqual(result['unused'], unused) + unspecified = set() + self.assertEqual(result['unspecified'], unspecified) + + def testNoPrefix(self): + def GitResult(command): + return '' + + json_string = ''' +{ + colors: { + toolbar: "rgb(255, 255, 255)", + } +} + ''' + self.assertRaises(KeyError, + FindInvalidCSSVariables, + json_string, + 'test', + git_runner=GitResult) + + +if __name__ == '__main__': + unittest.main()
diff --git a/tools/style_variable_generator/views_generator.py b/tools/style_variable_generator/views_generator.py index 3a284d5d..e9cb4d9 100644 --- a/tools/style_variable_generator/views_generator.py +++ b/tools/style_variable_generator/views_generator.py
@@ -34,7 +34,7 @@ 'Modes': Modes, 'out_file_path': None, 'namespace_name': None, - 'in_files': self.in_files, + 'in_files': self.in_file_to_context.keys(), } if self.out_file_path: globals['out_file_path'] = self.out_file_path
diff --git a/ui/base/clipboard/clipboard_ozone.cc b/ui/base/clipboard/clipboard_ozone.cc index b65e17e..12ca4cc 100644 --- a/ui/base/clipboard/clipboard_ozone.cc +++ b/ui/base/clipboard/clipboard_ozone.cc
@@ -38,6 +38,12 @@ namespace { +// TODO(crbug.com/1105892): those three constants can be found in a few other +// places. Perhaps it would be worth finding some common place for them? +constexpr char kMimeTypeX11String[] = "STRING"; +constexpr char kMimeTypeX11Text[] = "TEXT"; +constexpr char kMimeTypeX11Utf8String[] = "UTF8_STRING"; + // The amount of time to wait for a request to complete before aborting it. constexpr base::TimeDelta kRequestTimeout = base::TimeDelta::FromSeconds(10); @@ -102,7 +108,7 @@ auto it = offered_data_[buffer].find(mime_type); if (it == offered_data_[buffer].end()) return {}; - return base::make_span(it->second.data(), it->second.size()); + return base::make_span(it->second->front(), it->second->size()); } Request request(RequestType::kRead); @@ -113,7 +119,7 @@ auto it = offered_data_[buffer].find(mime_type); if (it == offered_data_[buffer].end()) return {}; - return base::make_span(it->second.data(), it->second.size()); + return base::make_span(it->second->front(), it->second->size()); } std::vector<std::string> RequestMimeTypes(ClipboardBuffer buffer) { @@ -145,9 +151,14 @@ ClipboardMonitor::GetInstance()->NotifyClipboardDataChanged(); } - void InsertData(std::vector<uint8_t> data, const std::string& mime_type) { - DCHECK_EQ(data_to_offer_.count(mime_type), 0U); - data_to_offer_[mime_type] = std::move(data); + void InsertData(std::vector<uint8_t> data, + const std::set<std::string>& mime_types) { + auto wrapped_data = scoped_refptr<base::RefCountedBytes>( + base::RefCountedBytes::TakeVector(&data)); + for (const auto& mime_type : mime_types) { + DCHECK_EQ(data_to_offer_.count(mime_type), 0U); + data_to_offer_[mime_type] = wrapped_data; + } ClipboardMonitor::GetInstance()->NotifyClipboardDataChanged(); } @@ -248,7 +259,7 @@ platform_clipboard_->GetAvailableMimeTypes(buffer, std::move(callback)); } - void OnTextRead(const base::Optional<std::vector<uint8_t>>& data) { + void OnTextRead(const base::Optional<PlatformClipboard::Data>& data) { // |data| is already set in request's data_map, so just finish request // processing. CompleteRequest(); @@ -543,7 +554,9 @@ void ClipboardOzone::WriteText(const char* text_data, size_t text_len) { std::vector<uint8_t> data(text_data, text_data + text_len); - async_clipboard_ozone_->InsertData(std::move(data), kMimeTypeText); + async_clipboard_ozone_->InsertData( + std::move(data), {kMimeTypeText, kMimeTypeX11Text, kMimeTypeX11String, + kMimeTypeX11Utf8String}); } void ClipboardOzone::WriteHTML(const char* markup_data, @@ -551,12 +564,12 @@ const char* url_data, size_t url_len) { std::vector<uint8_t> data(markup_data, markup_data + markup_len); - async_clipboard_ozone_->InsertData(std::move(data), kMimeTypeHTML); + async_clipboard_ozone_->InsertData(std::move(data), {kMimeTypeHTML}); } void ClipboardOzone::WriteRTF(const char* rtf_data, size_t data_len) { std::vector<uint8_t> data(rtf_data, rtf_data + data_len); - async_clipboard_ozone_->InsertData(std::move(data), kMimeTypeRTF); + async_clipboard_ozone_->InsertData(std::move(data), {kMimeTypeRTF}); } void ClipboardOzone::WriteBookmark(const char* title_data, @@ -572,25 +585,25 @@ std::vector<uint8_t> data( reinterpret_cast<const uint8_t*>(bookmark.data()), reinterpret_cast<const uint8_t*>(bookmark.data() + bookmark.size())); - async_clipboard_ozone_->InsertData(std::move(data), kMimeTypeMozillaURL); + async_clipboard_ozone_->InsertData(std::move(data), {kMimeTypeMozillaURL}); } void ClipboardOzone::WriteWebSmartPaste() { async_clipboard_ozone_->InsertData(std::vector<uint8_t>(), - kMimeTypeWebkitSmartPaste); + {kMimeTypeWebkitSmartPaste}); } void ClipboardOzone::WriteBitmap(const SkBitmap& bitmap) { std::vector<unsigned char> output; if (gfx::PNGCodec::FastEncodeBGRASkBitmap(bitmap, false, &output)) - async_clipboard_ozone_->InsertData(std::move(output), kMimeTypePNG); + async_clipboard_ozone_->InsertData(std::move(output), {kMimeTypePNG}); } void ClipboardOzone::WriteData(const ClipboardFormatType& format, const char* data_data, size_t data_len) { std::vector<uint8_t> data(data_data, data_data + data_len); - async_clipboard_ozone_->InsertData(std::move(data), format.GetName()); + async_clipboard_ozone_->InsertData(std::move(data), {format.GetName()}); } SkBitmap ClipboardOzone::ReadImageInternal(ClipboardBuffer buffer) const {
diff --git a/ui/file_manager/file_manager/cws_widget/cws_widget_container.css b/ui/file_manager/file_manager/cws_widget/cws_widget_container.css index 1d785104f6..f707ac1 100644 --- a/ui/file_manager/file_manager/cws_widget/cws_widget_container.css +++ b/ui/file_manager/file_manager/cws_widget/cws_widget_container.css
@@ -48,7 +48,7 @@ body.files-ng .cws-widget-buttons { align-items: center; - background: var(--cros-default-bg-color); + background: var(--cros-bg-color); display: flex; /* subtract the bottom padding from the container outside */ height: calc(64px - 20px); @@ -67,7 +67,7 @@ } body.files-ng .cws-widget-webstore-button { - color: var(--cros-default-button-background-color-primary); + color: var(--cros-button-background-color-primary); height: 24px; padding-inline-start: 0; }
diff --git a/ui/file_manager/file_manager/foreground/css/common.css b/ui/file_manager/file_manager/foreground/css/common.css index 4e9f4aa..9586aaf 100644 --- a/ui/file_manager/file_manager/foreground/css/common.css +++ b/ui/file_manager/file_manager/foreground/css/common.css
@@ -161,7 +161,7 @@ } .cr-dialog-container.files-ng .cr-dialog-buttons > button { - background-color: var(--cros-default-button-background-color-secondary); + background-color: var(--cros-button-background-color-secondary); border: 0; border-radius: 4px; box-sizing: border-box; @@ -184,76 +184,76 @@ .cr-dialog-container:not(.files-ng) .cr-dialog-buttons > button.cr-dialog-ok, .cr-dialog-container:not(.files-ng) .cr-dialog-buttons > button.cr-dialog-ok:hover { - background-color: var(--cros-default-button-background-color-primary); - color: var(--cros-default-button-label-color-primary); + background-color: var(--cros-button-background-color-primary); + color: var(--cros-button-label-color-primary); order: 1; } .cr-dialog-container.files-ng .cr-dialog-buttons > button.cr-dialog-ok, .cr-dialog-container.files-ng .cr-dialog-buttons > button.cr-dialog-ok:hover { - background-color: var(--cros-default-button-background-color-primary); - color: var(--cros-default-button-label-color-primary); + background-color: var(--cros-button-background-color-primary); + color: var(--cros-button-label-color-primary); order: 1; } .cr-dialog-container:not(.files-ng) .cr-dialog-buttons > button.cr-dialog-ok:hover { background: - linear-gradient(var(--cros-default-button-background-color-primary-hover-overlay), - var(--cros-default-button-background-color-primary-hover-overlay)); - var(--cros-default-button-background-color-primary), + linear-gradient(var(--cros-button-background-color-primary-hover-overlay), + var(--cros-button-background-color-primary-hover-overlay)); + var(--cros-button-background-color-primary), } .cr-dialog-container.files-ng .cr-dialog-buttons > button.cr-dialog-ok:hover { background: - linear-gradient(var(--cros-default-button-background-color-primary-hover-overlay), - var(--cros-default-button-background-color-primary-hover-overlay)), - var(--cros-default-button-background-color-primary); + linear-gradient(var(--cros-button-background-color-primary-hover-overlay), + var(--cros-button-background-color-primary-hover-overlay)), + var(--cros-button-background-color-primary); } .cr-dialog-container:not(.files-ng) .cr-dialog-buttons > button.cr-dialog-ok[disabled], .cr-dialog-container:not(.files-ng) .cr-dialog-buttons > button.cr-dialog-ok[disabled]:hover { background-color: - var(--cros-default-button-background-color-primary-disabled); - color: var(--cros-default-button-label-color-primary-disabled); + var(--cros-button-background-color-primary-disabled); + color: var(--cros-button-label-color-primary-disabled); } .cr-dialog-container.files-ng .cr-dialog-buttons > button.cr-dialog-ok[disabled], .cr-dialog-container.files-ng .cr-dialog-buttons > button.cr-dialog-ok[disabled]:hover { background-color: - var(--cros-default-button-background-color-primary-disabled); - color: var(--cros-default-button-label-color-primary-disabled); + var(--cros-button-background-color-primary-disabled); + color: var(--cros-button-label-color-primary-disabled); } .cr-dialog-container:not(.files-ng) .cr-dialog-buttons > button.cr-dialog-cancel { - border: 1px solid var(--cros-default-button-stroke-color-secondary); - color: var(--cros-default-button-label-color-secondary); + border: 1px solid var(--cros-button-stroke-color-secondary); + color: var(--cros-button-label-color-secondary); order: 0; } .cr-dialog-container.files-ng .cr-dialog-buttons > button.cr-dialog-cancel { - border: 1px solid var(--cros-default-button-stroke-color-secondary); - color: var(--cros-default-button-label-color-secondary); + border: 1px solid var(--cros-button-stroke-color-secondary); + color: var(--cros-button-label-color-secondary); order: 0; } .cr-dialog-container:not(.files-ng) .cr-dialog-buttons > button.cr-dialog-cancel:hover { - background: var(--cros-default-button-background-color-secondary-hover); + background: var(--cros-button-background-color-secondary-hover); } .cr-dialog-container.files-ng .cr-dialog-buttons > button.cr-dialog-cancel:hover { - background: var(--cros-default-button-background-color-secondary-hover); + background: var(--cros-button-background-color-secondary-hover); } .cr-dialog-container:not(.files-ng) .cr-dialog-buttons > button.cr-dialog-cancel[disabled], .cr-dialog-container:not(.files-ng) .cr-dialog-buttons > button.cr-dialog-cancel[disabled]:hover { - border: 1px solid var(--cros-default-button-stroke-color-secondary-disabled); - color: var(--cros-default-button-label-color-secondary-disabled); + border: 1px solid var(--cros-button-stroke-color-secondary-disabled); + color: var(--cros-button-label-color-secondary-disabled); } .cr-dialog-container.files-ng .cr-dialog-buttons > button.cr-dialog-cancel[disabled], .cr-dialog-container.files-ng .cr-dialog-buttons > button.cr-dialog-cancel[disabled]:hover { - border: 1px solid var(--cros-default-button-stroke-color-secondary-disabled); - color: var(--cros-default-button-label-color-secondary-disabled); + border: 1px solid var(--cros-button-stroke-color-secondary-disabled); + color: var(--cros-button-label-color-secondary-disabled); } .cr-dialog-container:not(.files-ng) .cr-dialog-buttons > button:not(:active):focus { @@ -327,11 +327,11 @@ } .cr-dialog-container:not(.files-ng) .cr-dialog-frame { - background-color: var(--cros-default-bg-color); + background-color: var(--cros-bg-color); border-radius: 2px; box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 2px 6px 0 rgba(0, 0, 0, 0.1); - color: var(--cros-default-text-color); + color: var(--cros-text-color-primary); cursor: default; display: flex; flex-direction: column; @@ -342,11 +342,11 @@ } .cr-dialog-container.files-ng .cr-dialog-frame { - background-color: var(--cros-default-bg-color); + background-color: var(--cros-bg-color); border-radius: 12px; box-shadow: 0 4px 8px 3px rgba(var(--google-grey-800-rgb), 15%), 0 1px 3px 0 rgba(var(--google-grey-800-rgb), 30%); - color: var(--cros-default-text-color); + color: var(--cros-text-color-primary); cursor: default; display: flex; flex-direction: column; @@ -420,7 +420,7 @@ } .cr-dialog-container.files-ng .cr-dialog-title { - color: var(--cros-default-text-color); + color: var(--cros-text-color-primary); display: block; font-size: 16px; font-weight: 500; @@ -438,7 +438,7 @@ .cr-dialog-container:not(.files-ng) .cr-dialog-text, .cr-dialog-container:not(.files-ng) .cr-dialog-title { - color: var(--cros-default-text-color); + color: var(--cros-text-color-primary); overflow: hidden; text-overflow: ellipsis; } @@ -449,11 +449,11 @@ } .cr-dialog-container.files-ng .cr-dialog-text { - color: var(--cros-default-text-color-secondary); + color: var(--cros-text-color-secondary); } .cr-dialog-container.files-ng .no-title .cr-dialog-text { - color: var(--cros-default-text-color); + color: var(--cros-text-color-primary); } .cr-dialog-container:not(.files-ng) .cr-dialog-frame input { @@ -563,7 +563,7 @@ /* Common typography styles for ChromeOS. */ body.files-ng .headline2 { - color: var(--cros-default-text-color); + color: var(--cros-text-color-primary); font-family: Roboto; font-size: 15px; font-weight: 500; @@ -571,7 +571,7 @@ } body.files-ng .button2 { - color: var(--cros-default-text-color); + color: var(--cros-text-color-primary); font-family: Roboto; font-size: 13px; font-weight: 500; @@ -579,14 +579,14 @@ } body.files-ng .body2-primary { - color: var(--cros-default-text-color); + color: var(--cros-text-color-primary); font-family: Roboto; font-size: 13px; line-height: 20px; } body.files-ng .annotation1-primary { - color: var(--cros-default-text-color); + color: var(--cros-text-color-primary); font-family: Roboto; font-size: 12px; line-height: 18px;
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css index 2d6061b7..0c2b974 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -78,7 +78,7 @@ } body.files-ng .dialog-container { - background-color: var(--cros-default-bg-color); + background-color: var(--cros-bg-color); } /* List and grid are inside this container. */ @@ -1393,8 +1393,8 @@ body.files-ng .dialog-footer .primary, body.files-ng .dialog-footer .primary:hover { - background-color: var(--cros-default-button-background-color-primary); - color: var(--cros-default-button-label-color-primary); + background-color: var(--cros-button-background-color-primary); + color: var(--cros-button-label-color-primary); } body:not(.files-ng) .dialog-footer .secondary { @@ -1402,9 +1402,9 @@ } body.files-ng .dialog-footer .secondary { - background-color: var(--cros-default-button-background-color-secondary); - border: 1px solid var(--cros-default-button-stroke-color-secondary); - color: var(--cros-default-button-label-color-secondary); + background-color: var(--cros-button-background-color-secondary); + border: 1px solid var(--cros-button-stroke-color-secondary); + color: var(--cros-button-label-color-secondary); margin-inline-end: 8px; } @@ -1413,7 +1413,7 @@ } body.files-ng .dialog-footer .secondary:hover { - background: var(--cros-default-button-background-color-secondary-hover); + background: var(--cros-button-background-color-secondary-hover); } body:not(.files-ng) .dialog-footer .select { @@ -3222,7 +3222,7 @@ } body.files-ng .table-row-cell .filename-label { - color: var(--cros-default-text-color); + color: var(--cros-text-color-primary); padding-top: 0; } @@ -3312,7 +3312,7 @@ } .cr-dialog-container.files-ng .install-linux-package-detail-label { - color: var(--cros-default-text-color); + color: var(--cros-text-color-primary); display: inline; margin-inline-end: 5px; } @@ -3324,7 +3324,7 @@ } .cr-dialog-container.files-ng .install-linux-package-detail-value { - color: var(--cros-default-text-color-secondary); + color: var(--cros-text-color-secondary); display: inline; margin-bottom: 5px; white-space: pre-wrap; @@ -3385,13 +3385,20 @@ background-color: rgba(0, 0, 0, 8%); } -#gear-menu, -#share-menu, -#sort-menu, -#tasks-menu { +body:not(.files-ng) #gear-menu, +body:not(.files-ng) #share-menu, +body:not(.files-ng) #sort-menu, +body:not(.files-ng) #tasks-menu { margin-top: 2px; } +/* + * TODO(files-ng): remove these rules and do them in the multi-menu JS because + * #tasks-menu is distinguished here: it is used as a menu and a submenu, thus + * gets 8px margin-top in all cases. It should only have this 8px gap when it + * is shown as a menu; it should have no margin-top when it is a submenu (just + * like every other submenu in files app - none of them have margin-top). + */ body.files-ng #gear-menu, body.files-ng #share-menu, body.files-ng #sort-menu,
diff --git a/ui/ozone/platform/wayland/common/data_util.cc b/ui/ozone/platform/wayland/common/data_util.cc index 55e594a..9077366 100644 --- a/ui/ozone/platform/wayland/common/data_util.cc +++ b/ui/ozone/platform/wayland/common/data_util.cc
@@ -46,34 +46,32 @@ // Converts raw data to either narrow or wide string. template <typename StringType> -StringType BytesTo(const PlatformClipboard::Data& bytes) { - if (bytes.size() % sizeof(typename StringType::value_type) != 0U) { +StringType BytesTo(PlatformClipboard::Data bytes) { + using ValueType = typename StringType::value_type; + if (bytes->size() % sizeof(ValueType) != 0U) { // This is suspicious. LOG(WARNING) << "Data is possibly truncated, or a wrong conversion is requested."; } - StringType result; - result.assign(reinterpret_cast<typename StringType::const_pointer>(&bytes[0]), - bytes.size() / sizeof(typename StringType::value_type)); + StringType result(bytes->front_as<ValueType>(), + bytes->size() / sizeof(ValueType)); return result; } -void AddString(const PlatformClipboard::Data& data, - OSExchangeData* os_exchange_data) { +void AddString(PlatformClipboard::Data data, OSExchangeData* os_exchange_data) { DCHECK(os_exchange_data); - if (data.empty()) + if (data->data().empty()) return; os_exchange_data->SetString(base::UTF8ToUTF16(BytesTo<std::string>(data))); } -void AddHtml(const PlatformClipboard::Data& data, - OSExchangeData* os_exchange_data) { +void AddHtml(PlatformClipboard::Data data, OSExchangeData* os_exchange_data) { DCHECK(os_exchange_data); - if (data.empty()) + if (data->data().empty()) return; os_exchange_data->SetHtml(base::UTF8ToUTF16(BytesTo<std::string>(data)), @@ -85,8 +83,7 @@ // 2. Non-comment lines shall be URIs (URNs or URLs). // 3. Lines are terminated with a CRLF pair. // 4. URL encoding is used. -void AddFiles(const PlatformClipboard::Data& data, - OSExchangeData* os_exchange_data) { +void AddFiles(PlatformClipboard::Data data, OSExchangeData* os_exchange_data) { DCHECK(os_exchange_data); std::string data_as_string = BytesTo<std::string>(data); @@ -124,11 +121,10 @@ // two lines separated with newline, where the first line is the URL and // the second one is page title. The unpleasant feature of text/x-moz-url is // that the URL has UTF-16 encoding. -void AddUrl(const PlatformClipboard::Data& data, - OSExchangeData* os_exchange_data) { +void AddUrl(PlatformClipboard::Data data, OSExchangeData* os_exchange_data) { DCHECK(os_exchange_data); - if (data.empty()) + if (data->data().empty()) return; base::string16 data_as_string16 = BytesTo<base::string16>(data); @@ -163,9 +159,10 @@ return exchange_data.HasAnyFormat(MimeTypeToFormat(mime_type), {}); } -void AddToOSExchangeData(const PlatformClipboard::Data& data, +void AddToOSExchangeData(PlatformClipboard::Data data, const std::string& mime_type, OSExchangeData* exchange_data) { + DCHECK(data); DCHECK(IsMimeTypeSupported(mime_type)); DCHECK(exchange_data); int format = MimeTypeToFormat(mime_type);
diff --git a/ui/ozone/platform/wayland/common/data_util.h b/ui/ozone/platform/wayland/common/data_util.h index d6c2d10e7..39c0308 100644 --- a/ui/ozone/platform/wayland/common/data_util.h +++ b/ui/ozone/platform/wayland/common/data_util.h
@@ -24,7 +24,7 @@ // Add clipboard |data| content with |mime_type| format to the |exchange_data|. // |mime_type| is assumed to be supported (See IsMimeTypeSupported for more). -void AddToOSExchangeData(const ui::PlatformClipboard::Data& data, +void AddToOSExchangeData(ui::PlatformClipboard::Data data, const std::string& mime_type, ui::OSExchangeData* exchange_data);
diff --git a/ui/ozone/platform/wayland/host/wayland_clipboard.cc b/ui/ozone/platform/wayland/host/wayland_clipboard.cc index a0e848a..cd99fdd 100644 --- a/ui/ozone/platform/wayland/host/wayland_clipboard.cc +++ b/ui/ozone/platform/wayland/host/wayland_clipboard.cc
@@ -109,7 +109,7 @@ if (it == data_.end() && mime_type == ui::kMimeTypeTextUtf8) it = data_.find(ui::kMimeTypeText); if (it != data_.end()) - contents->assign(it->second.begin(), it->second.end()); + contents->assign(it->second->data().begin(), it->second->data().end()); } // The device manager used to access data device and create data sources. @@ -157,8 +157,10 @@ data_map_ = data_map; read_clipboard_closure_ = std::move(callback); auto* clipboard = GetClipboard(buffer); - if (!clipboard || !clipboard->Read(mime_type)) - SetData({}, mime_type); + if (!clipboard || !clipboard->Read(mime_type)) { + SetData(scoped_refptr<base::RefCountedBytes>(new base::RefCountedBytes()), + mime_type); + } } bool WaylandClipboard::IsSelectionOwner(ClipboardBuffer buffer) { @@ -183,11 +185,12 @@ std::move(callback).Run(mime_types); } -void WaylandClipboard::SetData(const std::vector<uint8_t>& contents, +void WaylandClipboard::SetData(PlatformClipboard::Data contents, const std::string& mime_type) { if (!data_map_) return; + DCHECK(contents); (*data_map_)[mime_type] = contents; if (!read_clipboard_closure_.is_null()) {
diff --git a/ui/ozone/platform/wayland/host/wayland_clipboard.h b/ui/ozone/platform/wayland/host/wayland_clipboard.h index d464140..c8b724d 100644 --- a/ui/ozone/platform/wayland/host/wayland_clipboard.h +++ b/ui/ozone/platform/wayland/host/wayland_clipboard.h
@@ -56,8 +56,7 @@ // TODO(nickdiego): Get rid of these methods once DataDevice implementations // are decoupled from WaylandClipboard. - void SetData(const std::vector<uint8_t>& contents, - const std::string& mime_type); + void SetData(PlatformClipboard::Data contents, const std::string& mime_type); void UpdateSequenceNumber(ClipboardBuffer buffer); private:
diff --git a/ui/ozone/platform/wayland/host/wayland_data_device.cc b/ui/ozone/platform/wayland/host/wayland_data_device.cc index 1edd356..edbb6d472 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_device.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_device.cc
@@ -81,12 +81,12 @@ connection()->ScheduleFlush(); } -void WaylandDataDevice::ReadDragDataFromFD( - base::ScopedFD fd, - base::OnceCallback<void(const PlatformClipboard::Data&)> callback) { - PlatformClipboard::Data contents; +void WaylandDataDevice::ReadDragDataFromFD(base::ScopedFD fd, + RequestDataCallback callback) { + std::vector<uint8_t> contents; wl::ReadDataFromFD(std::move(fd), &contents); - std::move(callback).Run(contents); + std::move(callback).Run(scoped_refptr<base::RefCountedBytes>( + base::RefCountedBytes::TakeVector(&contents))); } // static
diff --git a/ui/ozone/platform/wayland/host/wayland_data_device.h b/ui/ozone/platform/wayland/host/wayland_data_device.h index 8aac88ae..12b84cf 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_device.h +++ b/ui/ozone/platform/wayland/host/wayland_data_device.h
@@ -33,8 +33,7 @@ // such as copy-and-paste and drag-and-drop mechanisms. class WaylandDataDevice : public WaylandDataDeviceBase { public: - using RequestDataCallback = - base::OnceCallback<void(const PlatformClipboard::Data&)>; + using RequestDataCallback = base::OnceCallback<void(PlatformClipboard::Data)>; // DragDelegate is responsible for handling drag and drop sessions. class DragDelegate {
diff --git a/ui/ozone/platform/wayland/host/wayland_data_device_base.cc b/ui/ozone/platform/wayland/host/wayland_data_device_base.cc index 3e020a3..7df5d9e 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_device_base.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_device_base.cc
@@ -56,7 +56,10 @@ const std::string& mime_type) { std::vector<uint8_t> contents; wl::ReadDataFromFD(std::move(fd), &contents); - connection_->clipboard()->SetData(contents, mime_type); + connection_->clipboard()->SetData( + scoped_refptr<base::RefCountedBytes>( + base::RefCountedBytes::TakeVector(&contents)), + mime_type); } void WaylandDataDeviceBase::RegisterDeferredReadCallback() {
diff --git a/ui/ozone/platform/wayland/host/wayland_data_device_unittest.cc b/ui/ozone/platform/wayland/host/wayland_data_device_unittest.cc index b4bedb5..13329fe 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_device_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_device_unittest.cc
@@ -34,13 +34,10 @@ template <typename StringType> ui::PlatformClipboard::Data ToClipboardData(const StringType& data_string) { - ui::PlatformClipboard::Data result; - auto* begin = - reinterpret_cast<typename ui::PlatformClipboard::Data::const_pointer>( - data_string.data()); - result.assign(begin, begin + (data_string.size() * - sizeof(typename StringType::value_type))); - return result; + std::vector<uint8_t> data_vector; + data_vector.assign(data_string.begin(), data_string.end()); + return scoped_refptr<base::RefCountedBytes>( + base::RefCountedBytes::TakeVector(&data_vector)); } } // namespace @@ -64,7 +61,7 @@ ~MockClipboardClient() = default; // Fill the clipboard backing store with sample data. - void SetData(const PlatformClipboard::Data& data, + void SetData(PlatformClipboard::Data data, const std::string& mime_type, PlatformClipboard::OfferDataClosure callback) { data_types_[mime_type] = data; @@ -115,17 +112,19 @@ TEST_P(WaylandDataDeviceManagerTest, WriteToClipboard) { // The client writes data to the clipboard ... - PlatformClipboard::Data data; - data.assign(wl::kSampleClipboardText, - wl::kSampleClipboardText + strlen(wl::kSampleClipboardText)); - clipboard_client_->SetData(data, wl::kTextMimeTypeUtf8, - base::BindOnce([]() {})); + std::vector<uint8_t> data_vector( + wl::kSampleClipboardText, + wl::kSampleClipboardText + strlen(wl::kSampleClipboardText)); + clipboard_client_->SetData( + scoped_refptr<base::RefCountedBytes>( + base::RefCountedBytes::TakeVector(&data_vector)), + {wl::kTextMimeTypeUtf8}, base::BindOnce([]() {})); Sync(); // ... and the server reads it. base::RunLoop run_loop; auto callback = base::BindOnce( - [](base::RunLoop* loop, PlatformClipboard::Data&& data) { + [](base::RunLoop* loop, std::vector<uint8_t>&& data) { std::string string_data(data.begin(), data.end()); EXPECT_EQ(wl::kSampleClipboardText, string_data); loop->Quit(); @@ -150,7 +149,8 @@ // expectation. auto callback = base::BindOnce([](const base::Optional<PlatformClipboard::Data>& data) { - std::string string_data = std::string(data->begin(), data->end()); + auto& bytes = data->get()->data(); + std::string string_data = std::string(bytes.begin(), bytes.end()); EXPECT_EQ(wl::kSampleClipboardText, string_data); }); clipboard_client_->ReadData(wl::kTextMimeTypeUtf8, std::move(callback)); @@ -163,7 +163,8 @@ // an empty string. auto callback = base::BindOnce([](const base::Optional<PlatformClipboard::Data>& data) { - std::string string_data = std::string(data->begin(), data->end()); + auto& bytes = data->get()->data(); + std::string string_data = std::string(bytes.begin(), bytes.end()); EXPECT_EQ("", string_data); }); clipboard_client_->ReadData(wl::kTextMimeTypeUtf8, std::move(callback)); @@ -171,10 +172,13 @@ TEST_P(WaylandDataDeviceManagerTest, IsSelectionOwner) { auto callback = base::BindOnce([]() {}); - PlatformClipboard::Data data; - data.assign(wl::kSampleClipboardText, - wl::kSampleClipboardText + strlen(wl::kSampleClipboardText)); - clipboard_client_->SetData(data, wl::kTextMimeTypeUtf8, std::move(callback)); + std::vector<uint8_t> data_vector( + wl::kSampleClipboardText, + wl::kSampleClipboardText + strlen(wl::kSampleClipboardText)); + clipboard_client_->SetData( + scoped_refptr<base::RefCountedBytes>( + base::RefCountedBytes::TakeVector(&data_vector)), + {wl::kTextMimeTypeUtf8}, std::move(callback)); Sync(); ASSERT_TRUE(clipboard_client_->IsSelectionOwner());
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc index f844fe9..6403855e 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
@@ -295,9 +295,10 @@ } void WaylandDataDragController::OnMimeTypeDataTransferred( - const PlatformClipboard::Data& contents) { + PlatformClipboard::Data contents) { DCHECK_EQ(state_, State::kTransferring); - if (!contents.empty()) { + DCHECK(contents); + if (!contents->data().empty()) { std::string mime_type = unprocessed_mime_types_.front(); wl::AddToOSExchangeData(contents, mime_type, received_data_.get()); }
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h index 9dcf515..5e4c15dd 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h +++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
@@ -80,7 +80,7 @@ void Offer(const OSExchangeData& data, int operation); void CreateIconSurfaceIfNeeded(const OSExchangeData& data); void HandleUnprocessedMimeTypes(); - void OnMimeTypeDataTransferred(const PlatformClipboard::Data& contents); + void OnMimeTypeDataTransferred(PlatformClipboard::Data contents); void OnDataTransferFinished( std::unique_ptr<ui::OSExchangeData> received_data); std::string GetNextUnprocessedMimeType();
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc index 8b1115b..15e43c8 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc
@@ -52,13 +52,13 @@ template <typename StringType> PlatformClipboard::Data ToClipboardData(const StringType& data_string) { - PlatformClipboard::Data result; - auto* begin = - reinterpret_cast<typename PlatformClipboard::Data::const_pointer>( - data_string.data()); - result.assign(begin, begin + (data_string.size() * - sizeof(typename StringType::value_type))); - return result; + auto* begin = reinterpret_cast<typename std::vector<uint8_t>::const_pointer>( + data_string.data()); + std::vector<uint8_t> result( + begin, + begin + (data_string.size() * sizeof(typename StringType::value_type))); + return scoped_refptr<base::RefCountedBytes>( + base::RefCountedBytes::TakeVector(&result)); } } // namespace @@ -155,7 +155,7 @@ // Now the server can read the data and give it to our callback. base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); auto callback = base::BindOnce( - [](base::RunLoop* loop, PlatformClipboard::Data&& data) { + [](base::RunLoop* loop, std::vector<uint8_t>&& data) { std::string result(data.begin(), data.end()); EXPECT_EQ(wl::kSampleTextForDragAndDrop, result); loop->Quit(); @@ -215,7 +215,7 @@ // to read it with a different mime type. base::RunLoop run_loop; auto callback = base::BindOnce( - [](base::RunLoop* loop, PlatformClipboard::Data&& data) { + [](base::RunLoop* loop, std::vector<uint8_t>&& data) { std::string result(data.begin(), data.end()); EXPECT_TRUE(result.empty()); loop->Quit(); @@ -243,7 +243,7 @@ // |kTextMimeTypeUtf8|. base::RunLoop run_loop; auto callback = base::BindOnce( - [](base::RunLoop* loop, PlatformClipboard::Data&& data) { + [](base::RunLoop* loop, std::vector<uint8_t>&& data) { std::string result(data.begin(), data.end()); EXPECT_EQ(wl::kSampleTextForDragAndDrop, result); loop->Quit(); @@ -278,10 +278,10 @@ Sync(); - auto callback = base::BindOnce([](const PlatformClipboard::Data& contents) { + auto callback = base::BindOnce([](PlatformClipboard::Data contents) { std::string result; - result.assign(reinterpret_cast<std::string::const_pointer>(&contents[0]), - contents.size()); + EXPECT_TRUE(contents); + result.assign(contents->front_as<char>(), contents->size()); EXPECT_EQ(wl::kSampleTextForDragAndDrop, result); });
diff --git a/ui/ozone/platform/wayland/test/test_data_offer.cc b/ui/ozone/platform/wayland/test/test_data_offer.cc index b830dad..4ba0bc14 100644 --- a/ui/ozone/platform/wayland/test/test_data_offer.cc +++ b/ui/ozone/platform/wayland/test/test_data_offer.cc
@@ -21,9 +21,9 @@ namespace { void WriteDataOnWorkerThread(base::ScopedFD fd, - const ui::PlatformClipboard::Data& data) { - if (!base::WriteFileDescriptor( - fd.get(), reinterpret_cast<const char*>(data.data()), data.size())) { + ui::PlatformClipboard::Data data) { + if (!base::WriteFileDescriptor(fd.get(), data->front_as<char>(), + data->size())) { LOG(ERROR) << "Failed to write selection data to clipboard."; } } @@ -81,7 +81,7 @@ } void TestDataOffer::OnOffer(const std::string& mime_type, - const ui::PlatformClipboard::Data& data) { + ui::PlatformClipboard::Data data) { data_to_offer_[mime_type] = data; wl_data_offer_send_offer(resource(), mime_type.c_str()); }
diff --git a/ui/ozone/platform/wayland/test/test_data_offer.h b/ui/ozone/platform/wayland/test/test_data_offer.h index 67080d3a..6b96582 100644 --- a/ui/ozone/platform/wayland/test/test_data_offer.h +++ b/ui/ozone/platform/wayland/test/test_data_offer.h
@@ -33,8 +33,7 @@ ~TestDataOffer() override; void Receive(const std::string& mime_type, base::ScopedFD fd); - void OnOffer(const std::string& mime_type, - const ui::PlatformClipboard::Data& data); + void OnOffer(const std::string& mime_type, ui::PlatformClipboard::Data data); private: const scoped_refptr<base::SequencedTaskRunner> task_runner_;
diff --git a/ui/ozone/platform/x11/x11_clipboard_ozone.cc b/ui/ozone/platform/x11/x11_clipboard_ozone.cc index fba01a8..e23c83b 100644 --- a/ui/ozone/platform/x11/x11_clipboard_ozone.cc +++ b/ui/ozone/platform/x11/x11_clipboard_ozone.cc
@@ -65,7 +65,7 @@ std::vector<std::string> mime_types; // Data most recently read from remote clipboard. - std::vector<unsigned char> data; + PlatformClipboard::Data data; // Mime type of most recently read data from remote clipboard. std::string data_mime_type; @@ -171,7 +171,7 @@ auto it = offer_data_map.find(key); if (it != offer_data_map.end()) { ui::SetArrayProperty(event.requestor, event.property, event.target, - it->second); + it->second->data()); } } @@ -228,7 +228,8 @@ ui::GetArrayProperty(x_window_, x_property_, &data, &type); ui::DeleteProperty(x_window_, x_property_); if (type != x11::Atom::None) - selection_state.data = std::move(data); + selection_state.data = scoped_refptr<base::RefCountedBytes>( + base::RefCountedBytes::TakeVector(&data)); // If we have a saved callback, invoke it now, otherwise this was a prefetch // and we have already saved |data_| for the next call to @@ -253,7 +254,7 @@ auto& selection_state = GetSelectionState(selection); selection_state.mime_types.clear(); selection_state.data_mime_type.clear(); - selection_state.data.clear(); + selection_state.data.reset(); QueryTargets(selection); } @@ -301,7 +302,7 @@ void X11ClipboardOzone::ReadRemoteClipboard(x11::Atom selection) { auto& selection_state = GetSelectionState(selection); - selection_state.data.clear(); + selection_state.data.reset(); // Allow conversions for text/plain[;charset=utf-8] <=> [UTF8_]STRING. std::string target = selection_state.data_mime_type; if (!Contains(selection_state.mime_types, target)) { @@ -346,8 +347,9 @@ // If we have already prefetched the clipboard for the correct mime type, // then send it right away, otherwise save the callback and attempt to get the // requested mime type from the remote clipboard. - if (!using_xfixes_ || (selection_state.data_mime_type == mime_type && - !selection_state.data.empty())) { + if (!using_xfixes_ || + (selection_state.data_mime_type == mime_type && selection_state.data && + !selection_state.data->data().empty())) { data_map->emplace(mime_type, selection_state.data); std::move(callback).Run(selection_state.data); return;
diff --git a/ui/ozone/public/platform_clipboard.h b/ui/ozone/public/platform_clipboard.h index 5ef3fb3d..7390222 100644 --- a/ui/ozone/public/platform_clipboard.h +++ b/ui/ozone/public/platform_clipboard.h
@@ -12,6 +12,7 @@ #include "base/callback_forward.h" #include "base/component_export.h" #include "base/macros.h" +#include "base/memory/ref_counted_memory.h" #include "base/optional.h" #include "ui/base/clipboard/clipboard_buffer.h" @@ -30,7 +31,7 @@ // DataMap is a map from "mime type" to associated data, whereas // the data can be organized differently for each mime type. - using Data = std::vector<uint8_t>; + using Data = scoped_refptr<base::RefCountedBytes>; using DataMap = std::unordered_map<std::string, Data>; // SequenceNumberUpdateCb is a repeating callback, which can be used to tell @@ -63,7 +64,7 @@ // RequestDataClosure is invoked to acknowledge that the requested clipboard // data has been read and stored into 'data_map'. using RequestDataClosure = - base::OnceCallback<void(const base::Optional<std::vector<uint8_t>>&)>; + base::OnceCallback<void(const base::Optional<Data>&)>; virtual void RequestClipboardData(ClipboardBuffer buffer, const std::string& mime_type, DataMap* data_map,
diff --git a/ui/webui/resources/css/cros_colors.json5 b/ui/webui/resources/css/cros_colors.json5 index 47a2c34..817153c9 100644 --- a/ui/webui/resources/css/cros_colors.json5 +++ b/ui/webui/resources/css/cros_colors.json5
@@ -18,26 +18,26 @@ /* * Core colors. */ - default_text_color: { + text_color_primary: { light: "$google_grey_900", dark: "$google_grey_200", }, - default_text_color_secondary: { + text_color_secondary: { light: "$google_grey_700", dark: "$google_grey_500", }, - default_bg_color: { + bg_color: { light: "#ffffff", dark: "$google_grey_900", }, - default_icon_color_primary: { + icon_color_primary: { light: "$google_grey_700", dark: "$google_grey_200", }, - default_icon_color_prominent: { + icon_color_prominent: { light: "$google_blue_600", dark: "$google_blue_300", }, @@ -45,20 +45,20 @@ /* * Component colors. */ - default_toolbar_bg_color: "#ffffff", - default_toolbar_search_bg_color: "$google_grey_100", + toolbar_bg_color: "#ffffff", + toolbar_search_bg_color: "$google_grey_100", menu_button_bg_color_active: "$google_blue_50", menu_button_bg_color_hover: "$google_grey_100", menu_button_outline_color_focused: "$google_blue_600", - toggle_color: "$default_icon_color_prominent", + toggle_color: "$icon_color_prominent", toggle_bg_color_inactive: "$google_grey_400", toggle_button_color_inactive: "#ffffff", toggle_ripple_color: "rgba($toggle_color_rgb, .2)", toggle_ripple_color_inactive: "rgba($google_grey_600_rgb, .15)", - radio_button_color: "$default_icon_color_prominent", + radio_button_color: "$icon_color_prominent", radio_button_ripple_color: "rgba($radio_button_color_rgb, .2)", radio_button_color_unchecked: "$google_grey_700", radio_button_ripple_color_unchecked: "rgba($google_grey_600_rgb, .15)", @@ -68,79 +68,79 @@ link_color: "$google_blue_700", /* button-primary */ - default_button_background_color_primary: - "$default_icon_color_prominent", - default_button_label_color_primary: { + button_background_color_primary: + "$icon_color_prominent", + button_label_color_primary: { light: "$google_grey_200", dark: "$google_grey_900", }, /* button-primary:hover */ /* TODO(calamity): Generate a linear-gradient() to use for compositing backgrounds */ - default_button_background_color_primary_hover_overlay: { + button_background_color_primary_hover_overlay: { light: "rgba(255, 255, 255, 0.08)", dark: "rgba(0, 0, 0, 0.08)", }, /* button-primary[disabled] */ - default_button_background_color_primary_disabled: { + button_background_color_primary_disabled: { light: "$google_grey_100", dark: "$google_grey_800", }, - default_button_label_color_primary_disabled: { + button_label_color_primary_disabled: { light: "$google_grey_600", dark: "$google_grey_500", }, /* button-secondary */ - default_button_label_color_secondary: - "$default_icon_color_prominent", - default_button_stroke_color_secondary: { + button_label_color_secondary: + "$icon_color_prominent", + button_stroke_color_secondary: { light: "$google_grey_300", dark: "$google_grey_700", }, /* button-secondary:hover */ - default_button_background_color_secondary_hover: - "rgba($default_icon_color_prominent_rgb, 0.04)", + button_background_color_secondary_hover: + "rgba($icon_color_prominent_rgb, 0.04)", /* button-secondary[disabled] */ - default_button_label_color_secondary_disabled: { + button_label_color_secondary_disabled: { light: "$google_grey_600", dark: "$google_grey_500", }, - default_button_stroke_color_secondary_disabled: { + button_stroke_color_secondary_disabled: { light: "$google_grey_100", dark: "$google_grey_800", }, /* textfield */ - default_textfield_background_color: { + textfield_background_color: { light: "$google_grey_100", dark: "rgba(0, 0, 0, 0.3)", }, - default_texfield_label_color: { + textfield_label_color: { light: "$google_grey_700", dark: "rgba(255, 255, 255, 0.6)", }, - default_texfield_input_color: { + textfield_input_color: { light: "$google_grey_900", dark: "rgba(255, 255, 255, 0.87)", }, /* textfield:focus */ - default_texfield_label_color_focus: "$default_icon_color_prominent", + textfield_label_color_focus: "$icon_color_prominent", /* textfield[error] */ - default_texfield_label_color_error: { + textfield_label_color_error: { light: "$google_red_600", dark: "$google_red_300", }, /* textfield[disabled] */ - default_textfield_background_color_disabled: { + textfield_background_color_disabled: { light: "rgba($google_grey_100_rgb, 0.38)", dark: "rgba(0, 0, 0, 0.11)", }, - default_texfield_label_color_disabled: { + textfield_label_color_disabled: { light: "rgba($google_grey_700_rgb, 0.38)", dark: "rgba(0, 0, 0, 0.23)", }, - default_texfield_input_color_disabled: { + textfield_input_color_disabled: { light: "rgba($google_grey_900_rgb, 0.38)", dark: "rgba(255, 255, 255, 0.33)", },