diff --git a/DEPS b/DEPS index 365cf1d..393ed56c 100644 --- a/DEPS +++ b/DEPS
@@ -133,7 +133,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'b595027bab397770e0f3e6c78cc17ceed9eaf6cd', + 'v8_revision': '90dd5c15e452371cf815d7dc773b96853bc7924b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -141,7 +141,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'd5ff4fadd867f7adee0e8f88e37230ce61d109c5', + 'angle_revision': 'a7440a2273f304c5b02148c050f4a5e9172ae977', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -149,7 +149,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '7f7405ec47e9ca045d6bf391a05a423e5f1338e9', + 'pdfium_revision': 'c75ce35aa1a75ab3aed909dad553a46719db2f48', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -196,7 +196,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': 'dc3ad63a09b8ca5e3f79ecb2f4794c1da6ced43b', + 'catapult_revision': '6145021beb12262bfb569601fd431b8d2de76c9d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -268,7 +268,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': '20b0c33913e45cd3d553b42a43b75b27af817833', + 'dawn_revision': 'cf52d711fbcbc7aa66e40c7524258d80d5efe444', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -767,7 +767,7 @@ }, 'src/third_party/breakpad/breakpad': - Var('chromium_git') + '/breakpad/breakpad.git' + '@' + '19a8433a604e6105575c08529fc8e0b2947f5af5', + Var('chromium_git') + '/breakpad/breakpad.git' + '@' + '232c45abee1753785ae32938589eede535bdb06d', 'src/third_party/byte_buddy': { 'packages': [ @@ -805,7 +805,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '4206f6a183ae23c0f0dc402e04631ec6ab5a2216', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'e255b9cdc43dd9a434abd2136e4e3fd9afb070f0', 'condition': 'checkout_linux', }, @@ -830,7 +830,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '0b62ed79ed5049332f58c06dbdb8e8bc4105010e', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '1fb046306b9ebe160eeacc7843ee1ddd15a47ffa', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1172,7 +1172,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '71cac8bfa4a8126c400d08ce0517771f5c29537b', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '86820d1f3a7d486e40bbaeda455b030d71f07c40', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1343,7 +1343,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '688fbfe33779392aa210d67d4aa12cb012f112c2', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'e9d2b4efdd5dddaa3a476c0ac2a9cf9125b39929', + Var('webrtc_git') + '/src.git' + '@' + '6fdbba3a0381a5b828d5c466bcacfbe9e7a44dff', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1384,7 +1384,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@8342a7f2fc299ccd32d5335f335316049654629a', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c0eaf0c733e8f3d5071647fe36035e368f217c4a', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_feature_list_creator.cc b/android_webview/browser/aw_feature_list_creator.cc index 28f2c20..6ea8ebadd 100644 --- a/android_webview/browser/aw_feature_list_creator.cc +++ b/android_webview/browser/aw_feature_list_creator.cc
@@ -170,12 +170,6 @@ std::vector<std::string>(), /*low_entropy_provider=*/nullptr, std::make_unique<base::FeatureList>(), aw_field_trials_.get(), &ignored_safe_seed_manager); - - // Activate a study which exercises permanent-consistency, to test the launch - // of permanent-consistency support in WebView. - // TODO(crbug/917537): Remove this after m73. - base::FieldTrialList::FindFullName("AndroidWebViewConsistencyTest"); - base::FieldTrialList::FindFullName("AndroidWebViewSessionConsistencyTest"); } void AwFeatureListCreator::CreateFeatureListAndFieldTrials() {
diff --git a/ash/DEPS b/ash/DEPS index 7b96327..1270d40 100644 --- a/ash/DEPS +++ b/ash/DEPS
@@ -59,8 +59,9 @@ "+chromeos/audio", "+chromeos/components/multidevice/logging/logging.h", "+chromeos/constants", + # TODO(stevenjb): Eliminate this. http://crbug.com/940810 + "+chromeos/dbus/audio", "+chromeos/dbus/biod/biod_client.h", - "+chromeos/dbus/cras_audio_client.h", "+chromeos/dbus/dbus_thread_manager.h", "+chromeos/dbus/fake_power_manager_client.h", "+chromeos/dbus/hammerd", @@ -68,7 +69,7 @@ "+chromeos/dbus/power_manager", "+chromeos/dbus/shill_device_client.h", "+chromeos/dbus/system_clock", - # TODO(jamescook): Eliminate this. http://crbug.com/644355 + # TODO(stevenjb): Eliminate this. http://crbug.com/644355 "+chromeos/network", "+chromeos/services/assistant/public" , "+chromeos/services/assistant/test_support",
diff --git a/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc b/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc index 154898f..c190e27 100644 --- a/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc +++ b/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc
@@ -89,11 +89,27 @@ illustration_view->AddChildView(text); } -views::ScrollView* CreateScrollView(std::unique_ptr<views::View> content_view) { - views::ScrollView* const scroller = new views::ScrollView(); +class ShortcutsListScrollView : public views::ScrollView { + public: + ShortcutsListScrollView() = default; + ~ShortcutsListScrollView() override = default; + + // views::View: + void OnFocus() override { SetHasFocusIndicator(true); } + + void OnBlur() override { SetHasFocusIndicator(false); } + + private: + DISALLOW_COPY_AND_ASSIGN(ShortcutsListScrollView); +}; + +ShortcutsListScrollView* CreateScrollView( + std::unique_ptr<views::View> content_view) { + ShortcutsListScrollView* const scroller = new ShortcutsListScrollView(); scroller->set_draw_overflow_indicator(false); scroller->ClipHeightTo(0, 0); scroller->SetContents(std::move(content_view)); + scroller->SetFocusBehavior(views::View::FocusBehavior::ALWAYS); return scroller; }
diff --git a/ash/system/unified/unified_slider_bubble_controller.cc b/ash/system/unified/unified_slider_bubble_controller.cc index aa793bc..f88ce28 100644 --- a/ash/system/unified/unified_slider_bubble_controller.cc +++ b/ash/system/unified/unified_slider_bubble_controller.cc
@@ -167,9 +167,9 @@ init_params.anchor_rect = tray_->shelf()->GetSystemTrayAnchorRect(); // Decrease bottom and right insets to compensate for the adjustment of // the respective edges in Shelf::GetSystemTrayAnchorRect(). - init_params.insets = - gfx::Insets(kUnifiedMenuPadding, kUnifiedMenuPadding, - kUnifiedMenuPadding - 1, kUnifiedMenuPadding - 1); + init_params.insets = gfx::Insets( + kUnifiedMenuPadding, kUnifiedMenuPadding, kUnifiedMenuPadding - 1, + kUnifiedMenuPadding - (base::i18n::IsRTL() ? 0 : 1)); init_params.corner_radius = kUnifiedTrayCornerRadius; init_params.has_shadow = false;
diff --git a/ash/system/unified/unified_system_tray_bubble.cc b/ash/system/unified/unified_system_tray_bubble.cc index 57cd0d5..e535c91 100644 --- a/ash/system/unified/unified_system_tray_bubble.cc +++ b/ash/system/unified/unified_system_tray_bubble.cc
@@ -84,9 +84,9 @@ init_params.anchor_rect = tray->shelf()->GetSystemTrayAnchorRect(); // Decrease bottom and right insets to compensate for the adjustment of // the respective edges in Shelf::GetSystemTrayAnchorRect(). - init_params.insets = - gfx::Insets(kUnifiedMenuPadding, kUnifiedMenuPadding, - kUnifiedMenuPadding - 1, kUnifiedMenuPadding - 1); + init_params.insets = gfx::Insets( + kUnifiedMenuPadding, kUnifiedMenuPadding, kUnifiedMenuPadding - 1, + kUnifiedMenuPadding - (base::i18n::IsRTL() ? 0 : 1)); init_params.corner_radius = kUnifiedTrayCornerRadius; init_params.has_shadow = false; init_params.show_by_click = show_by_click;
diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc index fe561bc..635b3ad 100644 --- a/ash/test/ash_test_helper.cc +++ b/ash/test/ash_test_helper.cc
@@ -31,7 +31,7 @@ #include "base/strings/string_split.h" #include "base/token.h" #include "chromeos/audio/cras_audio_handler.h" -#include "chromeos/dbus/cras_audio_client.h" +#include "chromeos/dbus/audio/cras_audio_client.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/power/power_policy_controller.h" #include "chromeos/network/network_handler.h"
diff --git a/ash/wm/overview/overview_controller.cc b/ash/wm/overview/overview_controller.cc index 5c12e00d..86e680d 100644 --- a/ash/wm/overview/overview_controller.cc +++ b/ash/wm/overview/overview_controller.cc
@@ -478,6 +478,7 @@ split_view_controller->EndSplitView(); if (IsSelecting()) ToggleOverview(); + MaximizeIfSnapped(active_window); ::wm::ActivateWindow(active_window); base::RecordAction( base::UserMetricsAction("Tablet_LongPressOverviewButtonExitSplitView"));
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index dc4f0bcf..3f1c3bc 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -388,7 +388,7 @@ overview_session_ = nullptr; while (!window_list_.empty()) - RemoveItem(window_list_.back().get(), /*reposition=*/false); + RemoveItem(window_list_.back().get()); // HomeLauncherGestureHandler will handle fading/sliding |shield_widget_| in // this exit mode. @@ -604,24 +604,20 @@ PositionWindows(animate); } -void OverviewGrid::RemoveItem(OverviewItem* overview_item, bool reposition) { +void OverviewGrid::RemoveItem(OverviewItem* overview_item) { auto* window = overview_item->GetWindow(); // Use reverse iterator to be efficiently when removing all. auto iter = std::find_if(window_list_.rbegin(), window_list_.rend(), [window](std::unique_ptr<OverviewItem>& item) { return item->GetWindow() == window; }); - if (iter != window_list_.rend()) { - window_observer_.Remove(window); - window_state_observer_.Remove(wm::GetWindowState(window)); - // Erase from the list first because deleting OverviewItem can lead to - // iterating through the |window_list_|. - std::unique_ptr<OverviewItem> tmp = std::move(*iter); - window_list_.erase(std::next(iter).base()); - } - - if (reposition) - PositionWindows(/*animate=*/true); + DCHECK(iter != window_list_.rend()); + window_observer_.Remove(window); + window_state_observer_.Remove(wm::GetWindowState(window)); + // Erase from the list first because deleting OverviewItem can lead to + // iterating through the |window_list_|. + std::unique_ptr<OverviewItem> tmp = std::move(*iter); + window_list_.erase(std::next(iter).base()); } void OverviewGrid::SetBoundsAndUpdatePositions(const gfx::Rect& bounds) { @@ -787,10 +783,8 @@ // happen in the primary display. // The |drop_target_widget_| may not in the same display as // |dragged_window|, which will cause |drop_target_item| to be null. - if (drop_target_item) { - overview_session_->RemoveOverviewItem(drop_target_item, - /*reposition=*/false); - } + if (drop_target_item) + overview_session_->RemoveItem(drop_target_item); drop_target_widget_.reset(); // Called to reset caption and title visibility after dragging.
diff --git a/ash/wm/overview/overview_grid.h b/ash/wm/overview/overview_grid.h index 3c7eaabd..332940b4 100644 --- a/ash/wm/overview/overview_grid.h +++ b/ash/wm/overview/overview_grid.h
@@ -98,9 +98,9 @@ // reposition with animation. void AddItem(aura::Window* window, bool reposition, bool animate); - // Removes |overview_item| from the grid. If |reposition| is true, reposition - // all window items in the grid after removing the item. - void RemoveItem(OverviewItem* overview_item, bool reposition); + // Removes |overview_item| from the grid. |overview_item| cannot already be + // absent from the grid. No items are repositioned, and there is no animation. + void RemoveItem(OverviewItem* overview_item); // Sets bounds for the window grid and positions all windows in the grid. void SetBoundsAndUpdatePositions(const gfx::Rect& bounds_in_screen);
diff --git a/ash/wm/overview/overview_item.cc b/ash/wm/overview/overview_item.cc index 5b5cdb3..9e865e6f 100644 --- a/ash/wm/overview/overview_item.cc +++ b/ash/wm/overview/overview_item.cc
@@ -28,6 +28,7 @@ #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ash/wm/window_state.h" #include "ash/wm/window_transient_descendant_iterator.h" +#include "ash/wm/wm_event.h" #include "base/auto_reset.h" #include "base/metrics/user_metrics.h" #include "ui/compositor/layer_animation_sequence.h" @@ -145,6 +146,17 @@ } void OverviewItem::RestoreWindow(bool reset_transform) { + // TODO(oshima): SplitViewController has its own logic to adjust the + // target state in |SplitViewController::OnOverviewModeEnding|. + // Unify the mechanism to control it and remove ifs. + if (Shell::Get() + ->tablet_mode_controller() + ->IsTabletModeWindowManagerEnabled() && + !Shell::Get()->split_view_controller()->IsSplitViewModeActive() && + reset_transform) { + MaximizeIfSnapped(GetWindow()); + } + caption_container_view_->ResetEventDelegate(); transform_window_.RestoreWindow( reset_transform, overview_session_->enter_exit_overview_type()); @@ -253,7 +265,7 @@ void OverviewItem::SetBounds(const gfx::RectF& target_bounds, OverviewAnimationType animation_type) { - if (in_bounds_update_) + if (in_bounds_update_ || !Shell::Get()->overview_controller()->IsSelecting()) return; // Do not animate if the resulting bounds does not change. The original @@ -675,6 +687,10 @@ const gfx::Rect& old_bounds, const gfx::Rect& new_bounds, ui::PropertyChangeReason reason) { + // Do not keep the overview bounds if we're shutting down. + if (!Shell::Get()->overview_controller()->IsSelecting()) + return; + if (reason == ui::PropertyChangeReason::NOT_FROM_ANIMATION) { if (window == GetWindow()) { transform_window_.ResizeMinimizedWidgetIfNeeded();
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc index 34949b42..4376153 100644 --- a/ash/wm/overview/overview_session.cc +++ b/ash/wm/overview/overview_session.cc
@@ -183,6 +183,8 @@ // constructed object. void OverviewSession::Init(const WindowList& windows, const WindowList& hide_windows) { + Shell::Get()->AddShellObserver(this); + hide_overview_windows_ = std::make_unique<ScopedOverviewHideWindows>(std::move(hide_windows)); if (restore_focus_window_) @@ -288,6 +290,7 @@ // restoring_minimized_windows() on a partially destructed object. void OverviewSession::Shutdown() { Shell::Get()->RemovePreTargetHandler(this); + Shell::Get()->RemoveShellObserver(this); // Stop observing screen metrics changes first to avoid auto-positioning // windows in response to work area changes from window activation. @@ -464,18 +467,18 @@ ::wm::ActivateWindow(GetOverviewFocusWindow()); } -void OverviewSession::RemoveOverviewItem(OverviewItem* item, bool reposition) { - if (item->GetWindow()->HasObserver(this)) { - item->GetWindow()->RemoveObserver(this); - observed_windows_.erase(item->GetWindow()); - if (item->GetWindow() == restore_focus_window_) +void OverviewSession::RemoveItem(OverviewItem* overview_item) { + if (overview_item->GetWindow()->HasObserver(this)) { + overview_item->GetWindow()->RemoveObserver(this); + observed_windows_.erase(overview_item->GetWindow()); + if (overview_item->GetWindow() == restore_focus_window_) restore_focus_window_ = nullptr; } - // Remove |item| from the corresponding grid. + // Remove |overview_item| from the corresponding grid. for (std::unique_ptr<OverviewGrid>& grid : grid_list_) { - if (grid->GetOverviewItemContaining(item->GetWindow())) { - grid->RemoveItem(item, reposition); + if (grid->GetOverviewItemContaining(overview_item->GetWindow())) { + grid->RemoveItem(overview_item); --num_items_; break; } @@ -817,6 +820,11 @@ event->StopPropagation(); } +void OverviewSession::OnShellDestroying() { + // Cancel selection will call |Shutodnw()|, which will remove observer. + CancelSelection(); +} + void OverviewSession::OnSplitViewStateChanged( SplitViewController::State previous_state, SplitViewController::State state) {
diff --git a/ash/wm/overview/overview_session.h b/ash/wm/overview/overview_session.h index 7eb9cf5d..c0daa82 100644 --- a/ash/wm/overview/overview_session.h +++ b/ash/wm/overview/overview_session.h
@@ -12,6 +12,7 @@ #include <vector> #include "ash/ash_export.h" +#include "ash/shell_observer.h" #include "ash/wm/overview/scoped_overview_hide_windows.h" #include "ash/wm/splitview/split_view_controller.h" #include "base/containers/flat_set.h" @@ -50,6 +51,7 @@ class ASH_EXPORT OverviewSession : public display::DisplayObserver, public aura::WindowObserver, public ui::EventHandler, + public ShellObserver, public SplitViewController::Observer { public: enum Direction { LEFT, UP, RIGHT, DOWN }; @@ -147,14 +149,12 @@ // then added to the overview. void AddItem(aura::Window* window, bool reposition, bool animate); - // Removes the overview item from the overview grid. And if - // |reposition| is true, re-position all windows in the target overview grid. - // This may be called in two scenarioes: 1) when a user drags an overview item - // to snap to one side of the screen, the item should be removed from the - // overview grid; 2) when a window (not from overview) ends its dragging while - // overview is open, the drop target should be removed. Note in both cases, - // the windows in the window grid do not need to be repositioned. - void RemoveOverviewItem(OverviewItem* item, bool reposition); + // Removes |overview_item| from the corresponding overview grid. This may be + // called in two scenarioes: 1) when a user drags an overview item to snap to + // one side of the screen, the item should be removed from the overview grid; + // 2) when a window (not from overview) ends its dragging while overview is + // open, the drop target should be removed. + void RemoveItem(OverviewItem* overview_item); void InitiateDrag(OverviewItem* item, const gfx::PointF& location_in_screen); void Drag(OverviewItem* item, const gfx::PointF& location_in_screen); @@ -268,6 +268,9 @@ // ui::EventHandler: void OnKeyEvent(ui::KeyEvent* event) override; + // ShelObserver: + void OnShellDestroying() override; + // SplitViewController::Observer: void OnSplitViewStateChanged(SplitViewController::State previous_state, SplitViewController::State state) override;
diff --git a/ash/wm/overview/overview_utils.cc b/ash/wm/overview/overview_utils.cc index da5f3af..3fa6edf 100644 --- a/ash/wm/overview/overview_utils.cc +++ b/ash/wm/overview/overview_utils.cc
@@ -10,6 +10,7 @@ #include "ash/home_screen/home_screen_controller.h" #include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/shell_window_ids.h" +#include "ash/scoped_animation_disabler.h" #include "ash/shell.h" #include "ash/wm/overview/cleanup_animation_observer.h" #include "ash/wm/overview/overview_controller.h" @@ -19,6 +20,7 @@ #include "ash/wm/splitview/split_view_utils.h" #include "ash/wm/window_state.h" #include "ash/wm/window_transient_descendant_iterator.h" +#include "ash/wm/wm_event.h" #include "base/no_destructor.h" #include "third_party/skia/include/pathops/SkPathOps.h" #include "ui/aura/window.h" @@ -304,4 +306,13 @@ return false; } +void MaximizeIfSnapped(aura::Window* window) { + auto* window_state = wm::GetWindowState(window); + if (window_state && window_state->IsSnapped()) { + ScopedAnimationDisabler disabler(window); + wm::WMEvent event(wm::WM_EVENT_MAXIMIZE); + window_state->OnWMEvent(&event); + } +} + } // namespace ash
diff --git a/ash/wm/overview/overview_utils.h b/ash/wm/overview/overview_utils.h index 5d412d8..a7a1c73 100644 --- a/ash/wm/overview/overview_utils.h +++ b/ash/wm/overview/overview_utils.h
@@ -81,6 +81,9 @@ // Checks if we are currently in sliding up on the shelf to hide overview mode. bool IsSlidingOutOverviewFromShelf(); +// Maximize the window if it is snapped without animation. +void MaximizeIfSnapped(aura::Window* window); + } // namespace ash #endif // ASH_WM_OVERVIEW_OVERVIEW_UTILS_H_
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc index d71b9c3..6e266a5 100644 --- a/ash/wm/splitview/split_view_controller.cc +++ b/ash/wm/splitview/split_view_controller.cc
@@ -856,8 +856,7 @@ // is unavailable to retrieve outside this function after // OnOverviewEnding is notified. overview_item->RestoreWindow(/*reset_transform=*/false); - overview_session->RemoveOverviewItem(overview_item.get(), - /*reposition=*/false); + overview_session->RemoveItem(overview_item.get()); SnapWindow(window, (default_snap_position_ == LEFT) ? RIGHT : LEFT); // If ending overview causes a window to snap, also do not do exiting // overview animation. @@ -1253,7 +1252,7 @@ // this will be need to updated. TabletModeWindowState::UpdateWindowPosition( wm::GetWindowState(insert_overview_window), /*animate=*/false); - InsertWindowToOverview(insert_overview_window); + InsertWindowToOverview(insert_overview_window, /*animate=*/false); } } @@ -1302,7 +1301,8 @@ // If there is no snapped window at this moment, ends split view mode. Note // this will update overview window grid bounds if the overview mode is // active at the moment. - EndSplitView(); + EndSplitView(window_drag ? EndReason::kWindowDragStarted + : EndReason::kNormal); } else { // If there is still one snapped window after minimizing/closing one snapped // window, update its snap state and open overview window grid. @@ -1594,7 +1594,7 @@ // repositioned in this case as they have been positioned to the right place // during dragging. item->RestoreWindow(/*reset_transform=*/false); - overview_session->RemoveOverviewItem(item, /*reposition=*/false); + overview_session->RemoveItem(item); } void SplitViewController::UpdateSnappingWindowTransformedBounds( @@ -1605,10 +1605,11 @@ } } -void SplitViewController::InsertWindowToOverview(aura::Window* window) { +void SplitViewController::InsertWindowToOverview(aura::Window* window, + bool animate) { if (!window || !GetOverviewSession()) return; - GetOverviewSession()->AddItem(window, /*reposition=*/true, /*animate=*/true); + GetOverviewSession()->AddItem(window, /*reposition=*/true, animate); } void SplitViewController::StartOverview(bool window_drag) { @@ -1701,6 +1702,16 @@ // Note SnapWindow() might put the previous window that was snapped at the // |desired_snap_position| in overview. SnapWindow(window, desired_snap_position); + // Reapply the bounds update because the bounds might have been + // modified by dragging operation. + // TODO(oshima): WindowState already gets notified when drag ends. Refactor + // WindowState so that each state implementation can take action when + // drag ends. + const wm::WMEvent event(desired_snap_position == SplitViewController::LEFT + ? wm::WM_EVENT_SNAP_LEFT + : wm::WM_EVENT_SNAP_RIGHT); + wm::GetWindowState(window)->OnWMEvent(&event); + if (!was_splitview_active) { // If splitview mode was not active before snapping the dragged // window, snap the initiator window to the other side of the screen
diff --git a/ash/wm/splitview/split_view_controller.h b/ash/wm/splitview/split_view_controller.h index 5b6ecdcd..2d6cef1 100644 --- a/ash/wm/splitview/split_view_controller.h +++ b/ash/wm/splitview/split_view_controller.h
@@ -64,12 +64,14 @@ // Why splitview was ended. For now, all reasons will be kNormal except when // the home launcher button is pressed, an unsnappable window just got - // activated, or the active user session changed. + // activated, the active user session changed, or the window dragging + // started. enum class EndReason { kNormal = 0, kHomeLauncherPressed, kUnsnappableWindowActivated, kActiveUserChanged, + kWindowDragStarted, }; class Observer { @@ -349,7 +351,7 @@ // Inserts |window| into overview window grid if overview mode is active. Do // nothing if overview mode is inactive at the moment. - void InsertWindowToOverview(aura::Window* window); + void InsertWindowToOverview(aura::Window* window, bool animate = true); // Starts/Ends overview mode if the overview mode is inactive/active. void StartOverview(bool window_drag = false);
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc index fe9fed1..f9ba055 100644 --- a/ash/wm/splitview/split_view_controller_unittest.cc +++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -2465,7 +2465,11 @@ // for the |dragged_window|. std::unique_ptr<WindowResizer> StartDrag(aura::Window* dragged_window, aura::Window* source_window) { + // Drag operation activates the window first, then activates the dragged + // window. Emulate this behavior. + wm::ActivateWindow(source_window); SetIsInTabDragging(dragged_window, /*is_dragging=*/true, source_window); + wm::ActivateWindow(dragged_window); std::unique_ptr<WindowResizer> resizer = CreateResizerForTest( dragged_window, dragged_window->bounds().origin(), HTCAPTION); GetBrowserWindowDragController(resizer.get()) @@ -3184,9 +3188,8 @@ OverviewGrid* current_grid = overview_session->GetGridWithRootWindow(window2->GetRootWindow()); ASSERT_TRUE(current_grid); - overview_session->RemoveOverviewItem( - current_grid->GetOverviewItemContaining(window2.get()), - /*reposition=*/false); + overview_session->RemoveItem( + current_grid->GetOverviewItemContaining(window2.get())); resizer = StartDrag(window2.get(), window1.get()); ASSERT_TRUE(resizer.get()); @@ -3223,9 +3226,8 @@ // 2.b. The dragged window can snap to the other side of the splitscreen, // causing overview mode to end. // Remove |window1| from overview first before tab dragging. - overview_session->RemoveOverviewItem( - current_grid->GetOverviewItemContaining(window1.get()), - /*reposition=*/false); + overview_session->RemoveItem( + current_grid->GetOverviewItemContaining(window1.get())); resizer = StartDrag(window1.get(), window2.get()); ASSERT_TRUE(resizer.get()); DragWindowTo(resizer.get(), gfx::Point(600, 500)); @@ -3806,12 +3808,15 @@ split_view_controller()->SnapWindow(window1.get(), SplitViewController::LEFT); split_view_controller()->SnapWindow(window2.get(), SplitViewController::RIGHT); + auto* window_state1 = wm::GetWindowState(window1.get()); + auto* window_state2 = wm::GetWindowState(window2.get()); // Drags |window2| to overview. std::unique_ptr<WindowResizer> resizer = StartDrag(window2.get(), window2.get()); gfx::Rect drop_target_bounds = GetDropTargetBoundsDuringDrag(window1.get()); DragWindowTo(resizer.get(), drop_target_bounds.CenterPoint()); + EXPECT_TRUE(window_state2->IsSnapped()); CompleteDrag(std::move(resizer)); OverviewController* selector_controller = Shell::Get()->overview_controller(); EXPECT_TRUE(selector_controller->IsSelecting()); @@ -3819,18 +3824,22 @@ window2.get())); EXPECT_EQ(split_view_controller()->state(), SplitViewController::LEFT_SNAPPED); + EXPECT_TRUE(window_state2->IsSnapped()); // Drags |window1| by a small distance. Both splitview and overview should be // ended and |window1| is the active window and above |window2|. resizer = StartDrag(window1.get(), window1.get()); DragWindowTo(resizer.get(), gfx::Point(10, 10)); + EXPECT_TRUE(window_state1->IsSnapped()); + EXPECT_TRUE(window_state2->IsSnapped()); + CompleteDrag(std::move(resizer)); EXPECT_FALSE(selector_controller->IsSelecting()); EXPECT_FALSE(split_view_controller()->IsSplitViewModeActive()); - EXPECT_TRUE(wm::GetWindowState(window1.get())->IsMaximized()); - EXPECT_TRUE(wm::GetWindowState(window2.get())->IsMaximized()); - EXPECT_TRUE(wm::GetWindowState(window1.get())->IsActive()); - EXPECT_FALSE(wm::GetWindowState(window2.get())->IsActive()); + EXPECT_TRUE(window_state1->IsMaximized()); + EXPECT_TRUE(window_state2->IsMaximized()); + EXPECT_TRUE(window_state1->IsActive()); + EXPECT_FALSE(window_state2->IsActive()); // |window1| should above |window2|. const aura::Window::Windows windows = window1->parent()->children(); auto window1_layer = std::find(windows.begin(), windows.end(), window1.get()); @@ -4055,6 +4064,9 @@ DragWindowTo(resizer.get(), gfx::Point(100, 200)); EXPECT_EQ(window1->bounds(), snapped_bounds1); EXPECT_EQ(window2->bounds(), snapped_bounds2); + EXPECT_EQ(split_view_controller()->state(), + SplitViewController::BOTH_SNAPPED); + CompleteDrag(std::move(resizer)); // In this case |window3| is supposed to merge back its source window // |window1|, so we only test the source window's bounds here.
diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager.cc b/ash/wm/tablet_mode/tablet_mode_window_manager.cc index 83f6cabbe..a8b59a5 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_manager.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_manager.cc
@@ -17,6 +17,7 @@ #include "ash/wm/mru_window_tracker.h" #include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_session.h" +#include "ash/wm/overview/overview_utils.h" #include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/splitview/split_view_utils.h" #include "ash/wm/tablet_mode/scoped_skip_user_session_blocked_check.h" @@ -83,8 +84,9 @@ window->RemoveObserver(this); added_windows_.clear(); Shell::Get()->RemoveShellObserver(this); - display::Screen::GetScreen()->RemoveObserver(this); Shell::Get()->session_controller()->RemoveObserver(this); + Shell::Get()->overview_controller()->RemoveObserver(this); + display::Screen::GetScreen()->RemoveObserver(this); EnableBackdropBehindTopWindowOnEachDisplay(false); RemoveWindowCreationObservers(); ArrangeWindowsForDesktopMode(was_in_overview); @@ -118,6 +120,27 @@ window_state_map_.erase(it); } +void TabletModeWindowManager::OnOverviewModeEndingAnimationComplete( + bool canceled) { + if (canceled) + return; + + auto* split_view_controller = Shell::Get()->split_view_controller(); + + // Maximize all snapped windows upon exiting overview mode except snapped + // windows in splitview mode. Note the snapped window might not be tracked in + // our |window_state_map_|. + MruWindowTracker::WindowList windows = + Shell::Get()->mru_window_tracker()->BuildWindowListIgnoreModal(); + for (auto* window : windows) { + if (split_view_controller->left_window() != window && + split_view_controller->right_window() != window) { + MaximizeIfSnapped(window); + } + } +} + +// ShellObserver: void TabletModeWindowManager::OnSplitViewModeEnded() { switch (Shell::Get()->split_view_controller()->end_reason()) { case SplitViewController::EndReason::kNormal: @@ -125,6 +148,7 @@ break; case SplitViewController::EndReason::kHomeLauncherPressed: case SplitViewController::EndReason::kActiveUserChanged: + case SplitViewController::EndReason::kWindowDragStarted: // For the case of kHomeLauncherPressed, the home launcher will minimize // the snapped windows after ending splitview, so avoid maximizing them // here. For the case of kActiveUserChanged, the snapped windows will be @@ -138,14 +162,8 @@ // window might not be tracked in our |window_state_map_|. MruWindowTracker::WindowList windows = Shell::Get()->mru_window_tracker()->BuildWindowListIgnoreModal(); - for (auto* window : windows) { - wm::WindowState* window_state = wm::GetWindowState(window); - if (window_state->IsSnapped()) { - ScopedAnimationDisabler disable(window); - wm::WMEvent event(wm::WM_EVENT_MAXIMIZE); - window_state->OnWMEvent(&event); - } - } + for (auto* window : windows) + MaximizeIfSnapped(window); } void TabletModeWindowManager::OnWindowDestroying(aura::Window* window) { @@ -337,6 +355,7 @@ display::Screen::GetScreen()->AddObserver(this); Shell::Get()->AddShellObserver(this); Shell::Get()->session_controller()->AddObserver(this); + Shell::Get()->overview_controller()->AddObserver(this); accounts_since_entering_tablet_.insert( Shell::Get()->session_controller()->GetActiveAccountId()); event_handler_ = std::make_unique<wm::TabletModeEventHandler>();
diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager.h b/ash/wm/tablet_mode/tablet_mode_window_manager.h index 55dff17..b6452464 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_manager.h +++ b/ash/wm/tablet_mode/tablet_mode_window_manager.h
@@ -15,6 +15,7 @@ #include "ash/session/session_observer.h" #include "ash/shell_observer.h" #include "ash/wm/mru_window_tracker.h" +#include "ash/wm/overview/overview_observer.h" #include "ash/wm/splitview/split_view_controller.h" #include "base/containers/flat_set.h" #include "base/macros.h" @@ -41,6 +42,7 @@ // original state. class ASH_EXPORT TabletModeWindowManager : public aura::WindowObserver, public display::DisplayObserver, + public OverviewObserver, public ShellObserver, public SessionObserver { public: @@ -59,6 +61,9 @@ // Called from a window state object when it gets destroyed. void WindowStateDestroyed(aura::Window* window); + // OverviewObserver: + void OnOverviewModeEndingAnimationComplete(bool canceled) override; + // ShellObserver: void OnSplitViewModeEnded() override;
diff --git a/base/test/fuzzed_data_provider.h b/base/test/fuzzed_data_provider.h index 19e829f..33d1c00 100644 --- a/base/test/fuzzed_data_provider.h +++ b/base/test/fuzzed_data_provider.h
@@ -12,6 +12,7 @@ #include <algorithm> #include <cstring> #include <string> +#include <type_traits> #include <utility> #include <vector> @@ -171,6 +172,16 @@ return array[ConsumeIntegralInRange<size_t>(0, size - 1)]; } + // Return an enum value. The enum must start at 0 and be contiguous. It must + // also contain kMaxValue aliased to its largest (inclusive) value. Such as: + // enum class Foo { SomeValue, OtherValue, kMaxValue = OtherValue }; + template <typename T> + T ConsumeEnum() { + static_assert(std::is_enum<T>::value, "|T| must be an enum type."); + return static_cast<T>(ConsumeIntegralInRange<uint32_t>( + 0, static_cast<uint32_t>(T::kMaxValue))); + } + // Reports the remaining bytes available for fuzzed input. size_t remaining_bytes() { return remaining_bytes_; }
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index b4c72e2..4c89f57 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8916737669163559168 \ No newline at end of file +8916712100220639312 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 5a44181d..cf6090e 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8916742152396029840 \ No newline at end of file +8916731962316481504 \ No newline at end of file
diff --git a/chrome/android/java/res/layout/permission_dialog.xml b/chrome/android/java/res/layout/permission_dialog.xml index cd44504..51189b5 100644 --- a/chrome/android/java/res/layout/permission_dialog.xml +++ b/chrome/android/java/res/layout/permission_dialog.xml
@@ -4,17 +4,19 @@ found in the LICENSE file. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:gravity="start" - style="@style/AlertDialogContent" > + style="@style/AlertDialogContent"> - <TextView + <org.chromium.chrome.browser.widget.TextViewWithCompoundDrawables android:id="@+id/text" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:textDirection="locale" - android:textSize="@dimen/dialog_text_size" android:paddingBottom="24dp" - android:drawablePadding="8dp" /> + android:drawablePadding="8dp" + android:textAppearance="@style/TextAppearance.BlackBody" + app:chromeDrawableTint="@color/default_icon_color_blue" /> </LinearLayout>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index fac9f9d4..71d60b1 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -495,7 +495,6 @@ https://www.google.com/design/spec/components/dialogs.html#dialogs-simple-dialogs --> <dimen name="dialog_width_unit">56dp</dimen> <!-- MD dialog widths are multiples of this. --> <dimen name="dialog_header_margin">14dp</dimen> - <dimen name="dialog_text_size">14sp</dimen> <dimen name="separator_height">1dp</dimen> <!-- Modern List Item dimensions -->
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java index 19523421..49fb997e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java
@@ -223,6 +223,7 @@ } private void detachLayoutIfNecessary() { + if (mSideSlideLayout == null) return; cancelDetachLayoutRunnable(); if (mSideSlideLayout.getParent() != null) { mParentView.removeView(mSideSlideLayout);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java index 81f60c06..696ffcb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java
@@ -223,7 +223,7 @@ long time = config.getDataReductionLastUpdateTime() - days * DateUtils.DAY_IN_MILLIS; for (int i = history.length - days, bucket = 0; i < history.length; i++, bucket++) { NetworkStats.Entry entry = new NetworkStats.Entry(); - entry.rxBytes = history[i]; + entry.rxBytes = Math.max(history[i], 0); long startTime = time + (DateUtils.DAY_IN_MILLIS * bucket); // Spread each day's record over the first hour of the day. networkStatsHistory.recordData(startTime, startTime + DateUtils.HOUR_IN_MILLIS, entry);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java index a816f68c..9a5430d8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/PageViewObserver.java
@@ -105,27 +105,44 @@ switchObserverToTab(tabModelSelector.getCurrentTab()); } + /** Notify PageViewObserver that {@code fqdn} was just suspended or un-suspended. */ + public void notifySiteSuspensionChanged(String fqdn, boolean isSuspended) { + if (mLastFqdn != null && mLastFqdn.equals(fqdn)) { + if (isSuspended) { + SuspendedTab.from(mCurrentTab).show(fqdn); + return; + } + + SuspendedTab suspendedTab = SuspendedTab.get(mCurrentTab); + if (suspendedTab != null && !isSuspended && suspendedTab.getFqdn().equals(fqdn)) { + suspendedTab.removeIfPresent(); + mCurrentTab.reload(); + } + } + } + private void updateUrl(String newUrl) { String newFqdn = newUrl == null ? "" : Uri.parse(newUrl).getHost(); - boolean didSuspend = false; + boolean sameDomain = mLastFqdn != null && mLastFqdn.equals(newFqdn); + if (newFqdn != null && mSuspensionTracker.isWebsiteSuspended(newFqdn)) { - SuspendedTab.create(mCurrentTab).show(); + SuspendedTab.from(mCurrentTab).show(newFqdn); didSuspend = true; } - if (mLastFqdn != null && mLastFqdn.equals(newFqdn)) return; + if (sameDomain) return; if (mLastFqdn != null) { mEventTracker.addWebsiteEvent(new WebsiteEvent( System.currentTimeMillis(), mLastFqdn, WebsiteEvent.EventType.STOP)); reportToPlatformIfDomainIsTracked("reportUsageStop", mLastFqdn); - mLastFqdn = null; } + mLastFqdn = newFqdn; + if (!URLUtil.isHttpUrl(newUrl) && !URLUtil.isHttpsUrl(newUrl) || didSuspend) return; - mLastFqdn = newFqdn; mEventTracker.addWebsiteEvent(new WebsiteEvent( System.currentTimeMillis(), mLastFqdn, WebsiteEvent.EventType.START)); reportToPlatformIfDomainIsTracked("reportUsageStart", mLastFqdn);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/SuspendedTab.java b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/SuspendedTab.java index dab2b05..e3c7061 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/SuspendedTab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/SuspendedTab.java
@@ -15,6 +15,7 @@ import android.widget.LinearLayout.LayoutParams; import android.widget.TextView; +import org.chromium.base.UserData; import org.chromium.chrome.R; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; @@ -24,43 +25,70 @@ * Represents the suspension page presented when a user tries to visit a site whose fully-qualified * domain name (FQDN) has been suspended via Digital Wellbeing. */ -public class SuspendedTab extends EmptyTabObserver { +public class SuspendedTab extends EmptyTabObserver implements UserData { private static final String DIGITAL_WELLBEING_DASHBOARD_ACTION = "com.google.android.apps.wellbeing.action.APP_USAGE_DASHBOARD"; + private static final Class<SuspendedTab> USER_DATA_KEY = SuspendedTab.class; + + public static SuspendedTab from(Tab tab) { + SuspendedTab suspendedTab = get(tab); + if (suspendedTab == null) { + suspendedTab = tab.getUserDataHost().setUserData(USER_DATA_KEY, new SuspendedTab(tab)); + } + return suspendedTab; + } + + public static SuspendedTab get(Tab tab) { + return tab.getUserDataHost().getUserData(USER_DATA_KEY); + } private final Tab mTab; private View mView; - - public static SuspendedTab create(Tab tab) { - return new SuspendedTab(tab); - } + private String mFqdn; private SuspendedTab(Tab tab) { mTab = tab; - mTab.addObserver(this); } /** * Show the suspended tab UI within the root view of the associated tab. This will stop loading - * of mTab so that the page is not also rendered. + * of mTab so that the page is not also rendered. If the suspended tab is already showing, this + * will update its fqdn to the given one. */ - public void show() { - if (mTab.getWebContents() == null) return; - + public void show(String fqdn) { + mFqdn = fqdn; + mTab.addObserver(this); mTab.stopLoading(); - attachView(); + if (isShowing()) { + updateFqdnText(); + } else { + attachView(); + } + } + + /** Remove the suspended tab UI if it's currently being shown. */ + public void removeIfPresent() { + removeViewIfPresent(); + + mTab.removeObserver(this); + mView = null; + mFqdn = null; + } + + /** @return the fqdn this SuspendedTab was last shown for. */ + public String getFqdn() { + return mFqdn; } private View createView() { Context context = mTab.getContext(); LayoutInflater inflater = LayoutInflater.from(context); - String fqdn = Uri.parse(mTab.getUrl()).getHost(); View suspendedTabView = inflater.inflate(R.layout.suspended_tab, null); TextView explanationText = (TextView) suspendedTabView.findViewById(R.id.suspended_tab_explanation); explanationText.setText( - context.getString(R.string.usage_stats_site_paused_explanation, fqdn)); + context.getString(R.string.usage_stats_site_paused_explanation, mFqdn)); View settingsLink = suspendedTabView.findViewById(R.id.suspended_tab_settings_button); settingsLink.setOnClickListener(new OnClickListener() { @@ -79,17 +107,20 @@ assert mView == null; ViewGroup parent = mTab.getContentView(); + // getContentView() will return null if the tab doesn't have a WebContents, which is + // possible in some situations, e.g. if the renderer crashes. + if (parent == null) return; mView = createView(); parent.addView(mView, new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); } - private void removeIfPresent() { - removeViewIfPresent(); - - mTab.removeObserver(this); - mView = null; + private void updateFqdnText() { + Context context = mTab.getContext(); + TextView explanationText = (TextView) mView.findViewById(R.id.suspended_tab_explanation); + explanationText.setText( + context.getString(R.string.usage_stats_site_paused_explanation, mFqdn)); } private void removeViewIfPresent() { @@ -102,15 +133,22 @@ return mView != null && mView.getParent() == mTab.getContentView(); } + private void removeSelfIfFqdnChanged(String url) { + String newFqdn = Uri.parse(url).getHost(); + if (newFqdn == null || !newFqdn.equals(mFqdn)) { + removeIfPresent(); + } + } + // TabObserver implementation. @Override public void onLoadUrl(Tab tab, LoadUrlParams params, int loadType) { - removeIfPresent(); + removeSelfIfFqdnChanged(params.getUrl()); } @Override public void onPageLoadStarted(Tab tab, String url) { - removeIfPresent(); + removeSelfIfFqdnChanged(url); } @Override @@ -127,4 +165,10 @@ attachView(); } } + + // UserData implementation. + @Override + public void destroy() { + mTab.removeObserver(this); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsService.java b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsService.java index 0be5e80..8e98f70 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsService.java
@@ -17,6 +17,7 @@ import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; @@ -33,6 +34,10 @@ private SuspensionTracker mSuspensionTracker; private TokenTracker mTokenTracker; private UsageStatsBridge mBridge; + // PageViewObservers are scoped to a given ChromeTabbedActivity, but UsageStatsService isn't. To + // allow for GC of the observer to happen when the activity goes away, we only hold weak + // references here. + private List<WeakReference<PageViewObserver>> mPageViewObservers; private DigitalWellbeingClient mClient; private boolean mOptInState; @@ -53,6 +58,7 @@ mEventTracker = new EventTracker(mBridge); mSuspensionTracker = new SuspensionTracker(mBridge); mTokenTracker = new TokenTracker(mBridge); + mPageViewObservers = new ArrayList<>(); mOptInState = getOptInState(); mClient = AppHooks.get().createDigitalWellbeingClient(); @@ -67,8 +73,10 @@ public PageViewObserver createPageViewObserver( TabModelSelector tabModelSelector, Activity activity) { ThreadUtils.assertOnUiThread(); - return new PageViewObserver( + PageViewObserver observer = new PageViewObserver( activity, tabModelSelector, mEventTracker, mTokenTracker, mSuspensionTracker); + mPageViewObservers.add(new WeakReference<>(observer)); + return observer; } /** @return Whether the user has authorized DW to access usage stats data. */ @@ -134,10 +142,19 @@ } /** - * Suspend or unsuspend every site in FQDNs, depending on the truthiness of <c>suspended</c>. + * Suspend or unsuspend every site in FQDNs, depending on the value of {@code suspended}. */ public Promise<Void> setWebsitesSuspendedAsync(List<String> fqdns, boolean suspended) { ThreadUtils.assertOnUiThread(); + for (WeakReference<PageViewObserver> observerRef : mPageViewObservers) { + PageViewObserver observer = observerRef.get(); + if (observer != null) { + for (String fqdn : fqdns) { + observer.notifySiteSuspensionChanged(fqdn, suspended); + } + } + } + return mSuspensionTracker.setWebsitesSuspended(fqdns, suspended); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchFeedFlowTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchFeedFlowTest.java index aa9a566..7d34575b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchFeedFlowTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/prefetch/PrefetchFeedFlowTest.java
@@ -21,6 +21,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.base.test.util.UrlUtils; @@ -51,6 +52,7 @@ import org.chromium.net.NetworkChangeNotifier; import org.chromium.net.NetworkChangeNotifierAutoDetect; import org.chromium.net.test.util.WebServer; +import org.chromium.ui.test.util.UiDisableIf; import java.io.IOException; import java.io.OutputStream; @@ -381,6 +383,7 @@ @Test @MediumTest @Feature({"OfflinePrefetchFeed"}) + @DisableIf.Device(type = {UiDisableIf.TABLET}) // https://crbug.com/950749 public void testPrefetchForbiddenByServer() throws Throwable { mOPS.setForbidGeneratePageBundle(true); @@ -399,6 +402,7 @@ @Test @MediumTest @Feature({"OfflinePrefetchFeed"}) + @DisableIf.Device(type = {UiDisableIf.TABLET}) // https://crbug.com/950749 public void testPrefetchBecomesEnabledByServer() throws Throwable { OfflineTestUtil.setPrefetchingEnabledByServer(false);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java index 3861f0e..8060470 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/usage_stats/PageViewObserverTest.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.usage_stats; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Matchers.any; @@ -26,6 +27,7 @@ import org.robolectric.annotation.Config; import org.chromium.base.Promise; +import org.chromium.base.UserDataHost; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab.TabHidingType; @@ -34,6 +36,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabSelectionType; +import org.chromium.content_public.browser.WebContents; import java.util.Arrays; @@ -62,19 +65,28 @@ private TokenTracker mTokenTracker; @Mock private SuspensionTracker mSuspensionTracker; + @Mock + private WebContents mWebContents; @Captor private ArgumentCaptor<TabObserver> mTabObserverCaptor; @Captor private ArgumentCaptor<TabModelObserver> mTabModelObserverCaptor; + private TabObserver mTabObserver; + private UserDataHost mUserDataHost; + @Before public void setUp() { MockitoAnnotations.initMocks(this); + mUserDataHost = new UserDataHost(); + doReturn(false).when(mTab).isIncognito(); doReturn(null).when(mTab).getUrl(); + doReturn(mWebContents).when(mTab).getWebContents(); doReturn(Arrays.asList(mTabModel)).when(mTabModelSelector).getModels(); doReturn(mTab).when(mTabModelSelector).getCurrentTab(); + doReturn(mUserDataHost).when(mTab).getUserDataHost(); doReturn(Promise.fulfilled("1")).when(mTokenTracker).getTokenForFqdn(anyString()); } @@ -205,6 +217,7 @@ PageViewObserver observer = createPageViewObserver(); onUpdateUrl(mTab, STARTING_URL); + doReturn(DIFFERENT_URL).when(mTab).getUrl(); doReturn(true).when(mSuspensionTracker).isWebsiteSuspended(DIFFERENT_FQDN); onUpdateUrl(mTab, DIFFERENT_URL); @@ -217,6 +230,7 @@ PageViewObserver observer = createPageViewObserver(); onUpdateUrl(mTab, STARTING_URL); + doReturn(DIFFERENT_URL).when(mTab).getUrl(); doReturn(true).when(mSuspensionTracker).isWebsiteSuspended(DIFFERENT_FQDN); onUpdateUrl(mTab, DIFFERENT_URL); @@ -227,6 +241,82 @@ verify(mTab, times(1)).removeObserver(suspendedTab); } + @Test + public void eagerSuspension() { + PageViewObserver observer = createPageViewObserver(); + onUpdateUrl(mTab, STARTING_URL); + + doReturn(STARTING_URL).when(mTab).getUrl(); + observer.notifySiteSuspensionChanged(STARTING_FQDN, true); + + verify(mTab, times(2)).addObserver(mTabObserverCaptor.capture()); + assertTrue(mTabObserverCaptor.getValue() instanceof SuspendedTab); + } + + @Test + public void eagerSuspension_navigateToDifferentSuspended() { + PageViewObserver observer = createPageViewObserver(); + onUpdateUrl(mTab, STARTING_URL); + + doReturn(STARTING_URL).when(mTab).getUrl(); + observer.notifySiteSuspensionChanged(STARTING_FQDN, true); + + verify(mTab, times(2)).addObserver(mTabObserverCaptor.capture()); + SuspendedTab suspendedTab = (SuspendedTab) mTabObserverCaptor.getValue(); + assertEquals(STARTING_FQDN, suspendedTab.getFqdn()); + + doReturn(true).when(mSuspensionTracker).isWebsiteSuspended(DIFFERENT_FQDN); + onUpdateUrl(mTab, DIFFERENT_URL); + + verify(mTab, times(3)).addObserver(any()); + assertEquals(DIFFERENT_FQDN, suspendedTab.getFqdn()); + } + + @Test + public void eagerUnsuspension() { + PageViewObserver observer = createPageViewObserver(); + onUpdateUrl(mTab, STARTING_URL); + + doReturn(STARTING_URL).when(mTab).getUrl(); + observer.notifySiteSuspensionChanged(STARTING_FQDN, true); + + verify(mTab, times(2)).addObserver(mTabObserverCaptor.capture()); + assertTrue(mTabObserverCaptor.getValue() instanceof SuspendedTab); + SuspendedTab suspendedTab = (SuspendedTab) mTabObserverCaptor.getValue(); + + observer.notifySiteSuspensionChanged(STARTING_FQDN, false); + verify(mTab, times(1)).removeObserver(suspendedTab); + } + + @Test + public void eagerUnsuspension_otherDomainActiveAndSuspended() { + PageViewObserver observer = createPageViewObserver(); + onUpdateUrl(mTab, STARTING_URL); + + doReturn(STARTING_URL).when(mTab).getUrl(); + observer.notifySiteSuspensionChanged(STARTING_FQDN, true); + verify(mTab, times(2)).addObserver(mTabObserverCaptor.capture()); + SuspendedTab suspendedTab = (SuspendedTab) mTabObserverCaptor.getValue(); + + doReturn(true).when(mSuspensionTracker).isWebsiteSuspended(DIFFERENT_FQDN); + onUpdateUrl(mTab, DIFFERENT_URL); + + // Notifying that STARTING_FQDN is no longer suspended shouldn't remove the active + // SuspendedTab for DIFFERENT_FQDN. + observer.notifySiteSuspensionChanged(STARTING_FQDN, false); + verify(mTab, times(0)).removeObserver(suspendedTab); + } + + @Test + public void eagerUnsuspension_notAlreadySuspended() { + PageViewObserver observer = createPageViewObserver(); + onUpdateUrl(mTab, STARTING_URL); + + observer.notifySiteSuspensionChanged(STARTING_FQDN, false); + verify(mTab, times(1)).addObserver(any()); + verify(mTab, times(0)).removeObserver(any()); + } + private PageViewObserver createPageViewObserver() { PageViewObserver observer = new PageViewObserver( mActivity, mTabModelSelector, mEventTracker, mTokenTracker, mSuspensionTracker); @@ -255,7 +345,11 @@ } private TabObserver getTabObserver() { - return mTabObserverCaptor.getValue(); + if (mTabObserver == null) { + mTabObserver = mTabObserverCaptor.getValue(); + } + + return mTabObserver; } private TabModelObserver getTabModelObserver() {
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index 87b2a02..ddb3816f 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -953,7 +953,7 @@ If an image doesn’t have a useful description, Chromium will try to provide one for you. To create descriptions, images are sent to Google. </message> <message name="IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_TEXT" desc="The text of a bubble that confirms users allows integrating the spelling service of Google to Chrome."> - Chromium can provide smarter spell-checking by sending what you type in the browser to Google servers, allowing you to use the same spell-checking technology used by Google search. + This uses the same spellchecker that's used in Google search. Text you type in the browser is sent to Google. You can always change this behavior in settings. </message> <if expr="not use_titlecase"> <message name="IDS_CONTENT_CONTEXT_OPENLINKNEWTAB_INAPP" desc="The name of the command to open a link in a newly created browser tab when the user is in an app window">
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 4e1f4f0..940e2e48 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -549,14 +549,17 @@ <message name="IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_BUBBLE_DISABLE" desc="The button text that disallows integrating the accessibility labels service of Google."> No thanks </message> - <message name="IDS_CONTENT_CONTEXT_SPELLING_ASK_GOOGLE" desc="The context-menu item that asks whether to integrate the spelling service of Google to Chrome. This text is also used as the title of a bubble which confirms it."> + <message name="IDS_CONTENT_CONTEXT_SPELLING_ASK_GOOGLE" desc="The context-menu item that asks whether to integrate the spelling service of Google to Chrome."> Use enhanced spell check </message> + <message name="IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_TITLE" desc="The title of the confirmation modal that pops up when the user turns on 'Use enhanced spell check'"> + Turn on enhanced spell check + </message> <message name="IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_ENABLE" desc="The button text that allows integrating the spelling service of Google."> - Enable + Turn on </message> <message name="IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_DISABLE" desc="The button text that disallows integrating the spelling service of Google."> - No thanks + Cancel </message> <message name="IDS_CONTENT_CONTEXT_SPELLING_CHECKING" desc="The place-holder message shown while the Spelling service is checking text"> Loading suggestion @@ -782,9 +785,12 @@ <message name="IDS_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_BUBBLE_DISABLE" desc="The button text that disallows integrating the accessibility labels service of Google."> No Thanks </message> - <message name="IDS_CONTENT_CONTEXT_SPELLING_ASK_GOOGLE" desc="In Title Case: The context-menu item that asks whether to integrate the spelling service of Google to Chrome. This text is also used as the title of a bubble which confirms it."> + <message name="IDS_CONTENT_CONTEXT_SPELLING_ASK_GOOGLE" desc="In Title Case: The context-menu item that asks whether to integrate the spelling service of Google to Chrome."> Use Enhanced Spell Check </message> + <message name="IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_TITLE" desc="The title of the confirmation modal that pops up when the user turns on 'Use enhanced spell check'"> + Turn On Enhanced Spell Check + </message> <message name="IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_ENABLE" desc="In Title Case: The button text that allows integrating the spelling service of Google."> Enable </message>
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index 813421d..53f7513 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -972,7 +972,7 @@ If an image doesn’t have a useful description, Chrome will try to provide one for you. To create descriptions, images are sent to Google. </message> <message name="IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_TEXT" desc="The text of a bubble that confirms users allows integrating the spelling service of Google to Chrome."> - Google Chrome can provide smarter spell-checking by sending what you type in the browser to Google servers, allowing you to use the same spell-checking technology used by Google search. + This uses the same spellchecker that's used in Google search. Text you type in the browser is sent to Google. You can always change this behavior in settings. </message> <if expr="not use_titlecase"> <message name="IDS_CONTENT_CONTEXT_OPENLINKNEWTAB_INAPP" desc="The name of the command to open a link in a newly created browser tab when the user is in an app window">
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 6dbccd6..18bd480 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -4435,7 +4435,7 @@ <message name="IDS_SETTINGS_MULTIDEVICE_SETUP_BUTTON" desc="Label of the button that opens a menu to the user that allows them to set up a connection between the user's phone and their Chromebook to give them access to special features."> Set up </message> - <message name="IDS_SETTINGS_MULTIDEVICE_VERIFY_BUTTON" desc="Label for the button to get the Chromebook to verify that it can connect with their phone." translateable="false"> + <message name="IDS_SETTINGS_MULTIDEVICE_VERIFY_BUTTON" desc="Label for the button to get the Chromebook to verify that it can connect with their phone."> Verify </message> <message name="IDS_SETTINGS_MULTIDEVICE_ENABLED" desc="Text to tell user multidevice features are turned on">
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 7a27050..b44d5f6 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -4039,6 +4039,11 @@ {"enable-portals", flag_descriptions::kEnablePortalsName, flag_descriptions::kEnablePortalsDescription, kOsAll, FEATURE_VALUE_TYPE(blink::features::kPortals)}, + {"enable-autofill-credit-card-authentication", + flag_descriptions::kEnableAutofillCreditCardAuthenticationName, + flag_descriptions::kEnableAutofillCreditCardAuthenticationDescription, + kOsAll, + FEATURE_VALUE_TYPE(autofill::features::kAutofillCreditCardAuthentication)}, // 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/apps/intent_helper/apps_navigation_throttle.cc b/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc index 66af5dc..0c71a4dd 100644 --- a/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc +++ b/chrome/browser/apps/intent_helper/apps_navigation_throttle.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/apps/intent_helper/apps_navigation_throttle.h" -#include <algorithm> #include <utility> #include "base/bind.h" @@ -350,9 +349,11 @@ Browser* browser = chrome::FindBrowserWithWebContents(web_contents); if (!browser) return; - const PickerShowState picker_show_state = GetPickerShowState(); + const PickerShowState picker_show_state = + GetPickerShowState(apps, web_contents, url); switch (picker_show_state) { case PickerShowState::kOmnibox: + ui_displayed_ = false; browser->window()->SetIntentPickerViewVisibility(true); break; case PickerShowState::kPopOut: @@ -365,7 +366,10 @@ } AppsNavigationThrottle::PickerShowState -AppsNavigationThrottle::GetPickerShowState() { +AppsNavigationThrottle::GetPickerShowState( + const std::vector<IntentPickerAppInfo>& apps_for_picker, + content::WebContents* web_contents, + const GURL& url) { return PickerShowState::kOmnibox; } @@ -377,26 +381,6 @@ ui_auto_display_service, url); } -bool AppsNavigationThrottle::ShouldAutoDisplayUi( - const std::vector<IntentPickerAppInfo>& apps_for_picker, - content::WebContents* web_contents, - const GURL& url) { - if (apps_for_picker.empty()) - return false; - - // Check if all the app candidates are PWAs. - bool only_pwa_apps = - std::all_of(apps_for_picker.begin(), apps_for_picker.end(), - [](const IntentPickerAppInfo& app_info) { - return app_info.type == apps::mojom::AppType::kWeb; - }); - if (only_pwa_apps) - return false; - - DCHECK(ui_auto_display_service_); - return ui_auto_display_service_->ShouldAutoDisplayUi(url); -} - // static AppsNavigationThrottle::PickerAction AppsNavigationThrottle::GetPickerAction( apps::mojom::AppType app_type,
diff --git a/chrome/browser/apps/intent_helper/apps_navigation_throttle.h b/chrome/browser/apps/intent_helper/apps_navigation_throttle.h index 042ab58..4550246 100644 --- a/chrome/browser/apps/intent_helper/apps_navigation_throttle.h +++ b/chrome/browser/apps/intent_helper/apps_navigation_throttle.h
@@ -177,20 +177,16 @@ std::vector<IntentPickerAppInfo> apps, IntentPickerResponse callback); - virtual PickerShowState GetPickerShowState(); + virtual PickerShowState GetPickerShowState( + const std::vector<IntentPickerAppInfo>& apps_for_picker, + content::WebContents* web_contents, + const GURL& url); virtual IntentPickerResponse GetOnPickerClosedCallback( content::WebContents* web_contents, IntentPickerAutoDisplayService* ui_auto_display_service, const GURL& url); - // Whether or not the intent picker UI should be displayed without the user - // clicking in the omnibox's icon. - bool ShouldAutoDisplayUi( - const std::vector<IntentPickerAppInfo>& apps_for_picker, - content::WebContents* web_contents, - const GURL& url); - // Keeps track of whether we already shown the UI or preferred app. Since // AppsNavigationThrottle cannot wait for the user (due to the non-blocking // nature of the feature) the best we can do is check if we launched a
diff --git a/chrome/browser/autocomplete/autocomplete_browsertest.cc b/chrome/browser/autocomplete/autocomplete_browsertest.cc index d0e4dd1a..1485d03 100644 --- a/chrome/browser/autocomplete/autocomplete_browsertest.cc +++ b/chrome/browser/autocomplete/autocomplete_browsertest.cc
@@ -98,7 +98,7 @@ // TODO(phajdan.jr): check state of IsSelectAll when it's consistent across // platforms. - location_bar->FocusLocation(); + location_bar->FocusLocation(true); EXPECT_FALSE(location_bar->GetDestinationURL().is_valid()); EXPECT_EQ(base::UTF8ToUTF16(url::kAboutBlankURL), omnibox_view->GetText());
diff --git a/chrome/browser/certificate_manager_model.cc b/chrome/browser/certificate_manager_model.cc index 15ce9af..f752cd58 100644 --- a/chrome/browser/certificate_manager_model.cc +++ b/chrome/browser/certificate_manager_model.cc
@@ -383,10 +383,8 @@ void Refresh() override { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - certificate_provider_service_->GetCertificates( - base::AdaptCallbackForRepeating( - base::BindOnce(&CertsSourceExtensions::DidGetCerts, - weak_ptr_factory_.GetWeakPtr()))); + certificate_provider_service_->GetCertificates(base::BindOnce( + &CertsSourceExtensions::DidGetCerts, weak_ptr_factory_.GetWeakPtr())); } bool SetCertTrust(CERTCertificate* cert,
diff --git a/chrome/browser/certificate_manager_model_unittest.cc b/chrome/browser/certificate_manager_model_unittest.cc index 3f26fa5..272a1f7 100644 --- a/chrome/browser/certificate_manager_model_unittest.cc +++ b/chrome/browser/certificate_manager_model_unittest.cc
@@ -259,12 +259,11 @@ extensions_hang_(extensions_hang) {} void GetCertificates( - const base::RepeatingCallback<void(net::ClientCertIdentityList)>& - callback) override { + base::OnceCallback<void(net::ClientCertIdentityList)> callback) override { if (*extensions_hang_) return; - callback.Run(FakeClientCertIdentityListFromCertificateList( + std::move(callback).Run(FakeClientCertIdentityListFromCertificateList( *extension_client_certificates_)); }
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 4fd55c0..b947523 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -2895,8 +2895,9 @@ auto_selected_identity->certificate(); net::ClientCertIdentity::SelfOwningAcquirePrivateKey( std::move(auto_selected_identity), - base::Bind(&content::ClientCertificateDelegate::ContinueWithCertificate, - base::Passed(&delegate), std::move(cert))); + base::BindOnce( + &content::ClientCertificateDelegate::ContinueWithCertificate, + std::move(delegate), std::move(cert))); LogClientAuthResult(ClientCertSelectionResult::kAutoSelect); return; }
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 9506b93..ce9768d 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -2150,8 +2150,6 @@ "login/screens/mock_update_screen.h", "login/screens/mock_welcome_screen.cc", "login/screens/mock_welcome_screen.h", - "login/test/help_app_test_helper.cc", - "login/test/help_app_test_helper.h", "login/test/test_condition_waiter.h", "login/test/test_predicate_waiter.cc", "login/test/test_predicate_waiter.h",
diff --git a/chrome/browser/chromeos/apps/intent_helper/chromeos_apps_navigation_throttle.cc b/chrome/browser/chromeos/apps/intent_helper/chromeos_apps_navigation_throttle.cc index 2d6010b0c..4111094 100644 --- a/chrome/browser/chromeos/apps/intent_helper/chromeos_apps_navigation_throttle.cc +++ b/chrome/browser/chromeos/apps/intent_helper/chromeos_apps_navigation_throttle.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/chromeos/apps/intent_helper/chromeos_apps_navigation_throttle.h" +#include <algorithm> #include <utility> #include "base/bind.h" @@ -231,31 +232,22 @@ std::vector<apps::IntentPickerAppInfo> apps_for_picker = FindPwaForUrl(web_contents, url, std::move(apps)); - // If we only have PWAs in the app list, do not show the intent picker. - // Instead just show the omnibox icon. This is to reduce annoyance to users - // until "Remember my choice" is available for desktop PWAs. - // TODO(crbug.com/826982): show the intent picker when the app registry is - // available to persist "Remember my choice" for PWAs. - if (ShouldAutoDisplayUi(apps_for_picker, web_contents, url)) { - ShowIntentPickerForApps( - web_contents, ui_auto_display_service_, url, std::move(apps_for_picker), - GetOnPickerClosedCallback(web_contents, ui_auto_display_service_, url)); - } else { - ui_displayed_ = false; - Browser* browser = chrome::FindBrowserWithWebContents(web_contents); - // If there were any candidates, show the intent picker icon in the omnibox - // so the user can manually pick if they wish. - if (browser && !apps_for_picker.empty()) - browser->window()->SetIntentPickerViewVisibility(/*visible=*/true); - } + ShowIntentPickerForApps( + web_contents, ui_auto_display_service_, url, std::move(apps_for_picker), + GetOnPickerClosedCallback(web_contents, ui_auto_display_service_, url)); // We are about to resume the navigation, which may destroy this object. Resume(); } apps::AppsNavigationThrottle::PickerShowState -ChromeOsAppsNavigationThrottle::GetPickerShowState() { - return PickerShowState::kPopOut; +ChromeOsAppsNavigationThrottle::GetPickerShowState( + const std::vector<apps::IntentPickerAppInfo>& apps_for_picker, + content::WebContents* web_contents, + const GURL& url) { + return ShouldAutoDisplayUi(apps_for_picker, web_contents, url) + ? PickerShowState::kPopOut + : PickerShowState::kOmnibox; } IntentPickerResponse ChromeOsAppsNavigationThrottle::GetOnPickerClosedCallback( @@ -272,4 +264,28 @@ if (web_contents) web_contents->ClosePage(); } + +bool ChromeOsAppsNavigationThrottle::ShouldAutoDisplayUi( + const std::vector<apps::IntentPickerAppInfo>& apps_for_picker, + content::WebContents* web_contents, + const GURL& url) { + if (apps_for_picker.empty()) + return false; + + // If we only have PWAs in the app list, do not show the intent picker. + // Instead just show the omnibox icon. This is to reduce annoyance to users + // until "Remember my choice" is available for desktop PWAs. + // TODO(crbug.com/826982): show the intent picker when the app registry is + // available to persist "Remember my choice" for PWAs. + bool only_pwa_apps = + std::all_of(apps_for_picker.begin(), apps_for_picker.end(), + [](const apps::IntentPickerAppInfo& app_info) { + return app_info.type == apps::mojom::AppType::kWeb; + }); + if (only_pwa_apps) + return false; + + DCHECK(ui_auto_display_service_); + return ui_auto_display_service_->ShouldAutoDisplayUi(url); +} } // namespace chromeos
diff --git a/chrome/browser/chromeos/apps/intent_helper/chromeos_apps_navigation_throttle.h b/chrome/browser/chromeos/apps/intent_helper/chromeos_apps_navigation_throttle.h index 74a9840f..00d51b4d 100644 --- a/chrome/browser/chromeos/apps/intent_helper/chromeos_apps_navigation_throttle.h +++ b/chrome/browser/chromeos/apps/intent_helper/chromeos_apps_navigation_throttle.h
@@ -102,7 +102,10 @@ apps::AppsNavigationAction action, std::vector<apps::IntentPickerAppInfo> apps) override; - PickerShowState GetPickerShowState() override; + PickerShowState GetPickerShowState( + const std::vector<apps::IntentPickerAppInfo>& apps_for_picker, + content::WebContents* web_contents, + const GURL& url) override; IntentPickerResponse GetOnPickerClosedCallback( content::WebContents* web_contents, @@ -111,6 +114,13 @@ void CloseTab(); + // Whether or not the intent picker UI should be displayed without the user + // clicking in the omnibox's icon. + bool ShouldAutoDisplayUi( + const std::vector<apps::IntentPickerAppInfo>& apps_for_picker, + content::WebContents* web_contents, + const GURL& url); + // True if ARC is enabled, false otherwise. const bool arc_enabled_;
diff --git a/chrome/browser/chromeos/assistant/assistant_util.cc b/chrome/browser/chromeos/assistant/assistant_util.cc index 3146049..dda3c07 100644 --- a/chrome/browser/chromeos/assistant/assistant_util.cc +++ b/chrome/browser/chromeos/assistant/assistant_util.cc
@@ -60,7 +60,9 @@ // Also accept runtime locale which maybe an approximation of user's pref // locale. const std::string kRuntimeLocale = icu::Locale::getDefault().getName(); - if (!pref_locale.empty()) { + // Bypass locale check when using fake gaia login. There is no need to enforce + // in these test environments. + if (!chromeos::switches::IsGaiaServicesDisabled() && !pref_locale.empty()) { base::ReplaceChars(pref_locale, "-", "_", &pref_locale); bool disallowed = !base::ContainsValue(kAllowedLocales, pref_locale) && !base::ContainsValue(kAllowedLocales, kRuntimeLocale);
diff --git a/chrome/browser/chromeos/certificate_provider/certificate_provider.h b/chrome/browser/chromeos/certificate_provider/certificate_provider.h index 8cb3214..2c8e00d8 100644 --- a/chrome/browser/chromeos/certificate_provider/certificate_provider.h +++ b/chrome/browser/chromeos/certificate_provider/certificate_provider.h
@@ -18,7 +18,7 @@ virtual ~CertificateProvider() {} virtual void GetCertificates( - const base::Callback<void(net::ClientCertIdentityList)>& callback) = 0; + base::OnceCallback<void(net::ClientCertIdentityList)> callback) = 0; virtual std::unique_ptr<CertificateProvider> Copy() = 0;
diff --git a/chrome/browser/chromeos/certificate_provider/certificate_provider_service.cc b/chrome/browser/chromeos/certificate_provider/certificate_provider_service.cc index 03c2d0f..98d5ecf6 100644 --- a/chrome/browser/chromeos/certificate_provider/certificate_provider_service.cc +++ b/chrome/browser/chromeos/certificate_provider/certificate_provider_service.cc
@@ -40,10 +40,10 @@ void PostIdentitiesToTaskRunner( const scoped_refptr<base::TaskRunner>& target_task_runner, - const base::Callback<void(net::ClientCertIdentityList)>& callback, + base::OnceCallback<void(net::ClientCertIdentityList)> callback, net::ClientCertIdentityList certs) { - target_task_runner->PostTask(FROM_HERE, - base::BindOnce(callback, std::move(certs))); + target_task_runner->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), std::move(certs))); } } // namespace @@ -59,15 +59,15 @@ const base::WeakPtr<CertificateProviderService>& service); ~CertificateProviderImpl() override; - void GetCertificates(const base::Callback<void(net::ClientCertIdentityList)>& - callback) override; + void GetCertificates( + base::OnceCallback<void(net::ClientCertIdentityList)> callback) override; std::unique_ptr<CertificateProvider> Copy() override; private: static void GetCertificatesOnServiceThread( const base::WeakPtr<CertificateProviderService>& service, - const base::Callback<void(net::ClientCertIdentityList)>& callback); + base::OnceCallback<void(net::ClientCertIdentityList)> callback); const scoped_refptr<base::SequencedTaskRunner> service_task_runner_; // Must be dereferenced on |service_task_runner_| only. @@ -134,7 +134,7 @@ service_(service) {} void AcquirePrivateKey( - const base::Callback<void(scoped_refptr<net::SSLPrivateKey>)>& + base::OnceCallback<void(scoped_refptr<net::SSLPrivateKey>)> private_key_callback) override; private: @@ -149,19 +149,15 @@ }; void CertificateProviderService::ClientCertIdentity::AcquirePrivateKey( - const base::Callback<void(scoped_refptr<net::SSLPrivateKey>)>& + base::OnceCallback<void(scoped_refptr<net::SSLPrivateKey>)> private_key_callback) { // The caller is responsible for keeping the ClientCertIdentity alive until // |private_key_callback| is run, so it's safe to use Unretained here. - if (base::PostTaskAndReplyWithResult( - service_task_runner_.get(), FROM_HERE, - base::Bind(&ClientCertIdentity::AcquirePrivateKeyOnServiceThread, + base::PostTaskAndReplyWithResult( + service_task_runner_.get(), FROM_HERE, + base::BindOnce(&ClientCertIdentity::AcquirePrivateKeyOnServiceThread, base::Unretained(this), base::Unretained(certificate())), - private_key_callback)) { - return; - } - // If the task could not be posted, behave as if there was no key. - private_key_callback.Run(nullptr); + std::move(private_key_callback)); } scoped_refptr<net::SSLPrivateKey> CertificateProviderService:: @@ -193,16 +189,16 @@ ~CertificateProviderImpl() {} void CertificateProviderService::CertificateProviderImpl::GetCertificates( - const base::Callback<void(net::ClientCertIdentityList)>& callback) { + base::OnceCallback<void(net::ClientCertIdentityList)> callback) { const scoped_refptr<base::TaskRunner> source_task_runner = base::ThreadTaskRunnerHandle::Get(); - const base::Callback<void(net::ClientCertIdentityList)> - callback_from_service_thread = - base::Bind(&PostIdentitiesToTaskRunner, source_task_runner, callback); + base::OnceCallback<void(net::ClientCertIdentityList)> + callback_from_service_thread = base::BindOnce( + &PostIdentitiesToTaskRunner, source_task_runner, std::move(callback)); service_task_runner_->PostTask( FROM_HERE, base::BindOnce(&GetCertificatesOnServiceThread, service_, - callback_from_service_thread)); + std::move(callback_from_service_thread))); } std::unique_ptr<CertificateProvider> @@ -215,12 +211,12 @@ void CertificateProviderService::CertificateProviderImpl:: GetCertificatesOnServiceThread( const base::WeakPtr<CertificateProviderService>& service, - const base::Callback<void(net::ClientCertIdentityList)>& callback) { + base::OnceCallback<void(net::ClientCertIdentityList)> callback) { if (!service) { - callback.Run(net::ClientCertIdentityList()); + std::move(callback).Run(net::ClientCertIdentityList()); return; } - service->GetCertificatesFromExtensions(callback); + service->GetCertificatesFromExtensions(std::move(callback)); } CertificateProviderService::SSLPrivateKey::SSLPrivateKey( @@ -348,10 +344,10 @@ } if (completed) { std::map<std::string, CertificateInfoList> certificates; - base::Callback<void(net::ClientCertIdentityList)> callback; + base::OnceCallback<void(net::ClientCertIdentityList)> callback; certificate_requests_.RemoveRequest(cert_request_id, &certificates, &callback); - UpdateCertificatesAndRun(certificates, callback); + UpdateCertificatesAndRun(certificates, std::move(callback)); } return true; } @@ -399,10 +395,10 @@ for (const int cert_request_id : certificate_requests_.DropExtension(extension_id)) { std::map<std::string, CertificateInfoList> certificates; - base::Callback<void(net::ClientCertIdentityList)> callback; + base::OnceCallback<void(net::ClientCertIdentityList)> callback; certificate_requests_.RemoveRequest(cert_request_id, &certificates, &callback); - UpdateCertificatesAndRun(certificates, callback); + UpdateCertificatesAndRun(certificates, std::move(callback)); } certificate_map_.RemoveExtension(extension_id); @@ -414,7 +410,7 @@ } void CertificateProviderService::GetCertificatesFromExtensions( - const base::Callback<void(net::ClientCertIdentityList)>& callback) { + base::OnceCallback<void(net::ClientCertIdentityList)> callback) { DCHECK(thread_checker_.CalledOnValidThread()); const std::vector<std::string> provider_extensions( @@ -423,14 +419,14 @@ if (provider_extensions.empty()) { DVLOG(2) << "No provider extensions left, clear all certificates."; UpdateCertificatesAndRun(std::map<std::string, CertificateInfoList>(), - callback); + std::move(callback)); return; } const int cert_request_id = certificate_requests_.AddRequest( - provider_extensions, callback, - base::Bind(&CertificateProviderService::TerminateCertificateRequest, - base::Unretained(this))); + provider_extensions, std::move(callback), + base::BindOnce(&CertificateProviderService::TerminateCertificateRequest, + base::Unretained(this))); DVLOG(2) << "Start certificate request " << cert_request_id; delegate_->BroadcastCertificateRequest(cert_request_id); @@ -438,7 +434,7 @@ void CertificateProviderService::UpdateCertificatesAndRun( const std::map<std::string, CertificateInfoList>& extension_to_certificates, - const base::Callback<void(net::ClientCertIdentityList)>& callback) { + base::OnceCallback<void(net::ClientCertIdentityList)> callback) { DCHECK(thread_checker_.CalledOnValidThread()); // Extensions are removed from the service's state when they're unloaded. @@ -453,7 +449,7 @@ weak_factory_.GetWeakPtr())); } - callback.Run(std::move(all_certs)); + std::move(callback).Run(std::move(all_certs)); } void CertificateProviderService::TerminateCertificateRequest( @@ -461,7 +457,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); std::map<std::string, CertificateInfoList> certificates; - base::Callback<void(net::ClientCertIdentityList)> callback; + base::OnceCallback<void(net::ClientCertIdentityList)> callback; if (!certificate_requests_.RemoveRequest(cert_request_id, &certificates, &callback)) { DLOG(WARNING) << "Request id " << cert_request_id << " unknown."; @@ -469,7 +465,7 @@ } DVLOG(1) << "Time out certificate request " << cert_request_id; - UpdateCertificatesAndRun(certificates, callback); + UpdateCertificatesAndRun(certificates, std::move(callback)); } void CertificateProviderService::RequestSignatureFromExtension(
diff --git a/chrome/browser/chromeos/certificate_provider/certificate_provider_service.h b/chrome/browser/chromeos/certificate_provider/certificate_provider_service.h index 7a94a61..ed5bcf7 100644 --- a/chrome/browser/chromeos/certificate_provider/certificate_provider_service.h +++ b/chrome/browser/chromeos/certificate_provider/certificate_provider_service.h
@@ -166,7 +166,7 @@ // |extension_to_certificates_| is updated and |callback| is run with the // retrieved list of certificates. void GetCertificatesFromExtensions( - const base::Callback<void(net::ClientCertIdentityList)>& callback); + base::OnceCallback<void(net::ClientCertIdentityList)> callback); // Copies the given certificates into the internal // |extension_to_certificates_|. Any previously stored certificates are @@ -174,7 +174,7 @@ void UpdateCertificatesAndRun( const std::map<std::string, CertificateInfoList>& extension_to_certificates, - const base::Callback<void(net::ClientCertIdentityList)>& callback); + base::OnceCallback<void(net::ClientCertIdentityList)> callback); // Terminates the certificate request with id |cert_request_id| by ignoring // pending replies from extensions. Certificates that were already reported
diff --git a/chrome/browser/chromeos/certificate_provider/certificate_provider_service_unittest.cc b/chrome/browser/chromeos/certificate_provider/certificate_provider_service_unittest.cc index 0055c874..ac750bc 100644 --- a/chrome/browser/chromeos/certificate_provider/certificate_provider_service_unittest.cc +++ b/chrome/browser/chromeos/certificate_provider/certificate_provider_service_unittest.cc
@@ -157,7 +157,7 @@ TestDelegate::RequestType::GET_CERTIFICATES); certificate_provider_->GetCertificates( - base::Bind(&StoreCertificates, certs)); + base::BindOnce(&StoreCertificates, certs)); task_runner_->RunUntilIdle(); EXPECT_EQ(TestDelegate::RequestType::NONE, @@ -168,7 +168,8 @@ scoped_refptr<net::SSLPrivateKey> FetchIdentityPrivateKey( net::ClientCertIdentity* identity) { scoped_refptr<net::SSLPrivateKey> ssl_private_key; - identity->AcquirePrivateKey(base::Bind(StorePrivateKey, &ssl_private_key)); + identity->AcquirePrivateKey( + base::BindOnce(StorePrivateKey, &ssl_private_key)); task_runner_->RunUntilIdle(); return ssl_private_key; } @@ -267,7 +268,7 @@ test_delegate_->ClearAndExpectRequest(TestDelegate::RequestType::NONE); certificate_provider_->GetCertificates( - base::Bind(&StoreCertificates, &certs)); + base::BindOnce(&StoreCertificates, &certs)); task_runner_->RunUntilIdle(); // As |certs| was not empty before, this ensures that StoreCertificates() was @@ -475,7 +476,7 @@ private_key->Sign( SSL_SIGN_RSA_PKCS1_SHA256, std::vector<uint8_t>(input.begin(), input.end()), - base::Bind(&ExpectOKAndStoreSignature, &received_signature)); + base::BindOnce(&ExpectOKAndStoreSignature, &received_signature)); task_runner_->RunUntilIdle(); @@ -512,7 +513,7 @@ net::Error error = net::OK; private_key->Sign(SSL_SIGN_RSA_PKCS1_SHA256, std::vector<uint8_t>(input.begin(), input.end()), - base::Bind(&ExpectEmptySignatureAndStoreError, &error)); + base::BindOnce(&ExpectEmptySignatureAndStoreError, &error)); task_runner_->RunUntilIdle();
diff --git a/chrome/browser/chromeos/certificate_provider/certificate_requests.cc b/chrome/browser/chromeos/certificate_provider/certificate_requests.cc index 830e840..56c61e29 100644 --- a/chrome/browser/chromeos/certificate_provider/certificate_requests.cc +++ b/chrome/browser/chromeos/certificate_provider/certificate_requests.cc
@@ -39,7 +39,7 @@ std::map<std::string, CertificateInfoList> extension_to_certificates; // The callback that must be run with the final list of certificates. - base::Callback<void(net::ClientCertIdentityList)> callback; + base::OnceCallback<void(net::ClientCertIdentityList)> callback; }; CertificateRequests::CertificateRequests() {} @@ -48,16 +48,16 @@ int CertificateRequests::AddRequest( const std::vector<std::string>& extension_ids, - const base::Callback<void(net::ClientCertIdentityList)>& callback, - const base::Callback<void(int)>& timeout_callback) { - std::unique_ptr<CertificateRequestState> state(new CertificateRequestState); - state->callback = callback; + base::OnceCallback<void(net::ClientCertIdentityList)> callback, + base::OnceCallback<void(int)> timeout_callback) { + auto state = std::make_unique<CertificateRequestState>(); + state->callback = std::move(callback); state->pending_extensions.insert(extension_ids.begin(), extension_ids.end()); const int request_id = next_free_request_id_++; state->timeout.Start( FROM_HERE, base::TimeDelta::FromMinutes(kGetCertificatesTimeoutInMinutes), - base::Bind(timeout_callback, request_id)); + base::BindOnce(std::move(timeout_callback), request_id)); const auto insert_result = requests_.insert(std::make_pair(request_id, std::move(state))); @@ -87,14 +87,14 @@ bool CertificateRequests::RemoveRequest( int request_id, std::map<std::string, CertificateInfoList>* certificates, - base::Callback<void(net::ClientCertIdentityList)>* callback) { + base::OnceCallback<void(net::ClientCertIdentityList)>* callback) { const auto it = requests_.find(request_id); if (it == requests_.end()) return false; CertificateRequestState& state = *it->second; *certificates = state.extension_to_certificates; - *callback = state.callback; + *callback = std::move(state.callback); requests_.erase(it); DVLOG(2) << "Completed certificate request " << request_id; return true;
diff --git a/chrome/browser/chromeos/certificate_provider/certificate_requests.h b/chrome/browser/chromeos/certificate_provider/certificate_requests.h index 1bf44ed..926e7010 100644 --- a/chrome/browser/chromeos/certificate_provider/certificate_requests.h +++ b/chrome/browser/chromeos/certificate_provider/certificate_requests.h
@@ -27,10 +27,9 @@ // request and be returned by RemoveRequest(). |timeout_callback| will be // called with the request id if this request times out before // SetCertificates() was called for all extensions in |extension_ids|. - int AddRequest( - const std::vector<std::string>& extension_ids, - const base::Callback<void(net::ClientCertIdentityList)>& callback, - const base::Callback<void(int)>& timeout_callback); + int AddRequest(const std::vector<std::string>& extension_ids, + base::OnceCallback<void(net::ClientCertIdentityList)> callback, + base::OnceCallback<void(int)> timeout_callback); // Returns whether this reply was expected, i.e. the request with |request_id| // was waiting for a reply from this extension. If it was expected, the @@ -47,7 +46,7 @@ bool RemoveRequest( int request_id, std::map<std::string, CertificateInfoList>* certificates, - base::Callback<void(net::ClientCertIdentityList)>* callback); + base::OnceCallback<void(net::ClientCertIdentityList)>* callback); // Removes this extension from all pending requests and returns the ids of // all completed requests.
diff --git a/chrome/browser/chromeos/dbus/dbus_helper.cc b/chrome/browser/chromeos/dbus/dbus_helper.cc index 01b1ce6..c21988bd 100644 --- a/chrome/browser/chromeos/dbus/dbus_helper.cc +++ b/chrome/browser/chromeos/dbus/dbus_helper.cc
@@ -10,9 +10,9 @@ #include "chrome/common/chrome_paths.h" #include "chromeos/constants/chromeos_paths.h" #include "chromeos/cryptohome/system_salt_getter.h" +#include "chromeos/dbus/audio/cras_audio_client.h" #include "chromeos/dbus/auth_policy/auth_policy_client.h" #include "chromeos/dbus/biod/biod_client.h" -#include "chromeos/dbus/cras_audio_client.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/hammerd/hammerd_client.h" #include "chromeos/dbus/kerberos/kerberos_client.h"
diff --git a/chrome/browser/chromeos/login/eula_browsertest.cc b/chrome/browser/chromeos/login/eula_browsertest.cc index 4f4fef1..8092a60 100644 --- a/chrome/browser/chromeos/login/eula_browsertest.cc +++ b/chrome/browser/chromeos/login/eula_browsertest.cc
@@ -8,29 +8,17 @@ #include <utility> #include "base/bind.h" -#include "base/callback.h" #include "base/macros.h" #include "base/run_loop.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "base/task/post_task.h" -#include "base/test/bind_test_util.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/login/test/help_app_test_helper.h" #include "chrome/browser/chromeos/login/test/js_checker.h" #include "chrome/browser/chromeos/login/test/oobe_base_test.h" #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h" #include "chrome/browser/chromeos/login/wizard_controller.h" -#include "chrome/browser/chromeos/settings/stats_reporting_controller.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" -#include "chrome/installer/util/google_update_settings.h" -#include "chromeos/dbus/cryptohome/fake_cryptohome_client.h" #include "components/guest_view/browser/guest_view_manager.h" -#include "components/metrics/metrics_pref_names.h" -#include "components/prefs/pref_service.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_ui.h" @@ -50,6 +38,7 @@ constexpr char kFakeOnlineEulaPath[] = "/intl/en-US/chrome/eula_text.html"; constexpr char kFakeOnlineEula[] = "No obligations at all"; + #if defined(GOOGLE_CHROME_BUILD) // See IDS_ABOUT_TERMS_OF_SERVICE for the complete text. constexpr char kOfflineEULAWarning[] = "Chrome OS Terms"; @@ -164,46 +153,6 @@ return *frame_set.begin(); } - // Returns an Oobe JSChecker that sends 'click' events instead of 'tap' - // events when interacting with UI elements. - test::JSChecker NonPolymerOobeJS() { - test::JSChecker js = test::OobeJS(); - js.set_polymer_ui(false); - return js; - } - - base::OnceClosure SetCollectStatsConsentClosure(bool consented) { - return base::BindOnce( - base::IgnoreResult(&GoogleUpdateSettings::SetCollectStatsConsent), - consented); - } - - // Waits until |blocking_closure| finishes executing. - void WaitForBlockingCall(base::OnceClosure blocking_closure) { - base::RunLoop runloop; - base::PostTaskWithTraitsAndReply(FROM_HERE, {base::MayBlock()}, - std::move(blocking_closure), - runloop.QuitClosure()); - runloop.Run(); - } - - // Waits and returns the result of evaluating |blocking_closure|. - bool EvaluateBlocking(base::OnceCallback<bool()> blocking_closure) { - bool result = false; - base::RunLoop runloop; - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock()}, std::move(blocking_closure), - base::BindOnce( - [](base::RepeatingClosure quit_closure, bool* result_out, - bool evaluation_result) { - *result_out = evaluation_result; - quit_closure.Run(); - }, - runloop.QuitClosure(), &result)); - runloop.Run(); - return result; - } - private: std::unique_ptr<HttpResponse> HandleRequest(const HttpRequest& request) { GURL request_url = GURL("http://localhost").Resolve(request.relative_url); @@ -262,113 +211,5 @@ std::string::npos); } -// Tests that clicking on "System security settings" button opens a dialog -// showing the TPM password. -IN_PROC_BROWSER_TEST_F(EulaTest, DisplaysTpmPassword) { - ShowEulaScreen(); - - NonPolymerOobeJS().TapOnPath({"oobe-eula-md", "installationSettings"}); - test::OobeJS().ExpectVisiblePath( - {"oobe-eula-md", "installationSettingsDialog"}); - - test::OobeJS().CreateWaiter( - "$('oobe-eula-md').$$('#eula-password').textContent.trim() !== ''"); - test::OobeJS().ExpectEQ( - "$('oobe-eula-md').$$('#eula-password').textContent.trim()", - std::string(FakeCryptohomeClient::kStubTpmPassword)); -} - -// Verifies statistic collection accepted flow. -// Advaces to the next screen and verifies stats collection is enabled. -IN_PROC_BROWSER_TEST_F(EulaTest, EnableUsageStats) { - ShowEulaScreen(); - - // Verify that toggle is enabled by default. - test::OobeJS().ExpectTrue("$('oobe-eula-md').$$('#usageStats').checked"); - - ASSERT_TRUE(StatsReportingController::IsInitialized()); - - // Explicitly set as false to make sure test modifies these values. - StatsReportingController::Get()->SetEnabled( - ProfileManager::GetActiveUserProfile(), false); - g_browser_process->local_state()->SetBoolean( - metrics::prefs::kMetricsReportingEnabled, false); - - WaitForBlockingCall(SetCollectStatsConsentClosure(false)); - - // Start Listening for StatsReportingController updates. - base::RunLoop runloop; - auto subscription = - StatsReportingController::Get()->AddObserver(runloop.QuitClosure()); - - // Advance to the next screen for changes to take effect. - test::OobeJS().TapOnPath({"oobe-eula-md", "acceptButton"}); - - // Wait for StartReporting update. - runloop.Run(); - - // Verify stats collection is enabled. - EXPECT_TRUE(StatsReportingController::Get()->IsEnabled()); - EXPECT_TRUE(g_browser_process->local_state()->GetBoolean( - metrics::prefs::kMetricsReportingEnabled)); - EXPECT_TRUE(EvaluateBlocking( - base::BindOnce(&GoogleUpdateSettings::GetCollectStatsConsent))); -} - -// Verify statistic collection denied flow. Clicks on usage stats toggle, -// advaces to the next screen and verifies stats collection is disabled. -IN_PROC_BROWSER_TEST_F(EulaTest, DisableUsageStats) { - ShowEulaScreen(); - - // Verify that toggle is enabled by default. - test::OobeJS().ExpectTrue("$('oobe-eula-md').$$('#usageStats').checked"); - - ASSERT_TRUE(StatsReportingController::IsInitialized()); - - // Explicitly set as true to make sure test modifies these values. - StatsReportingController::Get()->SetEnabled( - ProfileManager::GetActiveUserProfile(), true); - g_browser_process->local_state()->SetBoolean( - metrics::prefs::kMetricsReportingEnabled, true); - - WaitForBlockingCall(SetCollectStatsConsentClosure(true)); - - // Start Listening for StatsReportingController updates. - base::RunLoop runloop; - auto subscription = - StatsReportingController::Get()->AddObserver(runloop.QuitClosure()); - - // Click on the toggle to disable stats collection and advance to the next - // screen for changes to take effect. - NonPolymerOobeJS().TapOnPath({"oobe-eula-md", "usageStats"}); - test::OobeJS().TapOnPath({"oobe-eula-md", "acceptButton"}); - - // Wait for StartReportingController update. - runloop.Run(); - - // Verify stats collection is disabled. - EXPECT_FALSE(StatsReportingController::Get()->IsEnabled()); - EXPECT_FALSE(g_browser_process->local_state()->GetBoolean( - metrics::prefs::kMetricsReportingEnabled)); - EXPECT_FALSE(EvaluateBlocking( - base::BindOnce(&GoogleUpdateSettings::GetCollectStatsConsent))); -} - -// Tests that clicking on "Learn more" button opens a help dialog. -IN_PROC_BROWSER_TEST_F(EulaTest, LearnMore) { - ShowEulaScreen(); - - // Load HelperApp extension. - HelpAppTestHelper scoped_helper; - - // Start listening for help dialog creation. - HelpAppTestHelper::Waiter waiter; - - NonPolymerOobeJS().TapOnPath({"oobe-eula-md", "learn-more"}); - - // Wait until help dialog is displayed. - waiter.Wait(); -} - } // namespace } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/help_app_launcher.cc b/chrome/browser/chromeos/login/help_app_launcher.cc index e8dd6863..7ad126e 100644 --- a/chrome/browser/chromeos/login/help_app_launcher.cc +++ b/chrome/browser/chromeos/login/help_app_launcher.cc
@@ -24,12 +24,8 @@ namespace { -// Official HelpApp extension id. -const char kExtensionId[] = "honijodknafkokifofgiaalefdiedpko"; - -const char kHelpAppFormat[] = "chrome-extension://%s/oobe.html?id=%d"; - -const char* g_extension_id_for_test = nullptr; +const char kHelpAppFormat[] = + "chrome-extension://honijodknafkokifofgiaalefdiedpko/oobe.html?id=%d"; } // namespace @@ -49,24 +45,13 @@ if (!registry) return; - const char* extension_id = kExtensionId; - if (g_extension_id_for_test && *g_extension_id_for_test != '\0') { - extension_id = g_extension_id_for_test; - } - - GURL url(base::StringPrintf(kHelpAppFormat, extension_id, - static_cast<int>(help_topic_id))); + GURL url(base::StringPrintf(kHelpAppFormat, static_cast<int>(help_topic_id))); // HelpApp component extension presents only in official builds so we can // show help only when the extensions is installed. if (registry->enabled_extensions().GetByID(url.host())) ShowHelpTopicDialog(profile, GURL(url)); } -// static -void HelpAppLauncher::SetExtensionIdForTest(const char* extension_id) { - g_extension_id_for_test = extension_id; -} - /////////////////////////////////////////////////////////////////////////////// // HelpApp, protected:
diff --git a/chrome/browser/chromeos/login/help_app_launcher.h b/chrome/browser/chromeos/login/help_app_launcher.h index 77309678..1a5b2bd 100644 --- a/chrome/browser/chromeos/login/help_app_launcher.h +++ b/chrome/browser/chromeos/login/help_app_launcher.h
@@ -47,9 +47,6 @@ // Shows specified help topic. void ShowHelpTopic(HelpTopic help_topic_id); - // Allows tests to specify a different extension id to connect to. - static void SetExtensionIdForTest(const char* extension_id); - protected: virtual ~HelpAppLauncher();
diff --git a/chrome/browser/chromeos/login/lock/screen_locker_unittest.cc b/chrome/browser/chromeos/login/lock/screen_locker_unittest.cc index ac2f643a..095c766 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker_unittest.cc +++ b/chrome/browser/chromeos/login/lock/screen_locker_unittest.cc
@@ -22,8 +22,8 @@ #include "chrome/test/base/testing_profile_manager.h" #include "chromeos/audio/cras_audio_handler.h" #include "chromeos/cryptohome/system_salt_getter.h" +#include "chromeos/dbus/audio/cras_audio_client.h" #include "chromeos/dbus/biod/biod_client.h" -#include "chromeos/dbus/cras_audio_client.h" #include "chromeos/dbus/cryptohome/cryptohome_client.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/login/login_state/login_state.h"
diff --git a/chrome/browser/chromeos/login/screens/base_screen.h b/chrome/browser/chromeos/login/screens/base_screen.h index d9e2901..76970b82d 100644 --- a/chrome/browser/chromeos/login/screens/base_screen.h +++ b/chrome/browser/chromeos/login/screens/base_screen.h
@@ -55,12 +55,6 @@ virtual void OnConfigurationChanged(); private: - friend class BaseWebUIHandler; - friend class EnrollmentScreenTest; - friend class NetworkScreenTest; - friend class ScreenManager; - friend class UpdateScreenTest; - // Configuration itself is owned by WizardController and is accessible // to screen only between OnShow / OnHide calls. base::Value* configuration_ = nullptr;
diff --git a/chrome/browser/chromeos/login/screens/eula_screen.cc b/chrome/browser/chromeos/login/screens/eula_screen.cc index 3e48399..0acc4fd 100644 --- a/chrome/browser/chromeos/login/screens/eula_screen.cc +++ b/chrome/browser/chromeos/login/screens/eula_screen.cc
@@ -44,6 +44,24 @@ view_->Unbind(); } +GURL EulaScreen::GetOemEulaUrl() const { + const StartupCustomizationDocument* customization = + StartupCustomizationDocument::GetInstance(); + if (customization->IsReady()) { + // Previously we're using "initial locale" that device initially + // booted with out-of-box. http://crbug.com/145142 + std::string locale = g_browser_process->GetApplicationLocale(); + std::string eula_page = customization->GetEULAPage(locale); + if (!eula_page.empty()) + return GURL(eula_page); + + VLOG(1) << "No eula found for locale: " << locale; + } else { + LOG(ERROR) << "No manifest found."; + } + return GURL(); +} + void EulaScreen::InitiatePasswordFetch() { if (tpm_password_.empty()) { password_fetcher_.Fetch();
diff --git a/chrome/browser/chromeos/login/test/help_app_test_helper.cc b/chrome/browser/chromeos/login/test/help_app_test_helper.cc deleted file mode 100644 index e095e0e3..0000000 --- a/chrome/browser/chromeos/login/test/help_app_test_helper.cc +++ /dev/null
@@ -1,82 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chromeos/login/test/help_app_test_helper.h" - -#include "base/files/file_path.h" -#include "base/path_service.h" -#include "chrome/browser/chromeos/extensions/signin_screen_policy_provider.h" -#include "chrome/browser/chromeos/login/help_app_launcher.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/extensions/chrome_test_extension_loader.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/grit/generated_resources.h" -#include "ui/aura/env.h" -#include "ui/aura/window.h" -#include "ui/base/l10n/l10n_util.h" - -namespace chromeos { - -/////////////////////////////////////////////////////////////////////////////// -// HelpAppTestHelper::Waiter -/////////////////////////////////////////////////////////////////////////////// - -HelpAppTestHelper::Waiter::Waiter() { - aura::Env::GetInstance()->AddObserver(this); -} - -HelpAppTestHelper::Waiter::~Waiter() { - aura::Env::GetInstance()->RemoveObserver(this); -} - -void HelpAppTestHelper::Waiter::Wait() { - if (!dialog_visible_) - run_loop_.Run(); -} - -void HelpAppTestHelper::Waiter::OnWindowInitialized(aura::Window* window) { - window_observer_.Add(window); -} - -void HelpAppTestHelper::Waiter::OnWindowVisibilityChanged(aura::Window* window, - bool visible) { - if (IsHelpAppDialog(window) && visible && !dialog_visible_) { - dialog_visible_ = true; - run_loop_.QuitClosure().Run(); - } -} - -bool HelpAppTestHelper::Waiter::IsHelpAppDialog(aura::Window* window) { - return window->GetTitle() == - l10n_util::GetStringUTF16(IDS_LOGIN_OOBE_HELP_DIALOG_TITLE); -} - -/////////////////////////////////////////////////////////////////////////////// -// HelpAppTestHelper -/////////////////////////////////////////////////////////////////////////////// - -HelpAppTestHelper::HelpAppTestHelper() { - auto reset = GetScopedSigninScreenPolicyProviderDisablerForTesting(); - - base::FilePath test_data_dir; - base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); - extensions::ChromeTestExtensionLoader loader( - ProfileHelper::GetSigninProfile()); - loader.set_allow_incognito_access(true); - - scoped_refptr<const extensions::Extension> extension = - loader.LoadExtension(test_data_dir.AppendASCII("extensions") - .AppendASCII("api_test") - .AppendASCII("help_app")); - - DCHECK(extension && !extension->id().empty()); - - HelpAppLauncher::SetExtensionIdForTest(extension->id().c_str()); -} - -HelpAppTestHelper::~HelpAppTestHelper() { - HelpAppLauncher::SetExtensionIdForTest(nullptr); -} - -} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/test/help_app_test_helper.h b/chrome/browser/chromeos/login/test/help_app_test_helper.h deleted file mode 100644 index e752448..0000000 --- a/chrome/browser/chromeos/login/test/help_app_test_helper.h +++ /dev/null
@@ -1,57 +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_CHROMEOS_LOGIN_TEST_HELP_APP_TEST_HELPER_H_ -#define CHROME_BROWSER_CHROMEOS_LOGIN_TEST_HELP_APP_TEST_HELPER_H_ - -#include "base/macros.h" -#include "base/run_loop.h" -#include "base/scoped_observer.h" -#include "ui/aura/env_observer.h" -#include "ui/aura/window_observer.h" - -namespace chromeos { - -// Provides utilies for launching and interacting with HelpApp dialogs in tests. -class HelpAppTestHelper { - public: - // Waits for a HelpApp dialog to open and become visible. - class Waiter : public aura::EnvObserver, public aura::WindowObserver { - public: - Waiter(); - ~Waiter() override; - - // Blocks until a HelpApp dialog becomes visible. - void Wait(); - - // aura::EnvObserver - void OnWindowInitialized(aura::Window* window) override; - - // aura::WindowObserver - void OnWindowVisibilityChanged(aura::Window* window, bool visible) override; - - private: - bool IsHelpAppDialog(aura::Window* window); - - base::RunLoop run_loop_; - bool dialog_visible_ = false; - ScopedObserver<aura::Window, aura::WindowObserver> window_observer_{this}; - DISALLOW_COPY_AND_ASSIGN(Waiter); - }; - - HelpAppTestHelper(); - virtual ~HelpAppTestHelper(); - - // Performs setup to allow HelpApp dialogs to open in tests. - void SetUpHelpAppForTest(); - - // TODO(tonydeluna): Add utilities for interacting with the contents of the - // help dialogs. - - DISALLOW_COPY_AND_ASSIGN(HelpAppTestHelper); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_LOGIN_TEST_HELP_APP_TEST_HELPER_H_
diff --git a/chrome/browser/chromeos/login/test/js_checker.cc b/chrome/browser/chromeos/login/test/js_checker.cc index b4f8a5c..de4b3763 100644 --- a/chrome/browser/chromeos/login/test/js_checker.cc +++ b/chrome/browser/chromeos/login/test/js_checker.cc
@@ -237,11 +237,11 @@ void JSChecker::TapOnPath( std::initializer_list<base::StringPiece> element_ids) { ExpectVisiblePath(element_ids); - // TODO(crbug.com/949377): Switch to always firing 'click' events when - // missing OOBE UI components are migrated to handle 'click' events. + // All OOBE UI should be mobile-friendly, so use "tap" instead of "click". if (polymer_ui_) { Evaluate(GetOobeElementPath(element_ids) + ".fire('tap')"); } else { + // Old test-only UI (fake GAIA, fake SAML) only support "click". Evaluate(GetOobeElementPath(element_ids) + ".click()"); } }
diff --git a/chrome/browser/chromeos/net/client_cert_store_chromeos.cc b/chrome/browser/chromeos/net/client_cert_store_chromeos.cc index 025434e..18d0265 100644 --- a/chrome/browser/chromeos/net/client_cert_store_chromeos.cc +++ b/chrome/browser/chromeos/net/client_cert_store_chromeos.cc
@@ -12,6 +12,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback.h" +#include "base/callback_helpers.h" #include "base/location.h" #include "base/task/post_task.h" #include "base/threading/scoped_blocking_call.h" @@ -33,32 +34,35 @@ void ClientCertStoreChromeOS::GetClientCerts( const net::SSLCertRequestInfo& cert_request_info, - const ClientCertListCallback& callback) { + ClientCertListCallback callback) { // Caller is responsible for keeping the ClientCertStore alive until the // callback is run. - base::Callback<void(net::ClientCertIdentityList)> - get_platform_certs_and_filter = base::Bind( + base::OnceCallback<void(net::ClientCertIdentityList)> + get_platform_certs_and_filter = base::BindOnce( &ClientCertStoreChromeOS::GotAdditionalCerts, base::Unretained(this), - base::Unretained(&cert_request_info), callback); + base::Unretained(&cert_request_info), std::move(callback)); - base::Closure get_additional_certs_and_continue; + base::OnceClosure get_additional_certs_and_continue; if (cert_provider_) { - get_additional_certs_and_continue = base::Bind( - &CertificateProvider::GetCertificates, - base::Unretained(cert_provider_.get()), get_platform_certs_and_filter); + get_additional_certs_and_continue = + base::BindOnce(&CertificateProvider::GetCertificates, + base::Unretained(cert_provider_.get()), + std::move(get_platform_certs_and_filter)); } else { get_additional_certs_and_continue = - base::Bind(get_platform_certs_and_filter, - base::Passed(net::ClientCertIdentityList())); + base::BindOnce(std::move(get_platform_certs_and_filter), + net::ClientCertIdentityList()); } - if (cert_filter_->Init(get_additional_certs_and_continue)) - get_additional_certs_and_continue.Run(); + auto repeating_callback = base::AdaptCallbackForRepeating( + std::move(get_additional_certs_and_continue)); + if (cert_filter_->Init(repeating_callback)) + repeating_callback.Run(); } void ClientCertStoreChromeOS::GotAdditionalCerts( const net::SSLCertRequestInfo* request, - const ClientCertListCallback& callback, + ClientCertListCallback callback, net::ClientCertIdentityList additional_certs) { scoped_refptr<crypto::CryptoModuleBlockingPasswordDelegate> password_delegate; if (!password_delegate_factory_.is_null()) @@ -66,10 +70,10 @@ base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::Bind(&ClientCertStoreChromeOS::GetAndFilterCertsOnWorkerThread, - base::Unretained(this), password_delegate, - base::Unretained(request), base::Passed(&additional_certs)), - callback); + base::BindOnce(&ClientCertStoreChromeOS::GetAndFilterCertsOnWorkerThread, + base::Unretained(this), password_delegate, + base::Unretained(request), std::move(additional_certs)), + std::move(callback)); } net::ClientCertIdentityList
diff --git a/chrome/browser/chromeos/net/client_cert_store_chromeos.h b/chrome/browser/chromeos/net/client_cert_store_chromeos.h index f857469..9a5dfdd 100644 --- a/chrome/browser/chromeos/net/client_cert_store_chromeos.h +++ b/chrome/browser/chromeos/net/client_cert_store_chromeos.h
@@ -49,11 +49,11 @@ // net::ClientCertStore: void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info, - const ClientCertListCallback& callback) override; + ClientCertListCallback callback) override; private: void GotAdditionalCerts(const net::SSLCertRequestInfo* request, - const ClientCertListCallback& callback, + ClientCertListCallback callback, net::ClientCertIdentityList additional_certs); net::ClientCertIdentityList GetAndFilterCertsOnWorkerThread(
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc index 2e85258a..75ad099b 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc +++ b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
@@ -605,7 +605,7 @@ SelectCertificatesState* state_ptr = state.get(); state_ptr->cert_store_->GetClientCerts( *state_ptr->cert_request_info_, - base::Bind(&DidSelectCertificatesOnIOThread, base::Passed(&state))); + base::BindOnce(&DidSelectCertificatesOnIOThread, std::move(state))); } // Filters the obtained certificates on a worker thread. Used by
diff --git a/chrome/browser/chromeos/printing/cups_printers_manager.cc b/chrome/browser/chromeos/printing/cups_printers_manager.cc index 294e52f..9bd5d3d 100644 --- a/chrome/browser/chromeos/printing/cups_printers_manager.cc +++ b/chrome/browser/chromeos/printing/cups_printers_manager.cc
@@ -33,43 +33,6 @@ namespace chromeos { namespace { -class CupsPrintersManagerImpl; - -// Since CupsPrintersManager listens to multiple PrinterDetectors, we need to -// disambiguate incoming observer calls based on their source, and so can't -// implement PrinterDetector::Observer directly in CupsPrintersManagerImpl. -// -// Note that at the time the Proxy is constructed, CupsPrintersManagerImpl's -// construction may not be complete, so any callbacks into the parent need -// to be deferred. -class PrinterDetectorObserverProxy : public PrinterDetector::Observer { - public: - PrinterDetectorObserverProxy(CupsPrintersManagerImpl* parent, - int id, - PrinterDetector* detector) - : parent_(parent), id_(id), observer_(this) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_); - // It's ok to Add() before construction is complete because callbacks are on - // the same sequence, therefore we will complete construction before any - // detection callback will be processed. - observer_.Add(detector); - } - ~PrinterDetectorObserverProxy() override { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_); - } - - // Defined out of line because we need the CupsPrintersManagerImpl - // definition first. - void OnPrintersFound( - const std::vector<PrinterDetector::DetectedPrinter>& printers) override; - - private: - CupsPrintersManagerImpl* const parent_; - const int id_; - SEQUENCE_CHECKER(sequence_); - ScopedObserver<PrinterDetector, PrinterDetector::Observer> observer_; -}; - // This is akin to python's filter() builtin, but with reverse polarity on the // test function -- *remove* all entries in printers for which test_fn returns // true, discard the rest. @@ -118,14 +81,14 @@ // Callbacks may ensue immediately when the observer proxies are set up, so // these instantiations must come after everything else is initialized. - usb_detector_observer_proxy_ = - std::make_unique<PrinterDetectorObserverProxy>(this, kUsbDetector, - usb_detector_.get()); + usb_detector_->RegisterPrintersFoundCallback( + base::BindRepeating(&CupsPrintersManagerImpl::OnPrintersFound, + weak_ptr_factory_.GetWeakPtr(), kUsbDetector)); OnPrintersFound(kUsbDetector, usb_detector_->GetPrinters()); - zeroconf_detector_observer_proxy_ = - std::make_unique<PrinterDetectorObserverProxy>( - this, kZeroconfDetector, zeroconf_detector_.get()); + zeroconf_detector_->RegisterPrintersFoundCallback( + base::BindRepeating(&CupsPrintersManagerImpl::OnPrintersFound, + weak_ptr_factory_.GetWeakPtr(), kZeroconfDetector)); OnPrintersFound(kZeroconfDetector, zeroconf_detector_->GetPrinters()); native_printers_allowed_.Init(prefs::kUserNativePrintersAllowed, @@ -274,8 +237,7 @@ NotifyObservers({kEnterprise}); } - // Callback entry point for PrinterDetectorObserverProxys owned by this - // object. + // Callback for PrinterDetectors. void OnPrintersFound( int detector_id, const std::vector<PrinterDetector::DetectedPrinter>& printers) { @@ -513,11 +475,8 @@ synced_printers_manager_observer_; std::unique_ptr<PrinterDetector> usb_detector_; - std::unique_ptr<PrinterDetectorObserverProxy> usb_detector_observer_proxy_; std::unique_ptr<PrinterDetector> zeroconf_detector_; - std::unique_ptr<PrinterDetectorObserverProxy> - zeroconf_detector_observer_proxy_; scoped_refptr<PpdProvider> ppd_provider_; @@ -562,12 +521,6 @@ base::WeakPtrFactory<CupsPrintersManagerImpl> weak_ptr_factory_; }; -void PrinterDetectorObserverProxy::OnPrintersFound( - const std::vector<PrinterDetector::DetectedPrinter>& printers) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_); - parent_->OnPrintersFound(id_, printers); -} - } // namespace // static
diff --git a/chrome/browser/chromeos/printing/cups_printers_manager_unittest.cc b/chrome/browser/chromeos/printing/cups_printers_manager_unittest.cc index 7f4b1f5f..04ce83d 100644 --- a/chrome/browser/chromeos/printing/cups_printers_manager_unittest.cc +++ b/chrome/browser/chromeos/printing/cups_printers_manager_unittest.cc
@@ -164,11 +164,8 @@ FakePrinterDetector() {} ~FakePrinterDetector() override = default; - void AddObserver(Observer* observer) override { - observers_.AddObserver(observer); - } - void RemoveObserver(Observer* observer) override { - observers_.RemoveObserver(observer); + void RegisterPrintersFoundCallback(OnPrintersFoundCallback cb) override { + on_printers_found_callback_ = std::move(cb); } std::vector<DetectedPrinter> GetPrinters() override { return detections_; } @@ -177,9 +174,7 @@ const std::vector<PrinterDetector::DetectedPrinter>& new_detections) { detections_.insert(detections_.end(), new_detections.begin(), new_detections.end()); - for (Observer& observer : observers_) { - observer.OnPrintersFound(detections_); - } + on_printers_found_callback_.Run(detections_); } // Remove printers that have ids in ids. @@ -195,7 +190,7 @@ private: std::vector<DetectedPrinter> detections_; - base::ObserverList<PrinterDetector::Observer>::Unchecked observers_; + OnPrintersFoundCallback on_printers_found_callback_; }; // Fake PpdProvider backend. This fake generates PpdReferences based on
diff --git a/chrome/browser/chromeos/printing/printer_detector.h b/chrome/browser/chromeos/printing/printer_detector.h index da8c231..a31853e 100644 --- a/chrome/browser/chromeos/printing/printer_detector.h +++ b/chrome/browser/chromeos/printing/printer_detector.h
@@ -7,6 +7,7 @@ #include <vector> +#include "base/callback.h" #include "chromeos/printing/ppd_provider.h" #include "chromeos/printing/printer_configuration.h" @@ -23,7 +24,7 @@ // an up-to-date list of the printers detected is this: // // auto detector_ = PrinterDetectorImplementation::Create(); -// detector_->AddObserver(this); +// detector_->RegisterPrintersFoundCallback(cb); // printers_ = detector_->GetPrinters(); // class CHROMEOS_EXPORT PrinterDetector { @@ -37,28 +38,12 @@ PrinterSearchData ppd_search_data; }; - class Observer { - public: - virtual ~Observer() = default; - - // Called with a collection of printers as they are discovered. On each - // call |printers| is the full set of known printers; it is not - // incremental; printers may be added or removed. - // - // To avoid race conditions of printer state changes, you should register - // your Observer and call PrinterDetector::GetPrinters() to populate the - // initial state in the same sequenced atom. - virtual void OnPrintersFound( - const std::vector<DetectedPrinter>& printers) = 0; - }; + using OnPrintersFoundCallback = base::RepeatingCallback<void( + const std::vector<DetectedPrinter>& printers)>; virtual ~PrinterDetector() = default; - // Observer management. Observer callbacks will be performed on the calling - // sequence, but observers do not need to be on the same sequence as each - // other or the detector. - virtual void AddObserver(Observer* observer) = 0; - virtual void RemoveObserver(Observer* observer) = 0; + virtual void RegisterPrintersFoundCallback(OnPrintersFoundCallback cb) = 0; // Get the current list of known printers. virtual std::vector<DetectedPrinter> GetPrinters() = 0;
diff --git a/chrome/browser/chromeos/printing/usb_printer_detector.cc b/chrome/browser/chromeos/printing/usb_printer_detector.cc index d6142ae..dcbe4e01 100644 --- a/chrome/browser/chromeos/printing/usb_printer_detector.cc +++ b/chrome/browser/chromeos/printing/usb_printer_detector.cc
@@ -15,6 +15,7 @@ #include "base/macros.h" #include "base/observer_list_threadsafe.h" #include "base/scoped_observer.h" +#include "base/sequence_checker.h" #include "base/strings/utf_string_conversions.h" #include "base/synchronization/lock.h" #include "base/threading/sequenced_task_runner_handle.h" @@ -56,8 +57,6 @@ public: explicit UsbPrinterDetectorImpl(device::UsbService* usb_service) : usb_observer_(this), - observer_list_( - new base::ObserverListThreadSafe<UsbPrinterDetector::Observer>), weak_ptr_factory_(this) { if (usb_service) { usb_observer_.Add(usb_service); @@ -65,20 +64,20 @@ weak_ptr_factory_.GetWeakPtr())); } } - ~UsbPrinterDetectorImpl() override = default; - - // PrinterDetector interface function. - void AddObserver(UsbPrinterDetector::Observer* observer) override { - observer_list_->AddObserver(observer); + ~UsbPrinterDetectorImpl() override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_); } - // PrinterDetector interface function. - void RemoveObserver(UsbPrinterDetector::Observer* observer) override { - observer_list_->RemoveObserver(observer); + // PrinterDetector override. + void RegisterPrintersFoundCallback(OnPrintersFoundCallback cb) override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_); + DCHECK(!on_printers_found_callback_); + on_printers_found_callback_ = std::move(cb); } - // PrinterDetector interface function. + // PrinterDetector override. std::vector<DetectedPrinter> GetPrinters() override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_); base::AutoLock auto_lock(printers_lock_); return GetPrintersLocked(); } @@ -126,9 +125,9 @@ base::AutoLock auto_lock(printers_lock_); printers_[device->guid()] = entry; - observer_list_->Notify(FROM_HERE, - &PrinterDetector::Observer::OnPrintersFound, - GetPrintersLocked()); + if (on_printers_found_callback_) { + on_printers_found_callback_.Run(GetPrintersLocked()); + } } // UsbService::observer override. @@ -139,21 +138,23 @@ } base::AutoLock auto_lock(printers_lock_); printers_.erase(device->guid()); - observer_list_->Notify(FROM_HERE, - &PrinterDetector::Observer::OnPrintersFound, - GetPrintersLocked()); + if (on_printers_found_callback_) { + on_printers_found_callback_.Run(GetPrintersLocked()); + } } + SEQUENCE_CHECKER(sequence_); + // Map from USB GUID to DetectedPrinter for all detected printers, and // associated lock, since we don't require all access to be from the same // sequence. std::map<std::string, DetectedPrinter> printers_; base::Lock printers_lock_; + OnPrintersFoundCallback on_printers_found_callback_; + ScopedObserver<device::UsbService, device::UsbService::Observer> usb_observer_; - scoped_refptr<base::ObserverListThreadSafe<UsbPrinterDetector::Observer>> - observer_list_; base::WeakPtrFactory<UsbPrinterDetectorImpl> weak_ptr_factory_; };
diff --git a/chrome/browser/chromeos/printing/zeroconf_printer_detector.cc b/chrome/browser/chromeos/printing/zeroconf_printer_detector.cc index 2246539..efb2322 100644 --- a/chrome/browser/chromeos/printing/zeroconf_printer_detector.cc +++ b/chrome/browser/chromeos/printing/zeroconf_printer_detector.cc
@@ -10,7 +10,6 @@ #include <vector> #include "base/hash/md5.h" -#include "base/observer_list_threadsafe.h" #include "base/stl_util.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" @@ -210,8 +209,7 @@ public: // Normal constructor, connects to service discovery. ZeroconfPrinterDetectorImpl() - : discovery_client_(ServiceDiscoverySharedClient::GetInstance()), - observer_list_(new base::ObserverListThreadSafe<Observer>()) { + : discovery_client_(ServiceDiscoverySharedClient::GetInstance()) { CreateDeviceLister(kIppServiceName); CreateDeviceLister(kIppsServiceName); CreateDeviceLister(kIppEverywhereServiceName); @@ -221,8 +219,7 @@ // Testing constructor, uses injected backends. explicit ZeroconfPrinterDetectorImpl( std::map<std::string, std::unique_ptr<ServiceDiscoveryDeviceLister>>* - device_listers) - : observer_list_(new base::ObserverListThreadSafe<Observer>()) { + device_listers) { device_listers_.swap(*device_listers); for (auto& entry : device_listers_) { entry.second->Start(); @@ -232,19 +229,20 @@ ~ZeroconfPrinterDetectorImpl() override {} + // PrinterDetector override. + void RegisterPrintersFoundCallback(OnPrintersFoundCallback cb) override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_); + DCHECK(!on_printers_found_callback_); + on_printers_found_callback_ = std::move(cb); + } + + // PrinterDetector override. std::vector<DetectedPrinter> GetPrinters() override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_); base::AutoLock auto_lock(printers_lock_); return GetPrintersLocked(); } - void AddObserver(Observer* observer) override { - observer_list_->AddObserver(observer); - } - - void RemoveObserver(Observer* observer) override { - observer_list_->RemoveObserver(observer); - } - // ServiceDiscoveryDeviceLister::Delegate implementation void OnDeviceChanged(const std::string& service_type, bool added, @@ -258,9 +256,9 @@ } base::AutoLock auto_lock(printers_lock_); printers_[service_type][service_description.instance_name()] = printer; - observer_list_->Notify(FROM_HERE, - &PrinterDetector::Observer::OnPrintersFound, - GetPrintersLocked()); + if (on_printers_found_callback_) { + on_printers_found_callback_.Run(GetPrintersLocked()); + } } // ServiceDiscoveryDeviceLister::Delegate implementation. Remove the @@ -275,9 +273,9 @@ auto it = service_type_map.find(service_description.instance_name()); if (it != service_type_map.end()) { service_type_map.erase(it); - observer_list_->Notify(FROM_HERE, - &PrinterDetector::Observer::OnPrintersFound, - GetPrintersLocked()); + if (on_printers_found_callback_) { + on_printers_found_callback_.Run(GetPrintersLocked()); + } } else { LOG(WARNING) << "Device removal requested for unknown '" << service_name << "'"; @@ -290,9 +288,9 @@ base::AutoLock auto_lock(printers_lock_); if (!printers_[service_type].empty()) { printers_[service_type].clear(); - observer_list_->Notify(FROM_HERE, - &PrinterDetector::Observer::OnPrintersFound, - GetPrintersLocked()); + if (on_printers_found_callback_) { + on_printers_found_callback_.Run(GetPrintersLocked()); + } } // Request a new round of discovery from the lister. @@ -337,6 +335,8 @@ return ret; } + SEQUENCE_CHECKER(sequence_); + // Map from service type to map from instance name to associated known // printer, and associated lock. std::map<std::string, std::map<std::string, DetectedPrinter>> printers_; @@ -349,8 +349,7 @@ std::map<std::string, std::unique_ptr<ServiceDiscoveryDeviceLister>> device_listers_; - // Observers of this object. - scoped_refptr<base::ObserverListThreadSafe<Observer>> observer_list_; + OnPrintersFoundCallback on_printers_found_callback_; }; } // namespace
diff --git a/chrome/browser/chromeos/printing/zeroconf_printer_detector_unittest.cc b/chrome/browser/chromeos/printing/zeroconf_printer_detector_unittest.cc index de84ca9..fc1b06d7 100644 --- a/chrome/browser/chromeos/printing/zeroconf_printer_detector_unittest.cc +++ b/chrome/browser/chromeos/printing/zeroconf_printer_detector_unittest.cc
@@ -285,8 +285,7 @@ DeferringDelegate deferring_delegate_; }; -class ZeroconfPrinterDetectorTest : public testing::Test, - public PrinterDetector::Observer { +class ZeroconfPrinterDetectorTest : public testing::Test { public: ZeroconfPrinterDetectorTest() { auto* runner = scoped_task_environment_.GetMainThreadTaskRunner().get(); @@ -321,7 +320,8 @@ // keep the lister fakes accessible after ownership is transferred into the // detector. listers_.clear(); - detector_->AddObserver(this); + detector_->RegisterPrintersFoundCallback(base::BindRepeating( + &ZeroconfPrinterDetectorTest::OnPrintersFound, base::Unretained(this))); ipp_lister_->SetDelegate(detector_.get()); ipps_lister_->SetDelegate(detector_.get()); ippe_lister_->SetDelegate(detector_.get()); @@ -386,9 +386,9 @@ actual.ppd_search_data.make_and_model); } - // PrinterDetector::Observer callback. + // PrinterDetector callback. void OnPrintersFound( - const std::vector<PrinterDetector::DetectedPrinter>& printers) override { + const std::vector<PrinterDetector::DetectedPrinter>& printers) { printers_found_callbacks_.push_back(printers); }
diff --git a/chrome/browser/download/notification/download_item_notification.cc b/chrome/browser/download/notification/download_item_notification.cc index 46f0d65..13c4a400 100644 --- a/chrome/browser/download/notification/download_item_notification.cc +++ b/chrome/browser/download/notification/download_item_notification.cc
@@ -274,6 +274,9 @@ void DownloadItemNotification::Click( const base::Optional<int>& button_index, const base::Optional<base::string16>& reply) { + if (!item_) + return; + if (button_index) { if (*button_index < 0 || static_cast<size_t>(*button_index) >= button_actions_->size()) { @@ -355,6 +358,9 @@ } void DownloadItemNotification::Update() { + if (!item_) + return; + auto download_state = item_->GetState(); // When the download is just completed, interrupted or transitions to
diff --git a/chrome/browser/extensions/chrome_url_request_util.cc b/chrome/browser/extensions/chrome_url_request_util.cc index 51e835b..7e6616ea 100644 --- a/chrome/browser/extensions/chrome_url_request_util.cc +++ b/chrome/browser/extensions/chrome_url_request_util.cc
@@ -149,13 +149,14 @@ std::string* read_mime_type, net::CompletionOnceCallback callback, bool read_result) { - response_info_.headers->AddHeader( - base::StringPrintf("%s: %s", net::HttpRequestHeaders::kContentType, - read_mime_type->c_str())); + if (read_result) { + response_info_.headers->AddHeader( + base::StringPrintf("%s: %s", net::HttpRequestHeaders::kContentType, + read_mime_type->c_str())); + } *out_mime_type = *read_mime_type; DetermineCharset(*read_mime_type, data.get(), charset); - int result = read_result ? net::OK : net::ERR_INVALID_URL; - std::move(callback).Run(result); + std::move(callback).Run(net::OK); } // We need the filename of the resource to determine the mime type.
diff --git a/chrome/browser/extensions/extension_protocols_unittest.cc b/chrome/browser/extensions/extension_protocols_unittest.cc index 708c8f0b5..9be2b5d4 100644 --- a/chrome/browser/extensions/extension_protocols_unittest.cc +++ b/chrome/browser/extensions/extension_protocols_unittest.cc
@@ -791,7 +791,9 @@ const char* file_name; const char* expected_mime_type; } test_cases[] = { - {"json_file.json", "application/json"}, {"js_file.js", "text/javascript"}, + {"json_file.json", "application/json"}, + {"js_file.js", "text/javascript"}, + {"mem_file.mem", ""}, }; for (const auto& test_case : test_cases) {
diff --git a/chrome/browser/extensions/global_shortcut_listener_win.cc b/chrome/browser/extensions/global_shortcut_listener_win.cc index f5d0ac4..c5125495 100644 --- a/chrome/browser/extensions/global_shortcut_listener_win.cc +++ b/chrome/browser/extensions/global_shortcut_listener_win.cc
@@ -72,25 +72,19 @@ const ui::Accelerator& accelerator) { DCHECK(hotkeys_.find(accelerator) == hotkeys_.end()); - // If we want to listen for media keys, we should do that through the - // MediaKeysListenerManager, which will tell the manager to send us media keys - // and prevent the HardwareKeyMediaController from receiving the keys. + // TODO(https://crbug.com/950704): We should be using + // |media_keys_listener_manager->StartWatchingMediaKey(...)| here, but that + // currently breaks the GlobalCommandsApiTest.GlobalDuplicatedMediaKey test. + // Instead, we'll just disable the MediaKeysListenerManager handling here, and + // listen using the fallback RegisterHotKey method. if (content::MediaKeysListenerManager::IsMediaKeysListenerManagerEnabled() && Command::IsMediaKey(accelerator)) { content::MediaKeysListenerManager* media_keys_listener_manager = content::MediaKeysListenerManager::GetInstance(); DCHECK(media_keys_listener_manager); - bool success = media_keys_listener_manager->StartWatchingMediaKey( - accelerator.key_code(), this); - - // Map the hot key to nullptr, since we don't need a - // SingletonHwndHotKeyObserver when the MediaKeysListenerManager is taking - // care of it. - if (success) - hotkeys_[accelerator] = nullptr; - - return success; + registered_media_keys_++; + media_keys_listener_manager->DisableInternalMediaKeyHandling(); } // Convert Accelerator modifiers to OS modifiers. @@ -120,16 +114,19 @@ HotKeyMap::iterator it = hotkeys_.find(accelerator); DCHECK(it != hotkeys_.end()); - // If we're routing media keys through the MediaKeysListenerManager, then - // inform the manager that we're no longer listening to the given key. + // TODO(https://crbug.com/950704): We should be using + // |media_keys_listener_manager->StopWatchingMediaKey(...)| here. if (content::MediaKeysListenerManager::IsMediaKeysListenerManagerEnabled() && Command::IsMediaKey(accelerator)) { - content::MediaKeysListenerManager* media_keys_listener_manager = - content::MediaKeysListenerManager::GetInstance(); - DCHECK(media_keys_listener_manager); + registered_media_keys_--; + DCHECK_GE(registered_media_keys_, 0); + if (registered_media_keys_ == 0) { + content::MediaKeysListenerManager* media_keys_listener_manager = + content::MediaKeysListenerManager::GetInstance(); + DCHECK(media_keys_listener_manager); - media_keys_listener_manager->StopWatchingMediaKey(accelerator.key_code(), - this); + media_keys_listener_manager->EnableInternalMediaKeyHandling(); + } } hotkeys_.erase(it);
diff --git a/chrome/browser/extensions/global_shortcut_listener_win.h b/chrome/browser/extensions/global_shortcut_listener_win.h index 800c5c9..d7b245a 100644 --- a/chrome/browser/extensions/global_shortcut_listener_win.h +++ b/chrome/browser/extensions/global_shortcut_listener_win.h
@@ -46,6 +46,9 @@ // Whether this object is listening for global shortcuts. bool is_listening_; + // The number of media keys currently registered. + int registered_media_keys_ = 0; + // A map of registered accelerators and their registration ids. The value is // null for media keys if kHardwareMediaKeyHandling is true. using HotKeyMap = std::map<ui::Accelerator,
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 739a65d..93975ea8 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -825,6 +825,11 @@ "expiry_milestone": 76 }, { + "name": "enable-autofill-credit-card-authentication", + "owners": [ "jsaul@google.com", "manasverma@google.com" ], + "expiry_milestone": 79 + }, + { "name": "enable-autofill-credit-card-local-card-migration", "owners": [ "jiahuiguo@google.com", "siyua@google.com" ], "expiry_milestone": 76 @@ -2046,7 +2051,7 @@ }, { "name": "expensive-background-timer-throttling", - // "owners": [ "your-team" ], + "owners": [ "altimin" ], "expiry_milestone": 76 }, {
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 13314db7..cc7a8d4 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -402,6 +402,13 @@ const char kEnableAutofillCreditCardAblationExperimentDescription[] = "If enabled, credit card autofill suggestions will not display."; +const char kEnableAutofillCreditCardAuthenticationName[] = + "Allow using platform authenticators to retrieve server cards"; +const char kEnableAutofillCreditCardAuthenticationDescription[] = + "When enabled, users will be given the option to use a platform " + "authenticator (if available) to verify card ownership when retrieving " + "credit cards from Google Payments."; + const char kEnableAutofillCreditCardLastUsedDateDisplayName[] = "Display the last used date of a credit card in autofill."; const char kEnableAutofillCreditCardLastUsedDateDisplayDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 3c4addf3..c1a26f8b 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -270,6 +270,9 @@ extern const char kEnableAutofillCreditCardAblationExperimentDisplayName[]; extern const char kEnableAutofillCreditCardAblationExperimentDescription[]; +extern const char kEnableAutofillCreditCardAuthenticationName[]; +extern const char kEnableAutofillCreditCardAuthenticationDescription[]; + extern const char kEnableAutofillCreditCardLastUsedDateDisplayName[]; extern const char kEnableAutofillCreditCardLastUsedDateDisplayDescription[];
diff --git a/chrome/browser/google/google_brand_code_map_chromeos.cc b/chrome/browser/google/google_brand_code_map_chromeos.cc index 68cd1ce1..fe54292 100644 --- a/chrome/browser/google/google_brand_code_map_chromeos.cc +++ b/chrome/browser/google/google_brand_code_map_chromeos.cc
@@ -67,6 +67,7 @@ {"IHZG", {"MLLN", "EZTK", "GJEJ"}}, {"JBPA", {"VUZL", "XYPI", "XOWE"}}, {"JLRH", {"SAMJ", "GLJZ", "SKTN"}}, + {"JYXK", {"USZT", "XXPU", "LJHH"}}, {"LASN", {"ILWC", "BQYG", "RROZ"}}, {"LEAC", {"DMEA", "EXWD", "PBTU"}}, {"LEAE", {"QFVM", "GACH", "BMXB"}},
diff --git a/chrome/browser/media/cast_mirroring_service_host_browsertest.cc b/chrome/browser/media/cast_mirroring_service_host_browsertest.cc index 791b3ac..9e0616a 100644 --- a/chrome/browser/media/cast_mirroring_service_host_browsertest.cc +++ b/chrome/browser/media/cast_mirroring_service_host_browsertest.cc
@@ -28,6 +28,7 @@ using testing::_; using testing::InvokeWithoutArgs; +using testing::Return; namespace mirroring { @@ -178,7 +179,8 @@ void RequestRefreshFrame() { base::RunLoop run_loop; EXPECT_CALL(*video_frame_receiver_, OnBufferReadyCall(_)) - .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); + .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)) + .WillRepeatedly(Return()); video_frame_receiver_->RequestRefreshFrame(); run_loop.Run(); }
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index 96dbd31..f996f3d 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -1648,8 +1648,9 @@ // net::ClientCertStore: void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info, - const ClientCertListCallback& callback) override { - callback.Run(FakeClientCertIdentityListFromCertificateList(certs_)); + ClientCertListCallback callback) override { + std::move(callback).Run( + FakeClientCertIdentityListFromCertificateList(certs_)); } private:
diff --git a/chrome/browser/printing/print_browsertest.cc b/chrome/browser/printing/print_browsertest.cc index a2f6e6af..7c0b15e5 100644 --- a/chrome/browser/printing/print_browsertest.cc +++ b/chrome/browser/printing/print_browsertest.cc
@@ -87,7 +87,8 @@ class NupPrintingTestDelegate : public PrintingMessageFilter::TestDelegate { public: - NupPrintingTestDelegate() { + explicit NupPrintingTestDelegate(int initial_document_cookie) + : initial_document_cookie_(initial_document_cookie) { PrintingMessageFilter::SetDelegateForTesting(this); } ~NupPrintingTestDelegate() override { @@ -98,17 +99,31 @@ PrintMsg_Print_Params GetPrintParams() override { PrintMsg_Print_Params params; params.page_size = gfx::Size(612, 792); - params.content_size = gfx::Size(540, 720); + params.content_size = has_margin_ ? gfx::Size(540, 720) : params.page_size; params.printable_area = gfx::Rect(612, 792); params.dpi = gfx::Size(72, 72); - params.document_cookie = kDefaultDocumentCookie; + params.document_cookie = GetNextDocumentCookie(); params.pages_per_sheet = 4; params.printed_doc_type = IsOopifEnabled() ? SkiaDocumentType::MSKP : SkiaDocumentType::PDF; return params; } + int get_print_params_count() const { return get_print_params_count_; } + + void set_no_margin() { has_margin_ = false; } + private: + int GetNextDocumentCookie() { + int document_cookie = initial_document_cookie_ + get_print_params_count_; + ++get_print_params_count_; + return document_cookie; + } + + const int initial_document_cookie_; + int get_print_params_count_ = 0; + bool has_margin_ = true; + DISALLOW_COPY_AND_ASSIGN(NupPrintingTestDelegate); }; @@ -603,24 +618,52 @@ } // Printing frame content for the main frame of a generic webpage with N-up -// priting. This is a regression test for https://crbug.com/937247 +// printing. This is a regression test for https://crbug.com/937247 IN_PROC_BROWSER_TEST_F(PrintBrowserTest, PrintNup) { - NupPrintingTestDelegate test_delegate; + NupPrintingTestDelegate test_delegate(kDefaultDocumentCookie); ASSERT_TRUE(embedded_test_server()->Started()); GURL url(embedded_test_server()->GetURL("/printing/test1.html")); ui_test_utils::NavigateToURL(browser(), url); PrintAndWaitUntilPreviewIsReady(/*print_only_selection=*/false); + EXPECT_EQ(1, test_delegate.get_print_params_count()); } // Site per process version of PrintBrowserTest.PrintNup. IN_PROC_BROWSER_TEST_F(SitePerProcessPrintBrowserTest, PrintNup) { - NupPrintingTestDelegate test_delegate; + NupPrintingTestDelegate test_delegate(kDefaultDocumentCookie); ASSERT_TRUE(embedded_test_server()->Started()); GURL url(embedded_test_server()->GetURL("/printing/test1.html")); ui_test_utils::NavigateToURL(browser(), url); PrintAndWaitUntilPreviewIsReady(/*print_only_selection=*/false); + EXPECT_EQ(1, test_delegate.get_print_params_count()); +} + +// Printing frame content for the main frame of a generic webpage with N-up +// printing and no margins. This covers the test scenario described in +// https://crbug.com/944516 +IN_PROC_BROWSER_TEST_F(PrintBrowserTest, PrintNupNoMargins) { + NupPrintingTestDelegate test_delegate(kDefaultDocumentCookie); + test_delegate.set_no_margin(); + ASSERT_TRUE(embedded_test_server()->Started()); + GURL url(embedded_test_server()->GetURL("/printing/test1.html")); + ui_test_utils::NavigateToURL(browser(), url); + + PrintAndWaitUntilPreviewIsReady(/*print_only_selection=*/false); + EXPECT_EQ(2, test_delegate.get_print_params_count()); +} + +// Site per process version of PrintBrowserTest.PrintNup. +IN_PROC_BROWSER_TEST_F(SitePerProcessPrintBrowserTest, PrintNupNoMargins) { + NupPrintingTestDelegate test_delegate(kDefaultDocumentCookie); + test_delegate.set_no_margin(); + ASSERT_TRUE(embedded_test_server()->Started()); + GURL url(embedded_test_server()->GetURL("/printing/test1.html")); + ui_test_utils::NavigateToURL(browser(), url); + + PrintAndWaitUntilPreviewIsReady(/*print_only_selection=*/false); + EXPECT_EQ(2, test_delegate.get_print_params_count()); } } // namespace printing
diff --git a/chrome/browser/renderer_context_menu/spelling_bubble_model.cc b/chrome/browser/renderer_context_menu/spelling_bubble_model.cc index 06fcdf7..e20f77d2 100644 --- a/chrome/browser/renderer_context_menu/spelling_bubble_model.cc +++ b/chrome/browser/renderer_context_menu/spelling_bubble_model.cc
@@ -29,7 +29,7 @@ } base::string16 SpellingBubbleModel::GetTitle() const { - return l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPELLING_ASK_GOOGLE); + return l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPELLING_BUBBLE_TITLE); } base::string16 SpellingBubbleModel::GetMessageText() const {
diff --git a/chrome/browser/resources/chromeos/cellular_setup/OWNERS b/chrome/browser/resources/chromeos/cellular_setup/OWNERS index 75e2f312..fa033853 100644 --- a/chrome/browser/resources/chromeos/cellular_setup/OWNERS +++ b/chrome/browser/resources/chromeos/cellular_setup/OWNERS
@@ -1,2 +1 @@ -azeemarshad@chromium.org -khorimoto@chromium.org +file://ui/webui/resources/cr_components/chromeos/cellular_setup/OWNERS
diff --git a/chrome/browser/resources/chromeos/cellular_setup/cellular_setup_dialog.html b/chrome/browser/resources/chromeos/cellular_setup/cellular_setup_dialog.html index 8ec69bc7..babbec3 100644 --- a/chrome/browser/resources/chromeos/cellular_setup/cellular_setup_dialog.html +++ b/chrome/browser/resources/chromeos/cellular_setup/cellular_setup_dialog.html
@@ -17,7 +17,7 @@ </head> <body> <link rel="import" href="i18n_setup.html"> - <!-- TODO(khorimoto): Replace button with actual content.--> - <button>$i18n{cancel}</button> + <link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/cellular_setup.html"> + <cellular-setup></cellular-setup> </body> </html>
diff --git a/chrome/browser/resources/chromeos/login/oobe_eula.html b/chrome/browser/resources/chromeos/login/oobe_eula.html index 9bc2a14..ddff8a8 100644 --- a/chrome/browser/resources/chromeos/login/oobe_eula.html +++ b/chrome/browser/resources/chromeos/login/oobe_eula.html
@@ -71,7 +71,7 @@ </cr-toggle> <div id="usageStatsLabelContainer"> <span id="usageStatsLabel" i18n-content="checkboxLogging"></span> - <a id="learn-more" href="#" i18n-content="learnMore" + <a id="" href="#" i18n-content="learnMore" on-tap="onUsageStatsHelpLinkClicked_"> </a> </div> @@ -109,7 +109,7 @@ </div> <div class='password-row layout horizontal'> <div class="flex"></div> - <div id="eula-password">{{password}}</div> + <div>{{password}}</div> <div class="flex"></div> </div> </div>
diff --git a/chrome/browser/resources/md_user_manager/user_manager_pages.js b/chrome/browser/resources/md_user_manager/user_manager_pages.js index 591594d8..04761b5 100644 --- a/chrome/browser/resources/md_user_manager/user_manager_pages.js +++ b/chrome/browser/resources/md_user_manager/user_manager_pages.js
@@ -56,7 +56,7 @@ * This is to prevent events from propagating to the document element, which * erroneously triggers user-pod selections. * - * TODO(scottchen): re-examine if its necessary for user_pod_row.js to bind + * TODO(tangltom): re-examine if its necessary for user_pod_row.js to bind * listeners on the entire document element. * * @param {!Event} e
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/landing_view.html b/chrome/browser/resources/welcome/onboarding_welcome/landing_view.html index 35b8622a..648e986f 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/landing_view.html +++ b/chrome/browser/resources/welcome/onboarding_welcome/landing_view.html
@@ -18,8 +18,8 @@ outline: none; } </style> - <onboarding-background></onboarding-background> <div id="container"> + <onboarding-background></onboarding-background> <h2>$i18n{landingDescription}</h2> <h1 tabindex="-1">$i18n{landingTitle}</h1> <paper-button class="action-button" on-click="onNewUserClick_">
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/shared/splash_pages_shared_css.html b/chrome/browser/resources/welcome/onboarding_welcome/shared/splash_pages_shared_css.html index a5d332c8..d213efc6 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/shared/splash_pages_shared_css.html +++ b/chrome/browser/resources/welcome/onboarding_welcome/shared/splash_pages_shared_css.html
@@ -10,10 +10,11 @@ align-items: center; display: flex; flex-direction: column; - height: 100%; justify-content: center; margin: auto; + min-height: 100%; min-width: 800px; + position: relative; } h1 {
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/signin_view.html b/chrome/browser/resources/welcome/onboarding_welcome/signin_view.html index 5b6f232..101786f 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/signin_view.html +++ b/chrome/browser/resources/welcome/onboarding_welcome/signin_view.html
@@ -20,8 +20,8 @@ outline: none; } </style> - <onboarding-background></onboarding-background> <div id="container"> + <onboarding-background></onboarding-background> <h2>$i18n{signInSubHeader}</h2> <h1 tabindex="-1">$i18n{signInHeader}</h1> <paper-button class="action-button" on-click="onSignInClick_">
diff --git a/chrome/browser/site_isolation/site_per_process_text_input_browsertest.cc b/chrome/browser/site_isolation/site_per_process_text_input_browsertest.cc index 51235f4..baea2e5 100644 --- a/chrome/browser/site_isolation/site_per_process_text_input_browsertest.cc +++ b/chrome/browser/site_isolation/site_per_process_text_input_browsertest.cc
@@ -674,7 +674,7 @@ ASSERT_TRUE(window); LocationBar* location_bar = window->GetLocationBar(); ASSERT_TRUE(location_bar); - location_bar->FocusLocation(); + location_bar->FocusLocation(true); focus_input_and_wait_for_selection_bounds_change(); }
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc index 4305fae..766cb2e 100644 --- a/chrome/browser/ssl/ssl_browsertest.cc +++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -2445,8 +2445,8 @@ // net::ClientCertStore: void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info, - const ClientCertListCallback& callback) override { - callback.Run(std::move(list_)); + ClientCertListCallback callback) override { + std::move(callback).Run(std::move(list_)); } private:
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 8f617131..1d4793b 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1776,6 +1776,8 @@ "webui/signin/inline_login_handler_chromeos.h", "webui/signin/inline_login_handler_dialog_chromeos.cc", "webui/signin/inline_login_handler_dialog_chromeos.h", + "webui/signin/inline_login_handler_modal_delegate.cc", + "webui/signin/inline_login_handler_modal_delegate.h", "webui/version_handler_chromeos.cc", "webui/version_handler_chromeos.h", "window_sizer/window_sizer_ash.cc",
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 9814f062..0f2a2e18 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -1122,11 +1122,12 @@ // Two differences between this and FocusLocationBar(): // (1) This doesn't get recorded in user metrics, since it's called // internally. - // (2) This checks whether the location bar can be focused, and if not, clears - // the focus. FocusLocationBar() is only reached when the location bar is - // focusable, but this may be reached at other times, e.g. while in - // fullscreen mode, where we need to leave focus in a consistent state. - window_->SetFocusToLocationBar(); + // (2) This is called with |select_all| == false, because this is a renderer + // initiated focus (this method is a WebContentsDelegate override). + // We don't select-all for renderer initiated focuses, as the user may + // currently be typing something while the tab finishes loading. We don't + // want to clobber user input by selecting all while the user is typing. + window_->SetFocusToLocationBar(false); } content::KeyboardEventProcessingResult Browser::PreHandleKeyboardEvent(
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index bf5a3fa..3e4ebd9 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -1099,7 +1099,7 @@ void FocusLocationBar(Browser* browser) { base::RecordAction(UserMetricsAction("FocusLocation")); - browser->window()->SetFocusToLocationBar(); + browser->window()->SetFocusToLocationBar(true); } void FocusSearch(Browser* browser) {
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index b109b526..83eb1a4 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h
@@ -250,7 +250,7 @@ // Tries to focus the location bar. Clears the window focus (to avoid // inconsistent state) if this fails. - virtual void SetFocusToLocationBar() = 0; + virtual void SetFocusToLocationBar(bool select_all) = 0; // Informs the view whether or not a load is in progress for the current tab. // The view can use this notification to update the reload/stop button.
diff --git a/chrome/browser/ui/libgtkui/native_theme_gtk.cc b/chrome/browser/ui/libgtkui/native_theme_gtk.cc index d8d72cad..9cc6c94 100644 --- a/chrome/browser/ui/libgtkui/native_theme_gtk.cc +++ b/chrome/browser/ui/libgtkui/native_theme_gtk.cc
@@ -77,6 +77,8 @@ case ui::NativeTheme::kColorId_DialogBackground: case ui::NativeTheme::kColorId_BubbleBackground: return GetBgColor(""); + case ui::NativeTheme::kColorId_BubbleFooterBackground: + return GetBgColor("#statusbar"); // FocusableBorder case ui::NativeTheme::kColorId_FocusedBorderColor:
diff --git a/chrome/browser/ui/location_bar/location_bar.h b/chrome/browser/ui/location_bar/location_bar.h index 239d3ba..c4a0819 100644 --- a/chrome/browser/ui/location_bar/location_bar.h +++ b/chrome/browser/ui/location_bar/location_bar.h
@@ -44,8 +44,16 @@ // latency of page loads starting at user input. virtual void AcceptInput(base::TimeTicks match_selection_timestamp) = 0; - // Focuses the location bar and selects its contents. - virtual void FocusLocation() = 0; + // Focuses the location bar. Optionally also selects its contents. + // + // User-initiated focuses should have |select_all| set to true, as users + // are accustomed to being able to use Ctrl+L to select-all in the omnibox. + // + // Renderer-initiated focuses should have |select_all| set to false, as the + // user may be in the middle of typing while the tab finishes loading. + // In that case, we don't want to select-all and cause the user to clobber + // their already-typed text. + virtual void FocusLocation(bool select_all) = 0; // Puts the user into keyword mode with their default search provider. virtual void FocusSearch() = 0;
diff --git a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc index 5e2a74e2..c77f594 100644 --- a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc +++ b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
@@ -766,6 +766,24 @@ EXPECT_EQ(old_selected_line, popup_model->selected_line()); } +IN_PROC_BROWSER_TEST_F(OmniboxViewTest, + RendererInitiatedFocusPreservesUserText) { + OmniboxView* omnibox_view = nullptr; + ASSERT_NO_FATAL_FAILURE(GetOmniboxView(&omnibox_view)); + + // Type a single character. + ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_A, 0)); + EXPECT_EQ(base::ASCIIToUTF16("a"), omnibox_view->GetText()); + + // Simulate a renderer-initated focus event. + browser()->SetFocusToLocationBar(); + + // Type an additional character and verify that we didn't clobber the + // character we already typed. + ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_B, 0)); + EXPECT_EQ(base::ASCIIToUTF16("ab"), omnibox_view->GetText()); +} + IN_PROC_BROWSER_TEST_F(OmniboxViewTest, BasicTextOperations) { ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)); chrome::FocusLocationBar(browser());
diff --git a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc index 077b9a3..a718fc2 100644 --- a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc +++ b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc
@@ -74,7 +74,7 @@ ->OmniboxFocusChanged(OMNIBOX_FOCUS_VISIBLE, OMNIBOX_FOCUS_CHANGE_EXPLICIT); } else { - instant_browser()->window()->GetLocationBar()->FocusLocation(); + instant_browser()->window()->GetLocationBar()->FocusLocation(false); } }
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index f0bb928a..f473255 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -366,6 +366,7 @@ show_animation_->Show(); } + // ui::EF_MIDDLE_MOUSE_BUTTON opens all bookmarked links in separate tabs. set_triggerable_event_flags(ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON); }
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 70dd35b..a723a48e 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1086,7 +1086,7 @@ return GetLocationBarView(); } -void BrowserView::SetFocusToLocationBar() { +void BrowserView::SetFocusToLocationBar(bool select_all) { // On Windows, changing focus to the location bar causes the browser window to // become active. This can steal focus if the user has another window open // already. On Chrome OS, changing focus makes a view believe it has a focus @@ -1098,7 +1098,7 @@ #endif LocationBarView* location_bar = GetLocationBarView(); - location_bar->FocusLocation(); + location_bar->FocusLocation(select_all); if (!location_bar->omnibox_view()->HasFocus()) { // If none of location bar got focus, then clear focus. views::FocusManager* focus_manager = GetFocusManager();
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 4059a9c..2343a31 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -342,7 +342,7 @@ PageActionIconContainer* GetPageActionIconContainer() override; PageActionIconContainer* GetToolbarPageActionIconContainer() override; LocationBar* GetLocationBar() const override; - void SetFocusToLocationBar() override; + void SetFocusToLocationBar(bool select_all) override; void UpdateReloadStopState(bool is_loading, bool force) override; void UpdateToolbar(content::WebContents* contents) override; void UpdateToolbarVisibility(bool visible, bool animate) override;
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc index 6ff26af..5634d6c 100644 --- a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc
@@ -31,9 +31,8 @@ }; // Tests that clicking a link from a tabbed browser to within the scope of an -// installed app shows the intent picker with the installed app details. -// For chrome OS platform, the intent picker bubble will pop out while for -// other platforms, only intent picker icon will be show in Omnibox. +// installed app shows the intent picker icon in Omnibox. The intent picker +// bubble will only show up for android apps which is too hard to test. IN_PROC_BROWSER_TEST_P(IntentPickerBubbleViewBrowserTest, NavigationToInScopeLinkShowsIntentPicker) { InstallTestBookmarkApp(); @@ -55,15 +54,7 @@ IntentPickerBubbleView* intent_picker = IntentPickerBubbleView::intent_picker_bubble(); -#if defined(OS_CHROMEOS) - ASSERT_TRUE(intent_picker); - EXPECT_EQ(web_contents, intent_picker->web_contents()); - EXPECT_EQ(1u, intent_picker->GetAppInfoForTesting().size()); - EXPECT_EQ(GetAppName(), - intent_picker->GetAppInfoForTesting()[0].display_name); -#else EXPECT_FALSE(intent_picker); -#endif } // Tests that clicking a link from a tabbed browser to outside the scope of an
diff --git a/chrome/browser/ui/views/keyboard_access_browsertest.cc b/chrome/browser/ui/views/keyboard_access_browsertest.cc index 827844d..33c85150 100644 --- a/chrome/browser/ui/views/keyboard_access_browsertest.cc +++ b/chrome/browser/ui/views/keyboard_access_browsertest.cc
@@ -209,7 +209,7 @@ false); if (focus_omnibox) - browser()->window()->GetLocationBar()->FocusLocation(); + browser()->window()->GetLocationBar()->FocusLocation(false); #if defined(OS_CHROMEOS) // Chrome OS doesn't have a way to just focus the app menu, so we use Alt+F to @@ -384,7 +384,7 @@ browser_view->toolbar_button_provider()->GetAppMenuButton(), browser(), true); - browser()->window()->GetLocationBar()->FocusLocation(); + browser()->window()->GetLocationBar()->FocusLocation(false); ASSERT_TRUE(ui_test_utils::SendKeyPressSync( browser(), ui::VKEY_F10, false, false, false, false));
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index b57bbc4..7e3cb62 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -341,13 +341,17 @@ //////////////////////////////////////////////////////////////////////////////// // LocationBarView, public LocationBar implementation: -void LocationBarView::FocusLocation() { +void LocationBarView::FocusLocation(bool select_all) { const bool omnibox_already_focused = omnibox_view_->HasFocus(); omnibox_view_->SetFocus(); + if (omnibox_already_focused) omnibox_view()->model()->ClearKeyword(); + if (!select_all) + return; + omnibox_view_->SelectAll(true); // Only exit Query in Omnibox mode on focus command if the location bar was @@ -1205,7 +1209,7 @@ // LocationBarView, private DropdownBarHostDelegate implementation: void LocationBarView::FocusAndSelectAll() { - FocusLocation(); + FocusLocation(true); } ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h index d31abf64..cb3cd0e 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.h +++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -199,7 +199,7 @@ bool ActivateFirstInactiveBubbleForAccessibility(); // LocationBar: - void FocusLocation() override; + void FocusLocation(bool select_all) override; void Revert() override; OmniboxView* GetOmniboxView() override;
diff --git a/chrome/browser/ui/views/platform_keys_certificate_selector_chromeos.cc b/chrome/browser/ui/views/platform_keys_certificate_selector_chromeos.cc index d08e097..6b3a3615 100644 --- a/chrome/browser/ui/views/platform_keys_certificate_selector_chromeos.cc +++ b/chrome/browser/ui/views/platform_keys_certificate_selector_chromeos.cc
@@ -36,7 +36,7 @@ ~ClientCertIdentityPlatformKeys() override = default; void AcquirePrivateKey( - const base::Callback<void(scoped_refptr<net::SSLPrivateKey>)>& + base::OnceCallback<void(scoped_refptr<net::SSLPrivateKey>)> private_key_callback) override { NOTREACHED(); }
diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector.cc b/chrome/browser/ui/views/ssl_client_certificate_selector.cc index 75aa15a..8c0fbfb 100644 --- a/chrome/browser/ui/views/ssl_client_certificate_selector.cc +++ b/chrome/browser/ui/views/ssl_client_certificate_selector.cc
@@ -53,8 +53,8 @@ net::X509Certificate* cert = identity->certificate(); net::ClientCertIdentity::SelfOwningAcquirePrivateKey( std::move(identity), - base::Bind(&SSLClientAuthObserverImpl::GotPrivateKey, - base::Passed(&self), base::Unretained(cert))); + base::BindOnce(&SSLClientAuthObserverImpl::GotPrivateKey, + std::move(self), base::Unretained(cert))); } void GotPrivateKey(net::X509Certificate* cert,
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc index c908bae7..deafa983 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -618,7 +618,7 @@ bool ToolbarView::SetPaneFocusAndFocusDefault() { if (!location_bar_->HasFocus()) { SetPaneFocus(location_bar_); - location_bar_->FocusLocation(); + location_bar_->FocusLocation(true); return true; }
diff --git a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc index 0e68320..85c54f1 100644 --- a/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc +++ b/chrome/browser/ui/webui/chromeos/emulator/device_emulator_message_handler.cc
@@ -15,8 +15,8 @@ #include "chrome/browser/chromeos/system/fake_input_device_settings.h" #include "chrome/browser/chromeos/system/input_device_settings.h" #include "chrome/browser/ui/webui/chromeos/bluetooth_pairing_dialog.h" +#include "chromeos/dbus/audio/fake_cras_audio_client.h" #include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/fake_cras_audio_client.h" #include "chromeos/dbus/power/fake_power_manager_client.h" #include "content/public/browser/web_ui.h" #include "device/bluetooth/bluetooth_adapter_factory.h"
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc index 0375c27..b8e663f 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc
@@ -4,11 +4,43 @@ #include "chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h" +#include <memory> + +#include "ash/public/cpp/ash_features.h" +#include "ash/public/cpp/stylus_utils.h" +#include "chrome/browser/chromeos/android_sms/android_sms_app_manager.h" +#include "chrome/browser/chromeos/android_sms/android_sms_service_factory.h" +#include "chrome/browser/chromeos/arc/arc_util.h" +#include "chrome/browser/chromeos/crostini/crostini_util.h" +#include "chrome/browser/chromeos/login/demo_mode/demo_session.h" +#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h" +#include "chrome/browser/chromeos/multidevice_setup/multidevice_setup_client_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/chromeos/smb_shares/smb_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/crostini_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/date_time_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/internet_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h" +#include "chrome/browser/ui/webui/settings/tts_handler.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/browser_resources.h" +#include "chromeos/constants/chromeos_features.h" +#include "chromeos/constants/chromeos_switches.h" +#include "chromeos/services/multidevice_setup/public/cpp/prefs.h" +#include "components/arc/arc_util.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" +#include "ui/base/ui_base_features.h" namespace chromeos { namespace settings { @@ -19,8 +51,7 @@ content::WebUIDataSource* html_source = content::WebUIDataSource::Create(chrome::kChromeUIOSSettingsHost); - // TODO(jamescook): Factor out page handlers from MdSettingsUI and initialize - // them both there and here. + InitWebUIHandlers(profile, web_ui, html_source); html_source->UseGzip(); html_source->SetDefaultResource(IDR_OS_SETTINGS_HTML); @@ -30,5 +61,113 @@ OSSettingsUI::~OSSettingsUI() = default; +// static +void OSSettingsUI::InitWebUIHandlers(Profile* profile, + content::WebUI* web_ui, + content::WebUIDataSource* html_source) { + web_ui->AddMessageHandler(std::make_unique<AccessibilityHandler>(web_ui)); + web_ui->AddMessageHandler(std::make_unique<AndroidAppsHandler>(profile)); + if (crostini::IsCrostiniUIAllowedForProfile(profile, + false /* check_policy */)) { + web_ui->AddMessageHandler(std::make_unique<CrostiniHandler>(profile)); + } + web_ui->AddMessageHandler(CupsPrintersHandler::Create(web_ui)); + web_ui->AddMessageHandler( + base::WrapUnique(DateTimeHandler::Create(html_source))); + web_ui->AddMessageHandler(std::make_unique<FingerprintHandler>(profile)); + if (chromeos::switches::IsAssistantEnabled()) { + web_ui->AddMessageHandler( + std::make_unique<GoogleAssistantHandler>(profile)); + } + web_ui->AddMessageHandler(std::make_unique<KeyboardHandler>()); + web_ui->AddMessageHandler(std::make_unique<PointerHandler>()); + web_ui->AddMessageHandler(std::make_unique<StorageHandler>(profile)); + web_ui->AddMessageHandler(std::make_unique<StylusHandler>()); + web_ui->AddMessageHandler(std::make_unique<InternetHandler>(profile)); + web_ui->AddMessageHandler(std::make_unique<::settings::TtsHandler>()); + web_ui->AddMessageHandler( + std::make_unique<chromeos::smb_dialog::SmbHandler>(profile)); + + if (!profile->IsGuestSession()) { + chromeos::android_sms::AndroidSmsService* android_sms_service = + chromeos::android_sms::AndroidSmsServiceFactory::GetForBrowserContext( + profile); + web_ui->AddMessageHandler(std::make_unique<MultideviceHandler>( + profile->GetPrefs(), + chromeos::multidevice_setup::MultiDeviceSetupClientFactory:: + GetForProfile(profile), + android_sms_service + ? android_sms_service->android_sms_pairing_state_tracker() + : nullptr, + android_sms_service ? android_sms_service->android_sms_app_manager() + : nullptr)); + } + + html_source->AddBoolean( + "multideviceAllowedByPolicy", + chromeos::multidevice_setup::AreAnyMultiDeviceFeaturesAllowed( + profile->GetPrefs())); + html_source->AddBoolean( + "quickUnlockEnabled", + chromeos::quick_unlock::IsPinEnabled(profile->GetPrefs())); + html_source->AddBoolean( + "quickUnlockDisabledByPolicy", + chromeos::quick_unlock::IsPinDisabledByPolicy(profile->GetPrefs())); + const bool fingerprint_unlock_enabled = + chromeos::quick_unlock::IsFingerprintEnabled(profile); + html_source->AddBoolean("fingerprintUnlockEnabled", + fingerprint_unlock_enabled); + if (fingerprint_unlock_enabled) { + html_source->AddBoolean( + "isFingerprintReaderOnKeyboard", + chromeos::quick_unlock::IsFingerprintReaderOnKeyboard()); + } + html_source->AddBoolean("lockScreenNotificationsEnabled", + ash::features::IsLockScreenNotificationsEnabled()); + html_source->AddBoolean( + "lockScreenHideSensitiveNotificationsSupported", + ash::features::IsLockScreenHideSensitiveNotificationsSupported()); + html_source->AddBoolean("showTechnologyBadge", + !ash::features::IsSeparateNetworkIconsEnabled()); + html_source->AddBoolean("hasInternalStylus", + ash::stylus_utils::HasInternalStylus()); + + html_source->AddBoolean( + "showKioskNextShell", + base::FeatureList::IsEnabled(ash::features::kKioskNextShell)); + + html_source->AddBoolean("showCrostini", + crostini::IsCrostiniUIAllowedForProfile( + profile, false /* check_policy */)); + + html_source->AddBoolean("allowCrostini", + crostini::IsCrostiniUIAllowedForProfile(profile)); + + html_source->AddBoolean("isDemoSession", + chromeos::DemoSession::IsDeviceInDemoMode()); + + html_source->AddBoolean("assistantEnabled", + chromeos::switches::IsAssistantEnabled()); + + // We have 2 variants of Android apps settings. Default case, when the Play + // Store app exists we show expandable section that allows as to + // enable/disable the Play Store and link to Android settings which is + // available once settings app is registered in the system. + // For AOSP images we don't have the Play Store app. In last case we Android + // apps settings consists only from root link to Android settings and only + // visible once settings app is registered. + html_source->AddBoolean("androidAppsVisible", + arc::IsArcAllowedForProfile(profile)); + html_source->AddBoolean("havePlayStoreApp", arc::IsPlayStoreAvailable()); + + // TODO(mash): Support Chrome power settings in Mash. https://crbug.com/644348 + bool enable_power_settings = !::features::IsMultiProcessMash(); + html_source->AddBoolean("enablePowerSettings", enable_power_settings); + if (enable_power_settings) { + web_ui->AddMessageHandler( + std::make_unique<PowerHandler>(profile->GetPrefs())); + } +} + } // namespace settings } // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h index 6f5fdbdf..5a71248 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h
@@ -8,6 +8,13 @@ #include "base/macros.h" #include "content/public/browser/web_ui_controller.h" +class Profile; + +namespace content { +class WebUI; +class WebUIDataSource; +} // namespace content + namespace chromeos { namespace settings { @@ -17,6 +24,11 @@ explicit OSSettingsUI(content::WebUI* web_ui); ~OSSettingsUI() override; + // Initializes the WebUI message handlers for OS-specific settings. + static void InitWebUIHandlers(Profile* profile, + content::WebUI* web_ui, + content::WebUIDataSource* html_source); + private: DISALLOW_COPY_AND_ASSIGN(OSSettingsUI); };
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc index d01eb0f7..aab2166 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
@@ -73,49 +73,22 @@ #if defined(OS_WIN) || defined(OS_CHROMEOS) #include "chrome/browser/ui/webui/settings/languages_handler.h" -#include "chrome/browser/ui/webui/settings/tts_handler.h" #endif // defined(OS_WIN) || defined(OS_CHROMEOS) #if defined(OS_CHROMEOS) #include "ash/public/cpp/resources/grit/ash_public_unscaled_resources.h" -#include "ash/public/cpp/stylus_utils.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/account_manager/account_manager_util.h" -#include "chrome/browser/chromeos/android_sms/android_sms_app_manager.h" -#include "chrome/browser/chromeos/android_sms/android_sms_service_factory.h" -#include "chrome/browser/chromeos/arc/arc_util.h" -#include "chrome/browser/chromeos/crostini/crostini_util.h" -#include "chrome/browser/chromeos/login/demo_mode/demo_session.h" -#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h" -#include "chrome/browser/chromeos/multidevice_setup/multidevice_setup_client_factory.h" -#include "chrome/browser/ui/webui/chromeos/smb_shares/smb_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/account_manager_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h" #include "chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/crostini_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/date_time_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/internet_handler.h" -#include "chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h" +#include "chrome/browser/ui/webui/settings/chromeos/os_settings_ui.h" #include "chrome/browser/web_applications/system_web_app_manager.h" #include "chrome/common/chrome_switches.h" #include "chrome/grit/browser_resources.h" #include "chromeos/components/account_manager/account_manager.h" #include "chromeos/components/account_manager/account_manager_factory.h" -#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_pref_names.h" -#include "chromeos/constants/chromeos_switches.h" -#include "chromeos/services/multidevice_setup/public/cpp/prefs.h" -#include "components/arc/arc_util.h" -#include "ui/base/ui_base_features.h" +#include "components/prefs/pref_service.h" #include "ui/chromeos/resources/grit/ui_chromeos_resources.h" #else // !defined(OS_CHROMEOS) #include "chrome/browser/signin/account_consistency_mode_manager.h" @@ -181,6 +154,8 @@ AddSettingsPageUIHandler(std::make_unique<ImportDataHandler>()); #if defined(OS_WIN) || defined(OS_CHROMEOS) + // TODO(jamescook): Sort out how language is split between Chrome OS and + // and browser settings. AddSettingsPageUIHandler(std::make_unique<LanguagesHandler>(web_ui)); #endif // defined(OS_WIN) || defined(OS_CHROMEOS) @@ -199,11 +174,13 @@ AddSettingsPageUIHandler(std::make_unique<SecurityKeysHandler>()); #if defined(OS_CHROMEOS) - AddSettingsPageUIHandler( - std::make_unique<chromeos::settings::AccessibilityHandler>(web_ui)); - AddSettingsPageUIHandler( - std::make_unique<chromeos::settings::AndroidAppsHandler>(profile)); + // TODO: Remove this when SplitSettings is the default and there are no + // Chrome OS settings in the browser settings page. + chromeos::settings::OSSettingsUI::InitWebUIHandlers(profile, web_ui, + html_source); + // TODO(jamescook): Sort out how account management is split between Chrome OS + // and browser settings. if (chromeos::IsAccountManagerAvailable(profile)) { chromeos::AccountManagerFactory* factory = g_browser_process->platform_part()->GetAccountManagerFactory(); @@ -222,32 +199,6 @@ } AddSettingsPageUIHandler( std::make_unique<chromeos::settings::ChangePictureHandler>()); - if (crostini::IsCrostiniUIAllowedForProfile(profile, - false /* check_policy */)) { - AddSettingsPageUIHandler( - std::make_unique<chromeos::settings::CrostiniHandler>(profile)); - } - AddSettingsPageUIHandler( - chromeos::settings::CupsPrintersHandler::Create(web_ui)); - AddSettingsPageUIHandler( - std::make_unique<chromeos::settings::FingerprintHandler>(profile)); - if (chromeos::switches::IsAssistantEnabled()) { - AddSettingsPageUIHandler( - std::make_unique<chromeos::settings::GoogleAssistantHandler>(profile)); - } - AddSettingsPageUIHandler( - std::make_unique<chromeos::settings::KeyboardHandler>()); - AddSettingsPageUIHandler( - std::make_unique<chromeos::settings::PointerHandler>()); - AddSettingsPageUIHandler( - std::make_unique<chromeos::settings::StorageHandler>(profile)); - AddSettingsPageUIHandler( - std::make_unique<chromeos::settings::StylusHandler>()); - AddSettingsPageUIHandler( - std::make_unique<chromeos::settings::InternetHandler>(profile)); - AddSettingsPageUIHandler(std::make_unique<TtsHandler>()); - AddSettingsPageUIHandler( - std::make_unique<chromeos::smb_dialog::SmbHandler>(profile)); #else AddSettingsPageUIHandler(std::make_unique<DefaultBrowserHandler>()); AddSettingsPageUIHandler(std::make_unique<ManageProfileHandler>(profile)); @@ -288,93 +239,7 @@ html_source->AddBoolean("passwordProtectionAvailable", password_protection_available); -#if defined(OS_CHROMEOS) - if (!profile->IsGuestSession()) { - chromeos::android_sms::AndroidSmsService* android_sms_service = - chromeos::android_sms::AndroidSmsServiceFactory::GetForBrowserContext( - profile); - AddSettingsPageUIHandler( - std::make_unique<chromeos::settings::MultideviceHandler>( - profile->GetPrefs(), - chromeos::multidevice_setup::MultiDeviceSetupClientFactory:: - GetForProfile(profile), - android_sms_service - ? android_sms_service->android_sms_pairing_state_tracker() - : nullptr, - android_sms_service ? android_sms_service->android_sms_app_manager() - : nullptr)); - } - html_source->AddBoolean( - "multideviceAllowedByPolicy", - chromeos::multidevice_setup::AreAnyMultiDeviceFeaturesAllowed( - profile->GetPrefs())); - - AddSettingsPageUIHandler(base::WrapUnique( - chromeos::settings::DateTimeHandler::Create(html_source))); - - AddSettingsPageUIHandler( - std::make_unique<chromeos::settings::StylusHandler>()); - html_source->AddBoolean( - "quickUnlockEnabled", - chromeos::quick_unlock::IsPinEnabled(profile->GetPrefs())); - html_source->AddBoolean( - "quickUnlockDisabledByPolicy", - chromeos::quick_unlock::IsPinDisabledByPolicy(profile->GetPrefs())); - const bool fingerprint_unlock_enabled = - chromeos::quick_unlock::IsFingerprintEnabled(profile); - html_source->AddBoolean("fingerprintUnlockEnabled", - fingerprint_unlock_enabled); - if (fingerprint_unlock_enabled) { - html_source->AddBoolean( - "isFingerprintReaderOnKeyboard", - chromeos::quick_unlock::IsFingerprintReaderOnKeyboard()); - } - html_source->AddBoolean("lockScreenNotificationsEnabled", - ash::features::IsLockScreenNotificationsEnabled()); - html_source->AddBoolean( - "lockScreenHideSensitiveNotificationsSupported", - ash::features::IsLockScreenHideSensitiveNotificationsSupported()); - html_source->AddBoolean("showTechnologyBadge", - !ash::features::IsSeparateNetworkIconsEnabled()); - html_source->AddBoolean("hasInternalStylus", - ash::stylus_utils::HasInternalStylus()); - - html_source->AddBoolean( - "showKioskNextShell", - base::FeatureList::IsEnabled(ash::features::kKioskNextShell)); - - html_source->AddBoolean("showCrostini", - crostini::IsCrostiniUIAllowedForProfile( - profile, false /* check_policy */)); - - html_source->AddBoolean("allowCrostini", - crostini::IsCrostiniUIAllowedForProfile(profile)); - - html_source->AddBoolean("isDemoSession", - chromeos::DemoSession::IsDeviceInDemoMode()); - - html_source->AddBoolean("assistantEnabled", - chromeos::switches::IsAssistantEnabled()); - - // We have 2 variants of Android apps settings. Default case, when the Play - // Store app exists we show expandable section that allows as to - // enable/disable the Play Store and link to Android settings which is - // available once settings app is registered in the system. - // For AOSP images we don't have the Play Store app. In last case we Android - // apps settings consists only from root link to Android settings and only - // visible once settings app is registered. - html_source->AddBoolean("androidAppsVisible", - arc::IsArcAllowedForProfile(profile)); - html_source->AddBoolean("havePlayStoreApp", arc::IsPlayStoreAvailable()); - - // TODO(mash): Support Chrome power settings in Mash. https://crbug.com/644348 - bool enable_power_settings = !features::IsMultiProcessMash(); - html_source->AddBoolean("enablePowerSettings", enable_power_settings); - if (enable_power_settings) { - AddSettingsPageUIHandler(std::make_unique<chromeos::settings::PowerHandler>( - profile->GetPrefs())); - } -#else // !defined(OS_CHROMEOS) +#if !defined(OS_CHROMEOS) html_source->AddBoolean( "diceEnabled", AccountConsistencyModeManager::IsDiceEnabledForProfile(profile)); @@ -401,6 +266,7 @@ #if defined(OS_CHROMEOS) // Add the System Web App resources for Settings. + // TODO(jamescook|calamity): Migrate to chromeos::settings::OSSettingsUI. if (web_app::SystemWebAppManager::IsEnabled()) { html_source->AddResourcePath("icon-192.png", IDR_SETTINGS_LOGO_192); html_source->AddResourcePath("pwa.html", IDR_PWA_HTML);
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_dialog_chromeos.cc b/chrome/browser/ui/webui/signin/inline_login_handler_dialog_chromeos.cc index 7465d51..aaab6f0 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_dialog_chromeos.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler_dialog_chromeos.cc
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.h" #include "chrome/common/webui_url_constants.h" +#include "components/web_modal/web_contents_modal_dialog_manager.h" #include "net/base/url_util.h" #include "ui/aura/window.h" #include "ui/display/display.h" @@ -45,9 +46,34 @@ dialog->ShowSystemDialog(); } +gfx::Size InlineLoginHandlerDialogChromeOS::GetMaximumDialogSize() { + gfx::Size size; + GetDialogSize(&size); + return size; +} + +gfx::NativeView InlineLoginHandlerDialogChromeOS::GetHostView() const { + return dialog_window(); +} + +gfx::Point InlineLoginHandlerDialogChromeOS::GetDialogPosition( + const gfx::Size& size) { + gfx::Size host_size = GetHostView()->bounds().size(); + + // Show all sub-dialogs at center-top. + return gfx::Point(std::max(0, (host_size.width() - size.width()) / 2), 0); +} + +void InlineLoginHandlerDialogChromeOS::AddObserver( + web_modal::ModalDialogHostObserver* observer) {} + +void InlineLoginHandlerDialogChromeOS::RemoveObserver( + web_modal::ModalDialogHostObserver* observer) {} + InlineLoginHandlerDialogChromeOS::InlineLoginHandlerDialogChromeOS( const GURL& url) - : SystemWebDialogDelegate(url, base::string16() /* title */) {} + : SystemWebDialogDelegate(url, base::string16() /* title */), + delegate_(this) {} InlineLoginHandlerDialogChromeOS::~InlineLoginHandlerDialogChromeOS() { DCHECK_EQ(this, dialog); @@ -69,4 +95,15 @@ return false; } +void InlineLoginHandlerDialogChromeOS::OnDialogShown( + content::WebUI* webui, + content::RenderViewHost* render_view_host) { + SystemWebDialogDelegate::OnDialogShown(webui, render_view_host); + web_modal::WebContentsModalDialogManager::CreateForWebContents( + webui->GetWebContents()); + web_modal::WebContentsModalDialogManager::FromWebContents( + webui->GetWebContents()) + ->SetDelegate(&delegate_); +} + } // namespace chromeos
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_dialog_chromeos.h b/chrome/browser/ui/webui/signin/inline_login_handler_dialog_chromeos.h index 192f1be..703e4a2 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler_dialog_chromeos.h +++ b/chrome/browser/ui/webui/signin/inline_login_handler_dialog_chromeos.h
@@ -9,6 +9,8 @@ #include "base/macros.h" #include "chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.h" +#include "chrome/browser/ui/webui/signin/inline_login_handler_modal_delegate.h" +#include "components/web_modal/web_contents_modal_dialog_host.h" class GURL; @@ -17,13 +19,22 @@ // Extends from |SystemWebDialogDelegate| to create an always-on-top but movable // dialog. It is intentionally made movable so that users can copy-paste account // passwords from password managers. -class InlineLoginHandlerDialogChromeOS : public SystemWebDialogDelegate { +class InlineLoginHandlerDialogChromeOS + : public SystemWebDialogDelegate, + public web_modal::WebContentsModalDialogHost { public: // Displays the dialog. |email| is an optional parameter that if provided, // pre-fills the account email field in the sign-in dialog - useful for // account re-authentication. static void Show(const std::string& email = std::string()); + // web_modal::WebContentsModalDialogHost overrides. + gfx::Size GetMaximumDialogSize() override; + gfx::NativeView GetHostView() const override; + gfx::Point GetDialogPosition(const gfx::Size& size) override; + void AddObserver(web_modal::ModalDialogHostObserver* observer) override; + void RemoveObserver(web_modal::ModalDialogHostObserver* observer) override; + protected: explicit InlineLoginHandlerDialogChromeOS(const GURL& url); ~InlineLoginHandlerDialogChromeOS() override; @@ -32,8 +43,12 @@ void GetDialogSize(gfx::Size* size) const override; std::string GetDialogArgs() const override; bool ShouldShowDialogTitle() const override; + void OnDialogShown(content::WebUI* webui, + content::RenderViewHost* render_view_host) override; private: + InlineLoginHandlerModalDelegate delegate_; + DISALLOW_COPY_AND_ASSIGN(InlineLoginHandlerDialogChromeOS); };
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_modal_delegate.cc b/chrome/browser/ui/webui/signin/inline_login_handler_modal_delegate.cc new file mode 100644 index 0000000..c231c7b4 --- /dev/null +++ b/chrome/browser/ui/webui/signin/inline_login_handler_modal_delegate.cc
@@ -0,0 +1,23 @@ +// 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/webui/signin/inline_login_handler_modal_delegate.h" + +#include "base/logging.h" +#include "content/public/browser/web_contents.h" + +namespace chromeos { + +InlineLoginHandlerModalDelegate::InlineLoginHandlerModalDelegate( + web_modal::WebContentsModalDialogHost* host) + : host_(host) {} + +InlineLoginHandlerModalDelegate::~InlineLoginHandlerModalDelegate() = default; + +web_modal::WebContentsModalDialogHost* +InlineLoginHandlerModalDelegate::GetWebContentsModalDialogHost() { + return host_; +} + +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_modal_delegate.h b/chrome/browser/ui/webui/signin/inline_login_handler_modal_delegate.h new file mode 100644 index 0000000..8ca37afa --- /dev/null +++ b/chrome/browser/ui/webui/signin/inline_login_handler_modal_delegate.h
@@ -0,0 +1,38 @@ +// 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_WEBUI_SIGNIN_INLINE_LOGIN_HANDLER_MODAL_DELEGATE_H_ +#define CHROME_BROWSER_UI_WEBUI_SIGNIN_INLINE_LOGIN_HANDLER_MODAL_DELEGATE_H_ + +#include "base/macros.h" +#include "chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.h" + +namespace chromeos { + +// Used to display sub-modals inside |InlineLoginHandlerDialogChromeOS| modal +// dialog, e.g. displaying a dialog for accounts using 2FA with WebAuthn, +// where users can select alternate 2FAs. +class InlineLoginHandlerModalDelegate + : public ChromeWebModalDialogManagerDelegate { + public: + // |host| is a non owning pointer to the host dialog of this delegate + // (|InlineLoginHandlerDialogChromeOS|). + explicit InlineLoginHandlerModalDelegate( + web_modal::WebContentsModalDialogHost* host); + ~InlineLoginHandlerModalDelegate() override; + + // web_modal::WebContentsModalDialogManagerDelegate overrides. + web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost() + override; + + private: + // Non-owning pointer. + web_modal::WebContentsModalDialogHost* host_; + + DISALLOW_COPY_AND_ASSIGN(InlineLoginHandlerModalDelegate); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_SIGNIN_INLINE_LOGIN_HANDLER_MODAL_DELEGATE_H_
diff --git a/chrome/browser/vr/elements/viewport_aware_root.cc b/chrome/browser/vr/elements/viewport_aware_root.cc index eaa062a..aea3236 100644 --- a/chrome/browser/vr/elements/viewport_aware_root.cc +++ b/chrome/browser/vr/elements/viewport_aware_root.cc
@@ -42,8 +42,36 @@ ViewportAwareRoot::~ViewportAwareRoot() = default; bool ViewportAwareRoot::OnBeginFrame(const gfx::Transform& head_pose) { + // head_pose is head_from_world. Invert to get world_from_head. gfx::Vector3dF look_at = vr::GetForwardVector(head_pose); - return AdjustRotationForHeadPose(look_at); + bool changed = AdjustRotationForHeadPose(look_at); + if (recenter_on_rotate_) { + gfx::Transform world_from_head; + bool invertable = head_pose.GetInverse(&world_from_head); + DCHECK(invertable); // Pose data has been validated already. + gfx::Point3F head_pos_in_world_space{0.f, 0.f, 0.f}; + world_from_head.TransformPoint(&head_pos_in_world_space); + changed = AdjustTranslation(head_pos_in_world_space.x(), + head_pos_in_world_space.z(), changed); + } + return changed; +} + +bool ViewportAwareRoot::AdjustTranslation(float head_in_world_x, + float head_in_world_z, + bool did_rotate) { + gfx::Point3F center_point_in_world{0.f, 0.f, 0.f}; + LocalTransform().TransformPoint(¢er_point_in_world); + gfx::Vector2dF offset = {head_in_world_x - center_point_in_world.x(), + head_in_world_z - center_point_in_world.z()}; + + const float kMinTranslationLength = + 1.2f; // If you move 1.2m, we'll recenter. + if (did_rotate || offset.Length() > kMinTranslationLength) { + SetTranslate(head_in_world_x, center_point_in_world.y(), head_in_world_z); + return true; + } + return false; } bool ViewportAwareRoot::AdjustRotationForHeadPose( @@ -83,6 +111,8 @@ void ViewportAwareRoot::Reset() { viewport_aware_total_rotation_ = 0.f; + x_center = 0; + z_center = 0; SetRotate(0.f, 1.f, 0.f, gfx::DegToRad(viewport_aware_total_rotation_)); }
diff --git a/chrome/browser/vr/elements/viewport_aware_root.h b/chrome/browser/vr/elements/viewport_aware_root.h index 70427a4..110c28e2 100644 --- a/chrome/browser/vr/elements/viewport_aware_root.h +++ b/chrome/browser/vr/elements/viewport_aware_root.h
@@ -24,17 +24,24 @@ void Reset(); bool HasVisibleChildren(); + void SetRecenterOnRotate(bool recenter_on_rotate) { + recenter_on_rotate_ = true; + } protected: // Returns true if the rotation was adjusted. // Virtual for tests. virtual bool AdjustRotationForHeadPose(const gfx::Vector3dF& look_at); + virtual bool AdjustTranslation(float head_x, float head_z, bool did_rotate); private: bool OnBeginFrame(const gfx::Transform& head_pose) override; float viewport_aware_total_rotation_ = 0.f; + float x_center = 0; + float z_center = 0; bool children_visible_ = false; + bool recenter_on_rotate_ = false; DISALLOW_COPY_AND_ASSIGN(ViewportAwareRoot); };
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc index 755818c..287ab69 100644 --- a/chrome/browser/vr/ui_scene_creator.cc +++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -1873,11 +1873,21 @@ void UiSceneCreator::CreateViewportAwareRoot() { auto element = std::make_unique<ViewportAwareRoot>(); element->SetName(kWebVrViewportAwareRoot); + + // On Windows, allow the viewport-aware UI to translate as well as rotate, so + // it remains centered appropriately if the user moves. Only enabled for + // OS_WIN, since it conflicts with browser UI that isn't shown on Windows. +#if defined(OS_WIN) + element->SetRecenterOnRotate(true); +#endif scene_->AddUiElement(kWebVrRoot, std::move(element)); element = std::make_unique<ViewportAwareRoot>(); element->SetName(k2dBrowsingViewportAwareRoot); element->set_contributes_to_parent_bounds(false); +#if defined(OS_WIN) + element->SetRecenterOnRotate(true); +#endif scene_->AddUiElement(k2dBrowsingRepositioner, std::move(element)); }
diff --git a/chrome/browser/vr/win/vr_browser_renderer_thread_win.cc b/chrome/browser/vr/win/vr_browser_renderer_thread_win.cc index fcd22738..c7c9e264 100644 --- a/chrome/browser/vr/win/vr_browser_renderer_thread_win.cc +++ b/chrome/browser/vr/win/vr_browser_renderer_thread_win.cc
@@ -87,6 +87,7 @@ } void VRBrowserRendererThreadWin::StartWebXrTimeout() { + waiting_for_first_frame_ = true; overlay_->SetOverlayAndWebXRVisibility(draw_state_.ShouldDrawUI(), draw_state_.ShouldDrawWebXR()); @@ -115,6 +116,7 @@ if (!webxr_frame_timeout_closure_.IsCancelled()) webxr_frame_timeout_closure_.Cancel(); OnSpinnerVisibilityChanged(false); + waiting_for_first_frame_ = false; } int VRBrowserRendererThreadWin::GetNextRequestId() { @@ -455,7 +457,7 @@ if (!success && graphics_) { graphics_->ResetMemoryBuffer(); } - if (scheduler_ui_ && success) + if (scheduler_ui_ && success && !waiting_for_first_frame_) scheduler_ui_->OnWebXrFrameAvailable(); if (draw_state_.ShouldDrawUI() && started_) { overlay_->RequestNextOverlayPose( @@ -471,9 +473,9 @@ } bool VRBrowserRendererThreadWin::DrawState::ShouldDrawWebXR() { - return (prompt_ == ExternalPromptNotificationType::kPromptNone && - !spinner_visible_) || - indicators_visible_; + return ((prompt_ == ExternalPromptNotificationType::kPromptNone || + indicators_visible_) && + !spinner_visible_); } bool VRBrowserRendererThreadWin::DrawState::SetPrompt(
diff --git a/chrome/browser/vr/win/vr_browser_renderer_thread_win.h b/chrome/browser/vr/win/vr_browser_renderer_thread_win.h index a8675ee..ccf7465 100644 --- a/chrome/browser/vr/win/vr_browser_renderer_thread_win.h +++ b/chrome/browser/vr/win/vr_browser_renderer_thread_win.h
@@ -102,6 +102,7 @@ DrawState draw_state_; bool started_ = false; bool webxr_presenting_ = false; + bool waiting_for_first_frame_ = true; int current_request_id_ = 0; device::mojom::ImmersiveOverlayPtr overlay_;
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 66f188d1..7ef87da 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -230,7 +230,13 @@ // Enables or disables the ability to install PWAs from the omnibox. const base::Feature kDesktopPWAsOmniboxInstall{ - "DesktopPWAsOmniboxInstall", base::FEATURE_ENABLED_BY_DEFAULT}; + "DesktopPWAsOmniboxInstall", +#if defined(OS_CHROMEOS) + base::FEATURE_DISABLED_BY_DEFAULT +#else + base::FEATURE_ENABLED_BY_DEFAULT +#endif +}; // Disables downloads of unsafe file types over HTTP. const base::Feature kDisallowUnsafeHttpDownloads{
diff --git a/chrome/common/extensions/docs/templates/articles/webstore.html b/chrome/common/extensions/docs/templates/articles/webstore.html new file mode 100644 index 0000000..3a46f0a --- /dev/null +++ b/chrome/common/extensions/docs/templates/articles/webstore.html
@@ -0,0 +1,8 @@ +<h1>chrome.webstore</h1> + +<p> + As of 06/12/2018, inline installation is deprecated. For more information, + read our + <a href="https://blog.chromium.org/2018/06/improving-extension-transparency-for.html">Chromium Blog post</a> + and <a href="/extensions/inline_faq">Migration FAQ</a>. +</p>
diff --git a/chrome/common/extensions/docs/templates/intros/webstore.html b/chrome/common/extensions/docs/templates/intros/webstore.html deleted file mode 100644 index e9d5374..0000000 --- a/chrome/common/extensions/docs/templates/intros/webstore.html +++ /dev/null
@@ -1,7 +0,0 @@ -<p class="caution"> - <b>Important:</b> - As of 06/12/2018, inline installation is deprecated. - For more information, read our - <a href="https://blog.chromium.org/2018/06/improving-extension-transparency-for.html">Chromium Blog post</a> - and <a href="/extensions/inline_faq">Migration FAQ</a>. -</p>
diff --git a/chrome/common/extensions/docs/templates/public/extensions/webstore.html b/chrome/common/extensions/docs/templates/public/extensions/webstore.html index a21f5bd2..19a17f1 100644 --- a/chrome/common/extensions/docs/templates/public/extensions/webstore.html +++ b/chrome/common/extensions/docs/templates/public/extensions/webstore.html
@@ -1 +1 @@ -{{+partials.standard_extensions_api api:apis.extensions.webstore intro:intros.webstore/}} +{{+partials.standard_extensions_article article:articles.webstore/}}
diff --git a/chrome/renderer/extensions/automation_ax_tree_wrapper.cc b/chrome/renderer/extensions/automation_ax_tree_wrapper.cc index dd2433edb..8a019d0d 100644 --- a/chrome/renderer/extensions/automation_ax_tree_wrapper.cc +++ b/chrome/renderer/extensions/automation_ax_tree_wrapper.cc
@@ -189,6 +189,7 @@ return api::automation::EVENT_TYPE_ARIAATTRIBUTECHANGED; case ui::AXEventGenerator::Event::ACCESS_KEY_CHANGED: + case ui::AXEventGenerator::Event::CONTROLS_CHANGED: case ui::AXEventGenerator::Event::CLASS_NAME_CHANGED: case ui::AXEventGenerator::Event::DESCRIBED_BY_CHANGED: case ui::AXEventGenerator::Event::DESCRIPTION_CHANGED:
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index f339ac8..7bc7be9 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h
@@ -90,7 +90,7 @@ LocationBar* GetLocationBar() const override; PageActionIconContainer* GetPageActionIconContainer() override; PageActionIconContainer* GetToolbarPageActionIconContainer() override; - void SetFocusToLocationBar() override {} + void SetFocusToLocationBar(bool select_all) override {} void UpdateReloadStopState(bool is_loading, bool force) override {} void UpdateToolbar(content::WebContents* contents) override {} void UpdateToolbarVisibility(bool visible, bool animate) override {} @@ -195,7 +195,7 @@ base::TimeTicks GetMatchSelectionTimestamp() const override; void AcceptInput() override {} void AcceptInput(base::TimeTicks match_selection_timestamp) override {} - void FocusLocation() override {} + void FocusLocation(bool select_all) override {} void FocusSearch() override {} void UpdateContentSettingsIcons() override {} void UpdateSaveCreditCardIcon() override {}
diff --git a/chrome/test/chromedriver/client/chromedriver.py b/chrome/test/chromedriver/client/chromedriver.py index 94ee53a..b3747b0 100644 --- a/chrome/test/chromedriver/client/chromedriver.py +++ b/chrome/test/chromedriver/client/chromedriver.py
@@ -147,7 +147,7 @@ debugger_address=None, logging_prefs=None, mobile_emulation=None, experimental_options=None, download_dir=None, network_connection=None, - send_w3c_capability=None, send_w3c_request=None, + send_w3c_capability=True, send_w3c_request=True, page_load_strategy=None, unexpected_alert_behaviour=None, devtools_events_to_log=None, accept_insecure_certs=None, timeouts=None, test_name=None): @@ -226,7 +226,7 @@ options['prefs']['download'] = {} options['prefs']['download']['default_directory'] = download_dir - if send_w3c_capability: + if send_w3c_capability is not None: options['w3c'] = send_w3c_capability params = { @@ -314,10 +314,10 @@ def _ExecuteCommand(self, command, params={}): params = self._WrapValue(params) response = self._executor.Execute(command, params) - if (not self.w3c_compliant and 'status' in response + if ('status' in response and response['status'] != 0): raise _ExceptionForLegacyResponse(response) - elif (self.w3c_compliant and type(response['value']) is dict + elif (type(response['value']) is dict and 'error' in response['value']): raise _ExceptionForStandardResponse(response) return response @@ -331,7 +331,10 @@ return self.ExecuteCommand(Command.GET_WINDOW_HANDLES) def SwitchToWindow(self, handle_or_name): - self.ExecuteCommand(Command.SWITCH_TO_WINDOW, {'name': handle_or_name}) + if self.w3c_compliant: + self.ExecuteCommand(Command.SWITCH_TO_WINDOW, {'handle': handle_or_name}) + else: + self.ExecuteCommand(Command.SWITCH_TO_WINDOW, {'name': handle_or_name}) def GetCurrentWindowHandle(self): return self.ExecuteCommand(Command.GET_CURRENT_WINDOW_HANDLE) @@ -357,6 +360,16 @@ {'script': script, 'args': converted_args}) def SwitchToFrame(self, id_or_name): + if isinstance(id_or_name, basestring) and self.w3c_compliant: + try: + id_or_name = self.FindElement('css selector', + '[id="%s"]' % id_or_name) + except NoSuchElement: + try: + id_or_name = self.FindElement('css selector', + '[name="%s"]' % id_or_name) + except NoSuchElement: + raise NoSuchFrame(id_or_name) self.ExecuteCommand(Command.SWITCH_TO_FRAME, {'id': id_or_name}) def SwitchToFrameByIndex(self, index):
diff --git a/chrome/test/chromedriver/client/webelement.py b/chrome/test/chromedriver/client/webelement.py index 9eda862..e8bf6a6 100644 --- a/chrome/test/chromedriver/client/webelement.py +++ b/chrome/test/chromedriver/client/webelement.py
@@ -53,16 +53,16 @@ self._Execute(Command.CLEAR_ELEMENT) def SendKeys(self, *values): - typing = [] - for value in values: - if isinstance(value, int): - value = str(value) - for i in range(len(value)): - typing.append(value[i]) - self._Execute(Command.SEND_KEYS_TO_ELEMENT, {'value': typing}) - - def SendKeysW3c(self, text): - self._Execute(Command.SEND_KEYS_TO_ELEMENT, {'text': text}) + if self._chromedriver.w3c_compliant: + self._Execute(Command.SEND_KEYS_TO_ELEMENT, {'text': str(*values)}) + else: + typing = [] + for value in values: + if isinstance(value, int): + value = str(value) + for i in range(len(value)): + typing.append(value[i]) + self._Execute(Command.SEND_KEYS_TO_ELEMENT, {'value': typing}) def GetLocation(self): return self._Execute(Command.GET_ELEMENT_LOCATION)
diff --git a/chrome/test/chromedriver/server/http_handler.cc b/chrome/test/chromedriver/server/http_handler.cc index bbbf66f..3c4bcd30 100644 --- a/chrome/test/chromedriver/server/http_handler.cc +++ b/chrome/test/chromedriver/server/http_handler.cc
@@ -704,11 +704,10 @@ kSessionStorage), false /*w3c_standard_command*/)), - // No W3C equivalent. + // Non-standard command but supported in the foreseeable future. CommandMapping( kPost, "session/:sessionId/log", - WrapToCommand("GetLog", base::BindRepeating(&ExecuteGetLog), - false /*w3c_standard_command*/)), + WrapToCommand("GetLog", base::BindRepeating(&ExecuteGetLog))), // No W3C equivalent. CommandMapping(
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index 0a369bce..f7b56da 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -169,8 +169,6 @@ _ANDROID_NEGATIVE_FILTER = {} _ANDROID_NEGATIVE_FILTER['chrome'] = ( _NEGATIVE_FILTER + [ - # TODO(chrisgao): fix hang of tab crash test on android. - 'ChromeDriverTest.testTabCrash', # Android doesn't support switches and extensions. 'ChromeSwitchesCapabilityTest.*', 'ChromeExtensionsCapabilityTest.*', @@ -404,21 +402,6 @@ def testGetCurrentWindowHandle(self): self._driver.GetCurrentWindowHandle() - def testDragAndDropWithSVGImage(self): - self._driver.Load( - self.GetHttpUrlForFile('/chromedriver/drag_and_drop.svg')) - drag = self._driver.FindElement("css selector", "#GreenRectangle") - drop = self._driver.FindElement("css selector", "#FolderRectangle") - self._driver.MouseMoveTo(drag) - self._driver.MouseButtonDown() - self._driver.MouseMoveTo(drop) - self._driver.MouseButtonUp() - self.assertTrue(self._driver.IsAlertOpen()) - self.assertEquals('GreenRectangle has been dropped into a folder.', - self._driver.GetAlertMessage()) - self._driver.HandleAlert(True) - self.assertEquals('translate(300,55)', drag.GetAttribute("transform")) - def testCloseWindow(self): self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html')) old_handles = self._driver.GetWindowHandles() @@ -554,19 +537,16 @@ self._driver.Load(self.GetHttpUrlForFile( '/chromedriver/nested_frameset.html')) self._driver.SwitchToFrameByIndex(0) - self.assertTrue(self._driver.FindElement("css selector", "#link") - .IsDisplayed()) + self._driver.FindElement("css selector", "#link") self._driver.SwitchToMainFrame() self._driver.SwitchToFrame('2Frame') - self.assertTrue(self._driver.FindElement("css selector", "#l1") - .IsDisplayed()) + self._driver.FindElement("css selector", "#l1") self._driver.SwitchToMainFrame() self._driver.SwitchToFrame('fourth_frame') self.assertTrue('One' in self._driver.GetPageSource()) self._driver.SwitchToMainFrame() self._driver.SwitchToFrameByIndex(4) - self.assertTrue(self._driver.FindElement("css selector", "#aa1") - .IsDisplayed()) + self._driver.FindElement("css selector", "#aa1") def testExecuteInRemovedFrame(self): self._driver.ExecuteScript( @@ -622,13 +602,6 @@ self._driver.FindElement, 'tag name', 'divine') - def testUnexpectedAlertOpenExceptionMessage(self): - self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) - self._driver.ExecuteScript('window.alert("Hi");') - self.assertRaisesRegexp(chromedriver.UnexpectedAlertOpen, - 'unexpected alert open: {Alert text : Hi}', - self._driver.FindElement, 'tag name', 'divine') - def testFindElements(self): self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) self._driver.ExecuteScript( @@ -931,38 +904,11 @@ value = self._driver.ExecuteScript('return arguments[0].value;', text) self.assertEquals('', value) - def testSendKeysToElement(self): - self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) - text = self._driver.ExecuteScript( - 'document.body.innerHTML = \'<input type="text">\';' - 'var input = document.getElementsByTagName("input")[0];' - 'input.addEventListener("change", function() {' - ' document.body.appendChild(document.createElement("br"));' - '});' - 'return input;') - text.SendKeys('0123456789+-*/ Hi') - text.SendKeys(', there!') - value = self._driver.ExecuteScript('return arguments[0].value;', text) - self.assertEquals('0123456789+-*/ Hi, there!', value) - - def testSendingTabKeyMovesToNextInputElement(self): - self._driver.Load(self.GetHttpUrlForFile('/chromedriver/two_inputs.html')) - first = self._driver.FindElement('css selector', '#first') - second = self._driver.FindElement('css selector', '#second') - first.Click() - self._driver.SendKeys('snoopy') - self._driver.SendKeys(u'\uE004') - self._driver.SendKeys('prickly pete') - self.assertEquals('snoopy', self._driver.ExecuteScript( - 'return arguments[0].value;', first)) - self.assertEquals('prickly pete', self._driver.ExecuteScript( - 'return arguments[0].value;', second)) - def testSendKeysToInputFileElement(self): file_name = os.path.join(_TEST_DATA_DIR, 'anchor_download_test.png') self._driver.Load(ChromeDriverTest.GetHttpUrlForFile( '/chromedriver/file_input.html')) - elem = self._driver.FindElement('id', 'id_file') + elem = self._driver.FindElement('css selector', '#id_file') elem.SendKeys(file_name) text = self._driver.ExecuteScript( 'var input = document.getElementById("id_file").value;' @@ -1038,101 +984,6 @@ self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) self._driver.Refresh() - def testMouseMoveTo(self): - self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) - div = self._driver.ExecuteScript( - 'document.body.innerHTML = "<div>old</div>";' - 'var div = document.getElementsByTagName("div")[0];' - 'div.style["width"] = "100px";' - 'div.style["height"] = "100px";' - 'div.addEventListener("mouseover", function() {' - ' var div = document.getElementsByTagName("div")[0];' - ' div.innerHTML="new<br>";' - '});' - 'return div;') - self._driver.MouseMoveTo(div, 10, 10) - self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) - - def testMoveToElementAndClick(self): - # This page gets rendered differently depending on which platform the test - # is running on, and what window size is being used. So we need to do some - # sanity checks to make sure that the <a> element is split across two lines - # of text. - self._driver.Load(self.GetHttpUrlForFile('/chromedriver/multiline.html')) - - # Check that link element spans two lines and that the first ClientRect is - # above the second. - link = self._driver.FindElements('tag name', 'a')[0] - client_rects = self._driver.ExecuteScript( - 'return arguments[0].getClientRects();', link) - self.assertEquals(2, len(client_rects)) - self.assertTrue(client_rects[0]['bottom'] <= client_rects[1]['top']) - - # Check that the center of the link's bounding ClientRect is outside the - # element. - bounding_client_rect = self._driver.ExecuteScript( - 'return arguments[0].getBoundingClientRect();', link) - center = bounding_client_rect['left'] + bounding_client_rect['width'] / 2 - self.assertTrue(client_rects[1]['right'] < center) - self.assertTrue(center < client_rects[0]['left']) - - self._driver.MouseMoveTo(link) - self._driver.MouseClick() - self.assertTrue(self._driver.GetCurrentUrl().endswith('#top')) - - def testMouseClick(self): - self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) - div = self._driver.ExecuteScript( - 'document.body.innerHTML = "<div>old</div>";' - 'var div = document.getElementsByTagName("div")[0];' - 'div.style["width"] = "100px";' - 'div.style["height"] = "100px";' - 'div.addEventListener("click", function() {' - ' var div = document.getElementsByTagName("div")[0];' - ' div.innerHTML="new<br>";' - '});' - 'return div;') - self._driver.MouseMoveTo(div) - self._driver.MouseClick() - self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) - - def testMouseButtonDownAndUp(self): - self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) - self._driver.ExecuteScript( - 'document.body.innerHTML = "<div>old</div>";' - 'var div = document.getElementsByTagName("div")[0];' - 'div.style["width"] = "100px";' - 'div.style["height"] = "100px";' - 'div.addEventListener("mousedown", function() {' - ' var div = document.getElementsByTagName("div")[0];' - ' div.innerHTML="new1<br>";' - '});' - 'div.addEventListener("mouseup", function() {' - ' var div = document.getElementsByTagName("div")[0];' - ' div.innerHTML="new2<a></a>";' - '});') - self._driver.MouseMoveTo(None, 50, 50) - self._driver.MouseButtonDown() - self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) - self._driver.MouseButtonUp() - self.assertEquals(1, len(self._driver.FindElements('tag name', 'a'))) - - def testMouseDoubleClick(self): - self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) - div = self._driver.ExecuteScript( - 'document.body.innerHTML = "<div>old</div>";' - 'var div = document.getElementsByTagName("div")[0];' - 'div.style["width"] = "100px";' - 'div.style["height"] = "100px";' - 'div.addEventListener("dblclick", function() {' - ' var div = document.getElementsByTagName("div")[0];' - ' div.innerHTML="new<br>";' - '});' - 'return div;') - self._driver.MouseMoveTo(div, 1, 1) - self._driver.MouseDoubleClick() - self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) - def testAlert(self): self.assertFalse(self._driver.IsAlertOpen()) self._driver.ExecuteScript('window.confirmed = confirm(\'HI\');') @@ -1326,7 +1177,8 @@ self.WaitForCondition(lambda: len(GetPendingLogs(self._driver)) > 0 , 6) self.assertEqual('console-api', new_logs[0][0]['source']) - self.assertTrue('"RepeatedError" "Second" "Third"' in new_logs[0][0]['message']) + self.assertTrue('"RepeatedError" "Second" "Third"' in + new_logs[0][0]['message']) def testGetLogOnClosedWindow(self): self._driver.Load(self.GetHttpUrlForFile('/chromedriver/page_test.html')) @@ -1357,28 +1209,10 @@ ".*Uncaught TypeError: Cannot read property 'y' of undefined.*", self._driver.Load, url) - def testContextMenuEventFired(self): - self._driver.Load(self.GetHttpUrlForFile('/chromedriver/context_menu.html')) - self._driver.MouseMoveTo(self._driver.FindElement('tag name', 'div')) - self._driver.MouseClick(2) - self.assertTrue(self._driver.ExecuteScript('return success')) - - def testTabCrash(self): - # If a tab is crashed, the session will be deleted. - # When 31 is released, will reload the tab instead. - # https://bugs.chromium.org/p/chromedriver/issues/detail?id=547 - self.assertRaises(chromedriver.UnknownError, - self._driver.Load, 'chrome://crash') - self.assertRaises(chromedriver.InvalidSessionId, - self._driver.GetCurrentUrl) - def testDoesntHangOnDebugger(self): self._driver.Load('about:blank') self._driver.ExecuteScript('debugger;') - def testMobileEmulationDisabledByDefault(self): - self.assertFalse(self._driver.capabilities['mobileEmulationEnabled']) - def testChromeDriverSendLargeData(self): script = 'var s = ""; for (var i = 0; i < 10e6; i++) s += "0"; return s;' lots_of_data = self._driver.ExecuteScript(script) @@ -1604,20 +1438,6 @@ with self.assertRaises(chromedriver.StaleElementReference): elem.Click() - def testShadowDomDisplayed(self): - """Checks that trying to manipulate shadow DOM elements that are detached - from the document raises a StaleElementReference exception""" - self._driver.Load(self.GetHttpUrlForFile( - '/chromedriver/shadow_dom_test.html')) - elem = self._FindElementInShadowDom( - ["#innerDiv", "#parentDiv", "#button"]) - self.assertTrue(elem.IsDisplayed()) - elem2 = self._driver.FindElement("css selector", "#hostContent") - self.assertTrue(elem2.IsDisplayed()) - self._driver.ExecuteScript( - 'document.querySelector("#outerDiv").style.display="None";') - self.assertFalse(elem.IsDisplayed()) - def testTouchSingleTapElement(self): self._driver.Load(self.GetHttpUrlForFile( '/chromedriver/touch_action_tests.html')) @@ -1720,13 +1540,6 @@ width_after_pinch = self._driver.ExecuteScript('return window.innerWidth;') self.assertAlmostEqual(2.0, float(width_before_pinch) / width_after_pinch) - def testHasTouchScreen(self): - self.assertIn('hasTouchScreen', self._driver.capabilities) - if _ANDROID_PACKAGE_KEY: - self.assertTrue(self._driver.capabilities['hasTouchScreen']) - else: - self.assertFalse(self._driver.capabilities['hasTouchScreen']) - def testSwitchesToTopFrameAfterNavigation(self): self._driver.Load('about:blank') self._driver.Load(self.GetHttpUrlForFile('/chromedriver/outer.html')) @@ -2062,8 +1875,8 @@ ' document.body.appendChild(document.createElement("br"));' '});' 'return input;') - text.SendKeysW3c('0123456789+-*/ Hi') - text.SendKeysW3c(', there!') + text.SendKeys('0123456789+-*/ Hi') + text.SendKeys(', there!') value = self._driver.ExecuteScript('return arguments[0].value;', text) self.assertEquals('0123456789+-*/ Hi, there!', value) @@ -2076,6 +1889,201 @@ # In W3C mode, the alert is dismissed by default. self.assertFalse(self._driver.IsAlertOpen()) + +class ChromeDriverTestLegacy(ChromeDriverBaseTestWithWebServer): + """End to end tests for ChromeDriver in Legacy mode.""" + + def setUp(self): + self._driver = self.CreateDriver(send_w3c_capability=False, + send_w3c_request=False) + + def testContextMenuEventFired(self): + self._driver.Load(self.GetHttpUrlForFile('/chromedriver/context_menu.html')) + self._driver.MouseMoveTo(self._driver.FindElement('tag name', 'div')) + self._driver.MouseClick(2) + self.assertTrue(self._driver.ExecuteScript('return success')) + + def testDragAndDropWithSVGImage(self): + self._driver.Load( + self.GetHttpUrlForFile('/chromedriver/drag_and_drop.svg')) + drag = self._driver.FindElement("css selector", "#GreenRectangle") + drop = self._driver.FindElement("css selector", "#FolderRectangle") + self._driver.MouseMoveTo(drag) + self._driver.MouseButtonDown() + self._driver.MouseMoveTo(drop) + self._driver.MouseButtonUp() + self.assertTrue(self._driver.IsAlertOpen()) + self.assertEquals('GreenRectangle has been dropped into a folder.', + self._driver.GetAlertMessage()) + self._driver.HandleAlert(True) + self.assertEquals('translate(300,55)', drag.GetAttribute("transform")) + + def testMouseButtonDownAndUp(self): + self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) + self._driver.ExecuteScript( + 'document.body.innerHTML = "<div>old</div>";' + 'var div = document.getElementsByTagName("div")[0];' + 'div.style["width"] = "100px";' + 'div.style["height"] = "100px";' + 'div.addEventListener("mousedown", function() {' + ' var div = document.getElementsByTagName("div")[0];' + ' div.innerHTML="new1<br>";' + '});' + 'div.addEventListener("mouseup", function() {' + ' var div = document.getElementsByTagName("div")[0];' + ' div.innerHTML="new2<a></a>";' + '});') + self._driver.MouseMoveTo(None, 50, 50) + self._driver.MouseButtonDown() + self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) + self._driver.MouseButtonUp() + self.assertEquals(1, len(self._driver.FindElements('tag name', 'a'))) + + def testMouseClick(self): + self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) + div = self._driver.ExecuteScript( + 'document.body.innerHTML = "<div>old</div>";' + 'var div = document.getElementsByTagName("div")[0];' + 'div.style["width"] = "100px";' + 'div.style["height"] = "100px";' + 'div.addEventListener("click", function() {' + ' var div = document.getElementsByTagName("div")[0];' + ' div.innerHTML="new<br>";' + '});' + 'return div;') + self._driver.MouseMoveTo(div) + self._driver.MouseClick() + self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) + + def testMouseDoubleClick(self): + self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) + div = self._driver.ExecuteScript( + 'document.body.innerHTML = "<div>old</div>";' + 'var div = document.getElementsByTagName("div")[0];' + 'div.style["width"] = "100px";' + 'div.style["height"] = "100px";' + 'div.addEventListener("dblclick", function() {' + ' var div = document.getElementsByTagName("div")[0];' + ' div.innerHTML="new<br>";' + '});' + 'return div;') + self._driver.MouseMoveTo(div, 1, 1) + self._driver.MouseDoubleClick() + self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) + + def testMouseMoveTo(self): + self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) + div = self._driver.ExecuteScript( + 'document.body.innerHTML = "<div>old</div>";' + 'var div = document.getElementsByTagName("div")[0];' + 'div.style["width"] = "100px";' + 'div.style["height"] = "100px";' + 'div.addEventListener("mouseover", function() {' + ' var div = document.getElementsByTagName("div")[0];' + ' div.innerHTML="new<br>";' + '});' + 'return div;') + self._driver.MouseMoveTo(div, 10, 10) + self.assertEquals(1, len(self._driver.FindElements('tag name', 'br'))) + + def testMoveToElementAndClick(self): + # This page gets rendered differently depending on which platform the test + # is running on, and what window size is being used. So we need to do some + # sanity checks to make sure that the <a> element is split across two lines + # of text. + self._driver.Load(self.GetHttpUrlForFile('/chromedriver/multiline.html')) + + # Check that link element spans two lines and that the first ClientRect is + # above the second. + link = self._driver.FindElements('tag name', 'a')[0] + client_rects = self._driver.ExecuteScript( + 'return arguments[0].getClientRects();', link) + self.assertEquals(2, len(client_rects)) + self.assertTrue(client_rects[0]['bottom'] <= client_rects[1]['top']) + + # Check that the center of the link's bounding ClientRect is outside the + # element. + bounding_client_rect = self._driver.ExecuteScript( + 'return arguments[0].getBoundingClientRect();', link) + center = bounding_client_rect['left'] + bounding_client_rect['width'] / 2 + self.assertTrue(client_rects[1]['right'] < center) + self.assertTrue(center < client_rects[0]['left']) + + self._driver.MouseMoveTo(link) + self._driver.MouseClick() + self.assertTrue(self._driver.GetCurrentUrl().endswith('#top')) + + + def _FindElementInShadowDom(self, css_selectors): + """Find an element inside shadow DOM using CSS selectors. + The last item in css_selectors identify the element to find. All preceding + selectors identify the hierarchy of shadow hosts to traverse in order to + reach the target shadow DOM.""" + current = None + for selector in css_selectors: + if current is None: + # First CSS selector, start from root DOM. + current = self._driver + else: + # current is a shadow host selected previously. + # Enter the corresponding shadow root. + current = self._driver.ExecuteScript( + 'return arguments[0].shadowRoot', current) + current = current.FindElement('css selector', selector) + return current + + def testShadowDomDisplayed(self): + """Checks that trying to manipulate shadow DOM elements that are detached + from the document raises a StaleElementReference exception""" + self._driver.Load(self.GetHttpUrlForFile( + '/chromedriver/shadow_dom_test.html')) + elem = self._FindElementInShadowDom( + ["#innerDiv", "#parentDiv", "#button"]) + self.assertTrue(elem.IsDisplayed()) + elem2 = self._driver.FindElement("css selector", "#hostContent") + self.assertTrue(elem2.IsDisplayed()) + self._driver.ExecuteScript( + 'document.querySelector("#outerDiv").style.display="None";') + self.assertFalse(elem.IsDisplayed()) + + def testSendingTabKeyMovesToNextInputElement(self): + self._driver.Load(self.GetHttpUrlForFile('/chromedriver/two_inputs.html')) + first = self._driver.FindElement('css selector', '#first') + second = self._driver.FindElement('css selector', '#second') + first.Click() + self._driver.SendKeys('snoopy') + self._driver.SendKeys(u'\uE004') + self._driver.SendKeys('prickly pete') + self.assertEquals('snoopy', self._driver.ExecuteScript( + 'return arguments[0].value;', first)) + self.assertEquals('prickly pete', self._driver.ExecuteScript( + 'return arguments[0].value;', second)) + + def testMobileEmulationDisabledByDefault(self): + self.assertFalse(self._driver.capabilities['mobileEmulationEnabled']) + + def testSendKeysToElement(self): + self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) + text = self._driver.ExecuteScript( + 'document.body.innerHTML = \'<input type="text">\';' + 'var input = document.getElementsByTagName("input")[0];' + 'input.addEventListener("change", function() {' + ' document.body.appendChild(document.createElement("br"));' + '});' + 'return input;') + text.SendKeys('0123456789+-*/ Hi') + text.SendKeys(', there!') + value = self._driver.ExecuteScript('return arguments[0].value;', text) + self.assertEquals('0123456789+-*/ Hi, there!', value) + + def testUnexpectedAlertOpenExceptionMessage(self): + self._driver.Load(self.GetHttpUrlForFile('/chromedriver/empty.html')) + self._driver.ExecuteScript('window.alert("Hi");') + self.assertRaisesRegexp(chromedriver.UnexpectedAlertOpen, + 'unexpected alert open: {Alert text : Hi}', + self._driver.FindElement, 'tag name', 'divine') + + class ChromeDriverSiteIsolation(ChromeDriverBaseTestWithWebServer): """Tests for ChromeDriver with the new Site Isolation Chrome feature. @@ -2504,8 +2512,11 @@ self.assertEquals(timeouts['pageLoad'], 456) self.assertEquals(timeouts['script'], 789) - def testUnexpectedAlertBehaviour(self): - driver = self.CreateDriver(unexpected_alert_behaviour="accept") + # Run in Legacy mode + def testUnexpectedAlertBehaviourLegacy(self): + driver = self.CreateDriver(unexpected_alert_behaviour="accept", + send_w3c_capability=False, + send_w3c_request=False) self.assertEquals("accept", driver.capabilities['unexpectedAlertBehaviour']) driver.ExecuteScript('alert("HI");') @@ -2681,8 +2692,10 @@ def GlobalTearDown(): MobileEmulationCapabilityTest._http_server.Shutdown() + # Run in Legacy mode def testDeviceMetricsWithStandardWidth(self): driver = self.CreateDriver( + send_w3c_capability=False, send_w3c_request=False, mobile_emulation = { 'deviceMetrics': {'width': 360, 'height': 640, 'pixelRatio': 3}, 'userAgent': 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Bui' @@ -2695,8 +2708,10 @@ self.assertEqual(360, driver.ExecuteScript('return window.screen.width')) self.assertEqual(640, driver.ExecuteScript('return window.screen.height')) + # Run in Legacy mode def testDeviceMetricsWithDeviceWidth(self): driver = self.CreateDriver( + send_w3c_capability=False, send_w3c_request=False, mobile_emulation = { 'deviceMetrics': {'width': 360, 'height': 640, 'pixelRatio': 3}, 'userAgent': 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Bui' @@ -2759,8 +2774,10 @@ div.Click() self.assertEquals(1, len(driver.FindElements('tag name', 'br'))) + # Run in Legacy mode def testTapElement(self): driver = self.CreateDriver( + send_w3c_capability=False, send_w3c_request=False, mobile_emulation = {'deviceName': 'Nexus 5'}) driver.Load('about:blank') div = driver.ExecuteScript( @@ -2773,12 +2790,6 @@ div.SingleTap() self.assertEquals(1, len(driver.FindElements('tag name', 'br'))) - def testHasTouchScreen(self): - driver = self.CreateDriver( - mobile_emulation = {'deviceName': 'Nexus 5'}) - self.assertIn('hasTouchScreen', driver.capabilities) - self.assertTrue(driver.capabilities['hasTouchScreen']) - def testDoesntWaitWhenPageLoadStrategyIsNone(self): class HandleRequest(object): def __init__(self): @@ -2822,11 +2833,13 @@ self.assertRaises(chromedriver.UnknownError, driver.SetNetworkConnection, 0x1) + # Run in Legacy mode def testNetworkConnectionEnabled(self): # mobileEmulation must be enabled for networkConnection to be enabled driver = self.CreateDriver( mobile_emulation={'deviceName': 'Nexus 5'}, - network_connection=True) + network_connection=True, + send_w3c_capability=False, send_w3c_request=False) self.assertTrue(driver.capabilities['mobileEmulationEnabled']) self.assertTrue(driver.capabilities['networkConnectionEnabled']) @@ -2944,17 +2957,28 @@ network = driver.GetNetworkConnection() self.assertEquals(network, connection_type) - def testW3cCompliantResponses(self): - # It's an error to send W3C format request without W3C capability flag. - with self.assertRaises(chromedriver.SessionNotCreated): - self.CreateDriver(send_w3c_request=True) - - # Can disable W3C capability in a legacy format request. - driver = self.CreateDriver(send_w3c_capability=False) + def testDefaultComplianceMode(self): + driver = self.CreateDriver(send_w3c_capability=None, + send_w3c_request=False) self.assertFalse(driver.w3c_compliant) - # Can set W3C capability flag in a W3C format request. - driver = self.CreateDriver(send_w3c_capability=True, send_w3c_request=True) + def testW3cCompliantResponses(self): + # It's an error to send Legacy format request + # without Legacy capability flag. + with self.assertRaises(chromedriver.InvalidArgument): + self.CreateDriver(send_w3c_request=False) + + # It's an error to send Legacy format capability + # without Legacy request flag. + with self.assertRaises(chromedriver.SessionNotCreated): + self.CreateDriver(send_w3c_capability=False) + + # Can enable W3C capability in a W3C format request. + driver = self.CreateDriver(send_w3c_capability=True) + self.assertTrue(driver.w3c_compliant) + + # Can enable W3C request in a legacy format request. + driver = self.CreateDriver(send_w3c_request=True) self.assertTrue(driver.w3c_compliant) # Asserts that errors are being raised correctly in the test client @@ -2962,8 +2986,9 @@ self.assertRaises(chromedriver.UnknownError, driver.GetNetworkConnection) - def testNonCompliantByDefault(self): - driver = self.CreateDriver(); + # Can set Legacy capability flag in a Legacy format request. + driver = self.CreateDriver(send_w3c_capability=False, + send_w3c_request=False) self.assertFalse(driver.w3c_compliant) @@ -3248,8 +3273,10 @@ HeadlessInvalidCertificateTest._https_server = webserver.WebServer( chrome_paths.GetTestData(), cert_path) if _ANDROID_PACKAGE_KEY: - HeadlessInvalidCertificateTest._device = device_utils.DeviceUtils.HealthyDevices()[0] - https_host_port = HeadlessInvalidCertificateTest._https_server._server.server_port + HeadlessInvalidCertificateTest._device = device_utils.DeviceUtils\ + .HealthyDevices()[0] + https_host_port = HeadlessInvalidCertificateTest._https_server._server\ + .server_port forwarder.Forwarder.Map([(https_host_port, https_host_port)], ChromeDriverTest._device)
diff --git a/chrome/test/data/extensions/api_test/help_app/manifest.json b/chrome/test/data/extensions/api_test/help_app/manifest.json deleted file mode 100644 index 5b9d0ef..0000000 --- a/chrome/test/data/extensions/api_test/help_app/manifest.json +++ /dev/null
@@ -1,8 +0,0 @@ -{ - "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuCAA3/rQ/X5xUBc2DhjXGB7U0Fn6memyWN5u3XYc1QzNdKodI5hmqVRi6yVePzmQuSdsA2M7wG0enGkg7qfQKNydcHPM7z/J0GEmSqzadrtz5QzWN2JemkIB3ilB7gO1RcyEluuHDhepCbVCwIr3VbguaaoatW4zYndqgC9mNOF5M73G44s6GkCunNcHtUaleaRiwt12y+WZsKIfRW90ijyESlSOEmGVhWwMld9SnAJv/P7apNr2HfQR4Bemriu02ypAPuJQ6zpvK+DRFdXu1bb7gOuN10+zPCjrt8SLs79rZ974bA56gAqUjDf3kLtJiHXMavCPUf3Fs1mvpzKTJwIDAQAB", - "name": "Help", - "version": "4.0", - "description" : "Test Chrome OS Help", - "manifest_version": 2, - "incognito" : "split" -}
diff --git a/chrome/test/data/extensions/api_test/help_app/oobe.html b/chrome/test/data/extensions/api_test/help_app/oobe.html deleted file mode 100644 index 058b00e..0000000 --- a/chrome/test/data/extensions/api_test/help_app/oobe.html +++ /dev/null
@@ -1,9 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<title>Fake Help App</title> -</head> -<body> - In official builds this shows help pages. -</body> -</html>
diff --git a/chrome/test/data/webui/cr_elements/cr_action_menu_test.js b/chrome/test/data/webui/cr_elements/cr_action_menu_test.js index e5b5a6d..8a5fb38 100644 --- a/chrome/test/data/webui/cr_elements/cr_action_menu_test.js +++ b/chrome/test/data/webui/cr_elements/cr_action_menu_test.js
@@ -347,7 +347,7 @@ menu.close(); }); - // TODO(scottchen): fix flakiness and re-enable this test. + // TODO(dpapad): fix flakiness and re-enable this test. test.skip( '[auto-reposition] enables repositioning if content changes', function(done) {
diff --git a/chrome/test/data/webui/settings/crostini_page_test.js b/chrome/test/data/webui/settings/crostini_page_test.js index bdbe01a..a24cea3 100644 --- a/chrome/test/data/webui/settings/crostini_page_test.js +++ b/chrome/test/data/webui/settings/crostini_page_test.js
@@ -106,7 +106,7 @@ test('Sanity', function() { assertTrue(!!subpage.$$('#crostini-shared-paths')); - assertTrue(!subpage.$$('#crostini-shared-usb-devices')); + assertTrue(!!subpage.$$('#crostini-shared-usb-devices')); assertTrue(!!subpage.$$('#crostini-export-import')); assertTrue(!!subpage.$$('#remove')); });
diff --git a/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc b/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc index 427cb99..55a85b5 100644 --- a/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc +++ b/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc
@@ -196,6 +196,7 @@ case ui::AXEventGenerator::Event::ACCESS_KEY_CHANGED: case ui::AXEventGenerator::Event::CLASS_NAME_CHANGED: + case ui::AXEventGenerator::Event::CONTROLS_CHANGED: case ui::AXEventGenerator::Event::DESCRIBED_BY_CHANGED: case ui::AXEventGenerator::Event::DESCRIPTION_CHANGED: case ui::AXEventGenerator::Event::ENABLED_CHANGED:
diff --git a/chromeos/audio/audio_device.h b/chromeos/audio/audio_device.h index c26e2de..647ff06 100644 --- a/chromeos/audio/audio_device.h +++ b/chromeos/audio/audio_device.h
@@ -12,7 +12,7 @@ #include <vector> #include "base/component_export.h" -#include "chromeos/dbus/audio_node.h" +#include "chromeos/dbus/audio/audio_node.h" namespace chromeos {
diff --git a/chromeos/audio/audio_devices_pref_handler_impl_unittest.cc b/chromeos/audio/audio_devices_pref_handler_impl_unittest.cc index b72eca7..5c35499 100644 --- a/chromeos/audio/audio_devices_pref_handler_impl_unittest.cc +++ b/chromeos/audio/audio_devices_pref_handler_impl_unittest.cc
@@ -11,7 +11,7 @@ #include "chromeos/audio/audio_device.h" #include "chromeos/audio/audio_devices_pref_handler.h" #include "chromeos/constants/chromeos_pref_names.h" -#include "chromeos/dbus/audio_node.h" +#include "chromeos/dbus/audio/audio_node.h" #include "components/prefs/scoped_user_pref_update.h" #include "components/prefs/testing_pref_service.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromeos/audio/cras_audio_handler.h b/chromeos/audio/cras_audio_handler.h index 4cd58f5e..1603d6d 100644 --- a/chromeos/audio/cras_audio_handler.h +++ b/chromeos/audio/cras_audio_handler.h
@@ -22,9 +22,9 @@ #include "chromeos/audio/audio_device.h" #include "chromeos/audio/audio_devices_pref_handler.h" #include "chromeos/audio/audio_pref_observer.h" -#include "chromeos/dbus/audio_node.h" -#include "chromeos/dbus/cras_audio_client.h" -#include "chromeos/dbus/volume_state.h" +#include "chromeos/dbus/audio/audio_node.h" +#include "chromeos/dbus/audio/cras_audio_client.h" +#include "chromeos/dbus/audio/volume_state.h" #include "media/base/video_facing.h" namespace base {
diff --git a/chromeos/audio/cras_audio_handler_unittest.cc b/chromeos/audio/cras_audio_handler_unittest.cc index 3cda8e30..5b5405d 100644 --- a/chromeos/audio/cras_audio_handler_unittest.cc +++ b/chromeos/audio/cras_audio_handler_unittest.cc
@@ -20,8 +20,8 @@ #include "base/values.h" #include "chromeos/audio/audio_devices_pref_handler.h" #include "chromeos/audio/audio_devices_pref_handler_stub.h" -#include "chromeos/dbus/audio_node.h" -#include "chromeos/dbus/fake_cras_audio_client.h" +#include "chromeos/dbus/audio/audio_node.h" +#include "chromeos/dbus/audio/fake_cras_audio_client.h" #include "media/base/video_facing.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index 6d87db7..5e931e01 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -24,7 +24,7 @@ // Enables or disables Crostini support for usb mounting. const base::Feature kCrostiniUsbSupport{"CrostiniUsbSupport", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Enables or disables Crostini usb mounting for unsupported devices. // To enable, CrostiniUsbSupport must also be enabled.
diff --git a/chromeos/dbus/BUILD.gn b/chromeos/dbus/BUILD.gn index 931208b..28145cb 100644 --- a/chromeos/dbus/BUILD.gn +++ b/chromeos/dbus/BUILD.gn
@@ -42,16 +42,20 @@ "arc_obb_mounter_client.h", "arc_oemcrypto_client.cc", "arc_oemcrypto_client.h", - "audio_node.cc", - "audio_node.h", + "audio/audio_node.cc", + "audio/audio_node.h", + "audio/cras_audio_client.cc", + "audio/cras_audio_client.h", + "audio/fake_cras_audio_client.cc", + "audio/fake_cras_audio_client.h", + "audio/volume_state.cc", + "audio/volume_state.h", "cec_service_client.cc", "cec_service_client.h", "cicerone_client.cc", "cicerone_client.h", "concierge_client.cc", "concierge_client.h", - "cras_audio_client.cc", - "cras_audio_client.h", "cros_disks_client.cc", "cros_disks_client.h", "dbus_client.h", @@ -80,8 +84,6 @@ "fake_cicerone_client.h", "fake_concierge_client.cc", "fake_concierge_client.h", - "fake_cras_audio_client.cc", - "fake_cras_audio_client.h", "fake_cros_disks_client.cc", "fake_cros_disks_client.h", "fake_debug_daemon_client.cc", @@ -132,8 +134,6 @@ "util/version_loader.h", "virtual_file_provider_client.cc", "virtual_file_provider_client.h", - "volume_state.cc", - "volume_state.h", ] } @@ -202,12 +202,12 @@ "//third_party/icu", ] sources = [ + "audio/cras_audio_client_unittest.cc", "auth_policy/fake_auth_policy_client_unittest.cc", "biod/biod_client_unittest.cc", "biod/fake_biod_client_unittest.cc", "blocking_method_caller_unittest.cc", "cec_service_client_unittest.cc", - "cras_audio_client_unittest.cc", "cros_disks_client_unittest.cc", "cryptohome/fake_cryptohome_client_unittest.cc", "dbus_thread_manager_unittest.cc",
diff --git a/chromeos/dbus/audio_node.cc b/chromeos/dbus/audio/audio_node.cc similarity index 77% rename from chromeos/dbus/audio_node.cc rename to chromeos/dbus/audio/audio_node.cc index f8f0baef3..7d459fc 100644 --- a/chromeos/dbus/audio_node.cc +++ b/chromeos/dbus/audio/audio_node.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/dbus/audio_node.h" +#include "chromeos/dbus/audio/audio_node.h" #include <stdint.h> @@ -41,12 +41,8 @@ std::string AudioNode::ToString() const { std::string result; - base::StringAppendF(&result, - "is_input = %s ", - is_input ? "true" : "false"); - base::StringAppendF(&result, - "id = 0x%" PRIx64 " ", - id); + base::StringAppendF(&result, "is_input = %s ", is_input ? "true" : "false"); + base::StringAppendF(&result, "id = 0x%" PRIx64 " ", id); base::StringAppendF(&result, "stable_device_id_version = %d", StableDeviceIdVersion()); base::StringAppendF(&result, "stable_device_id_v1 = 0x%" PRIx64 " ", @@ -54,15 +50,9 @@ base::StringAppendF(&result, "stable_device_id_v2 = 0x%" PRIx64 " ", stable_device_id_v2); base::StringAppendF(&result, "device_name = %s ", device_name.c_str()); - base::StringAppendF(&result, - "type = %s ", - type.c_str()); - base::StringAppendF(&result, - "name = %s ", - name.c_str()); - base::StringAppendF(&result, - "active = %s ", - active ? "true" : "false"); + base::StringAppendF(&result, "type = %s ", type.c_str()); + base::StringAppendF(&result, "name = %s ", name.c_str()); + base::StringAppendF(&result, "active = %s ", active ? "true" : "false"); base::StringAppendF(&result, "plugged_time= %s ", base::NumberToString(plugged_time).c_str());
diff --git a/chromeos/dbus/audio_node.h b/chromeos/dbus/audio/audio_node.h similarity index 90% rename from chromeos/dbus/audio_node.h rename to chromeos/dbus/audio/audio_node.h index a19f984..30af6ae3 100644 --- a/chromeos/dbus/audio_node.h +++ b/chromeos/dbus/audio/audio_node.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_DBUS_AUDIO_NODE_H_ -#define CHROMEOS_DBUS_AUDIO_NODE_H_ +#ifndef CHROMEOS_DBUS_AUDIO_AUDIO_NODE_H_ +#define CHROMEOS_DBUS_AUDIO_AUDIO_NODE_H_ #include <stdint.h> @@ -52,4 +52,4 @@ } // namespace chromeos -#endif // CHROMEOS_DBUS_AUDIO_NODE_H_ +#endif // CHROMEOS_DBUS_AUDIO_AUDIO_NODE_H_
diff --git a/chromeos/dbus/cras_audio_client.cc b/chromeos/dbus/audio/cras_audio_client.cc similarity index 97% rename from chromeos/dbus/cras_audio_client.cc rename to chromeos/dbus/audio/cras_audio_client.cc index 04eb8c87..5566ff7 100644 --- a/chromeos/dbus/cras_audio_client.cc +++ b/chromeos/dbus/audio/cras_audio_client.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/dbus/cras_audio_client.h" +#include "chromeos/dbus/audio/cras_audio_client.h" #include <stdint.h> @@ -13,7 +13,7 @@ #include "base/format_macros.h" #include "base/macros.h" #include "base/strings/stringprintf.h" -#include "chromeos/dbus/fake_cras_audio_client.h" +#include "chromeos/dbus/audio/fake_cras_audio_client.h" #include "dbus/bus.h" #include "dbus/message.h" #include "dbus/object_path.h" @@ -160,8 +160,7 @@ } void GetNodes(DBusMethodCallback<AudioNodeList> callback) override { - dbus::MethodCall method_call(cras::kCrasControlInterface, - cras::kGetNodes); + dbus::MethodCall method_call(cras::kCrasControlInterface, cras::kGetNodes); cras_proxy_->CallMethod( &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::BindOnce(&CrasAudioClientImpl::OnGetNodes, @@ -330,8 +329,7 @@ dbus::MessageReader reader(signal); bool system_mute, user_mute; if (!reader.PopBool(&system_mute) || !reader.PopBool(&user_mute)) { - LOG(ERROR) << "Error reading signal from cras:" - << signal->ToString(); + LOG(ERROR) << "Error reading signal from cras:" << signal->ToString(); } for (auto& observer : observers_) observer.OutputMuteChanged(user_mute); @@ -342,8 +340,7 @@ dbus::MessageReader reader(signal); bool mute; if (!reader.PopBool(&mute)) { - LOG(ERROR) << "Error reading signal from cras:" - << signal->ToString(); + LOG(ERROR) << "Error reading signal from cras:" << signal->ToString(); } for (auto& observer : observers_) observer.InputMuteChanged(mute); @@ -358,8 +355,7 @@ dbus::MessageReader reader(signal); uint64_t node_id; if (!reader.PopUint64(&node_id)) { - LOG(ERROR) << "Error reading signal from cras:" - << signal->ToString(); + LOG(ERROR) << "Error reading signal from cras:" << signal->ToString(); } for (auto& observer : observers_) observer.ActiveOutputNodeChanged(node_id); @@ -369,8 +365,7 @@ dbus::MessageReader reader(signal); uint64_t node_id; if (!reader.PopUint64(&node_id)) { - LOG(ERROR) << "Error reading signal from cras:" - << signal->ToString(); + LOG(ERROR) << "Error reading signal from cras:" << signal->ToString(); } for (auto& observer : observers_) observer.ActiveInputNodeChanged(node_id); @@ -559,7 +554,7 @@ if (!array_reader->PopDictEntry(&dict_entry_reader) || !dict_entry_reader.PopString(&key) || !dict_entry_reader.PopVariant(&value_reader)) { - return false; + return false; } if (key == cras::kIsInputProperty) {
diff --git a/chromeos/dbus/cras_audio_client.h b/chromeos/dbus/audio/cras_audio_client.h similarity index 94% rename from chromeos/dbus/cras_audio_client.h rename to chromeos/dbus/audio/cras_audio_client.h index 3ef45d09..037dc7b 100644 --- a/chromeos/dbus/cras_audio_client.h +++ b/chromeos/dbus/audio/cras_audio_client.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_DBUS_CRAS_AUDIO_CLIENT_H_ -#define CHROMEOS_DBUS_CRAS_AUDIO_CLIENT_H_ +#ifndef CHROMEOS_DBUS_AUDIO_CRAS_AUDIO_CLIENT_H_ +#define CHROMEOS_DBUS_AUDIO_CRAS_AUDIO_CLIENT_H_ #include <stdint.h> @@ -14,10 +14,13 @@ #include "base/component_export.h" #include "base/macros.h" #include "base/observer_list.h" -#include "chromeos/dbus/audio_node.h" -#include "chromeos/dbus/dbus_client.h" +#include "chromeos/dbus/audio/audio_node.h" +#include "chromeos/dbus/audio/volume_state.h" #include "chromeos/dbus/dbus_method_call_status.h" -#include "chromeos/dbus/volume_state.h" + +namespace dbus { +class Bus; +} namespace chromeos { @@ -144,7 +147,8 @@ virtual void SwapLeftRight(uint64_t node_id, bool swap) = 0; virtual void SetGlobalOutputChannelRemix( - int32_t channels, const std::vector<double>& mixer) = 0; + int32_t channels, + const std::vector<double>& mixer) = 0; // Runs the callback as soon as the service becomes available. virtual void WaitForServiceToBeAvailable( @@ -162,4 +166,4 @@ } // namespace chromeos -#endif // CHROMEOS_DBUS_CRAS_AUDIO_CLIENT_H_ +#endif // CHROMEOS_DBUS_AUDIO_CRAS_AUDIO_CLIENT_H_
diff --git a/chromeos/dbus/cras_audio_client_unittest.cc b/chromeos/dbus/audio/cras_audio_client_unittest.cc similarity index 95% rename from chromeos/dbus/cras_audio_client_unittest.cc rename to chromeos/dbus/audio/cras_audio_client_unittest.cc index 23b00b5..6e6495b 100644 --- a/chromeos/dbus/cras_audio_client_unittest.cc +++ b/chromeos/dbus/audio/cras_audio_client_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/dbus/cras_audio_client.h" +#include "chromeos/dbus/audio/cras_audio_client.h" #include <memory> #include <string> @@ -254,8 +254,8 @@ class CrasAudioClientTest : public testing::Test { public: - CrasAudioClientTest() : interface_name_(cras::kCrasControlInterface), - response_(nullptr) {} + CrasAudioClientTest() + : interface_name_(cras::kCrasControlInterface), response_(nullptr) {} void SetUp() override { // Create a mock bus. @@ -264,10 +264,9 @@ mock_bus_ = new dbus::MockBus(options); // Create a mock cras proxy. - mock_cras_proxy_ = new dbus::MockObjectProxy( - mock_bus_.get(), - cras::kCrasServiceName, - dbus::ObjectPath(cras::kCrasServicePath)); + mock_cras_proxy_ = + new dbus::MockObjectProxy(mock_bus_.get(), cras::kCrasServiceName, + dbus::ObjectPath(cras::kCrasServicePath)); // Set an expectation so mock_cras_proxy's CallMethod() will use // OnCallMethod() to return responses. @@ -370,8 +369,8 @@ protected: // A callback to intercept and check the method call arguments. - typedef base::Callback<void( - dbus::MessageReader* reader)> ArgumentCheckCallback; + typedef base::Callback<void(dbus::MessageReader* reader)> + ArgumentCheckCallback; // Sets expectations for called method name and arguments, and sets response. void PrepareForMethodCall(const std::string& method_name, @@ -413,7 +412,7 @@ } // Send output node volume changed signal to the tested client. - void SendOutputNodeVolumeChangedSignal(dbus::Signal *signal) { + void SendOutputNodeVolumeChangedSignal(dbus::Signal* signal) { ASSERT_FALSE(output_node_volume_changed_handler_.is_null()); output_node_volume_changed_handler_.Run(signal); } @@ -605,8 +604,7 @@ const bool kSystemMuteOn = false; const bool kUserMuteOn = true; // Create a signal. - dbus::Signal signal(cras::kCrasControlInterface, - cras::kOutputMuteChanged); + dbus::Signal signal(cras::kCrasControlInterface, cras::kOutputMuteChanged); dbus::MessageWriter writer(&signal); writer.AppendBool(kSystemMuteOn); writer.AppendBool(kUserMuteOn); @@ -635,8 +633,7 @@ TEST_F(CrasAudioClientTest, InputMuteChanged) { const bool kInputMuteOn = true; // Create a signal. - dbus::Signal signal(cras::kCrasControlInterface, - cras::kInputMuteChanged); + dbus::Signal signal(cras::kCrasControlInterface, cras::kInputMuteChanged); dbus::MessageWriter writer(&signal); writer.AppendBool(kInputMuteOn); @@ -711,8 +708,7 @@ TEST_F(CrasAudioClientTest, NodesChanged) { // Create a signal. - dbus::Signal signal(cras::kCrasControlInterface, - cras::kNodesChanged); + dbus::Signal signal(cras::kCrasControlInterface, cras::kNodesChanged); // Set expectations. MockObserver observer; EXPECT_CALL(observer, NodesChanged()).Times(1); @@ -830,8 +826,7 @@ WriteNodesToResponse(expected_node_list, &writer); // Set expectations. - PrepareForMethodCall(cras::kGetNodes, - base::Bind(&ExpectNoArgument), + PrepareForMethodCall(cras::kGetNodes, base::Bind(&ExpectNoArgument), response.get()); // Call method. bool called = false; @@ -871,11 +866,10 @@ std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); // Set expectations. - PrepareForMethodCall(cras::kSetOutputNodeVolume, - base::Bind(&ExpectUint64AndInt32Arguments, - kNodeId, - kVolume), - response.get()); + PrepareForMethodCall( + cras::kSetOutputNodeVolume, + base::Bind(&ExpectUint64AndInt32Arguments, kNodeId, kVolume), + response.get()); // Call method. client()->SetOutputNodeVolume(kNodeId, kVolume); // Run the message loop. @@ -904,11 +898,10 @@ std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); // Set expectations. - PrepareForMethodCall(cras::kSetInputNodeGain, - base::Bind(&ExpectUint64AndInt32Arguments, - kNodeId, - kInputGain), - response.get()); + PrepareForMethodCall( + cras::kSetInputNodeGain, + base::Bind(&ExpectUint64AndInt32Arguments, kNodeId, kInputGain), + response.get()); // Call method. client()->SetInputNodeGain(kNodeId, kInputGain); // Run the message loop. @@ -1027,11 +1020,10 @@ std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); // Set expectations. - PrepareForMethodCall(cras::kSwapLeftRight, - base::Bind(&ExpectUint64AndBoolArguments, - kNodeId, - kSwap), - response.get()); + PrepareForMethodCall( + cras::kSwapLeftRight, + base::Bind(&ExpectUint64AndBoolArguments, kNodeId, kSwap), + response.get()); // Call method. client()->SwapLeftRight(kNodeId, kSwap); // Run the message loop. @@ -1045,11 +1037,10 @@ std::unique_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); // Set expectations. - PrepareForMethodCall(cras::kSetGlobalOutputChannelRemix, - base::Bind(&ExpectInt32AndArrayOfDoublesArguments, - kChannels, - kMixer), - response.get()); + PrepareForMethodCall( + cras::kSetGlobalOutputChannelRemix, + base::Bind(&ExpectInt32AndArrayOfDoublesArguments, kChannels, kMixer), + response.get()); // Call method. client()->SetGlobalOutputChannelRemix(kChannels, kMixer);
diff --git a/chromeos/dbus/fake_cras_audio_client.cc b/chromeos/dbus/audio/fake_cras_audio_client.cc similarity index 98% rename from chromeos/dbus/fake_cras_audio_client.cc rename to chromeos/dbus/audio/fake_cras_audio_client.cc index 7e51b5da..778f5d64 100644 --- a/chromeos/dbus/fake_cras_audio_client.cc +++ b/chromeos/dbus/audio/fake_cras_audio_client.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/dbus/fake_cras_audio_client.h" +#include "chromeos/dbus/audio/fake_cras_audio_client.h" #include <utility> @@ -205,7 +205,8 @@ void FakeCrasAudioClient::SwapLeftRight(uint64_t node_id, bool swap) {} void FakeCrasAudioClient::SetGlobalOutputChannelRemix( - int32_t channels, const std::vector<double>& mixer) {} + int32_t channels, + const std::vector<double>& mixer) {} void FakeCrasAudioClient::AddActiveOutputNode(uint64_t node_id) { for (size_t i = 0; i < node_list_.size(); ++i) {
diff --git a/chromeos/dbus/fake_cras_audio_client.h b/chromeos/dbus/audio/fake_cras_audio_client.h similarity index 94% rename from chromeos/dbus/fake_cras_audio_client.h rename to chromeos/dbus/audio/fake_cras_audio_client.h index e26ff85..0915ae2 100644 --- a/chromeos/dbus/fake_cras_audio_client.h +++ b/chromeos/dbus/audio/fake_cras_audio_client.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_DBUS_FAKE_CRAS_AUDIO_CLIENT_H_ -#define CHROMEOS_DBUS_FAKE_CRAS_AUDIO_CLIENT_H_ +#ifndef CHROMEOS_DBUS_AUDIO_FAKE_CRAS_AUDIO_CLIENT_H_ +#define CHROMEOS_DBUS_AUDIO_FAKE_CRAS_AUDIO_CLIENT_H_ #include <stdint.h> @@ -11,7 +11,7 @@ #include "base/component_export.h" #include "base/macros.h" -#include "chromeos/dbus/cras_audio_client.h" +#include "chromeos/dbus/audio/cras_audio_client.h" namespace chromeos { @@ -99,4 +99,4 @@ } // namespace chromeos -#endif // CHROMEOS_DBUS_FAKE_CRAS_AUDIO_CLIENT_H_ +#endif // CHROMEOS_DBUS_AUDIO_FAKE_CRAS_AUDIO_CLIENT_H_
diff --git a/chromeos/dbus/audio/volume_state.cc b/chromeos/dbus/audio/volume_state.cc new file mode 100644 index 0000000..78a2211 --- /dev/null +++ b/chromeos/dbus/audio/volume_state.cc
@@ -0,0 +1,32 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/dbus/audio/volume_state.h" + +#include "base/format_macros.h" +#include "base/strings/stringprintf.h" + +namespace chromeos { + +VolumeState::VolumeState() + : output_volume(0), + output_system_mute(false), + input_gain(0), + input_mute(false), + output_user_mute(false) {} + +std::string VolumeState::ToString() const { + std::string result; + base::StringAppendF(&result, "output_volume = %d ", output_volume); + base::StringAppendF(&result, "output_system_mute = %s ", + output_system_mute ? "true" : "false"); + base::StringAppendF(&result, "input_gain = %d ", input_gain); + base::StringAppendF(&result, "input_mute = %s ", + input_mute ? "true" : "false"); + base::StringAppendF(&result, "output_user_mute = %s ", + output_user_mute ? "true" : "false"); + return result; +} + +} // namespace chromeos
diff --git a/chromeos/dbus/volume_state.h b/chromeos/dbus/audio/volume_state.h similarity index 79% rename from chromeos/dbus/volume_state.h rename to chromeos/dbus/audio/volume_state.h index 80e00ac..41dde91 100644 --- a/chromeos/dbus/volume_state.h +++ b/chromeos/dbus/audio/volume_state.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_DBUS_VOLUME_STATE_H_ -#define CHROMEOS_DBUS_VOLUME_STATE_H_ +#ifndef CHROMEOS_DBUS_AUDIO_VOLUME_STATE_H_ +#define CHROMEOS_DBUS_AUDIO_VOLUME_STATE_H_ #include <stdint.h> @@ -26,4 +26,4 @@ } // namespace chromeos -#endif // CHROMEOS_DBUS_VOLUME_STATE_H_ +#endif // CHROMEOS_DBUS_AUDIO_VOLUME_STATE_H_
diff --git a/chromeos/dbus/cryptohome/fake_cryptohome_client.cc b/chromeos/dbus/cryptohome/fake_cryptohome_client.cc index 2e108ca1..587fcafb 100644 --- a/chromeos/dbus/cryptohome/fake_cryptohome_client.cc +++ b/chromeos/dbus/cryptohome/fake_cryptohome_client.cc
@@ -47,9 +47,6 @@ } // namespace -// static -constexpr char FakeCryptohomeClient::kStubTpmPassword[] = "Stub-TPM-password"; - FakeCryptohomeClient::FakeCryptohomeClient() : service_is_available_(true), remove_firmware_management_parameters_from_tpm_call_count_(0), @@ -187,6 +184,7 @@ void FakeCryptohomeClient::TpmGetPassword( DBusMethodCallback<std::string> callback) { + constexpr char kStubTpmPassword[] = "Stub-TPM-password"; base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(std::move(callback), std::string(kStubTpmPassword)));
diff --git a/chromeos/dbus/cryptohome/fake_cryptohome_client.h b/chromeos/dbus/cryptohome/fake_cryptohome_client.h index e28d25d8..982127e 100644 --- a/chromeos/dbus/cryptohome/fake_cryptohome_client.h +++ b/chromeos/dbus/cryptohome/fake_cryptohome_client.h
@@ -36,9 +36,6 @@ // Checks that a FakeCryptohome instance was initialized and returns it. static FakeCryptohomeClient* Get(); - // Expose stub password for tests. - static const char kStubTpmPassword[]; - // CryptohomeClient overrides void AddObserver(Observer* observer) override; void RemoveObserver(Observer* observer) override;
diff --git a/chromeos/dbus/volume_state.cc b/chromeos/dbus/volume_state.cc deleted file mode 100644 index 9f105c4f..0000000 --- a/chromeos/dbus/volume_state.cc +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chromeos/dbus/volume_state.h" - -#include "base/format_macros.h" -#include "base/strings/stringprintf.h" - -namespace chromeos { - -VolumeState::VolumeState() - : output_volume(0), - output_system_mute(false), - input_gain(0), - input_mute(false), - output_user_mute(false) { -} - -std::string VolumeState::ToString() const { - std::string result; - base::StringAppendF(&result, - "output_volume = %d ", - output_volume); - base::StringAppendF(&result, - "output_system_mute = %s ", - output_system_mute ? "true" : "false"); - base::StringAppendF(&result, - "input_gain = %d ", - input_gain); - base::StringAppendF(&result, - "input_mute = %s ", - input_mute ? "true" : "false"); - base::StringAppendF(&result, - "output_user_mute = %s ", - output_user_mute ? "true" : "false"); - return result; -} - -} // namespace chromeos
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index 7563255..7f1fb17 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -23,6 +23,11 @@ const base::Feature kAutofillCreditCardAblationExperiment{ "AutofillCreditCardAblationExperiment", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enables the use of platform authenticators through WebAuthn to retrieve +// credit cards from Google payments. +const base::Feature kAutofillCreditCardAuthentication{ + "AutofillCreditCardAuthentication", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kAutofillCreditCardLocalCardMigration{ "AutofillCreditCardLocalCardMigration", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h index 869a3bc3..b0062c96 100644 --- a/components/autofill/core/common/autofill_payments_features.h +++ b/components/autofill/core/common/autofill_payments_features.h
@@ -20,6 +20,7 @@ // All features in alphabetical order. extern const base::Feature kAutofillCreditCardAblationExperiment; +extern const base::Feature kAutofillCreditCardAuthentication; extern const base::Feature kAutofillCreditCardLocalCardMigration; extern const base::Feature kAutofillDoNotUploadSaveUnsupportedCards; extern const base::Feature kAutofillDownstreamUseGooglePayBrandingOniOS;
diff --git a/components/content_capture/browser/content_capture_receiver.cc b/components/content_capture/browser/content_capture_receiver.cc index 394869b..10b1f4c 100644 --- a/components/content_capture/browser/content_capture_receiver.cc +++ b/components/content_capture/browser/content_capture_receiver.cc
@@ -46,6 +46,10 @@ // We can't avoid copy the data here, because id need to be overriden. ContentCaptureData content(data); content.id = id_; + // Always have frame URL attached, since the ContentCaptureConsumer will + // be reset once activity is resumed, URL is needed to rebuild session. + if (!first_data) + content.value = frame_content_capture_data_.value; manager->DidCaptureContent(this, content); }
diff --git a/components/content_capture/browser/content_capture_receiver_test.cc b/components/content_capture/browser/content_capture_receiver_test.cc index 9ada1eb1..c5476e53 100644 --- a/components/content_capture/browser/content_capture_receiver_test.cc +++ b/components/content_capture/browser/content_capture_receiver_test.cc
@@ -121,6 +121,15 @@ test_data2_.value = base::ASCIIToUTF16("http://foo.org/bar"); test_data2_.bounds = gfx::Rect(10, 10); test_data2_.children.push_back(child); + // Update to test_data_. + ContentCaptureData child2; + // Have the unique id for text content. + child2.id = 3; + child2.value = base::ASCIIToUTF16("World"); + child2.bounds = gfx::Rect(5, 10, 5, 5); + test_data_update_.value = base::ASCIIToUTF16("http://foo.com/bar"); + test_data_update_.bounds = gfx::Rect(10, 10); + test_data_update_.children.push_back(child2); } void SetupChildFrame() { @@ -143,6 +152,9 @@ const ContentCaptureData& test_data() const { return test_data_; } const ContentCaptureData& test_data2() const { return test_data2_; } + const ContentCaptureData& test_data_update() const { + return test_data_update_; + } const std::vector<int64_t>& expected_removed_ids() const { return expected_removed_ids_; } @@ -163,6 +175,14 @@ return expected; } + ContentCaptureData GetExpectedTestDataUpdate(bool main_frame) const { + ContentCaptureData expected(test_data_update_); + // Replaces the id with expected id. + expected.id = ContentCaptureReceiver::GetIdFrom(main_frame ? main_frame_ + : child_frame_); + return expected; + } + ContentCaptureReceiverManagerHelper* content_capture_receiver_manager_helper() const { return content_capture_receiver_manager_helper_; @@ -213,6 +233,7 @@ content::RenderFrameHost* child_frame_ = nullptr; ContentCaptureData test_data_; ContentCaptureData test_data2_; + ContentCaptureData test_data_update_; // Expected removed Ids. std::vector<int64_t> expected_removed_ids_{2}; }; @@ -237,14 +258,14 @@ EXPECT_EQ(GetExpectedTestData(true /* main_frame */), content_capture_receiver_manager_helper()->captured_data()); // Simulates to update the content within the same document. - DidCaptureContent(test_data2(), false /* first_data */); + DidCaptureContent(test_data_update(), false /* first_data */); // Verifies to get test_data2() with correct frame content id. EXPECT_TRUE( content_capture_receiver_manager_helper()->parent_session().empty()); // Verifies that the sesssion isn't removed. EXPECT_TRUE( content_capture_receiver_manager_helper()->removed_session().empty()); - EXPECT_EQ(GetExpectedTestData2(true /* main_frame */), + EXPECT_EQ(GetExpectedTestDataUpdate(true /* main_frame */), content_capture_receiver_manager_helper()->captured_data()); }
diff --git a/components/cronet/native/sample/sample_executor.h b/components/cronet/native/sample/sample_executor.h index df32032..f7108d7 100644 --- a/components/cronet/native/sample/sample_executor.h +++ b/components/cronet/native/sample/sample_executor.h
@@ -24,7 +24,7 @@ // Gets Cronet_ExecutorPtr implemented by |this|. Cronet_ExecutorPtr GetExecutor(); - // Shuts down the executor, so all pendning tasks are destroyed without + // Shuts down the executor, so all pending tasks are destroyed without // getting executed. void ShutdownExecutor();
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc index 3279d3cf..ab0a87e 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
@@ -4,6 +4,7 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h" +#include <algorithm> #include <cmath> #include <utility> #include <vector> @@ -325,7 +326,8 @@ int64_t GetListPrefValue(size_t index) { MaybeInitialize(); - return GetInt64PrefValue(*update_, index); + return std::max(GetInt64PrefValue(*update_, index), + static_cast<int64_t>(0)); } private:
diff --git a/components/flags_ui/resources/flags.css b/components/flags_ui/resources/flags.css index 4e0d048..32d6f4d 100644 --- a/components/flags_ui/resources/flags.css +++ b/components/flags_ui/resources/flags.css
@@ -41,8 +41,10 @@ --link-color: var(--google-blue-700); --separator-color: rgba(0, 0, 0, .06); --toolbar-color: white; + --toolbar-height: 57px; background: white; + overflow-y: scroll; } html[dark] { @@ -99,7 +101,7 @@ display: flex; flex: 1; flex-direction: column; - margin: 0 auto; + margin: var(--toolbar-height) auto 0; max-width: calc(700px + 2 * var(--side-padding)); width: 100%; } @@ -132,6 +134,7 @@ box-shadow: 0 2px 2px 0 var(--shadow-color); box-sizing: border-box; flex: none; + height: var(--toolbar-height); left: 0; position: fixed; top: 0; @@ -408,9 +411,7 @@ top: 0; } -.tab:active, -.tab:focus { - background: var(--toolbar-color); +html:not(.focus-outline-visible) .tab:focus { outline: 0; }
diff --git a/components/omnibox/browser/vector_icons/answer_dictionary.icon b/components/omnibox/browser/vector_icons/answer_dictionary.icon index 2d7ec5f..57b02f1 100644 --- a/components/omnibox/browser/vector_icons/answer_dictionary.icon +++ b/components/omnibox/browser/vector_icons/answer_dictionary.icon
@@ -3,30 +3,27 @@ // found in the LICENSE file. // Source: definition_16px.svg --> SVGOMG --> Skiafy +// Appearance Description: A book with large bookmark. -CANVAS_DIMENSIONS, 16, -MOVE_TO, 1, 13, -R_H_LINE_TO, 14, -R_V_LINE_TO, 2, -H_LINE_TO, 1, -CLOSE, -MOVE_TO, 13, 1, -R_H_LINE_TO, 1, -R_V_LINE_TO, 10, -R_H_LINE_TO, -1, -CLOSE, -MOVE_TO, 5.81f, 1, -LINE_TO, 2, 11, -R_H_LINE_TO, 1.56f, -R_LINE_TO, 0.78f, -2.14f, -R_H_LINE_TO, 4.33f, -LINE_TO, 9.44f, 11, -H_LINE_TO, 11, -LINE_TO, 7.2f, 1, -H_LINE_TO, 5.81f, -CLOSE, -R_MOVE_TO, -0.95f, 6.43f, -R_LINE_TO, 1.65f, -4.52f, -R_LINE_TO, 1.65f, 4.52f, -H_LINE_TO, 4.85f, +CANVAS_DIMENSIONS, 16, +MOVE_TO, 13, 1, +H_LINE_TO, 3, +R_CUBIC_TO, -0.6f, 0, -1, 0.4f, -1, 1, +R_V_LINE_TO, 12, +R_CUBIC_TO, 0, 0.6f, 0.4f, 1, 1, 1, +R_H_LINE_TO, 10, +R_CUBIC_TO, 0.6f, 0, 1, -0.4f, 1, -1, +V_LINE_TO, 2, +R_CUBIC_TO, 0, -0.6f, -0.4f, -1, -1, -1, +CLOSE, +R_MOVE_TO, -1, 12, +H_LINE_TO, 4, +V_LINE_TO, 3, +R_H_LINE_TO, 1, +R_V_LINE_TO, 6, +R_LINE_TO, 2, -1.1f, +LINE_TO, 9, 9, +V_LINE_TO, 3, +R_H_LINE_TO, 3, +R_V_LINE_TO, 10, CLOSE
diff --git a/components/omnibox/browser/vector_icons/answer_when_is.icon b/components/omnibox/browser/vector_icons/answer_when_is.icon index afc2d935..ea8a42bf 100644 --- a/components/omnibox/browser/vector_icons/answer_when_is.icon +++ b/components/omnibox/browser/vector_icons/answer_when_is.icon
@@ -1,25 +1,33 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Source: time_16px.svg --> SVGOMG --> Skiafy - -CANVAS_DIMENSIONS, 16, -MOVE_TO, 8, 0, -ARC_TO, 7.99f, 7.99f, 0, 0, 0, 0, 8, -R_CUBIC_TO, 0, 4.42f, 3.58f, 8, 8, 8, -R_ARC_TO, 8, 8, 0, 1, 0, 0, -16, -CLOSE, -MOVE_TO, 8, 14, -R_CUBIC_TO, -3.31f, 0, -6, -2.68f, -6, -6, -R_CUBIC_TO, 0, -3.32f, 2.69f, -6, 6, -6, -R_CUBIC_TO, 3.31f, 0, 6, 2.69f, 6, 6, -R_CUBIC_TO, 0, 3.31f, -2.68f, 6, -6, 6, -CLOSE, -MOVE_TO, 8, 5, -H_LINE_TO, 7, -R_V_LINE_TO, 3.93f, -LINE_TO, 10.5f, 11, -R_LINE_TO, 0.5f, -0.81f, -R_LINE_TO, -3, -1.75f, -CLOSE +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Source: calendar_16px.svg --> SVGOMG --> Skiafy +// Appearance Description: A calendar marking one day with a circle. + +CANVAS_DIMENSIONS, 16, +CIRCLE, 10, 10, 2, +MOVE_TO, 13.7f, 2, +H_LINE_TO, 13, +V_LINE_TO, 1, +R_H_LINE_TO, -2, +R_V_LINE_TO, 1, +H_LINE_TO, 5, +V_LINE_TO, 1, +H_LINE_TO, 3, +R_V_LINE_TO, 1, +R_H_LINE_TO, -0.7f, +CUBIC_TO, 1.6f, 2, 1, 2.6f, 1, 3.3f, +R_V_LINE_TO, 10.3f, +R_CUBIC_TO, 0, 0.8f, 0.6f, 1.4f, 1.3f, 1.4f, +R_H_LINE_TO, 11.3f, +R_CUBIC_TO, 0.7f, 0, 1.3f, -0.6f, 1.3f, -1.3f, +V_LINE_TO, 3.3f, +R_CUBIC_TO, 0.1f, -0.7f, -0.5f, -1.3f, -1.2f, -1.3f, +CLOSE, +MOVE_TO, 13, 13, +H_LINE_TO, 3, +V_LINE_TO, 5, +R_H_LINE_TO, 10, +R_V_LINE_TO, 8, +CLOSE
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index bc9134a..b6fa8404 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -2097,10 +2097,15 @@ # with the windows 8 sdk it does the wrong thing. "__ATLHOST_H__", ] + sources += [ + "media/system_media_controls_notifier.cc", + "media/system_media_controls_notifier.h", + ] deps += [ "//third_party/blink/public/common:font_unique_name_table_proto", "//third_party/iaccessible2", "//third_party/isimpledom", + "//ui/base/win/system_media_controls", ] libs += [ "comctl32.lib",
diff --git a/content/browser/accessibility/accessibility_action_browsertest.cc b/content/browser/accessibility/accessibility_action_browsertest.cc index d7fcd7f..925da66 100644 --- a/content/browser/accessibility/accessibility_action_browsertest.cc +++ b/content/browser/accessibility/accessibility_action_browsertest.cc
@@ -591,4 +591,99 @@ } } +IN_PROC_BROWSER_TEST_F(AccessibilityActionBrowserTest, + AriaControlsChangedEvent) { + NavigateToURL(shell(), GURL(url::kAboutBlankURL)); + + AccessibilityNotificationWaiter waiter(shell()->web_contents(), + ui::kAXModeComplete, + ax::mojom::Event::kLoadComplete); + GURL url( + "data:text/html," + "<body>" + "<script>" + "function setcontrols(ele, event) {" + " ele.setAttribute('aria-controls', 'radio1 radio2');" + "}" + "</script>" + "<div id='radiogroup' role='radiogroup' aria-label='group'" + " onclick='setcontrols(this, event)'>" + "<div id='radio1' role='radio'>radio1</div>" + "<div id='radio2' role='radio'>radio2</div>" + "</div>" + "</body>"); + NavigateToURL(shell(), url); + waiter.WaitForNotification(); + + BrowserAccessibility* target = + FindNode(ax::mojom::Role::kRadioGroup, "group"); + ASSERT_NE(nullptr, target); + BrowserAccessibility* radio1 = + FindNode(ax::mojom::Role::kRadioButton, "radio1"); + ASSERT_NE(nullptr, radio1); + BrowserAccessibility* radio2 = + FindNode(ax::mojom::Role::kRadioButton, "radio2"); + ASSERT_NE(nullptr, radio2); + + AccessibilityNotificationWaiter waiter2( + shell()->web_contents(), ui::kAXModeComplete, + ui::AXEventGenerator::Event::CONTROLS_CHANGED); + GetManager()->DoDefaultAction(*target); + waiter2.WaitForNotification(); + + auto&& control_list = target->GetData().GetIntListAttribute( + ax::mojom::IntListAttribute::kControlsIds); + EXPECT_EQ(2u, control_list.size()); + + auto find_radio1 = + std::find(control_list.cbegin(), control_list.cend(), radio1->GetId()); + auto find_radio2 = + std::find(control_list.cbegin(), control_list.cend(), radio2->GetId()); + EXPECT_NE(find_radio1, control_list.cend()); + EXPECT_NE(find_radio2, control_list.cend()); +} + +IN_PROC_BROWSER_TEST_F(AccessibilityActionBrowserTest, FocusLostOnDeletedNode) { + NavigateToURL(shell(), GURL(url::kAboutBlankURL)); + + GURL url( + "data:text/html," + "<button id='1'>1</button>" + "<iframe id='iframe' srcdoc=\"" + "<button id='2'>2</button>" + "\"></iframe>"); + + NavigateToURL(shell(), url); + EnableAccessibilityForWebContents(shell()->web_contents()); + + auto FocusNodeAndReload = [this, &url](const std::string& node_name, + const std::string& focus_node_script) { + WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(), + node_name); + BrowserAccessibility* node = FindNode(ax::mojom::Role::kButton, node_name); + ASSERT_NE(nullptr, node); + + EXPECT_TRUE(ExecuteScript(shell(), focus_node_script)); + WaitForAccessibilityFocusChange(); + + EXPECT_EQ(node->GetId(), + GetFocusedAccessibilityNodeInfo(shell()->web_contents()).id); + + // Reloading the frames will achieve two things: + // 1. Force the deletion of the node being tested. + // 2. Lose focus on the node by focusing a new frame. + AccessibilityNotificationWaiter load_waiter( + shell()->web_contents(), ui::kAXModeComplete, + ax::mojom::Event::kLoadComplete); + NavigateToURL(shell(), url); + load_waiter.WaitForNotification(); + }; + + FocusNodeAndReload("1", "document.getElementById('1').focus();"); + FocusNodeAndReload("2", + "var iframe = document.getElementById('iframe');" + "var inner_doc = iframe.contentWindow.document;" + "inner_doc.getElementById('2').focus();"); +} + } // namespace content
diff --git a/content/browser/accessibility/accessibility_tree_formatter_blink.cc b/content/browser/accessibility/accessibility_tree_formatter_blink.cc index 9905afa0..ecbc5a0 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_blink.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_blink.cc
@@ -223,8 +223,8 @@ dict->SetInteger("boundsWidth", bounds.width()); dict->SetInteger("boundsHeight", bounds.height()); - bool offscreen = false; - gfx::Rect page_bounds = node.GetPageBoundsRect(&offscreen); + ui::AXOffscreenResult offscreen_result = ui::AXOffscreenResult::kOnscreen; + gfx::Rect page_bounds = node.GetClippedRootFrameBoundsRect(&offscreen_result); dict->SetInteger("pageBoundsX", page_bounds.x()); dict->SetInteger("pageBoundsY", page_bounds.y()); dict->SetInteger("pageBoundsWidth", page_bounds.width()); @@ -234,7 +234,8 @@ node.GetData().relative_bounds.transform && !node.GetData().relative_bounds.transform->IsIdentity()); - gfx::Rect unclipped_bounds = node.GetPageBoundsRect(&offscreen, false); + gfx::Rect unclipped_bounds = + node.GetUnclippedRootFrameBoundsRect(&offscreen_result); dict->SetInteger("unclippedBoundsX", unclipped_bounds.x()); dict->SetInteger("unclippedBoundsY", unclipped_bounds.y()); dict->SetInteger("unclippedBoundsWidth", unclipped_bounds.width()); @@ -248,7 +249,7 @@ dict->SetBoolean(ui::ToString(state), true); } - if (offscreen) + if (offscreen_result == ui::AXOffscreenResult::kOffscreen) dict->SetBoolean(STATE_OFFSCREEN, true); for (int32_t attr_index =
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index cd47876..baf9f95 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -351,56 +351,117 @@ return GetData().html_attributes; } -gfx::Rect BrowserAccessibility::GetFrameBoundsRect() const { - return RelativeToAbsoluteBounds(gfx::RectF(), true); +gfx::Rect BrowserAccessibility::GetClippedScreenBoundsRect( + ui::AXOffscreenResult* offscreen_result) const { + return GetBoundsRect(ui::AXCoordinateSystem::kScreen, + ui::AXClippingBehavior::kClipped, offscreen_result); } -gfx::Rect BrowserAccessibility::GetPageBoundsRect(bool* offscreen, - bool clip_bounds) const { - return RelativeToAbsoluteBounds(gfx::RectF(), false, offscreen, clip_bounds); +gfx::Rect BrowserAccessibility::GetUnclippedScreenBoundsRect( + ui::AXOffscreenResult* offscreen_result) const { + return GetBoundsRect(ui::AXCoordinateSystem::kScreen, + ui::AXClippingBehavior::kUnclipped, offscreen_result); } -gfx::Rect BrowserAccessibility::GetTextRangeBoundsRect( - int start_offset, - int end_offset, - ui::AXPlatformNodeDelegate::TextRangeBoundsCoordinateSystem - coordinate_system) const { +gfx::Rect BrowserAccessibility::GetClippedRootFrameBoundsRect( + ui::AXOffscreenResult* offscreen_result) const { + return GetBoundsRect(ui::AXCoordinateSystem::kRootFrame, + ui::AXClippingBehavior::kClipped, offscreen_result); +} + +gfx::Rect BrowserAccessibility::GetUnclippedRootFrameBoundsRect( + ui::AXOffscreenResult* offscreen_result) const { + return GetBoundsRect(ui::AXCoordinateSystem::kRootFrame, + ui::AXClippingBehavior::kUnclipped, offscreen_result); +} + +gfx::Rect BrowserAccessibility::GetClippedFrameBoundsRect( + ui::AXOffscreenResult* offscreen_result) const { + return GetBoundsRect(ui::AXCoordinateSystem::kFrame, + ui::AXClippingBehavior::kUnclipped, offscreen_result); +} + +gfx::Rect BrowserAccessibility::GetUnclippedScreenRangeBoundsRect( + const int start_offset, + const int end_offset, + ui::AXOffscreenResult* offscreen_result) const { + return GetRangeBoundsRect( + start_offset, end_offset, ui::AXCoordinateSystem::kScreen, + ui::AXClippingBehavior::kUnclipped, offscreen_result); +} + +gfx::Rect BrowserAccessibility::GetUnclippedRootFrameRangeBoundsRect( + const int start_offset, + const int end_offset, + ui::AXOffscreenResult* offscreen_result) const { + return GetRangeBoundsRect( + start_offset, end_offset, ui::AXCoordinateSystem::kRootFrame, + ui::AXClippingBehavior::kUnclipped, offscreen_result); +} + +gfx::Rect BrowserAccessibility::GetBoundsRect( + const ui::AXCoordinateSystem coordinate_system, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result) const { + return RelativeToAbsoluteBounds(gfx::RectF(), coordinate_system, + clipping_behavior, offscreen_result); +} + +gfx::Rect BrowserAccessibility::GetRangeBoundsRect( + const int start_offset, + const int end_offset, + const ui::AXCoordinateSystem coordinate_system, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result) const { + int effective_start_offset = start_offset; + int effective_end_offset = end_offset; + + if (effective_start_offset == effective_end_offset) + return gfx::Rect(); + if (effective_start_offset > effective_end_offset) + std::swap(effective_start_offset, effective_end_offset); + const base::string16& text_str = GetText(); - if (start_offset == end_offset) + if (effective_start_offset < 0 || + effective_start_offset >= static_cast<int>(text_str.size())) return gfx::Rect(); - - if (start_offset > end_offset) - std::swap(start_offset, end_offset); - - if (start_offset < 0 || start_offset >= static_cast<int>(text_str.size())) - return gfx::Rect(); - if (end_offset < 0 || end_offset > static_cast<int>(text_str.size())) + if (effective_end_offset < 0 || + effective_end_offset > static_cast<int>(text_str.size())) return gfx::Rect(); switch (coordinate_system) { - case ui::AXPlatformNodeDelegate::TextRangeBoundsCoordinateSystem::Screen: - return GetScreenBoundsForRange(start_offset, end_offset - start_offset); - case ui::AXPlatformNodeDelegate::Window: - return GetPageBoundsForRange(start_offset, end_offset - start_offset); - case ui::AXPlatformNodeDelegate::Parent: - if (!PlatformGetParent()) - return gfx::Rect(); - return GetPageBoundsForRange(start_offset, end_offset - start_offset) - - PlatformGetParent()->GetPageBoundsRect().OffsetFromOrigin(); + case ui::AXCoordinateSystem::kScreen: { + gfx::Rect bounds = GetRootFrameRangeBoundsRect( + effective_start_offset, effective_end_offset - effective_start_offset, + clipping_behavior, offscreen_result); + bounds.Offset(manager_->GetViewBounds().OffsetFromOrigin()); + return bounds; + } + case ui::AXCoordinateSystem::kRootFrame: + return GetRootFrameRangeBoundsRect( + effective_start_offset, effective_end_offset - effective_start_offset, + clipping_behavior, offscreen_result); + case ui::AXCoordinateSystem::kFrame: + NOTIMPLEMENTED(); + return gfx::Rect(); } } -gfx::Rect BrowserAccessibility::GetPageBoundsForRange(int start, - int len, - bool clipped) const { +gfx::Rect BrowserAccessibility::GetRootFrameRangeBoundsRect( + int start, + int len, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result) const { DCHECK_GE(start, 0); DCHECK_GE(len, 0); // Standard text fields such as textarea have an embedded div inside them that // holds all the text. // TODO(nektar): This is fragile! Replace with code that flattens tree. - if (IsPlainTextField() && InternalChildCount() == 1) - return InternalGetChild(0)->GetPageBoundsForRange(start, len); + if (IsPlainTextField() && InternalChildCount() == 1) { + return InternalGetChild(0)->GetRootFrameRangeBoundsRect( + start, len, clipping_behavior, offscreen_result); + } if (GetRole() != ax::mojom::Role::kStaticText) { gfx::Rect bounds; @@ -414,10 +475,12 @@ if (start < child_length_in_parent) { gfx::Rect child_rect; if (child->IsTextOnlyObject()) { - child_rect = child->GetPageBoundsForRange(start, len); + child_rect = child->GetRootFrameRangeBoundsRect( + start, len, clipping_behavior, offscreen_result); } else { - child_rect = child->GetPageBoundsForRange( - 0, static_cast<int>(child->GetText().size())); + child_rect = child->GetRootFrameRangeBoundsRect( + 0, static_cast<int>(child->GetText().size()), clipping_behavior, + offscreen_result); } bounds.Union(child_rect); len -= (child_length_in_parent - start); @@ -429,7 +492,9 @@ } // When past the end of text, the area will be 0. // In this case, use bounds provided for the caret. - return bounds.IsEmpty() ? GetPageBoundsPastEndOfText() : bounds; + return bounds.IsEmpty() ? GetRootFrameBoundsPastEndOfText(clipping_behavior, + offscreen_result) + : bounds; } int end = start + len; @@ -516,8 +581,8 @@ // Don't clip bounds. Some screen magnifiers (e.g. ZoomText) prefer to // get unclipped bounds so that they can make smooth scrolling calculations. gfx::Rect absolute_child_rect = child->RelativeToAbsoluteBounds( - child_overlap_rect, false /* frame_only */, nullptr /* offscreen */, - clipped /* clip_bounds */); + child_overlap_rect, ui::AXCoordinateSystem::kRootFrame, + clipping_behavior, offscreen_result); if (bounds.width() == 0 && bounds.height() == 0) { bounds = absolute_child_rect; } else { @@ -528,10 +593,13 @@ return bounds; } -gfx::Rect BrowserAccessibility::GetScreenBoundsForRange(int start, - int len, - bool clipped) const { - gfx::Rect bounds = GetPageBoundsForRange(start, len, clipped); +gfx::Rect BrowserAccessibility::GetScreenRangeBoundsRect( + int start, + int len, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result) const { + gfx::Rect bounds = GetRootFrameRangeBoundsRect(start, len, clipping_behavior, + offscreen_result); // Adjust the bounds by the top left corner of the containing view's bounds // in screen coordinates. @@ -540,10 +608,9 @@ return bounds; } -// Get a rect for a 1-width character past the end of text. This is what ATs -// expect when getting the character extents past the last character in a line, -// and equals what the caret bounds would be when past the end of the text. -gfx::Rect BrowserAccessibility::GetPageBoundsPastEndOfText() const { +gfx::Rect BrowserAccessibility::GetRootFrameBoundsPastEndOfText( + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result) const { // Step 1: get approximate caret bounds. The thickness may not yet be correct. gfx::Rect bounds; if (InternalChildCount() > 0) { @@ -551,12 +618,14 @@ // available, and then correct for thickness of caret. BrowserAccessibility* child = InternalGetChild(InternalChildCount() - 1); int child_text_len = child->GetText().size(); - bounds = child->GetPageBoundsForRange(child_text_len, child_text_len); + bounds = child->GetRootFrameRangeBoundsRect( + child_text_len, child_text_len, clipping_behavior, offscreen_result); if (bounds.width() == 0 && bounds.height() == 0) return bounds; // Inline text boxes info not yet available. } else { // Compute bounds of where caret would be, based on bounds of object. - bounds = GetPageBoundsRect(); + bounds = GetBoundsRect(ui::AXCoordinateSystem::kRootFrame, + clipping_behavior, offscreen_result); } // Step 2: correct for the thickness of the caret. @@ -928,13 +997,16 @@ gfx::Rect BrowserAccessibility::RelativeToAbsoluteBounds( gfx::RectF bounds, - bool frame_only, - bool* offscreen, - bool clip_bounds) const { + const ui::AXCoordinateSystem coordinate_system, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result) const { + const bool clip_bounds = + clipping_behavior == ui::AXClippingBehavior::kClipped; + bool offscreen = false; const BrowserAccessibility* node = this; while (node) { bounds = node->manager()->ax_tree()->RelativeToTreeBounds( - node->node(), bounds, offscreen, clip_bounds); + node->node(), bounds, &offscreen, clip_bounds); // On some platforms we need to unapply root scroll offsets. const BrowserAccessibility* root = node->manager()->GetRoot(); @@ -948,19 +1020,28 @@ } } - if (frame_only) + if (coordinate_system == ui::AXCoordinateSystem::kFrame) break; node = root->PlatformGetParent(); } + if (coordinate_system == ui::AXCoordinateSystem::kScreen) + bounds.Offset(manager()->GetViewBounds().OffsetFromOrigin()); + + if (offscreen_result) { + *offscreen_result = offscreen ? ui::AXOffscreenResult::kOffscreen + : ui::AXOffscreenResult::kOnscreen; + } + return gfx::ToEnclosingRect(bounds); } bool BrowserAccessibility::IsOffscreen() const { - bool offscreen = false; - RelativeToAbsoluteBounds(gfx::RectF(), false, &offscreen); - return offscreen; + ui::AXOffscreenResult offscreen_result = ui::AXOffscreenResult::kOnscreen; + RelativeToAbsoluteBounds(gfx::RectF(), ui::AXCoordinateSystem::kRootFrame, + ui::AXClippingBehavior::kClipped, &offscreen_result); + return offscreen_result == ui::AXOffscreenResult::kOffscreen; } bool BrowserAccessibility::IsWebContent() const { @@ -1154,26 +1235,6 @@ return child->GetNativeViewAccessible(); } -gfx::Rect BrowserAccessibility::GetClippedScreenBoundsRect() const { - gfx::Rect bounds = GetPageBoundsRect(nullptr, true); - - // Adjust the bounds by the top left corner of the containing view's bounds - // in screen coordinates. - bounds.Offset(manager_->GetViewBounds().OffsetFromOrigin()); - - return bounds; -} - -gfx::Rect BrowserAccessibility::GetUnclippedScreenBoundsRect() const { - gfx::Rect bounds = GetPageBoundsRect(nullptr, false); - - // Adjust the bounds by the top left corner of the containing view's bounds - // in screen coordinates. - bounds.Offset(manager_->GetViewBounds().OffsetFromOrigin()); - - return bounds; -} - gfx::NativeViewAccessible BrowserAccessibility::HitTestSync(int x, int y) { auto* accessible = manager_->CachingAsyncHitTest(gfx::Point(x, y)); if (!accessible)
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h index 2d07fcf..b4b9189e 100644 --- a/content/browser/accessibility/browser_accessibility.h +++ b/content/browser/accessibility/browser_accessibility.h
@@ -159,33 +159,46 @@ // Returns nullptr if there are no children. BrowserAccessibility* InternalDeepestLastChild() const; - // Returns the bounds of this object in coordinates relative to this frame. - gfx::Rect GetFrameBoundsRect() const; + // Derivative utils for AXPlatformNodeDelegate::GetBoundsRect + gfx::Rect GetClippedScreenBoundsRect( + ui::AXOffscreenResult* offscreen_result = nullptr) const; + gfx::Rect GetUnclippedScreenBoundsRect( + ui::AXOffscreenResult* offscreen_result = nullptr) const; + gfx::Rect GetClippedRootFrameBoundsRect( + ui::AXOffscreenResult* offscreen_result = nullptr) const; + gfx::Rect GetUnclippedRootFrameBoundsRect( + ui::AXOffscreenResult* offscreen_result = nullptr) const; + gfx::Rect GetClippedFrameBoundsRect( + ui::AXOffscreenResult* offscreen_result = nullptr) const; - // Returns the bounds of this object in coordinates relative to the - // page (specifically, the top-left corner of the topmost web contents). - // Optionally updates |offscreen| to be true if the element is offscreen - // within its page. Clips bounds by default unless |clip_bounds| is false. - gfx::Rect GetPageBoundsRect(bool* offscreen = nullptr, - bool clip_bounds = true) const; + // Derivative utils for AXPlatformNodeDelegate::GetRangeBoundsRect + gfx::Rect GetUnclippedScreenRangeBoundsRect( + const int start_offset, + const int end_offset, + ui::AXOffscreenResult* offscreen_result = nullptr) const; + gfx::Rect GetUnclippedRootFrameRangeBoundsRect( + const int start_offset, + const int end_offset, + ui::AXOffscreenResult* offscreen_result = nullptr) const; + + // DEPRECATED: Prefer using the interfaces provided by AXPlatformNodeDelegate + // when writing new code. + gfx::Rect GetScreenRangeBoundsRect( + int start, + int len, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result = nullptr) const; // Returns the bounds of the given range in coordinates relative to the - // top-left corner of the overall web area. Only valid when the - // role is WebAXRoleStaticText. - gfx::Rect GetPageBoundsForRange(int start, - int len, - bool clipped = false) const; - - // Convert a bounding rectangle from this node's coordinate system - // (which is relative to its nearest scrollable ancestor) to - // absolute bounds, either in page coordinates (when |frameOnly| is - // false), or in frame coordinates (when |frameOnly| is true). - // Updates optional |offscreen| to be true if the node is offscreen. - // If |clip_bounds| is set to false, will return unclipped bounds. - virtual gfx::Rect RelativeToAbsoluteBounds(gfx::RectF bounds, - bool frame_only, - bool* offscreen = nullptr, - bool clip_bounds = true) const; + // top-left corner of the overall web area. Only valid when the role is + // WebAXRoleStaticText. + // DEPRECATED (for public use): Prefer using the interfaces provided by + // AXPlatformNodeDelegate when writing new non-private code. + gfx::Rect GetRootFrameRangeBoundsRect( + int start, + int len, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result = nullptr) const; // This is to handle the cases such as ARIA textbox, where the value should // be calculated from the object's inner text. @@ -355,16 +368,16 @@ gfx::NativeViewAccessible GetParent() override; int GetChildCount() override; gfx::NativeViewAccessible ChildAtIndex(int index) override; - gfx::Rect GetClippedScreenBoundsRect() const override; - gfx::Rect GetUnclippedScreenBoundsRect() const override; - gfx::Rect GetScreenBoundsForRange(int start, - int len, - bool clipped = false) const override; - gfx::Rect GetTextRangeBoundsRect( - int start_offset, - int end_offset, - ui::AXPlatformNodeDelegate::TextRangeBoundsCoordinateSystem - coordinate_system) const override; + gfx::Rect GetBoundsRect( + const ui::AXCoordinateSystem coordinate_system, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result = nullptr) const override; + gfx::Rect GetRangeBoundsRect( + const int start_offset, + const int end_offset, + const ui::AXCoordinateSystem coordinate_system, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result = nullptr) const override; gfx::NativeViewAccessible HitTestSync(int x, int y) override; gfx::NativeViewAccessible GetFocus() override; ui::AXPlatformNode* GetFromNodeID(int32_t id) override; @@ -457,7 +470,27 @@ // text, depending on the platform. base::string16 GetInnerText() const; - gfx::Rect GetPageBoundsPastEndOfText() const; + // Return the bounds after converting from this node's coordinate system + // (which is relative to its nearest scrollable ancestor) to the coordinate + // system specified. If the clipping behavior is set to clipped, clipping is + // applied to all bounding boxes so that the resulting rect is within the + // window. If the clipping behavior is unclipped, the resulting rect may be + // outside of the window or offscreen. If an offscreen result address is + // provided, it will be populated depending on whether the returned bounding + // box is onscreen or offscreen. + gfx::Rect RelativeToAbsoluteBounds( + gfx::RectF bounds, + const ui::AXCoordinateSystem coordinate_system, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result) const; + + // Return a rect for a 1-width character past the end of text. This is what + // ATs expect when getting the character extents past the last character in a + // line, and equals what the caret bounds would be when past the end of the + // text. + gfx::Rect GetRootFrameBoundsPastEndOfText( + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result = nullptr) const; // Given a set of node ids, return the nodes in this delegate's tree to // which they correspond.
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc index 761b7832..1e076ad 100644 --- a/content/browser/accessibility/browser_accessibility_android.cc +++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -1215,18 +1215,18 @@ // If this is a web area inside of an iframe, try to use the bounds of // the containing element. BrowserAccessibility* parent = PlatformGetParent(); - while (parent && (parent->GetPageBoundsRect().width() == 0 || - parent->GetPageBoundsRect().height() == 0)) { + while (parent && (parent->GetClippedRootFrameBoundsRect().width() == 0 || + parent->GetClippedRootFrameBoundsRect().height() == 0)) { parent = parent->PlatformGetParent(); } if (parent) - bounds = parent->GetPageBoundsRect(); + bounds = parent->GetClippedRootFrameBoundsRect(); else - bounds = GetPageBoundsRect(); + bounds = GetClippedRootFrameBoundsRect(); } else { // Otherwise this is something like a scrollable div, just use the // bounds of this object itself. - bounds = GetPageBoundsRect(); + bounds = GetClippedRootFrameBoundsRect(); } // Scroll by 80% of one page. @@ -1526,7 +1526,7 @@ CHECK_EQ(ax::mojom::Role::kInlineTextBox, child->GetRole()); // TODO(dmazzoni): replace this with a proper API to determine // if two inline text boxes are on the same line. http://crbug.com/421771 - int y = child->GetPageBoundsRect().y(); + int y = child->GetClippedRootFrameBoundsRect().y(); if (i == 0) { line_starts->push_back(offset); } else if (y != last_y) {
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index 864129f..5759578 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -1517,7 +1517,7 @@ - (NSPoint)origin { if (![self instanceActive]) return NSMakePoint(0, 0); - gfx::Rect bounds = owner_->GetPageBoundsRect(); + gfx::Rect bounds = owner_->GetClippedRootFrameBoundsRect(); return NSMakePoint(bounds.x(), bounds.y()); } @@ -2063,7 +2063,7 @@ - (NSValue*)size { if (![self instanceActive]) return nil; - gfx::Rect bounds = owner_->GetPageBoundsRect(); + gfx::Rect bounds = owner_->GetClippedRootFrameBoundsRect(); return [NSValue valueWithSize:NSMakeSize(bounds.width(), bounds.height())]; } @@ -2675,7 +2675,7 @@ return nil; NSRange range = [(NSValue*)parameter rangeValue]; gfx::Rect rect = - owner_->GetScreenBoundsForRange(range.location, range.length); + owner_->GetUnclippedScreenRangeBoundsRect(range.location, range.length); NSRect nsrect = [self rectInScreen:rect]; return [NSValue valueWithRect:nsrect]; } @@ -2734,7 +2734,7 @@ DCHECK_GE(startOffset, 0); DCHECK_GE(endOffset, 0); - gfx::Rect rect = BrowserAccessibilityManager::GetPageBoundsForRange( + gfx::Rect rect = BrowserAccessibilityManager::GetRootFrameRangeBoundsRect( *startObject, startOffset, *endObject, endOffset); NSRect nsrect = [self rectInScreen:rect]; return [NSValue valueWithRect:nsrect];
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc index 42141e7..b9f2412 100644 --- a/content/browser/accessibility/browser_accessibility_com_win.cc +++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -186,10 +186,10 @@ *x = bounds.x(); *y = bounds.y(); } else if (coordinate_type == IA2_COORDTYPE_PARENT_RELATIVE) { - gfx::Rect bounds = owner()->GetPageBoundsRect(); + gfx::Rect bounds = owner()->GetClippedRootFrameBoundsRect(); gfx::Rect parent_bounds = owner()->PlatformGetParent() - ? owner()->PlatformGetParent()->GetPageBoundsRect() + ? owner()->PlatformGetParent()->GetClippedRootFrameBoundsRect() : gfx::Rect(); *x = bounds.x() - parent_bounds.x(); *y = bounds.y() - parent_bounds.y(); @@ -209,8 +209,8 @@ if (!height || !width) return E_INVALIDARG; - *height = owner()->GetPageBoundsRect().height(); - *width = owner()->GetPageBoundsRect().width(); + *height = owner()->GetClippedRootFrameBoundsRect().height(); + *width = owner()->GetClippedRootFrameBoundsRect().width(); return S_OK; } @@ -249,13 +249,15 @@ gfx::Rect character_bounds; if (coordinate_type == IA2_COORDTYPE_SCREEN_RELATIVE) { - character_bounds = owner()->GetScreenBoundsForRange(offset, 1); + character_bounds = owner()->GetScreenRangeBoundsRect( + offset, 1, ui::AXClippingBehavior::kUnclipped); } else if (coordinate_type == IA2_COORDTYPE_PARENT_RELATIVE) { - character_bounds = owner()->GetPageBoundsForRange(offset, 1); + character_bounds = owner()->GetRootFrameRangeBoundsRect( + offset, 1, ui::AXClippingBehavior::kUnclipped); if (owner()->PlatformGetParent()) { character_bounds -= owner() ->PlatformGetParent() - ->GetPageBoundsRect(nullptr, false) + ->GetUnclippedRootFrameBoundsRect() .OffsetFromOrigin(); } } else { @@ -532,10 +534,10 @@ LONG length = end_index - start_index + 1; DCHECK_GE(length, 0); - gfx::Rect string_bounds = owner()->GetPageBoundsForRange(start_index, length); - + gfx::Rect string_bounds = owner()->GetRootFrameRangeBoundsRect( + start_index, length, ui::AXClippingBehavior::kUnclipped); string_bounds -= - owner()->GetPageBoundsRect(nullptr, false).OffsetFromOrigin(); + owner()->GetUnclippedRootFrameBoundsRect().OffsetFromOrigin(); x -= string_bounds.x(); y -= string_bounds.y(); @@ -1476,8 +1478,8 @@ return E_INVALIDARG; } - gfx::Rect bounds = - owner()->GetScreenBoundsForRange(start_index, end_index - start_index); + gfx::Rect bounds = owner()->GetScreenRangeBoundsRect( + start_index, end_index - start_index, ui::AXClippingBehavior::kUnclipped); *out_x = bounds.x(); *out_y = bounds.y(); *out_width = bounds.width(); @@ -1506,7 +1508,8 @@ manager->ScrollToMakeVisible( *owner(), - owner()->GetPageBoundsForRange(start_index, end_index - start_index)); + owner()->GetRootFrameRangeBoundsRect(start_index, end_index - start_index, + ui::AXClippingBehavior::kUnclipped)); return S_OK; }
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc index d785b61..5d26862 100644 --- a/content/browser/accessibility/browser_accessibility_manager.cc +++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -156,8 +156,6 @@ factory_(factory), tree_(new ui::AXSerializableTree()), user_is_navigating_away_(false), - last_focused_node_(nullptr), - last_focused_manager_(nullptr), connected_to_parent_tree_node_(false), ax_tree_id_(ui::AXTreeIDUnknown()), device_scale_factor_(1.0f), @@ -174,8 +172,6 @@ factory_(factory), tree_(new ui::AXSerializableTree()), user_is_navigating_away_(false), - last_focused_node_(nullptr), - last_focused_manager_(nullptr), ax_tree_id_(ui::AXTreeIDUnknown()), device_scale_factor_(1.0f), use_custom_device_scale_factor_for_testing_(false), @@ -214,6 +210,13 @@ false; // static +base::Optional<int32_t> BrowserAccessibilityManager::last_focused_node_id_ = {}; + +// static +base::Optional<ui::AXTreeID> + BrowserAccessibilityManager::last_focused_node_tree_id_ = {}; + +// static ui::AXTreeUpdate BrowserAccessibilityManager::GetEmptyDocument() { ui::AXNodeData empty_document; empty_document.id = 0; @@ -247,15 +250,14 @@ focus = nullptr; } - if (focus != last_focused_node_) { - if (last_focused_node_) - OnFocusLost(last_focused_node_); + BrowserAccessibility* last_focused_node = GetLastFocusedNode(); + if (focus != last_focused_node) { + if (last_focused_node) + OnFocusLost(last_focused_node); if (focus) FireFocusEvent(focus); } - - last_focused_node_ = focus; - last_focused_manager_ = focus ? focus->manager() : nullptr; + SetLastFocusedNode(focus); } bool BrowserAccessibilityManager::CanFireEvents() { @@ -343,10 +345,8 @@ } void BrowserAccessibilityManager::OnWindowBlurred() { - if (IsRootTree()) { - last_focused_node_ = nullptr; - last_focused_manager_ = nullptr; - } + if (IsRootTree()) + SetLastFocusedNode(nullptr); } void BrowserAccessibilityManager::UserIsNavigatingAway() { @@ -402,7 +402,8 @@ } // If this page is hidden by an interstitial, suppress all events. - if (GetRootManager()->hidden_by_interstitial_page()) { + BrowserAccessibilityManager* root_manager = GetRootManager(); + if (root_manager->hidden_by_interstitial_page()) { event_generator_.ClearEvents(); return; } @@ -425,7 +426,7 @@ // Screen readers might not do the right thing if they're not aware of what // has focus, so always try that first. Nothing will be fired if the window // itself isn't focused or if focus hasn't changed. - GetRootManager()->FireFocusEventsIfNeeded(); + root_manager->FireFocusEventsIfNeeded(); // Fire any events related to changes to the tree. for (auto targeted_event : event_generator_) { @@ -457,7 +458,7 @@ continue; if (event.event_type == ax::mojom::Event::kHover) - GetRootManager()->CacheHitTestResult(event_target); + root_manager->CacheHitTestResult(event_target); FireBlinkEvent(event.event_type, event_target); } @@ -1090,7 +1091,7 @@ } // static -gfx::Rect BrowserAccessibilityManager::GetPageBoundsForRange( +gfx::Rect BrowserAccessibilityManager::GetRootFrameRangeBoundsRect( const BrowserAccessibility& start_object, int start_offset, const BrowserAccessibility& end_object, @@ -1107,8 +1108,9 @@ return gfx::Rect(); } - return start_object.GetPageBoundsForRange(start_offset, - end_offset - start_offset); + return start_object.GetRootFrameRangeBoundsRect( + start_offset, end_offset - start_offset, + ui::AXClippingBehavior::kUnclipped); } gfx::Rect result; @@ -1137,10 +1139,11 @@ start_char_index = start_offset; if (current == last) end_char_index = end_offset; - result.Union(current->GetPageBoundsForRange( - start_char_index, end_char_index - start_char_index)); + result.Union(current->GetRootFrameRangeBoundsRect( + start_char_index, end_char_index - start_char_index, + ui::AXClippingBehavior::kUnclipped)); } else { - result.Union(current->GetPageBoundsRect()); + result.Union(current->GetClippedRootFrameBoundsRect()); } if (current == last) @@ -1156,12 +1159,10 @@ ui::AXNode* node) { DCHECK(node); if (BrowserAccessibility* wrapper = GetFromAXNode(node)) { - if (wrapper == last_focused_node_) { - last_focused_node_ = nullptr; - last_focused_manager_ = nullptr; - } - wrapper->Destroy(); + if (wrapper == GetLastFocusedNode()) + SetLastFocusedNode(nullptr); id_wrapper_map_.erase(node->id()); + wrapper->Destroy(); } } @@ -1204,6 +1205,12 @@ ui::AXTree* tree, bool root_changed, const std::vector<ui::AXTreeObserver::Change>& changes) { + // When the root changes and this is the root manager, we may need to + // fire a new focus event. + if (root_changed && last_focused_node_tree_id_ && + ax_tree_id_ == last_focused_node_tree_id_.value()) + SetLastFocusedNode(nullptr); + bool ax_tree_id_changed = false; if (GetTreeData().tree_id != ui::AXTreeIDUnknown() && GetTreeData().tree_id != ax_tree_id_) { @@ -1218,13 +1225,6 @@ // we're properly connected. if (ax_tree_id_changed || root_changed) connected_to_parent_tree_node_ = false; - - // When the root changes and this is the root manager, we may need to - // fire a new focus event. - if (root_changed && last_focused_manager_ == this) { - last_focused_node_ = nullptr; - last_focused_manager_ = nullptr; - } } ui::AXNode* BrowserAccessibilityManager::GetNodeFromTree(ui::AXTreeID tree_id, @@ -1274,6 +1274,30 @@ return delegate()->AccessibilityIsMainFrame(); } +// static +void BrowserAccessibilityManager::SetLastFocusedNode( + BrowserAccessibility* node) { + if (node) { + DCHECK(node->manager()); + last_focused_node_id_ = node->GetId(); + last_focused_node_tree_id_ = node->manager()->ax_tree_id(); + } else { + last_focused_node_id_.reset(); + last_focused_node_tree_id_.reset(); + } +} + +// static +BrowserAccessibility* BrowserAccessibilityManager::GetLastFocusedNode() { + if (last_focused_node_id_) { + DCHECK(last_focused_node_tree_id_); + if (BrowserAccessibilityManager* last_focused_manager = + FromID(last_focused_node_tree_id_.value())) + return last_focused_manager->GetFromID(last_focused_node_id_.value()); + } + return nullptr; +} + ui::AXTreeUpdate BrowserAccessibilityManager::SnapshotAXTreeForTesting() { std::unique_ptr< ui::AXTreeSource<const ui::AXNode*, ui::AXNodeData, ui::AXTreeData>>
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h index 3bc89525..b1e8eaf 100644 --- a/content/browser/accessibility/browser_accessibility_manager.h +++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -361,7 +361,7 @@ const BrowserAccessibility& end_object, int end_offset); - static gfx::Rect GetPageBoundsForRange( + static gfx::Rect GetRootFrameRangeBoundsRect( const BrowserAccessibility& start_object, int start_offset, const BrowserAccessibility& end_object, @@ -431,6 +431,9 @@ virtual void SendLocationChangeEvents( const std::vector<AccessibilityHostMsg_LocationChangeParams>& params); + static void SetLastFocusedNode(BrowserAccessibility* node); + static BrowserAccessibility* GetLastFocusedNode(); + protected: // The object that can perform actions on our behalf. BrowserAccessibilityDelegate* delegate_; @@ -453,16 +456,6 @@ BrowserAccessibilityFindInPageInfo find_in_page_info_; - // These are only used by the root BrowserAccessibilityManager of a - // frame tree. Stores the last focused node and last focused manager so - // that when focus might have changed we can figure out whether we need - // to fire a focus event. - // - // NOTE: these pointers are not cleared, so they should never be - // dereferenced, only used for comparison. - BrowserAccessibility* last_focused_node_; - BrowserAccessibilityManager* last_focused_manager_; - // These cache the AX tree ID, node ID, and global screen bounds of the // last object found by an asynchronous hit test. Subsequent hit test // requests that remain within this object's bounds will return the same @@ -496,6 +489,15 @@ // flakiness. See NeverSuppressOrDelayEventsForTesting() for details. static bool never_suppress_or_delay_events_for_testing_; + // Stores the id of the last focused node across all frames, as well as the id + // of the tree that contains it, so that when focus might have changed we can + // figure out whether we need to fire a focus event. + // + // NOTE: Don't use or modify these properties directly, use the + // SetLastFocusedNode and GetLastFocusedNode methods instead. + static base::Optional<int32_t> last_focused_node_id_; + static base::Optional<ui::AXTreeID> last_focused_node_tree_id_; + private: DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManager); };
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc index 3b0d41b..3d6729e7 100644 --- a/content/browser/accessibility/browser_accessibility_manager_android.cc +++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -202,6 +202,7 @@ case ui::AXEventGenerator::Event::CHILDREN_CHANGED: case ui::AXEventGenerator::Event::CLASS_NAME_CHANGED: case ui::AXEventGenerator::Event::COLLAPSED: + case ui::AXEventGenerator::Event::CONTROLS_CHANGED: case ui::AXEventGenerator::Event::DESCRIBED_BY_CHANGED: case ui::AXEventGenerator::Event::DESCRIPTION_CHANGED: case ui::AXEventGenerator::Event::DOCUMENT_TITLE_CHANGED:
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm index a66ff87..21de0d4 100644 --- a/content/browser/accessibility/browser_accessibility_manager_mac.mm +++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -374,6 +374,7 @@ case ui::AXEventGenerator::Event::ACCESS_KEY_CHANGED: case ui::AXEventGenerator::Event::AUTO_COMPLETE_CHANGED: case ui::AXEventGenerator::Event::CHILDREN_CHANGED: + case ui::AXEventGenerator::Event::CONTROLS_CHANGED: case ui::AXEventGenerator::Event::CLASS_NAME_CHANGED: case ui::AXEventGenerator::Event::DESCRIBED_BY_CHANGED: case ui::AXEventGenerator::Event::DESCRIPTION_CHANGED:
diff --git a/content/browser/accessibility/browser_accessibility_manager_unittest.cc b/content/browser/accessibility/browser_accessibility_manager_unittest.cc index 4ac2bbc..0d2fddd 100644 --- a/content/browser/accessibility/browser_accessibility_manager_unittest.cc +++ b/content/browser/accessibility/browser_accessibility_manager_unittest.cc
@@ -634,28 +634,49 @@ ASSERT_NE(nullptr, static_text_accessible); EXPECT_EQ(gfx::Rect(100, 100, 6, 9).ToString(), - static_text_accessible->GetPageBoundsForRange(0, 1).ToString()); + static_text_accessible + ->GetRootFrameRangeBoundsRect( + 0, 1, ui::AXClippingBehavior::kUnclipped) + .ToString()); EXPECT_EQ(gfx::Rect(100, 100, 26, 9).ToString(), - static_text_accessible->GetPageBoundsForRange(0, 5).ToString()); + static_text_accessible + ->GetRootFrameRangeBoundsRect( + 0, 5, ui::AXClippingBehavior::kUnclipped) + .ToString()); EXPECT_EQ(gfx::Rect(100, 109, 5, 9).ToString(), - static_text_accessible->GetPageBoundsForRange(7, 1).ToString()); + static_text_accessible + ->GetRootFrameRangeBoundsRect( + 7, 1, ui::AXClippingBehavior::kUnclipped) + .ToString()); EXPECT_EQ(gfx::Rect(100, 109, 25, 9).ToString(), - static_text_accessible->GetPageBoundsForRange(7, 5).ToString()); + static_text_accessible + ->GetRootFrameRangeBoundsRect( + 7, 5, ui::AXClippingBehavior::kUnclipped) + .ToString()); EXPECT_EQ(gfx::Rect(100, 100, 29, 18).ToString(), - static_text_accessible->GetPageBoundsForRange(5, 3).ToString()); + static_text_accessible + ->GetRootFrameRangeBoundsRect( + 5, 3, ui::AXClippingBehavior::kUnclipped) + .ToString()); EXPECT_EQ(gfx::Rect(100, 100, 29, 18).ToString(), - static_text_accessible->GetPageBoundsForRange(0, 13).ToString()); + static_text_accessible + ->GetRootFrameRangeBoundsRect( + 0, 13, ui::AXClippingBehavior::kUnclipped) + .ToString()); // Note that each child in the parent element is represented by a single // embedded object character and not by its text. // TODO(nektar): Investigate failure on Linux. EXPECT_EQ(gfx::Rect(100, 100, 29, 18).ToString(), - root_accessible->GetPageBoundsForRange(0, 13).ToString()); + root_accessible + ->GetRootFrameRangeBoundsRect( + 0, 13, ui::AXClippingBehavior::kUnclipped) + .ToString()); } TEST_F(BrowserAccessibilityManagerTest, BoundsForRangeMultiElement) { @@ -718,50 +739,50 @@ // The first line. EXPECT_EQ(gfx::Rect(0, 20, 33, 9).ToString(), manager - ->GetPageBoundsForRange(*static_text_accessible, 0, - *static_text_accessible, 3) + ->GetRootFrameRangeBoundsRect(*static_text_accessible, 0, + *static_text_accessible, 3) .ToString()); // Part of the first line. EXPECT_EQ(gfx::Rect(0, 20, 21, 9).ToString(), manager - ->GetPageBoundsForRange(*static_text_accessible, 0, - *static_text_accessible, 2) + ->GetRootFrameRangeBoundsRect(*static_text_accessible, 0, + *static_text_accessible, 2) .ToString()); // Part of the first line. EXPECT_EQ(gfx::Rect(10, 20, 23, 9).ToString(), manager - ->GetPageBoundsForRange(*static_text_accessible, 1, - *static_text_accessible, 3) + ->GetRootFrameRangeBoundsRect(*static_text_accessible, 1, + *static_text_accessible, 3) .ToString()); // The second line. EXPECT_EQ(gfx::Rect(10, 40, 33, 9).ToString(), manager - ->GetPageBoundsForRange(*static_text_accessible2, 0, - *static_text_accessible2, 3) + ->GetRootFrameRangeBoundsRect(*static_text_accessible2, 0, + *static_text_accessible2, 3) .ToString()); // All of both lines. EXPECT_EQ(gfx::Rect(0, 20, 43, 29).ToString(), manager - ->GetPageBoundsForRange(*static_text_accessible, 0, - *static_text_accessible2, 3) + ->GetRootFrameRangeBoundsRect(*static_text_accessible, 0, + *static_text_accessible2, 3) .ToString()); // Part of both lines. EXPECT_EQ(gfx::Rect(10, 20, 23, 29).ToString(), manager - ->GetPageBoundsForRange(*static_text_accessible, 2, - *static_text_accessible2, 1) + ->GetRootFrameRangeBoundsRect(*static_text_accessible, 2, + *static_text_accessible2, 1) .ToString()); // Part of both lines in reverse order. EXPECT_EQ(gfx::Rect(10, 20, 23, 29).ToString(), manager - ->GetPageBoundsForRange(*static_text_accessible2, 1, - *static_text_accessible, 2) + ->GetRootFrameRangeBoundsRect(*static_text_accessible2, 1, + *static_text_accessible, 2) .ToString()); } @@ -771,8 +792,9 @@ // words, on-screen it would look like "123cba". This is possible to // achieve if the source string had unicode control characters // to switch directions. This test doesn't worry about how, though - it just - // tests that if something like that were to occur, GetPageBoundsForRange - // returns the correct bounds for different ranges. + // tests that if something like that were to occur, + // GetRootFrameRangeBoundsRect returns the correct bounds for different + // ranges. ui::AXNodeData root; root.id = 1; @@ -827,24 +849,42 @@ ASSERT_NE(nullptr, static_text_accessible); EXPECT_EQ(gfx::Rect(100, 100, 60, 20).ToString(), - static_text_accessible->GetPageBoundsForRange(0, 6).ToString()); + static_text_accessible + ->GetRootFrameRangeBoundsRect( + 0, 6, ui::AXClippingBehavior::kUnclipped) + .ToString()); EXPECT_EQ(gfx::Rect(100, 100, 10, 20).ToString(), - static_text_accessible->GetPageBoundsForRange(0, 1).ToString()); + static_text_accessible + ->GetRootFrameRangeBoundsRect( + 0, 1, ui::AXClippingBehavior::kUnclipped) + .ToString()); EXPECT_EQ(gfx::Rect(100, 100, 30, 20).ToString(), - static_text_accessible->GetPageBoundsForRange(0, 3).ToString()); + static_text_accessible + ->GetRootFrameRangeBoundsRect( + 0, 3, ui::AXClippingBehavior::kUnclipped) + .ToString()); EXPECT_EQ(gfx::Rect(150, 100, 10, 20).ToString(), - static_text_accessible->GetPageBoundsForRange(3, 1).ToString()); + static_text_accessible + ->GetRootFrameRangeBoundsRect( + 3, 1, ui::AXClippingBehavior::kUnclipped) + .ToString()); EXPECT_EQ(gfx::Rect(130, 100, 30, 20).ToString(), - static_text_accessible->GetPageBoundsForRange(3, 3).ToString()); + static_text_accessible + ->GetRootFrameRangeBoundsRect( + 3, 3, ui::AXClippingBehavior::kUnclipped) + .ToString()); // This range is only two characters, but because of the direction switch // the bounds are as wide as four characters. EXPECT_EQ(gfx::Rect(120, 100, 40, 20).ToString(), - static_text_accessible->GetPageBoundsForRange(2, 2).ToString()); + static_text_accessible + ->GetRootFrameRangeBoundsRect( + 2, 2, ui::AXClippingBehavior::kUnclipped) + .ToString()); } TEST_F(BrowserAccessibilityManagerTest, BoundsForRangeScrolledWindow) { @@ -890,10 +930,16 @@ if (manager->UseRootScrollOffsetsWhenComputingBounds()) { EXPECT_EQ(gfx::Rect(75, 50, 16, 9).ToString(), - static_text_accessible->GetPageBoundsForRange(0, 3).ToString()); + static_text_accessible + ->GetRootFrameRangeBoundsRect( + 0, 3, ui::AXClippingBehavior::kUnclipped) + .ToString()); } else { EXPECT_EQ(gfx::Rect(100, 100, 16, 9).ToString(), - static_text_accessible->GetPageBoundsForRange(0, 3).ToString()); + static_text_accessible + ->GetRootFrameRangeBoundsRect( + 0, 3, ui::AXClippingBehavior::kUnclipped) + .ToString()); } } @@ -968,22 +1014,40 @@ ASSERT_NE(nullptr, div_accessible); EXPECT_EQ(gfx::Rect(100, 100, 20, 20).ToString(), - div_accessible->GetPageBoundsForRange(0, 1).ToString()); + div_accessible + ->GetRootFrameRangeBoundsRect( + 0, 1, ui::AXClippingBehavior::kUnclipped) + .ToString()); EXPECT_EQ(gfx::Rect(100, 100, 40, 20).ToString(), - div_accessible->GetPageBoundsForRange(0, 2).ToString()); + div_accessible + ->GetRootFrameRangeBoundsRect( + 0, 2, ui::AXClippingBehavior::kUnclipped) + .ToString()); EXPECT_EQ(gfx::Rect(100, 100, 80, 20).ToString(), - div_accessible->GetPageBoundsForRange(0, 4).ToString()); + div_accessible + ->GetRootFrameRangeBoundsRect( + 0, 4, ui::AXClippingBehavior::kUnclipped) + .ToString()); EXPECT_EQ(gfx::Rect(120, 100, 60, 20).ToString(), - div_accessible->GetPageBoundsForRange(1, 3).ToString()); + div_accessible + ->GetRootFrameRangeBoundsRect( + 1, 3, ui::AXClippingBehavior::kUnclipped) + .ToString()); EXPECT_EQ(gfx::Rect(120, 100, 80, 20).ToString(), - div_accessible->GetPageBoundsForRange(1, 4).ToString()); + div_accessible + ->GetRootFrameRangeBoundsRect( + 1, 4, ui::AXClippingBehavior::kUnclipped) + .ToString()); EXPECT_EQ(gfx::Rect(100, 100, 100, 20).ToString(), - div_accessible->GetPageBoundsForRange(0, 5).ToString()); + div_accessible + ->GetRootFrameRangeBoundsRect( + 0, 5, ui::AXClippingBehavior::kUnclipped) + .ToString()); } TEST_F(BrowserAccessibilityManagerTest, TestNextPreviousInTreeOrder) {
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc index bd5ae4f..994bcae6 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.cc +++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -127,6 +127,12 @@ case ax::mojom::Event::kScrolledToAnchor: FireWinAccessibilityEvent(EVENT_SYSTEM_SCROLLINGSTART, node); break; + case ax::mojom::Event::kTextChanged: + FireUiaTextContainerEvent(UIA_Text_TextChangedEventId, node); + break; + case ax::mojom::Event::kTextSelectionChanged: + FireUiaTextContainerEvent(UIA_Text_TextSelectionChangedEventId, node); + break; default: break; } @@ -178,6 +184,9 @@ FireUiaPropertyChangedEvent( UIA_ExpandCollapseExpandCollapseStatePropertyId, node); break; + case ui::AXEventGenerator::Event::CONTROLS_CHANGED: + FireUiaPropertyChangedEvent(UIA_ControllerForPropertyId, node); + break; case ui::AXEventGenerator::Event::DESCRIBED_BY_CHANGED: FireUiaPropertyChangedEvent(UIA_DescribedByPropertyId, node); break; @@ -381,6 +390,21 @@ } } +void BrowserAccessibilityManagerWin::FireUiaTextContainerEvent( + LONG uia_event, + BrowserAccessibility* node) { + // If the node supports text pattern, fire the event from itself, otherwise, + // fire the event from the closest ancestor that supports text pattern. + while (node) { + if (ToBrowserAccessibilityWin(node)->GetCOM()->IsPatternProviderSupported( + UIA_TextPatternId)) { + FireUiaAccessibilityEvent(uia_event, node); + return; + } + node = node->PlatformGetParent(); + } +} + bool BrowserAccessibilityManagerWin::CanFireEvents() { if (!BrowserAccessibilityManager::CanFireEvents()) return false;
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.h b/content/browser/accessibility/browser_accessibility_manager_win.h index 3d337f6..ed3b9c9 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.h +++ b/content/browser/accessibility/browser_accessibility_manager_win.h
@@ -58,6 +58,7 @@ void FireUiaAccessibilityEvent(LONG uia_event, BrowserAccessibility* node); void FireUiaPropertyChangedEvent(LONG uia_property, BrowserAccessibility* node); + void FireUiaTextContainerEvent(LONG uia_event, BrowserAccessibility* node); // Track this object and post a VISIBLE_DATA_CHANGED notification when // its container scrolls.
diff --git a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc index f4ce89ed..cebad7e 100644 --- a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc +++ b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
@@ -19,6 +19,7 @@ #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/render_widget_host_view.h" +#include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/shell/browser/shell.h" @@ -70,6 +71,26 @@ void TearDownOnMainThread() override; protected: + void LoadInitialAccessibilityTreeFromUrl( + const GURL& url, + ui::AXMode accessibility_mode = ui::kAXModeComplete) { + AccessibilityNotificationWaiter waiter(shell()->web_contents(), + accessibility_mode, + ax::mojom::Event::kLoadComplete); + NavigateToURL(shell(), url); + waiter.WaitForNotification(); + } + + void LoadInitialAccessibilityTreeFromHtmlFilePath( + const std::string& html_file_path, + ui::AXMode accessibility_mode = ui::kAXModeComplete) { + if (!embedded_test_server()->Started()) + ASSERT_TRUE(embedded_test_server()->Start()); + ASSERT_TRUE(embedded_test_server()->Started()); + LoadInitialAccessibilityTreeFromUrl( + embedded_test_server()->GetURL(html_file_path), accessibility_mode); + } + BrowserAccessibilityManager* GetManager() { WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(shell()->web_contents()); @@ -604,4 +625,109 @@ GetAttr(input2, StringAttribute::kPlaceholder).c_str()); } +// On Android root scroll offset is handled by the Java layer. The final rect +// bounds is device specific. +#ifndef OS_ANDROID +IN_PROC_BROWSER_TEST_F(CrossPlatformAccessibilityBrowserTest, + GetBoundsRectUnclippedRootFrameFromIFrame) { + // Start by loading a document with iframes. + LoadInitialAccessibilityTreeFromHtmlFilePath( + "/accessibility/html/iframe-padding.html"); + WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(), + "Second Button"); + + // Get the delegate for the iframe leaf of the top-level accessibility tree + // for the second iframe. + BrowserAccessibilityManager* browser_accessibility_manager = GetManager(); + ASSERT_NE(nullptr, browser_accessibility_manager); + BrowserAccessibility* root_browser_accessibility = + browser_accessibility_manager->GetRoot(); + ASSERT_NE(nullptr, root_browser_accessibility); + BrowserAccessibility* leaf_iframe_browser_accessibility = + root_browser_accessibility->InternalDeepestLastChild(); + ASSERT_NE(nullptr, leaf_iframe_browser_accessibility); + ASSERT_EQ(ax::mojom::Role::kIframe, + leaf_iframe_browser_accessibility->GetRole()); + + // The frame coordinates of the iframe node within the top-level tree is + // relative to the top level frame. That is why the top-level default padding + // is included. + ASSERT_EQ(gfx::Rect(30, 230, 300, 100).ToString(), + leaf_iframe_browser_accessibility + ->GetBoundsRect(ui::AXCoordinateSystem::kRootFrame, + ui::AXClippingBehavior::kUnclipped) + .ToString()); + + // Now get the root delegate of the iframe's accessibility tree. + AXTreeID iframe_tree_id = AXTreeID::FromString( + leaf_iframe_browser_accessibility->GetStringAttribute( + ax::mojom::StringAttribute::kChildTreeId)); + BrowserAccessibilityManager* iframe_browser_accessibility_manager = + BrowserAccessibilityManager::FromID(iframe_tree_id); + ASSERT_NE(nullptr, iframe_browser_accessibility_manager); + BrowserAccessibility* root_iframe_browser_accessibility = + iframe_browser_accessibility_manager->GetRoot(); + ASSERT_NE(nullptr, root_iframe_browser_accessibility); + ASSERT_EQ(ax::mojom::Role::kRootWebArea, + root_iframe_browser_accessibility->GetRole()); + + // The root frame bounds of the iframe are still relative to the top-level + // frame. + ASSERT_EQ(gfx::Rect(30, 230, 300, 100).ToString(), + root_iframe_browser_accessibility + ->GetBoundsRect(ui::AXCoordinateSystem::kRootFrame, + ui::AXClippingBehavior::kUnclipped) + .ToString()); +} + +IN_PROC_BROWSER_TEST_F(CrossPlatformAccessibilityBrowserTest, + GetBoundsRectUnclippedFrameFromIFrame) { + // Start by loading a document with iframes. + LoadInitialAccessibilityTreeFromHtmlFilePath( + "/accessibility/html/iframe-padding.html"); + WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(), + "Second Button"); + + // Get the delegate for the iframe leaf of the top-level accessibility tree + // for the second iframe. + BrowserAccessibilityManager* browser_accessibility_manager = GetManager(); + ASSERT_NE(nullptr, browser_accessibility_manager); + BrowserAccessibility* root_browser_accessibility = + browser_accessibility_manager->GetRoot(); + ASSERT_NE(nullptr, root_browser_accessibility); + BrowserAccessibility* leaf_iframe_browser_accessibility = + root_browser_accessibility->InternalDeepestLastChild(); + ASSERT_NE(nullptr, leaf_iframe_browser_accessibility); + ASSERT_EQ(ax::mojom::Role::kIframe, + leaf_iframe_browser_accessibility->GetRole()); + + // The frame coordinates of the iframe node within the top-level tree is + // relative to the top level frame. + ASSERT_EQ(gfx::Rect(30, 230, 300, 100).ToString(), + leaf_iframe_browser_accessibility + ->GetBoundsRect(ui::AXCoordinateSystem::kFrame, + ui::AXClippingBehavior::kUnclipped) + .ToString()); + + // Now get the root delegate of the iframe's accessibility tree. + AXTreeID iframe_tree_id = AXTreeID::FromString( + leaf_iframe_browser_accessibility->GetStringAttribute( + ax::mojom::StringAttribute::kChildTreeId)); + BrowserAccessibilityManager* iframe_browser_accessibility_manager = + BrowserAccessibilityManager::FromID(iframe_tree_id); + ASSERT_NE(nullptr, iframe_browser_accessibility_manager); + BrowserAccessibility* root_iframe_browser_accessibility = + iframe_browser_accessibility_manager->GetRoot(); + ASSERT_NE(nullptr, root_iframe_browser_accessibility); + ASSERT_EQ(ax::mojom::Role::kRootWebArea, + root_iframe_browser_accessibility->GetRole()); + + // The frame bounds of the iframe are now relative to itself. + ASSERT_EQ(gfx::Rect(0, 0, 300, 100).ToString(), + root_iframe_browser_accessibility + ->GetBoundsRect(ui::AXCoordinateSystem::kFrame, + ui::AXClippingBehavior::kUnclipped) + .ToString()); +} +#endif } // namespace content
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc index 8531dfe..3827cbf 100644 --- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -241,6 +241,11 @@ } IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest, + AccessibilityEventsAriaControlsChanged) { + RunEventTest(FILE_PATH_LITERAL("aria-controls-changed.html")); +} + +IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest, AccessibilityEventsAriaTreeCollapse) { RunEventTest(FILE_PATH_LITERAL("aria-tree-collapse.html")); } @@ -579,6 +584,11 @@ } IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest, + AccessibilityEventsTextSelectionChanged) { + RunEventTest(FILE_PATH_LITERAL("text-selection-changed.html")); +} + +IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest, AccessibilityEventsAriaCheckedChanged) { RunEventTest(FILE_PATH_LITERAL("aria-checked-changed.html")); }
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index 991047b..d0c4466 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -248,6 +248,10 @@ RunCSSTest(FILE_PATH_LITERAL("pseudo-element-alternative-text.html")); } +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityCSSDOMElements) { + RunCSSTest(FILE_PATH_LITERAL("dom-element-css-alternative-text.html")); +} + IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityCSSTableIncomplete) { RunCSSTest(FILE_PATH_LITERAL("table-incomplete.html"));
diff --git a/content/browser/accessibility/web_contents_accessibility_android.cc b/content/browser/accessibility/web_contents_accessibility_android.cc index af4cc7c..6dede06 100644 --- a/content/browser/accessibility/web_contents_accessibility_android.cc +++ b/content/browser/accessibility/web_contents_accessibility_android.cc
@@ -698,12 +698,13 @@ float dip_scale = use_zoom_for_dsf_enabled_ ? 1 / root_manager_->device_scale_factor() : 1.0; - gfx::Rect absolute_rect = gfx::ScaleToEnclosingRect(node->GetPageBoundsRect(), - dip_scale, dip_scale); + gfx::Rect absolute_rect = gfx::ScaleToEnclosingRect( + node->GetUnclippedRootFrameBoundsRect(), dip_scale, dip_scale); gfx::Rect parent_relative_rect = absolute_rect; if (node->PlatformGetParent()) { gfx::Rect parent_rect = gfx::ScaleToEnclosingRect( - node->PlatformGetParent()->GetPageBoundsRect(), dip_scale, dip_scale); + node->PlatformGetParent()->GetUnclippedRootFrameBoundsRect(), dip_scale, + dip_scale); parent_relative_rect.Offset(-parent_rect.OffsetFromOrigin()); } bool is_root = node->PlatformGetParent() == NULL; @@ -850,9 +851,10 @@ const JavaParamRef<jobject>& obj, jint unique_id) { BrowserAccessibilityAndroid* node = GetAXFromUniqueID(unique_id); - if (node) + if (node) { node->manager()->ScrollToMakeVisible( - *node, gfx::Rect(node->GetFrameBoundsRect().size())); + *node, gfx::Rect(node->GetClippedFrameBoundsRect().size())); + } } void WebContentsAccessibilityAndroid::SetTextFieldValue( @@ -1196,10 +1198,11 @@ return nullptr; } - gfx::Rect object_bounds = node->GetPageBoundsRect(); + gfx::Rect object_bounds = node->GetUnclippedRootFrameBoundsRect(); int coords[4 * len]; for (int i = 0; i < len; i++) { - gfx::Rect char_bounds = node->GetPageBoundsForRange(start + i, 1, false); + gfx::Rect char_bounds = node->GetRootFrameRangeBoundsRect( + start + i, 1, ui::AXClippingBehavior::kUnclipped); if (char_bounds.IsEmpty()) char_bounds = object_bounds; coords[4 * i + 0] = char_bounds.x();
diff --git a/content/browser/image_capture/OWNERS b/content/browser/image_capture/OWNERS index cc7f7bb..c261502 100644 --- a/content/browser/image_capture/OWNERS +++ b/content/browser/image_capture/OWNERS
@@ -1,7 +1,5 @@ +mcasas@chromium.org miu@chromium.org -# Original (legacy) owner. -mcasas@chromium.org - # COMPONENT: Blink>ImageCapture -# TEAM: webrtc-dev@chromium.org +# TEAM: media-dev@chromium.org
diff --git a/content/browser/loader/resource_loader_unittest.cc b/content/browser/loader/resource_loader_unittest.cc index f21530f..0f774df 100644 --- a/content/browser/loader/resource_loader_unittest.cc +++ b/content/browser/loader/resource_loader_unittest.cc
@@ -96,11 +96,12 @@ // net::ClientCertStore: void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info, - const ClientCertListCallback& callback) override { + ClientCertListCallback callback) override { *requested_authorities_ = cert_request_info.cert_authorities; ++(*request_count_); - callback.Run(net::FakeClientCertIdentityListFromCertificateList(response_)); + std::move(callback).Run( + net::FakeClientCertIdentityListFromCertificateList(response_)); } private: @@ -122,15 +123,14 @@ on_loader_deleted_callback_(on_loader_deleted_callback) {} // net::ClientCertStore: - void GetClientCerts( - const net::SSLCertRequestInfo& cert_request_info, - const ClientCertListCallback& cert_selected_callback) override { + void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info, + ClientCertListCallback cert_selected_callback) override { // Don't destroy |loader_| while it's on the stack. base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce(&LoaderDestroyingCertStore::DoCallback, - base::Unretained(loader_), cert_selected_callback, - on_loader_deleted_callback_)); + FROM_HERE, base::BindOnce(&LoaderDestroyingCertStore::DoCallback, + base::Unretained(loader_), + std::move(cert_selected_callback), + on_loader_deleted_callback_)); } private: @@ -138,10 +138,10 @@ // LoaderDestroyingCertStore (ClientCertStores are actually handles, and not // global cert stores). static void DoCallback(std::unique_ptr<ResourceLoader>* loader, - const ClientCertListCallback& cert_selected_callback, + ClientCertListCallback cert_selected_callback, const base::Closure& on_loader_deleted_callback) { loader->reset(); - cert_selected_callback.Run(net::ClientCertIdentityList()); + std::move(cert_selected_callback).Run(net::ClientCertIdentityList()); on_loader_deleted_callback.Run(); }
diff --git a/content/browser/media/media_keys_listener_manager_impl.cc b/content/browser/media/media_keys_listener_manager_impl.cc index 6e0472dc..9cfc9a2 100644 --- a/content/browser/media/media_keys_listener_manager_impl.cc +++ b/content/browser/media/media_keys_listener_manager_impl.cc
@@ -22,6 +22,10 @@ #include "ui/base/now_playing/now_playing_info_center_delegate.h" #endif +#if defined(OS_WIN) +#include "content/browser/media/system_media_controls_notifier.h" +#endif + namespace content { MediaKeysListenerManagerImpl::ListeningData::ListeningData() @@ -159,6 +163,12 @@ } #endif +#if defined(OS_WIN) + system_media_controls_notifier_ = + std::make_unique<SystemMediaControlsNotifier>(connector_); + system_media_controls_notifier_->Initialize(); +#endif // defined(OS_WIN) + auxiliary_services_started_ = true; }
diff --git a/content/browser/media/media_keys_listener_manager_impl.h b/content/browser/media/media_keys_listener_manager_impl.h index be19904..f37dd5f5 100644 --- a/content/browser/media/media_keys_listener_manager_impl.h +++ b/content/browser/media/media_keys_listener_manager_impl.h
@@ -28,6 +28,10 @@ class NowPlayingInfoCenterNotifier; #endif +#if defined(OS_WIN) +class SystemMediaControlsNotifier; +#endif // defined(OS_WIN) + // Listens for media keys and decides which listeners receive which events. In // particular, it owns one of its delegates (HardwareKeyMediaController), and // only propagates to the HardwareKeyMediaController if no other delegates are @@ -114,6 +118,10 @@ now_playing_info_center_notifier_; #endif +#if defined(OS_WIN) + std::unique_ptr<SystemMediaControlsNotifier> system_media_controls_notifier_; +#endif // defined(OS_WIN) + DISALLOW_COPY_AND_ASSIGN(MediaKeysListenerManagerImpl); };
diff --git a/content/browser/media/system_media_controls_notifier.cc b/content/browser/media/system_media_controls_notifier.cc new file mode 100644 index 0000000..2d701e2 --- /dev/null +++ b/content/browser/media/system_media_controls_notifier.cc
@@ -0,0 +1,75 @@ +// 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 "content/browser/media/system_media_controls_notifier.h" + +#include <memory> +#include <utility> + +#include "services/media_session/public/mojom/constants.mojom.h" +#include "services/media_session/public/mojom/media_session.mojom.h" +#include "services/service_manager/public/cpp/connector.h" +#include "ui/base/win/system_media_controls/system_media_controls_service.h" + +namespace content { + +using ABI::Windows::Media::MediaPlaybackStatus; + +SystemMediaControlsNotifier::SystemMediaControlsNotifier( + service_manager::Connector* connector) + : connector_(connector) {} + +SystemMediaControlsNotifier::~SystemMediaControlsNotifier() = default; + +void SystemMediaControlsNotifier::Initialize() { + // |service_| can be set in tests. + if (!service_) + service_ = system_media_controls::SystemMediaControlsService::GetInstance(); + + // |service_| can still be null if the current system does not support System + // Media Transport Controls. + if (!service_) + return; + + // |connector_| can be null in tests. + if (!connector_) + return; + + // Connect to the MediaControllerManager and create a MediaController that + // controls the active session so we can observe it. + media_session::mojom::MediaControllerManagerPtr controller_manager_ptr; + connector_->BindInterface(media_session::mojom::kServiceName, + mojo::MakeRequest(&controller_manager_ptr)); + controller_manager_ptr->CreateActiveMediaController( + mojo::MakeRequest(&media_controller_ptr_)); + + // Observe the active media controller for changes to playback state and + // supported actions. + media_session::mojom::MediaControllerObserverPtr media_controller_observer; + media_controller_observer_binding_.Bind( + mojo::MakeRequest(&media_controller_observer)); + media_controller_ptr_->AddObserver(std::move(media_controller_observer)); +} + +void SystemMediaControlsNotifier::MediaSessionInfoChanged( + media_session::mojom::MediaSessionInfoPtr session_info) { + DCHECK(service_); + + session_info_ = std::move(session_info); + if (session_info_) { + if (session_info_->playback_state == + media_session::mojom::MediaPlaybackState::kPlaying) { + service_->SetPlaybackStatus( + MediaPlaybackStatus::MediaPlaybackStatus_Playing); + } else { + service_->SetPlaybackStatus( + MediaPlaybackStatus::MediaPlaybackStatus_Paused); + } + } else { + service_->SetPlaybackStatus( + MediaPlaybackStatus::MediaPlaybackStatus_Stopped); + } +} + +} // namespace content
diff --git a/content/browser/media/system_media_controls_notifier.h b/content/browser/media/system_media_controls_notifier.h new file mode 100644 index 0000000..ed7bc8e --- /dev/null +++ b/content/browser/media/system_media_controls_notifier.h
@@ -0,0 +1,73 @@ +// 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 CONTENT_BROWSER_MEDIA_SYSTEM_MEDIA_CONTROLS_NOTIFIER_H_ +#define CONTENT_BROWSER_MEDIA_SYSTEM_MEDIA_CONTROLS_NOTIFIER_H_ + +#include <memory> +#include <vector> + +#include "content/common/content_export.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/media_session/public/mojom/media_controller.mojom.h" + +namespace system_media_controls { +class SystemMediaControlsService; +} // namespace system_media_controls + +namespace service_manager { +class Connector; +} // namespace service_manager + +namespace content { + +// The SystemMediaControlsNotifier connects to Window's "System Media Transport +// Controls" and keeps the OS informed of the current media playstate and +// metadata. It observes changes to the active Media Session and updates the +// SMTC accordingly. +class CONTENT_EXPORT SystemMediaControlsNotifier + : public media_session::mojom::MediaControllerObserver { + public: + explicit SystemMediaControlsNotifier(service_manager::Connector* connector); + ~SystemMediaControlsNotifier() override; + + void Initialize(); + + // media_session::mojom::MediaControllerObserver implementation. + void MediaSessionInfoChanged( + media_session::mojom::MediaSessionInfoPtr session_info) override; + void MediaSessionMetadataChanged( + const base::Optional<media_session::MediaMetadata>& metadata) override {} + void MediaSessionActionsChanged( + const std::vector<media_session::mojom::MediaSessionAction>& actions) + override {} + void MediaSessionChanged( + const base::Optional<base::UnguessableToken>& request_id) override {} + + void SetSystemMediaControlsServiceForTesting( + system_media_controls::SystemMediaControlsService* service) { + service_ = service; + } + + private: + // Our connection to Window's System Media Transport Controls. + system_media_controls::SystemMediaControlsService* service_ = nullptr; + + // used to connect to the Media Session service. + service_manager::Connector* connector_; + + // Tracks current media session state/metadata. + media_session::mojom::MediaControllerPtr media_controller_ptr_; + media_session::mojom::MediaSessionInfoPtr session_info_; + + // Used to receive updates to the active media controller. + mojo::Binding<media_session::mojom::MediaControllerObserver> + media_controller_observer_binding_{this}; + + DISALLOW_COPY_AND_ASSIGN(SystemMediaControlsNotifier); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_MEDIA_SYSTEM_MEDIA_CONTROLS_NOTIFIER_H_
diff --git a/content/browser/media/system_media_controls_notifier_unittest.cc b/content/browser/media/system_media_controls_notifier_unittest.cc new file mode 100644 index 0000000..ab90552 --- /dev/null +++ b/content/browser/media/system_media_controls_notifier_unittest.cc
@@ -0,0 +1,84 @@ +// 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 "content/browser/media/system_media_controls_notifier.h" + +#include <memory> +#include <utility> + +#include "services/media_session/public/mojom/media_session.mojom.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/win/system_media_controls/mock_system_media_controls_service.h" + +namespace content { + +using ABI::Windows::Media::MediaPlaybackStatus; +using media_session::mojom::MediaPlaybackState; +using media_session::mojom::MediaSessionInfo; +using media_session::mojom::MediaSessionInfoPtr; +using testing::Expectation; + +class SystemMediaControlsNotifierTest : public testing::Test { + public: + SystemMediaControlsNotifierTest() = default; + ~SystemMediaControlsNotifierTest() override = default; + + void SetUp() override { + notifier_ = + std::make_unique<SystemMediaControlsNotifier>(/*connector=*/nullptr); + notifier_->SetSystemMediaControlsServiceForTesting( + &mock_system_media_controls_service_); + notifier_->Initialize(); + } + + protected: + void SimulatePlaying() { + MediaSessionInfoPtr session_info(MediaSessionInfo::New()); + session_info->playback_state = MediaPlaybackState::kPlaying; + notifier_->MediaSessionInfoChanged(std::move(session_info)); + } + + void SimulatePaused() { + MediaSessionInfoPtr session_info(MediaSessionInfo::New()); + session_info->playback_state = MediaPlaybackState::kPaused; + notifier_->MediaSessionInfoChanged(std::move(session_info)); + } + + void SimulateStopped() { notifier_->MediaSessionInfoChanged(nullptr); } + + SystemMediaControlsNotifier& notifier() { return *notifier_; } + system_media_controls::testing::MockSystemMediaControlsService& + mock_system_media_controls_service() { + return mock_system_media_controls_service_; + } + + private: + std::unique_ptr<SystemMediaControlsNotifier> notifier_; + system_media_controls::testing::MockSystemMediaControlsService + mock_system_media_controls_service_; + + DISALLOW_COPY_AND_ASSIGN(SystemMediaControlsNotifierTest); +}; + +TEST_F(SystemMediaControlsNotifierTest, ProperlyUpdatesPlaybackState) { + Expectation playing = EXPECT_CALL( + mock_system_media_controls_service(), + SetPlaybackStatus(MediaPlaybackStatus::MediaPlaybackStatus_Playing)); + Expectation paused = + EXPECT_CALL( + mock_system_media_controls_service(), + SetPlaybackStatus(MediaPlaybackStatus::MediaPlaybackStatus_Paused)) + .After(playing); + EXPECT_CALL( + mock_system_media_controls_service(), + SetPlaybackStatus(MediaPlaybackStatus::MediaPlaybackStatus_Stopped)) + .After(paused); + + SimulatePlaying(); + SimulatePaused(); + SimulateStopped(); +} + +} // namespace content
diff --git a/content/browser/portal/portal.cc b/content/browser/portal/portal.cc index 8e5c70e..55dcb5cf 100644 --- a/content/browser/portal/portal.cc +++ b/content/browser/portal/portal.cc
@@ -101,12 +101,13 @@ if (!portal_contents_) { // Create the Portal WebContents. WebContents::CreateParams params(outer_contents_impl->GetBrowserContext()); - portal_contents_ = WebContents::Create(params); + SetPortalContents(WebContents::Create(params)); web_contents_created = true; } - portal_contents_impl_ = static_cast<WebContentsImpl*>(portal_contents_.get()); - portal_contents_impl_->set_portal(this); - portal_contents_impl_->SetDelegate(this); + + DCHECK_EQ(portal_contents_.get(), portal_contents_impl_); + DCHECK_EQ(portal_contents_impl_->portal(), this); + DCHECK_EQ(portal_contents_impl_->GetDelegate(), this); outer_contents_impl->AttachInnerWebContents(std::move(portal_contents_), outer_node->current_frame_host()); @@ -136,6 +137,7 @@ if (outer_contents->portal()) { mojo::ReportBadMessage("Portal::Activate called on nested portal"); + binding_->Close(); // Also deletes |this|. return; } @@ -144,19 +146,24 @@ std::unique_ptr<WebContents> portal_contents = portal_contents_impl_->DetachFromOuterWebContents(); - static_cast<RenderWidgetHostViewBase*>( - outer_contents->GetMainFrame()->GetView()) - ->Destroy(); - std::unique_ptr<WebContents> contents = delegate->SwapWebContents( - outer_contents, std::move(portal_contents), true, is_loading); - CHECK_EQ(contents.get(), outer_contents); + auto* outer_contents_main_frame_view = static_cast<RenderWidgetHostViewBase*>( + outer_contents->GetMainFrame()->GetView()); + if (outer_contents_main_frame_view) + outer_contents_main_frame_view->Destroy(); + std::unique_ptr<WebContents> predecessor_web_contents = + delegate->SwapWebContents(outer_contents, std::move(portal_contents), + true, is_loading); + CHECK_EQ(predecessor_web_contents.get(), outer_contents); + portal_contents_impl_->set_portal(nullptr); + blink::mojom::PortalAssociatedPtr portal_ptr; Portal* portal = Create(portal_contents_impl_->GetMainFrame(), mojo::MakeRequest(&portal_ptr)); + portal->SetPortalContents(std::move(predecessor_web_contents)); + portal_contents_impl_->GetMainFrame()->OnPortalActivated( portal->portal_token_, portal_ptr.PassInterface(), std::move(data)); - portal->portal_contents_ = std::move(contents); std::move(callback).Run(); } @@ -192,4 +199,11 @@ binding_ = binding; } +void Portal::SetPortalContents(std::unique_ptr<WebContents> web_contents) { + portal_contents_ = std::move(web_contents); + portal_contents_impl_ = static_cast<WebContentsImpl*>(portal_contents_.get()); + portal_contents_impl_->SetDelegate(this); + portal_contents_impl_->set_portal(this); +} + } // namespace content
diff --git a/content/browser/portal/portal.h b/content/browser/portal/portal.h index 96025cb3..5829af8 100644 --- a/content/browser/portal/portal.h +++ b/content/browser/portal/portal.h
@@ -88,6 +88,8 @@ private: explicit Portal(RenderFrameHostImpl* owner_render_frame_host); + void SetPortalContents(std::unique_ptr<WebContents> web_contents); + RenderFrameHostImpl* owner_render_frame_host_; // Uniquely identifies the portal, this token is used by the browser process
diff --git a/content/browser/renderer_host/media/OWNERS b/content/browser/renderer_host/media/OWNERS index 107a4d64..68a9bdc 100644 --- a/content/browser/renderer_host/media/OWNERS +++ b/content/browser/renderer_host/media/OWNERS
@@ -7,10 +7,8 @@ olka@chromium.org maxmorin@chromium.org +per-file *video*=mcasas@chromium.org per-file *video*=chfremer@chromium.org -# Original (legacy) owner. -per-file *video*=mcasas@chromium.org - +# TEAM: media-capture-and-streams@grotations.appspotmail.com # COMPONENT: Blink>GetUserMedia -# TEAM: webrtc-dev@chromium.org
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc index 4648ff8..b0ada0c 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -42,7 +42,7 @@ #if defined(OS_CHROMEOS) #include "chromeos/audio/cras_audio_handler.h" -#include "chromeos/dbus/cras_audio_client.h" +#include "chromeos/dbus/audio/cras_audio_client.h" #endif using ::testing::_;
diff --git a/content/browser/ssl/ssl_client_auth_handler.cc b/content/browser/ssl/ssl_client_auth_handler.cc index 29bafea..e2a1dbd 100644 --- a/content/browser/ssl/ssl_client_auth_handler.cc +++ b/content/browser/ssl/ssl_client_auth_handler.cc
@@ -98,7 +98,7 @@ // callback. client_cert_store_->GetClientCerts( *cert_request_info_, - base::Bind(&SSLClientAuthHandler::Core::DidGetClientCerts, this)); + base::BindOnce(&SSLClientAuthHandler::Core::DidGetClientCerts, this)); } else { DidGetClientCerts(net::ClientCertIdentityList()); }
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc index 2b0e315..4eeaaeb3 100644 --- a/content/browser/tracing/tracing_controller_impl.cc +++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -40,6 +40,7 @@ #include "services/service_manager/public/cpp/connector.h" #include "services/tracing/public/cpp/trace_event_agent.h" #include "services/tracing/public/cpp/traced_process_impl.h" +#include "services/tracing/public/cpp/tracing_features.h" #include "services/tracing/public/mojom/constants.mojom.h" #include "v8/include/v8-version-string.h" @@ -220,7 +221,7 @@ // this does not happen; however, if the service manager is teared down during // tracing, e.g. at Chrome shutdown, tracing controller may finish flushing // traces without waiting for tracing agents. - if (trace_config_) { + if (trace_config_ && !tracing::TracingUsesPerfettoBackend()) { DCHECK(IsTracing()); metadata_dict->SetString("trace-config", trace_config_->ToString()); }
diff --git a/content/browser/webrtc/OWNERS b/content/browser/webrtc/OWNERS index 106f113a..4002051 100644 --- a/content/browser/webrtc/OWNERS +++ b/content/browser/webrtc/OWNERS
@@ -1,12 +1,9 @@ chfremer@chromium.org emircan@chromium.org guidou@chromium.org +mcasas@chromium.org tommi@chromium.org per-file *test*=phoglund@chromium.org -# Original (legacy) owner. -mcasas@chromium.org - # COMPONENT: Blink>WebRTC -# TEAM: webrtc-dev@chromium.org
diff --git a/content/browser/webrtc/webrtc_content_browsertest_base.cc b/content/browser/webrtc/webrtc_content_browsertest_base.cc index a29cd1f..d13dc9b 100644 --- a/content/browser/webrtc/webrtc_content_browsertest_base.cc +++ b/content/browser/webrtc/webrtc_content_browsertest_base.cc
@@ -24,7 +24,7 @@ #if defined(OS_CHROMEOS) #include "chromeos/audio/cras_audio_handler.h" -#include "chromeos/dbus/cras_audio_client.h" +#include "chromeos/dbus/audio/cras_audio_client.h" #endif namespace content {
diff --git a/content/renderer/image_capture/OWNERS b/content/renderer/image_capture/OWNERS index ab8e7ba..57aa41f 100644 --- a/content/renderer/image_capture/OWNERS +++ b/content/renderer/image_capture/OWNERS
@@ -1,7 +1,5 @@ +mcasas@chromium.org reillyg@chromium.org -# Original (legacy) owner. -mcasas@chromium.org - # COMPONENT: Blink>ImageCapture -# TEAM: webrtc-dev@chromium.org +# TEAM: media-dev@chromium.org
diff --git a/content/renderer/media/stream/OWNERS b/content/renderer/media/stream/OWNERS index 32889cc..c205d4f9 100644 --- a/content/renderer/media/stream/OWNERS +++ b/content/renderer/media/stream/OWNERS
@@ -2,5 +2,5 @@ per-file media_stream_audio_processor*=aluebs@chromium.org -# TEAM: webrtc-dev@chromium.org +# TEAM: media-capture-and-streams@grotations.appspotmail.com # COMPONENT: Blink>GetUserMedia
diff --git a/content/renderer/media_capture_from_element/OWNERS b/content/renderer/media_capture_from_element/OWNERS index d176cccc..446f8fb0 100644 --- a/content/renderer/media_capture_from_element/OWNERS +++ b/content/renderer/media_capture_from_element/OWNERS
@@ -1,7 +1,4 @@ emircan@chromium.org - -# Original (legacy) owner. mcasas@chromium.org # COMPONENT: Blink>MediaStream>CaptureFromElement -# TEAM: webrtc-dev@chromium.org
diff --git a/content/renderer/media_recorder/OWNERS b/content/renderer/media_recorder/OWNERS index c6eb0c4..6675929 100644 --- a/content/renderer/media_recorder/OWNERS +++ b/content/renderer/media_recorder/OWNERS
@@ -1,7 +1,5 @@ emircan@chromium.org - -# Original (legacy) owner. mcasas@chromium.org # COMPONENT: Blink>MediaRecording -# TEAM: webrtc-dev@chromium.org +# TEAM: media-dev@chromium.org
diff --git a/content/shell/test_runner/accessibility_controller.cc b/content/shell/test_runner/accessibility_controller.cc index 3957b4a..97a8d9d 100644 --- a/content/shell/test_runner/accessibility_controller.cc +++ b/content/shell/test_runner/accessibility_controller.cc
@@ -260,7 +260,6 @@ blink::WebNode node = obj.GetNode(); if (!node.IsNull() && node.IsElementNode()) { blink::WebElement element = node.To<blink::WebElement>(); - element.GetAttribute("id"); if (element.GetAttribute("id") == id) return elements_.GetOrCreate(obj); } @@ -269,7 +268,7 @@ for (unsigned i = 0; i < childCount; i++) { v8::Local<v8::Object> result = FindAccessibleElementByIdRecursive(obj.ChildAt(i), id); - if (*result) + if (!result.IsEmpty()) return result; }
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 5052d6a..18455585 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1250,7 +1250,7 @@ deps += [ "//chromeos/audio", - # TODO(stevenjb): Replace with //chromeos/dbus/cras once extracted. + # TODO(stevenjb): Replace with //chromeos/dbus/audio once extracted. # https://crbug.com/940810. "//chromeos/dbus", ] @@ -2129,10 +2129,12 @@ } } if (is_win) { + sources += [ "../browser/media/system_media_controls_notifier_unittest.cc" ] deps += [ "//third_party/blink/public/common", "//third_party/blink/public/common:font_unique_name_table_proto", "//third_party/iaccessible2", + "//ui/base/win/system_media_controls:test_support", ] libs = [ "dwrite.lib", @@ -2156,7 +2158,7 @@ deps += [ "//chromeos/audio", - # TODO(stevenjb): Replace with //chromeos/dbus/cras once extracted. + # TODO(stevenjb): Replace with //chromeos/dbus/audio once extracted. # https://crbug.com/940810. "//chromeos/dbus", ]
diff --git a/content/test/DEPS b/content/test/DEPS index c4e0990..e743fb947 100644 --- a/content/test/DEPS +++ b/content/test/DEPS
@@ -13,7 +13,7 @@ # For WebRTC tests. "+chromeos/audio", - "+chromeos/dbus/cras_audio_client.h", + "+chromeos/dbus/audio", # Testing utilities can access anything in content/ "+content", "+device/bluetooth", # For WebBluetooth tests
diff --git a/content/test/data/accessibility/aria/aria-owns-expected-blink.txt b/content/test/data/accessibility/aria/aria-owns-expected-blink.txt index faf94dc..580d01f 100644 --- a/content/test/data/accessibility/aria/aria-owns-expected-blink.txt +++ b/content/test/data/accessibility/aria/aria-owns-expected-blink.txt
@@ -1,8 +1,8 @@ rootWebArea ++list ++++listItem +++++++listMarker name='• ' ++++++genericContainer -++++++++listMarker name='• ' ++++++++staticText name='One' ++++++++++inlineTextBox name='One' ++++listItem
diff --git a/content/test/data/accessibility/aria/aria-owns-expected-mac.txt b/content/test/data/accessibility/aria/aria-owns-expected-mac.txt index c2b9c52..4481ffe 100644 --- a/content/test/data/accessibility/aria/aria-owns-expected-mac.txt +++ b/content/test/data/accessibility/aria/aria-owns-expected-mac.txt
@@ -1,8 +1,8 @@ AXWebArea ++AXList ++++AXGroup +++++++AXListMarker AXValue='• ' ++++++AXGroup -++++++++AXListMarker AXValue='• ' ++++++++AXStaticText AXValue='One' ++++AXGroup ++++++AXListMarker AXValue='• '
diff --git a/content/test/data/accessibility/css/dom-element-css-alternative-text-expected-auralinux.txt b/content/test/data/accessibility/css/dom-element-css-alternative-text-expected-auralinux.txt new file mode 100644 index 0000000..1747a89 --- /dev/null +++ b/content/test/data/accessibility/css/dom-element-css-alternative-text-expected-auralinux.txt
@@ -0,0 +1,3 @@ +[document web] +++[section] +++++[image] name='alternative text'
diff --git a/content/test/data/accessibility/css/dom-element-css-alternative-text-expected-blink.txt b/content/test/data/accessibility/css/dom-element-css-alternative-text-expected-blink.txt new file mode 100644 index 0000000..ff1a61a --- /dev/null +++ b/content/test/data/accessibility/css/dom-element-css-alternative-text-expected-blink.txt
@@ -0,0 +1,3 @@ +rootWebArea +++genericContainer +++++image name='alternative text'
diff --git a/content/test/data/accessibility/css/dom-element-css-alternative-text.html b/content/test/data/accessibility/css/dom-element-css-alternative-text.html new file mode 100644 index 0000000..a0e2774 --- /dev/null +++ b/content/test/data/accessibility/css/dom-element-css-alternative-text.html
@@ -0,0 +1,14 @@ + +<!DOCTYPE html> +<html> +<head> + <style> + #element { + content: url(bullet.png) / "alternative text"; + } + </style> +</head> +<body> + <span id="element">DOM text</span> +</body> +</html>
diff --git a/content/test/data/accessibility/event/add-hidden-attribute-expected-win.txt b/content/test/data/accessibility/event/add-hidden-attribute-expected-win.txt index 2e7b947..4b87b52 100644 --- a/content/test/data/accessibility/event/add-hidden-attribute-expected-win.txt +++ b/content/test/data/accessibility/event/add-hidden-attribute-expected-win.txt
@@ -1,3 +1,3 @@ EVENT_OBJECT_HIDE on <div#item3> role=ROLE_SYSTEM_LISTITEM name="Item 3" PosInSet=3 SetSize=3 EVENT_OBJECT_REORDER on <div> role=ROLE_SYSTEM_LIST SetSize=2 -IA2_EVENT_TEXT_REMOVED on <div> role=ROLE_SYSTEM_LIST SetSize=3 old_text={'<obj>' start=2 end=3} +IA2_EVENT_TEXT_REMOVED on <div> role=ROLE_SYSTEM_LIST SetSize=2 old_text={'<obj>' start=2 end=3}
diff --git a/content/test/data/accessibility/event/add-hidden-attribute-subtree-expected-win.txt b/content/test/data/accessibility/event/add-hidden-attribute-subtree-expected-win.txt index e556781..c7a7def 100644 --- a/content/test/data/accessibility/event/add-hidden-attribute-subtree-expected-win.txt +++ b/content/test/data/accessibility/event/add-hidden-attribute-subtree-expected-win.txt
@@ -1,3 +1,3 @@ EVENT_OBJECT_HIDE on <li#item3> role=ROLE_SYSTEM_LISTITEM PosInSet=3 SetSize=3 EVENT_OBJECT_REORDER on <ul> role=ROLE_SYSTEM_LIST SetSize=2 -IA2_EVENT_TEXT_REMOVED on <ul> role=ROLE_SYSTEM_LIST SetSize=3 old_text={'<obj>' start=2 end=3} +IA2_EVENT_TEXT_REMOVED on <ul> role=ROLE_SYSTEM_LIST SetSize=2 old_text={'<obj>' start=2 end=3}
diff --git a/content/test/data/accessibility/event/add-subtree-expected-win.txt b/content/test/data/accessibility/event/add-subtree-expected-win.txt index de590142..57b78be 100644 --- a/content/test/data/accessibility/event/add-subtree-expected-win.txt +++ b/content/test/data/accessibility/event/add-subtree-expected-win.txt
@@ -1,3 +1,3 @@ EVENT_OBJECT_REORDER on <ul> role=ROLE_SYSTEM_LIST SetSize=3 EVENT_OBJECT_SHOW on <li> role=ROLE_SYSTEM_LISTITEM PosInSet=3 SetSize=3 -IA2_EVENT_TEXT_INSERTED on <ul> role=ROLE_SYSTEM_LIST SetSize=2 new_text={'<obj>' start=2 end=3} +IA2_EVENT_TEXT_INSERTED on <ul> role=ROLE_SYSTEM_LIST SetSize=3 new_text={'<obj>' start=2 end=3}
diff --git a/content/test/data/accessibility/event/aria-combo-box-focus.html b/content/test/data/accessibility/event/aria-combo-box-focus.html index 7f95c02..8453827 100644 --- a/content/test/data/accessibility/event/aria-combo-box-focus.html +++ b/content/test/data/accessibility/event/aria-combo-box-focus.html
@@ -2,6 +2,7 @@ This line is to unflake the test, but may not be necessary (crbug.com/c/791268): @WIN-DENY:EVENT_OBJECT_LOCATIONCHANGE* @WIN-DENY:EVENT_OBJECT_SHOW* +@UIA-WIN-DENY:Text_TextSelectionChanged* --> <!DOCTYPE html> <html>
diff --git a/content/test/data/accessibility/event/aria-controls-changed-expected-uia-win.txt b/content/test/data/accessibility/event/aria-controls-changed-expected-uia-win.txt new file mode 100644 index 0000000..d4270214 --- /dev/null +++ b/content/test/data/accessibility/event/aria-controls-changed-expected-uia-win.txt
@@ -0,0 +1,3 @@ +ControllerFor changed on role=radiogroup +=== Start Continuation === +ControllerFor changed on role=button
diff --git a/content/test/data/accessibility/event/aria-controls-changed.html b/content/test/data/accessibility/event/aria-controls-changed.html new file mode 100644 index 0000000..22ed288 --- /dev/null +++ b/content/test/data/accessibility/event/aria-controls-changed.html
@@ -0,0 +1,29 @@ +<!-- +@UIA-WIN-DENY:* +@UIA-WIN-ALLOW:ControllerFor* +--> +<!DOCTYPE html> +<div id="radiogroup" role="radiogroup"> + <div id="radio1" role="radio">radio1</div> + <div id="radio2" role="radio">radio2</div> + <div id="radio3" role="radio">radio3</div> +</div> + +<input id="input1" type="text"> +<input id="input2" type="text"> +<button role="button" aria-controls="input1"></button> + +<script> + var go_passes = [ + () => document.querySelector('div[role=radiogroup]').setAttribute( + 'aria-controls', 'radio1 radio2 radio3'), + () => document.querySelector('button[role=button]').setAttribute( + 'aria-controls', 'input2'), + ]; + + var current_pass = 0; + function go() { + go_passes[current_pass++].call(); + return current_pass < go_passes.length; + } +</script>
diff --git a/content/test/data/accessibility/event/description-change-indirect.html b/content/test/data/accessibility/event/description-change-indirect.html index f5888b5..6cc0c53 100644 --- a/content/test/data/accessibility/event/description-change-indirect.html +++ b/content/test/data/accessibility/event/description-change-indirect.html
@@ -1,6 +1,7 @@ <!-- @BLINK-ALLOW:description=* @WIN-ALLOW:description=* +@UIA-WIN-DENY:Text_TextChanged* @MAC-ALLOW:AXDescription* @MAC-ALLOW:AXDescription* -->
diff --git a/content/test/data/accessibility/event/description-change.html b/content/test/data/accessibility/event/description-change.html index c080dc39..0a9e6c1 100644 --- a/content/test/data/accessibility/event/description-change.html +++ b/content/test/data/accessibility/event/description-change.html
@@ -1,3 +1,6 @@ +<!-- +@UIA-WIN-DENY:Text_TextChanged* +--> <!DOCTYPE html> <html> <body>
diff --git a/content/test/data/accessibility/event/live-region-change.html b/content/test/data/accessibility/event/live-region-change.html index caf272b..0624e55 100644 --- a/content/test/data/accessibility/event/live-region-change.html +++ b/content/test/data/accessibility/event/live-region-change.html
@@ -1,3 +1,6 @@ +<!-- +@UIA-WIN-DENY:Text_TextChanged* +--> <!DOCTYPE html> <html> <body>
diff --git a/content/test/data/accessibility/event/live-region-create.html b/content/test/data/accessibility/event/live-region-create.html index a887b2a..5f09c9e 100644 --- a/content/test/data/accessibility/event/live-region-create.html +++ b/content/test/data/accessibility/event/live-region-create.html
@@ -1,3 +1,6 @@ +<!-- +@UIA-WIN-DENY:Text_TextChanged* +--> <!DOCTYPE html> <html> <body>
diff --git a/content/test/data/accessibility/event/menulist-collapse-next.html b/content/test/data/accessibility/event/menulist-collapse-next.html index 0d985ed..d1b01f5 100644 --- a/content/test/data/accessibility/event/menulist-collapse-next.html +++ b/content/test/data/accessibility/event/menulist-collapse-next.html
@@ -1,3 +1,6 @@ +<!-- +@UIA-WIN-DENY:Text_TextChanged* +--> <!DOCTYPE html> <html> <body>
diff --git a/content/test/data/accessibility/event/menulist-collapse.html b/content/test/data/accessibility/event/menulist-collapse.html index ad7f1855..ac1dacb4a 100644 --- a/content/test/data/accessibility/event/menulist-collapse.html +++ b/content/test/data/accessibility/event/menulist-collapse.html
@@ -1,3 +1,6 @@ +<!-- +@UIA-WIN-DENY:Text_TextChanged* +--> <!DOCTYPE html> <html> <body>
diff --git a/content/test/data/accessibility/event/menulist-focus.html b/content/test/data/accessibility/event/menulist-focus.html index 73ba0b0..bc5b9b0 100644 --- a/content/test/data/accessibility/event/menulist-focus.html +++ b/content/test/data/accessibility/event/menulist-focus.html
@@ -1,3 +1,6 @@ +<!-- +@UIA-WIN-DENY:Text_TextChanged* +--> <!DOCTYPE html> <html> <body>
diff --git a/content/test/data/accessibility/event/name-change-indirect.html b/content/test/data/accessibility/event/name-change-indirect.html index 7064872..6f8a356 100644 --- a/content/test/data/accessibility/event/name-change-indirect.html +++ b/content/test/data/accessibility/event/name-change-indirect.html
@@ -1,3 +1,6 @@ +<!-- +@UIA-WIN-DENY:Text_TextChanged* +--> <!DOCTYPE html> <html> <body>
diff --git a/content/test/data/accessibility/event/name-change.html b/content/test/data/accessibility/event/name-change.html index c2646d3..23f9899a 100644 --- a/content/test/data/accessibility/event/name-change.html +++ b/content/test/data/accessibility/event/name-change.html
@@ -1,3 +1,6 @@ +<!-- +@UIA-WIN-DENY:Text_TextChanged* +--> <!DOCTYPE html> <html> <body>
diff --git a/content/test/data/accessibility/event/remove-child-expected-win.txt b/content/test/data/accessibility/event/remove-child-expected-win.txt index 2e7b947..4b87b52 100644 --- a/content/test/data/accessibility/event/remove-child-expected-win.txt +++ b/content/test/data/accessibility/event/remove-child-expected-win.txt
@@ -1,3 +1,3 @@ EVENT_OBJECT_HIDE on <div#item3> role=ROLE_SYSTEM_LISTITEM name="Item 3" PosInSet=3 SetSize=3 EVENT_OBJECT_REORDER on <div> role=ROLE_SYSTEM_LIST SetSize=2 -IA2_EVENT_TEXT_REMOVED on <div> role=ROLE_SYSTEM_LIST SetSize=3 old_text={'<obj>' start=2 end=3} +IA2_EVENT_TEXT_REMOVED on <div> role=ROLE_SYSTEM_LIST SetSize=2 old_text={'<obj>' start=2 end=3}
diff --git a/content/test/data/accessibility/event/text-changed-contenteditable-expected-auralinux.txt b/content/test/data/accessibility/event/text-changed-contenteditable-expected-auralinux.txt index 1d49e7e7..4419f72 100644 --- a/content/test/data/accessibility/event/text-changed-contenteditable-expected-auralinux.txt +++ b/content/test/data/accessibility/event/text-changed-contenteditable-expected-auralinux.txt
@@ -14,11 +14,11 @@ STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT -TEXT-INSERT (start=0 length=16 'Before Div After') role=ROLE_SECTION name='(null)' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT -TEXT-INSERT (start=0 length=22 'Before Paragraph After') role=ROLE_PARAGRAPH name='(null)' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT -TEXT-INSERT (start=0 length=9 'Modified ') role=ROLE_PARAGRAPH name='(null)' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT -TEXT-INSERT (start=0 length=9 'Modified ') role=ROLE_SECTION name='(null)' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT -TEXT-REMOVE (start=0 length=3 'Div') role=ROLE_SECTION name='(null)' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT -TEXT-REMOVE (start=0 length=3 'Div') role=ROLE_SECTION name='(null)' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT -TEXT-REMOVE (start=0 length=9 'Paragraph') role=ROLE_PARAGRAPH name='(null)' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT -TEXT-REMOVE (start=0 length=9 'Paragraph') role=ROLE_PARAGRAPH name='(null)' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT +TEXT-INSERT (start=0 length=16 'Before Div After') role=ROLE_SECTION name='d3' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT +TEXT-INSERT (start=0 length=22 'Before Paragraph After') role=ROLE_PARAGRAPH name='p3' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT +TEXT-INSERT (start=0 length=9 'Modified ') role=ROLE_PARAGRAPH name='p1' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT +TEXT-INSERT (start=0 length=9 'Modified ') role=ROLE_SECTION name='d1' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT +TEXT-REMOVE (start=0 length=3 'Div') role=ROLE_SECTION name='d2' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT +TEXT-REMOVE (start=0 length=3 'Div') role=ROLE_SECTION name='d3' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT +TEXT-REMOVE (start=0 length=9 'Paragraph') role=ROLE_PARAGRAPH name='p2' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT +TEXT-REMOVE (start=0 length=9 'Paragraph') role=ROLE_PARAGRAPH name='p3' EDITABLE,ENABLED,FOCUSABLE,MULTI-LINE,SENSITIVE,SHOWING,VISIBLE,SELECTABLE-TEXT
diff --git a/content/test/data/accessibility/event/text-changed-contenteditable-expected-uia-win.txt b/content/test/data/accessibility/event/text-changed-contenteditable-expected-uia-win.txt new file mode 100644 index 0000000..c34ee1e --- /dev/null +++ b/content/test/data/accessibility/event/text-changed-contenteditable-expected-uia-win.txt
@@ -0,0 +1,4 @@ +Text_TextChanged on role=group, name=d1 +Text_TextChanged on role=group, name=d3 +Text_TextChanged on role=group, name=p1 +Text_TextChanged on role=group, name=p3
diff --git a/content/test/data/accessibility/event/text-changed-contenteditable-expected-win.txt b/content/test/data/accessibility/event/text-changed-contenteditable-expected-win.txt new file mode 100644 index 0000000..0d46f381 --- /dev/null +++ b/content/test/data/accessibility/event/text-changed-contenteditable-expected-win.txt
@@ -0,0 +1,24 @@ +EVENT_OBJECT_HIDE on role=ROLE_SYSTEM_STATICTEXT name="Div" IA2_STATE_EDITABLE +EVENT_OBJECT_HIDE on role=ROLE_SYSTEM_STATICTEXT name="Div" IA2_STATE_EDITABLE +EVENT_OBJECT_HIDE on role=ROLE_SYSTEM_STATICTEXT name="Div" IA2_STATE_EDITABLE +EVENT_OBJECT_HIDE on role=ROLE_SYSTEM_STATICTEXT name="Paragraph" IA2_STATE_EDITABLE +EVENT_OBJECT_HIDE on role=ROLE_SYSTEM_STATICTEXT name="Paragraph" IA2_STATE_EDITABLE +EVENT_OBJECT_HIDE on role=ROLE_SYSTEM_STATICTEXT name="Paragraph" IA2_STATE_EDITABLE +EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_STATICTEXT name="Before Div After" IA2_STATE_EDITABLE +EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_STATICTEXT name="Before Paragraph After" IA2_STATE_EDITABLE +EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_STATICTEXT name="Modified Div" IA2_STATE_EDITABLE +EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_STATICTEXT name="Modified Paragraph" IA2_STATE_EDITABLE +EVENT_OBJECT_VALUECHANGE on <div#d1> role=DIV name="d1" value="Modified Div" FOCUSABLE IA2_STATE_EDITABLE,IA2_STATE_MULTI_LINE,IA2_STATE_SELECTABLE_TEXT +EVENT_OBJECT_VALUECHANGE on <div#d2> role=DIV name="d2" FOCUSABLE IA2_STATE_EDITABLE,IA2_STATE_MULTI_LINE,IA2_STATE_SELECTABLE_TEXT +EVENT_OBJECT_VALUECHANGE on <div#d3> role=DIV name="d3" value="Before Div After" FOCUSABLE IA2_STATE_EDITABLE,IA2_STATE_MULTI_LINE,IA2_STATE_SELECTABLE_TEXT +EVENT_OBJECT_VALUECHANGE on <p#p1> role=P name="p1" value="Modified Paragraph" FOCUSABLE IA2_STATE_EDITABLE,IA2_STATE_MULTI_LINE,IA2_STATE_SELECTABLE_TEXT +EVENT_OBJECT_VALUECHANGE on <p#p2> role=P name="p2" FOCUSABLE IA2_STATE_EDITABLE,IA2_STATE_MULTI_LINE,IA2_STATE_SELECTABLE_TEXT +EVENT_OBJECT_VALUECHANGE on <p#p3> role=P name="p3" value="Before Paragraph After" FOCUSABLE IA2_STATE_EDITABLE,IA2_STATE_MULTI_LINE,IA2_STATE_SELECTABLE_TEXT +IA2_EVENT_TEXT_INSERTED on <div#d1> role=DIV name="d1" value="Modified Div" FOCUSABLE IA2_STATE_EDITABLE,IA2_STATE_MULTI_LINE,IA2_STATE_SELECTABLE_TEXT new_text={'Modified ' start=0 end=9} +IA2_EVENT_TEXT_INSERTED on <div#d3> role=DIV name="d3" value="Before Div After" FOCUSABLE IA2_STATE_EDITABLE,IA2_STATE_MULTI_LINE,IA2_STATE_SELECTABLE_TEXT new_text={'Before Div After' start=0 end=16} +IA2_EVENT_TEXT_INSERTED on <p#p1> role=P name="p1" value="Modified Paragraph" FOCUSABLE IA2_STATE_EDITABLE,IA2_STATE_MULTI_LINE,IA2_STATE_SELECTABLE_TEXT new_text={'Modified ' start=0 end=9} +IA2_EVENT_TEXT_INSERTED on <p#p3> role=P name="p3" value="Before Paragraph After" FOCUSABLE IA2_STATE_EDITABLE,IA2_STATE_MULTI_LINE,IA2_STATE_SELECTABLE_TEXT new_text={'Before Paragraph After' start=0 end=22} +IA2_EVENT_TEXT_REMOVED on <div#d2> role=DIV name="d2" FOCUSABLE IA2_STATE_EDITABLE,IA2_STATE_MULTI_LINE,IA2_STATE_SELECTABLE_TEXT old_text={'Div' start=0 end=3} +IA2_EVENT_TEXT_REMOVED on <div#d3> role=DIV name="d3" value="Before Div After" FOCUSABLE IA2_STATE_EDITABLE,IA2_STATE_MULTI_LINE,IA2_STATE_SELECTABLE_TEXT old_text={'Div' start=0 end=3} +IA2_EVENT_TEXT_REMOVED on <p#p2> role=P name="p2" FOCUSABLE IA2_STATE_EDITABLE,IA2_STATE_MULTI_LINE,IA2_STATE_SELECTABLE_TEXT old_text={'Paragraph' start=0 end=9} +IA2_EVENT_TEXT_REMOVED on <p#p3> role=P name="p3" value="Before Paragraph After" FOCUSABLE IA2_STATE_EDITABLE,IA2_STATE_MULTI_LINE,IA2_STATE_SELECTABLE_TEXT old_text={'Paragraph' start=0 end=9}
diff --git a/content/test/data/accessibility/event/text-changed-contenteditable.html b/content/test/data/accessibility/event/text-changed-contenteditable.html index db0f3248..f7b1f57 100644 --- a/content/test/data/accessibility/event/text-changed-contenteditable.html +++ b/content/test/data/accessibility/event/text-changed-contenteditable.html
@@ -1,12 +1,16 @@ +<!-- +The children changed / reorder event is fired an unpredictable number of times. +@WIN-DENY:EVENT_OBJECT_REORDER* +--> <!DOCTYPE html> <html> <body> -<p id="p1" contenteditable>Paragraph</p> -<p id="p2" contenteditable>Paragraph</p> -<p id="p3" contenteditable>Paragraph</p> -<div id="d1" contenteditable>Div</div> -<div id="d2" contenteditable>Div</div> -<div id="d3" contenteditable>Div</div> +<p id="p1" aria-label="p1" contenteditable>Paragraph</p> +<p id="p2" aria-label="p2" contenteditable>Paragraph</p> +<p id="p3" aria-label="p3" contenteditable>Paragraph</p> +<div id="d1" aria-label="d1" contenteditable>Div</div> +<div id="d2" aria-label="d2" contenteditable>Div</div> +<div id="d3" aria-label="d3" contenteditable>Div</div> <script> function go() { document.querySelector('#p1').textContent = 'Modified Paragraph';
diff --git a/content/test/data/accessibility/event/text-changed-expected-auralinux.txt b/content/test/data/accessibility/event/text-changed-expected-auralinux.txt index 6e87438..8fa35bd 100644 --- a/content/test/data/accessibility/event/text-changed-expected-auralinux.txt +++ b/content/test/data/accessibility/event/text-changed-expected-auralinux.txt
@@ -1,5 +1,5 @@ +NAME-CHANGED:Modified Div role=ROLE_TEXT name='Modified Div' ENABLED,SENSITIVE,SHOWING,VISIBLE NAME-CHANGED:Modified Heading role=ROLE_TEXT name='Modified Heading' ENABLED,SENSITIVE,SHOWING,VISIBLE -NAME-CHANGED:Text modified role=ROLE_TEXT name='Text modified' ENABLED,SENSITIVE,SHOWING,VISIBLE STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT @@ -7,4 +7,3 @@ STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT STATE-CHANGE:DEFUNCT:TRUE role=ROLE_INVALID name='(null)' DEFUNCT -
diff --git a/content/test/data/accessibility/event/text-changed-expected-uia-win.txt b/content/test/data/accessibility/event/text-changed-expected-uia-win.txt index abbec0f..81b32ff 100644 --- a/content/test/data/accessibility/event/text-changed-expected-uia-win.txt +++ b/content/test/data/accessibility/event/text-changed-expected-uia-win.txt
@@ -1,2 +1,5 @@ -Name changed on role=description, name=Text modified -Name changed on role=heading, name=Heading +Name changed on role=description, name=Modified Div +Name changed on role=heading, name=h +Text_TextChanged on role=description, name=Modified Div +Text_TextChanged on role=document +Text_TextChanged on role=heading, name=h
diff --git a/content/test/data/accessibility/event/text-changed-expected-win.txt b/content/test/data/accessibility/event/text-changed-expected-win.txt index 7dbfc10..9b465af 100644 --- a/content/test/data/accessibility/event/text-changed-expected-win.txt +++ b/content/test/data/accessibility/event/text-changed-expected-win.txt
@@ -1,8 +1,8 @@ EVENT_OBJECT_HIDE on role=ROLE_SYSTEM_STATICTEXT name="Para" EVENT_OBJECT_SHOW on role=ROLE_SYSTEM_STATICTEXT name="Modified Para" -IA2_EVENT_TEXT_INSERTED on <div> role=DIV name="div" new_text={'Text modified' start=0 end=13} -IA2_EVENT_TEXT_INSERTED on <h2#h> role=H2 name="Heading" level=2 new_text={'Modified Heading' start=0 end=16} -IA2_EVENT_TEXT_INSERTED on <p#p> role=P new_text={'Modified Para' start=0 end=13} -IA2_EVENT_TEXT_REMOVED on <div> role=DIV name="div" old_text={'Div' start=0 end=3} -IA2_EVENT_TEXT_REMOVED on <h2#h> role=H2 name="Heading" level=2 old_text={'Heading' start=0 end=7} -IA2_EVENT_TEXT_REMOVED on <p#p> role=P old_text={'Para' start=0 end=4} +IA2_EVENT_TEXT_INSERTED on <div#d> role=DIV name="d" new_text={'Modified Div' start=0 end=12} +IA2_EVENT_TEXT_INSERTED on <h2#h> role=H2 name="h" level=2 new_text={'Modified Heading' start=0 end=16} +IA2_EVENT_TEXT_INSERTED on <p#p> role=P name="p" new_text={'Modified Para' start=0 end=13} +IA2_EVENT_TEXT_REMOVED on <div#d> role=DIV name="d" old_text={'Div' start=0 end=3} +IA2_EVENT_TEXT_REMOVED on <h2#h> role=H2 name="h" level=2 old_text={'Heading' start=0 end=7} +IA2_EVENT_TEXT_REMOVED on <p#p> role=P name="p" old_text={'Para' start=0 end=4}
diff --git a/content/test/data/accessibility/event/text-changed.html b/content/test/data/accessibility/event/text-changed.html index 77f4ebc..cf715e3c 100644 --- a/content/test/data/accessibility/event/text-changed.html +++ b/content/test/data/accessibility/event/text-changed.html
@@ -5,14 +5,14 @@ <!DOCTYPE html> <html> <body> -<p id="p">Para</p> -<h2 id="h">Heading</h2> -<div aria-label="div">Div</div> +<p id="p" aria-label="p">Para</p> +<h2 id="h" aria-label="h">Heading</h2> +<div id="d" aria-label="d">Div</div> <script> function go() { document.querySelector('#p').textContent = 'Modified Para'; document.querySelector('#h').firstChild.data = 'Modified Heading'; - document.querySelector('div').firstChild.data = 'Text modified'; + document.querySelector('#d').firstChild.data = 'Modified Div'; } </script> </body>
diff --git a/content/test/data/accessibility/event/text-selection-changed-expected-uia-win.txt b/content/test/data/accessibility/event/text-selection-changed-expected-uia-win.txt new file mode 100644 index 0000000..9a5505b --- /dev/null +++ b/content/test/data/accessibility/event/text-selection-changed-expected-uia-win.txt
@@ -0,0 +1,5 @@ +Text_TextSelectionChanged on role=document +=== Start Continuation === +Text_TextSelectionChanged on role=textbox, name=input +=== Start Continuation === +Text_TextSelectionChanged on role=textbox, name=textarea
diff --git a/content/test/data/accessibility/event/text-selection-changed.html b/content/test/data/accessibility/event/text-selection-changed.html new file mode 100644 index 0000000..6b9dfa4 --- /dev/null +++ b/content/test/data/accessibility/event/text-selection-changed.html
@@ -0,0 +1,34 @@ +<!-- +@UIA-WIN-DENY:AutomationFocusChanged* +--> +<!DOCTYPE html> +<div> + <h1 id="header" aria-label="title">title</h1> + <input id="input" aria-label="input" value="input"/> + <textarea id="textarea" aria-label="textarea"></textarea> +</div> +<script> + var input = document.getElementById("input"); + var header = document.getElementById("header"); + var textarea = document.getElementById("textarea"); + + const go_passes = [ + () => { + var range = document.createRange(); + range.selectNodeContents(header); + window.getSelection().removeAllRanges(); + window.getSelection().addRange(range); + }, + () => { + input.focus(); + input.setSelectionRange(2, 3); + }, + () => textarea.select(), + ]; + + var current_pass = 0; + function go() { + go_passes[current_pass++].call(); + return current_pass < go_passes.length; + } +</script>
diff --git a/content/test/data/accessibility/html/modal-dialog-opened-expected-android.txt b/content/test/data/accessibility/html/modal-dialog-opened-expected-android.txt index badc901b..2b5b6e0 100644 --- a/content/test/data/accessibility/html/modal-dialog-opened-expected-android.txt +++ b/content/test/data/accessibility/html/modal-dialog-opened-expected-android.txt
@@ -1,5 +1,5 @@ android.webkit.WebView focusable scrollable -++android.view.View ++android.app.Dialog role_description='dialog' ++++android.view.View name='The dialog subtree should be the only text content in the accessibility tree. ' ++++android.view.View role_description='link' clickable focusable focused link name='Link inside the dialog.' +++android.view.View \ No newline at end of file
diff --git a/content/test/data/accessibility/html/modal-dialog-opened-expected-auralinux.txt b/content/test/data/accessibility/html/modal-dialog-opened-expected-auralinux.txt index 6a184f3..210eb46 100644 --- a/content/test/data/accessibility/html/modal-dialog-opened-expected-auralinux.txt +++ b/content/test/data/accessibility/html/modal-dialog-opened-expected-auralinux.txt
@@ -1,6 +1,6 @@ [document web] -++[section] ++[dialog] modal ++++[text] name='The dialog subtree should be the only text content in the accessibility tree. ' ++++[link] name='Link inside the dialog.' ++++++[text] name='Link inside the dialog.' +++[section]
diff --git a/content/test/data/accessibility/html/modal-dialog-opened-expected-blink.txt b/content/test/data/accessibility/html/modal-dialog-opened-expected-blink.txt index 7bf19fc..1cf7805 100644 --- a/content/test/data/accessibility/html/modal-dialog-opened-expected-blink.txt +++ b/content/test/data/accessibility/html/modal-dialog-opened-expected-blink.txt
@@ -1,8 +1,8 @@ rootWebArea -++genericContainer ++dialog ++++staticText name='The dialog subtree should be the only text content in the accessibility tree. ' ++++++inlineTextBox name='The dialog subtree should be the only text content in the accessibility tree. ' ++++link name='Link inside the dialog.' ++++++staticText name='Link inside the dialog.' ++++++++inlineTextBox name='Link inside the dialog.' +++genericContainer
diff --git a/content/test/data/accessibility/html/modal-dialog-opened-expected-mac.txt b/content/test/data/accessibility/html/modal-dialog-opened-expected-mac.txt index e3e9609b..b2f19e8 100644 --- a/content/test/data/accessibility/html/modal-dialog-opened-expected-mac.txt +++ b/content/test/data/accessibility/html/modal-dialog-opened-expected-mac.txt
@@ -1,6 +1,6 @@ AXWebArea -++AXGroup ++AXGroup AXSubrole=AXApplicationDialog ++++AXStaticText AXValue='The dialog subtree should be the only text content in the accessibility tree. ' ++++AXLink AXTitle='Link inside the dialog.' ++++++AXStaticText AXValue='Link inside the dialog.' +++AXGroup
diff --git a/content/test/data/accessibility/html/modal-dialog-opened-expected-win.txt b/content/test/data/accessibility/html/modal-dialog-opened-expected-win.txt index 09ab3cb..8fd398a 100644 --- a/content/test/data/accessibility/html/modal-dialog-opened-expected-win.txt +++ b/content/test/data/accessibility/html/modal-dialog-opened-expected-win.txt
@@ -1,6 +1,6 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE -++IA2_ROLE_SECTION ++ROLE_SYSTEM_DIALOG IA2_STATE_MODAL ++++ROLE_SYSTEM_STATICTEXT name='The dialog subtree should be the only text content in the accessibility tree. ' ++++ROLE_SYSTEM_LINK name='Link inside the dialog.' FOCUSABLE ++++++ROLE_SYSTEM_STATICTEXT name='Link inside the dialog.' +++IA2_ROLE_SECTION
diff --git a/content/test/data/accessibility/html/modal-dialog-stack-expected-android.txt b/content/test/data/accessibility/html/modal-dialog-stack-expected-android.txt index 75cb37a..aaa0943 100644 --- a/content/test/data/accessibility/html/modal-dialog-stack-expected-android.txt +++ b/content/test/data/accessibility/html/modal-dialog-stack-expected-android.txt
@@ -1,5 +1,5 @@ android.webkit.WebView focusable focused scrollable -++android.view.View ++android.app.Dialog role_description='dialog' ++++android.view.View name='This is the now active dialog. Of course it should be in the tree. ' ++++android.widget.Button role_description='button' clickable focusable name='This is in the active dialog and should be in the tree.' +++android.view.View
diff --git a/content/test/data/accessibility/html/modal-dialog-stack-expected-auralinux.txt b/content/test/data/accessibility/html/modal-dialog-stack-expected-auralinux.txt index 7a0a189..c072723 100644 --- a/content/test/data/accessibility/html/modal-dialog-stack-expected-auralinux.txt +++ b/content/test/data/accessibility/html/modal-dialog-stack-expected-auralinux.txt
@@ -1,5 +1,5 @@ [document web] -++[section] ++[dialog] modal ++++[text] name='This is the now active dialog. Of course it should be in the tree. ' ++++[push button] name='This is in the active dialog and should be in the tree.' +++[section]
diff --git a/content/test/data/accessibility/html/modal-dialog-stack-expected-blink.txt b/content/test/data/accessibility/html/modal-dialog-stack-expected-blink.txt index 127caf8..98dcc461 100644 --- a/content/test/data/accessibility/html/modal-dialog-stack-expected-blink.txt +++ b/content/test/data/accessibility/html/modal-dialog-stack-expected-blink.txt
@@ -1,6 +1,6 @@ rootWebArea -++genericContainer ++dialog ++++staticText name='This is the now active dialog. Of course it should be in the tree. ' ++++++inlineTextBox name='This is the now active dialog. Of course it should be in the tree. ' ++++button name='This is in the active dialog and should be in the tree.' +++genericContainer
diff --git a/content/test/data/accessibility/html/modal-dialog-stack-expected-mac.txt b/content/test/data/accessibility/html/modal-dialog-stack-expected-mac.txt index fd373b1..1561a8b7 100644 --- a/content/test/data/accessibility/html/modal-dialog-stack-expected-mac.txt +++ b/content/test/data/accessibility/html/modal-dialog-stack-expected-mac.txt
@@ -1,5 +1,5 @@ AXWebArea -++AXGroup ++AXGroup AXSubrole=AXApplicationDialog ++++AXStaticText AXValue='This is the now active dialog. Of course it should be in the tree. ' ++++AXButton AXTitle='This is in the active dialog and should be in the tree.' +++AXGroup
diff --git a/content/test/data/accessibility/html/modal-dialog-stack-expected-win.txt b/content/test/data/accessibility/html/modal-dialog-stack-expected-win.txt index df25937bd..0160c77e 100644 --- a/content/test/data/accessibility/html/modal-dialog-stack-expected-win.txt +++ b/content/test/data/accessibility/html/modal-dialog-stack-expected-win.txt
@@ -1,5 +1,5 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE -++IA2_ROLE_SECTION ++ROLE_SYSTEM_DIALOG IA2_STATE_MODAL ++++ROLE_SYSTEM_STATICTEXT name='This is the now active dialog. Of course it should be in the tree. ' ++++ROLE_SYSTEM_PUSHBUTTON name='This is in the active dialog and should be in the tree.' FOCUSABLE +++IA2_ROLE_SECTION
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index 99dae1d..48bc2272 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -312,6 +312,10 @@ self.Flaky('deqp/functional/gles3/multisample.html', ['win', ('amd', 0x6613)], bug=687374) + # Failing on AMD RX 550 + self.Skip('deqp/functional/gles3/fborender/shared_colorbuffer_02.html', + ['win', ('amd', 0x699f)], bug=3354) # ANGLE bug ID + # Win / Intel self.Fail('conformance/rendering/rendering-stencil-large-viewport.html', ['win', 'intel', 'd3d11'], bug=782317) @@ -455,6 +459,8 @@ ['linux', 'passthrough', 'opengl', 'intel'], bug=2760) # ANGLE bug self.Fail('conformance2/textures/misc/tex-mipmap-levels.html', ['linux', 'passthrough', 'opengl', 'intel'], bug=2761) # ANGLE bug + self.Flaky('conformance/extensions/webgl-compressed-texture-s3tc.html', + ['linux', 'passthrough', 'opengl', 'intel'], bug=950787) # Regressions in 10.12.4. self.Fail('conformance2/textures/misc/tex-base-level-bug.html',
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py index 74ab3d0..f2b5ff1 100644 --- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -338,10 +338,14 @@ self.Fail('conformance/rendering/clipping-wide-points.html', ['win', 'amd', 'opengl'], bug=1506) # angle bug ID # AMD RX 550 Failures + self.Skip('conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html', + ['win', ('amd', 0x699f), 'opengl'], bug=950123) self.Skip('conformance/glsl/misc/fragcolor-fragdata-invariant.html', ['win', ('amd', 0x699f), 'opengl'], bug=950123) self.Skip('conformance/glsl/samplers/glsl-function-texture2dprojlod.html', ['win', ('amd', 0x699f), 'opengl'], bug=950123) + self.Skip('conformance/rendering/line-rendering-quality.html', + ['win', ('amd', 0x699f), 'opengl'], bug=950123) # Mark ANGLE's OpenGL as flaky on Windows Amd self.Flaky('conformance/*', ['win', 'amd', 'opengl'], bug=582083)
diff --git a/content/test/ppapi/ppapi_test.cc b/content/test/ppapi/ppapi_test.cc index d3c9b29..b622d12 100644 --- a/content/test/ppapi/ppapi_test.cc +++ b/content/test/ppapi/ppapi_test.cc
@@ -22,7 +22,7 @@ #if defined(OS_CHROMEOS) #include "chromeos/audio/cras_audio_handler.h" -#include "chromeos/dbus/cras_audio_client.h" +#include "chromeos/dbus/audio/cras_audio_client.h" #endif namespace content {
diff --git a/docs/sublime_ide.md b/docs/sublime_ide.md index 2526e6b3..9706386 100644 --- a/docs/sublime_ide.md +++ b/docs/sublime_ide.md
@@ -262,7 +262,7 @@ page](https://github.com/karlinjf/ChromiumXRefs/). -## Code Completion, Error Highlighting, Go-to-Definition, and Find References with LSP +## Code Completion, Error Highlighting, Go-to-Definition, and Find References with LSP (clangd) Gives Sublime Text 3 rich editing features for languages with Language Server Protocol support. It searches the current compilation unit for definitions and @@ -270,28 +270,15 @@ In this case, we're going to add C/C++ support. -1. Install clangd +1. Refer to [clangd.md](clangd.md) to install clangd and build a compilation + database. - ```shell - sudo apt-get install clangd - ``` +1. Install the [LSP Package](https://github.com/tomv564/LSP) and enable clangd + support by following the [link](https://clang.llvm.org/extra/clangd/Installation.html#editor-plugins) + and following the instructions for Sublime Text. -1. Build a compilation database (clangd learns how to compile chromium objects - with this). You'll need to run this periodically to keep it up to date. - - ```shell - ninja -C out -t compdb cxx > compile_commands.json - mv compile_commands.json <path_to_src> - ``` - -1. Install the LSP package in sublime-text - -1. Open a source file in your chromium project - -1. Ctrl+Shift+P and select "LSP: enable language server in project" and select - clangd - -To remove sublime text's auto completion and only show LSPs (recommended), set the following LSP preference: +To remove sublime text's auto completion and only show LSPs (recommended), set +the following LSP preference: ```json "only_show_lsp_completions": true
diff --git a/extensions/browser/api/audio/audio_apitest_chromeos.cc b/extensions/browser/api/audio/audio_apitest_chromeos.cc index eb5e76f..5b0d7ba3 100644 --- a/extensions/browser/api/audio/audio_apitest_chromeos.cc +++ b/extensions/browser/api/audio/audio_apitest_chromeos.cc
@@ -13,7 +13,7 @@ #include "build/build_config.h" #include "chromeos/audio/audio_devices_pref_handler_stub.h" #include "chromeos/audio/cras_audio_handler.h" -#include "chromeos/dbus/fake_cras_audio_client.h" +#include "chromeos/dbus/audio/fake_cras_audio_client.h" #include "extensions/common/features/feature_session_type.h" #include "extensions/common/switches.h" #include "extensions/shell/test/shell_apitest.h"
diff --git a/extensions/common/features/simple_feature.cc b/extensions/common/features/simple_feature.cc index 3746bc1..f8f6318 100644 --- a/extensions/common/features/simple_feature.cc +++ b/extensions/common/features/simple_feature.cc
@@ -187,10 +187,6 @@ } bool IsAllowlistedForTest(const HashedExtensionId& hashed_id) { - // TODO(jackhou): Delete the commandline allowlisting mechanism. - // Since it is only used it tests, ideally it should not be set via the - // commandline. At the moment the commandline is used as a mechanism to pass - // the id to the renderer process. const std::string& allowlisted_id = g_allowlist_info.Get().hashed_id; return !allowlisted_id.empty() && allowlisted_id == hashed_id.value(); } @@ -603,8 +599,10 @@ return CreateAvailability(NOT_FOUND_IN_WHITELIST); } - if (location_ && !MatchesManifestLocation(location)) + if (location_ && !MatchesManifestLocation(location) && + !IsAllowlistedForTest(hashed_id)) { return CreateAvailability(INVALID_LOCATION); + } if (min_manifest_version_ && manifest_version < *min_manifest_version_) return CreateAvailability(INVALID_MIN_MANIFEST_VERSION);
diff --git a/extensions/shell/browser/shell_audio_controller_chromeos_unittest.cc b/extensions/shell/browser/shell_audio_controller_chromeos_unittest.cc index 80a6cb2..f8525f3 100644 --- a/extensions/shell/browser/shell_audio_controller_chromeos_unittest.cc +++ b/extensions/shell/browser/shell_audio_controller_chromeos_unittest.cc
@@ -13,8 +13,8 @@ #include "chromeos/audio/audio_device.h" #include "chromeos/audio/audio_devices_pref_handler.h" #include "chromeos/audio/cras_audio_handler.h" -#include "chromeos/dbus/audio_node.h" -#include "chromeos/dbus/fake_cras_audio_client.h" +#include "chromeos/dbus/audio/audio_node.h" +#include "chromeos/dbus/audio/fake_cras_audio_client.h" #include "testing/gtest/include/gtest/gtest.h" using chromeos::AudioDevice;
diff --git a/extensions/shell/browser/shell_browser_main_parts.cc b/extensions/shell/browser/shell_browser_main_parts.cc index c97008d..8a7860cc 100644 --- a/extensions/shell/browser/shell_browser_main_parts.cc +++ b/extensions/shell/browser/shell_browser_main_parts.cc
@@ -64,7 +64,7 @@ #endif #if defined(OS_CHROMEOS) -#include "chromeos/dbus/cras_audio_client.h" +#include "chromeos/dbus/audio/cras_audio_client.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/power/power_manager_client.h" #elif defined(OS_LINUX)
diff --git a/fuchsia/engine/BUILD.gn b/fuchsia/engine/BUILD.gn index 1ee7c32..1112933128 100644 --- a/fuchsia/engine/BUILD.gn +++ b/fuchsia/engine/BUILD.gn
@@ -71,6 +71,7 @@ "//content/public/child", "//content/public/common", "//content/public/renderer", + "//fuchsia:web_fidl", "//fuchsia/base", "//fuchsia/base:modular", "//mojo/public/cpp/bindings", @@ -78,6 +79,7 @@ "//services/service_manager/sandbox", "//skia/public/interfaces", "//third_party/blink/public/common", + "//third_party/fuchsia-sdk/sdk:web", "//ui/aura", "//ui/base/ime", "//ui/display", @@ -92,10 +94,6 @@ data = [ "$root_out_dir/webrunner.pak", ] - public_deps = [ - "//fuchsia:web_fidl", - "//third_party/fuchsia-sdk/sdk:web", - ] configs += [ ":web_engine_implementation" ] sources = [ "browser/context_impl.cc", @@ -104,8 +102,16 @@ "browser/discarding_event_filter.h", "browser/frame_impl.cc", "browser/frame_impl.h", + "browser/legacy_context_bridge.cc", + "browser/legacy_context_bridge.h", + "browser/legacy_frame_bridge.cc", + "browser/legacy_frame_bridge.h", "browser/legacy_message_port_bridge.cc", "browser/legacy_message_port_bridge.h", + "browser/legacy_navigation_controller_bridge.cc", + "browser/legacy_navigation_controller_bridge.h", + "browser/legacy_navigation_event_listener_bridge.cc", + "browser/legacy_navigation_event_listener_bridge.h", "browser/message_port_impl.cc", "browser/message_port_impl.h", "browser/web_engine_browser_context.cc", @@ -227,6 +233,7 @@ ":web_engine_core", "//base/test:run_all_unittests", "//base/test:test_support", + "//fuchsia:web_fidl", "//testing/gmock", "//testing/gtest", ]
diff --git a/fuchsia/engine/browser/context_impl.cc b/fuchsia/engine/browser/context_impl.cc index 749177d..ad3fc6e0 100644 --- a/fuchsia/engine/browser/context_impl.cc +++ b/fuchsia/engine/browser/context_impl.cc
@@ -11,6 +11,7 @@ #include "base/fuchsia/fuchsia_logging.h" #include "content/public/browser/web_contents.h" #include "fuchsia/engine/browser/frame_impl.h" +#include "fuchsia/engine/browser/legacy_frame_bridge.h" ContextImpl::ContextImpl(content::BrowserContext* browser_context) : browser_context_(browser_context) {} @@ -18,12 +19,13 @@ ContextImpl::~ContextImpl() = default; void ContextImpl::CreateFrame( - fidl::InterfaceRequest<chromium::web::Frame> frame_request) { + fidl::InterfaceRequest<fuchsia::web::Frame> frame) { content::WebContents::CreateParams create_params(browser_context_, nullptr); create_params.initially_hidden = true; auto web_contents = content::WebContents::Create(create_params); + frames_.insert(std::make_unique<FrameImpl>(std::move(web_contents), this, - std::move(frame_request))); + std::move(frame))); } void ContextImpl::DestroyFrame(FrameImpl* frame) { @@ -35,8 +37,7 @@ return allow_javascript_injection_; } -FrameImpl* ContextImpl::GetFrameImplForTest( - chromium::web::FramePtr* frame_ptr) { +FrameImpl* ContextImpl::GetFrameImplForTest(fuchsia::web::FramePtr* frame_ptr) { DCHECK(frame_ptr); // Find the FrameImpl whose channel is connected to |frame_ptr| by inspecting @@ -60,3 +61,15 @@ return nullptr; } + +FrameImpl* ContextImpl::GetFrameImplForTest( + chromium::web::FramePtr* frame_ptr) { + DCHECK(frame_ptr); + + fuchsia::web::FramePtr* fuchsia_frame_ptr = + LegacyFrameBridge::GetFramePtrForTest(frame_ptr); + if (!fuchsia_frame_ptr) + return nullptr; + + return GetFrameImplForTest(fuchsia_frame_ptr); +}
diff --git a/fuchsia/engine/browser/context_impl.h b/fuchsia/engine/browser/context_impl.h index 4e68f91..c28f23fe5 100644 --- a/fuchsia/engine/browser/context_impl.h +++ b/fuchsia/engine/browser/context_impl.h
@@ -5,7 +5,7 @@ #ifndef FUCHSIA_ENGINE_BROWSER_CONTEXT_IMPL_H_ #define FUCHSIA_ENGINE_BROWSER_CONTEXT_IMPL_H_ -#include <lib/fidl/cpp/binding_set.h> +#include <fuchsia/web/cpp/fidl.h> #include <memory> #include <set> @@ -20,10 +20,10 @@ class FrameImpl; -// Implementation of Context from //fuchsia/fidl/context.fidl. +// Implementation of Context from fuchsia.web. // Owns a BrowserContext instance and uses it to create new WebContents/Frames. // All created Frames are owned by this object. -class WEB_ENGINE_EXPORT ContextImpl : public chromium::web::Context { +class WEB_ENGINE_EXPORT ContextImpl : public fuchsia::web::Context { public: // |browser_context| must outlive ContextImpl. explicit ContextImpl(content::BrowserContext* browser_context); @@ -41,11 +41,12 @@ // Returns |true| if JS injection was enabled for this Context. bool IsJavaScriptInjectionAllowed(); - // chromium::web::Context implementation. - void CreateFrame(fidl::InterfaceRequest<chromium::web::Frame> frame) override; + // fuchsia::web::Context implementation. + void CreateFrame(fidl::InterfaceRequest<fuchsia::web::Frame> frame) override; // Gets the underlying FrameImpl service object associated with a connected // |frame_ptr| client. + FrameImpl* GetFrameImplForTest(fuchsia::web::FramePtr* frame_ptr); FrameImpl* GetFrameImplForTest(chromium::web::FramePtr* frame_ptr); private:
diff --git a/fuchsia/engine/browser/frame_impl.cc b/fuchsia/engine/browser/frame_impl.cc index ed0b2c0..29ad5c99 100644 --- a/fuchsia/engine/browser/frame_impl.cc +++ b/fuchsia/engine/browser/frame_impl.cc
@@ -4,14 +4,11 @@ #include "fuchsia/engine/browser/frame_impl.h" -#include <zircon/syscalls.h> - -#include <string> +#include <limits> #include "base/bind_helpers.h" #include "base/fuchsia/fuchsia_logging.h" -#include "base/logging.h" -#include "base/run_loop.h" +#include "base/strings/strcat.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "content/public/browser/browser_thread.h" @@ -23,7 +20,6 @@ #include "content/public/common/was_activated_option.h" #include "fuchsia/base/mem_buffer_util.h" #include "fuchsia/engine/browser/context_impl.h" -#include "fuchsia/engine/browser/legacy_message_port_bridge.h" #include "fuchsia/engine/browser/message_port_impl.h" #include "mojo/public/cpp/system/platform_handle.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" @@ -37,6 +33,11 @@ namespace { +// logging::LogSeverity does not define a value to disable logging so set a +// value much lower than logging::LOG_VERBOSE here. +const logging::LogSeverity kLogSeverityNone = + std::numeric_limits<logging::LogSeverity>::min(); + // Layout manager that allows only one child window and stretches it to fill the // parent. class LayoutManagerImpl : public aura::LayoutManager { @@ -75,40 +76,54 @@ DISALLOW_COPY_AND_ASSIGN(LayoutManagerImpl); }; -chromium::web::NavigationEntry ConvertContentNavigationEntry( +fuchsia::web::NavigationState ConvertContentNavigationEntry( content::NavigationEntry* entry) { DCHECK(entry); - chromium::web::NavigationEntry converted; - converted.title = base::UTF16ToUTF8(entry->GetTitleForDisplay()); - converted.url = entry->GetURL().spec(); - converted.is_error = - entry->GetPageType() == content::PageType::PAGE_TYPE_ERROR; + + fuchsia::web::NavigationState converted; + converted.set_title(base::UTF16ToUTF8(entry->GetTitleForDisplay())); + converted.set_url(entry->GetURL().spec()); + + switch (entry->GetPageType()) { + case content::PageType::PAGE_TYPE_NORMAL: + case content::PageType::PAGE_TYPE_INTERSTITIAL: + converted.set_page_type(fuchsia::web::PageType::NORMAL); + break; + case content::PageType::PAGE_TYPE_ERROR: + converted.set_page_type(fuchsia::web::PageType::ERROR); + break; + } return converted; } -// Computes the observable differences between |entry_1| and |entry_2|. +// Computes the observable differences between |old_entry| and |new_entry|. // Returns true if they are different, |false| if their observable fields are // identical. -bool ComputeNavigationEvent(const chromium::web::NavigationEntry& old_entry, - const chromium::web::NavigationEntry& new_entry, - chromium::web::NavigationEvent* computed_event) { - DCHECK(computed_event); +bool DiffNavigationEntries(const fuchsia::web::NavigationState& old_entry, + const fuchsia::web::NavigationState& new_entry, + fuchsia::web::NavigationState* difference) { + DCHECK(difference); bool is_changed = false; - if (old_entry.title != new_entry.title) { + DCHECK(new_entry.has_title()); + if (!old_entry.has_title() || (new_entry.title() != old_entry.title())) { is_changed = true; - computed_event->title = new_entry.title; + difference->set_title(new_entry.title()); } - if (old_entry.url != new_entry.url) { + DCHECK(new_entry.has_url()); + if (!old_entry.has_url() || (new_entry.url() != old_entry.url())) { is_changed = true; - computed_event->url = new_entry.url; + difference->set_url(new_entry.url()); } - computed_event->is_error = new_entry.is_error; - if (old_entry.is_error != new_entry.is_error) + DCHECK(new_entry.has_page_type()); + if (!old_entry.has_page_type() || + (new_entry.page_type() != old_entry.page_type())) { is_changed = true; + difference->set_page_type(new_entry.page_type()); + } return is_changed; } @@ -180,12 +195,33 @@ DISALLOW_COPY_AND_ASSIGN(ScenicWindowTreeHost); }; +logging::LogSeverity ConsoleLogLevelToLoggingSeverity( + fuchsia::web::ConsoleLogLevel level) { + switch (level) { + case fuchsia::web::ConsoleLogLevel::NONE: + return kLogSeverityNone; + case fuchsia::web::ConsoleLogLevel::DEBUG: + return logging::LOG_VERBOSE; + case fuchsia::web::ConsoleLogLevel::INFO: + return logging::LOG_INFO; + case fuchsia::web::ConsoleLogLevel::WARN: + return logging::LOG_WARNING; + case fuchsia::web::ConsoleLogLevel::ERROR: + return logging::LOG_ERROR; + } + NOTREACHED() + << "Unknown log level: " + << static_cast<std::underlying_type<fuchsia::web::ConsoleLogLevel>::type>( + level); +} + } // namespace FrameImpl::FrameImpl(std::unique_ptr<content::WebContents> web_contents, ContextImpl* context, - fidl::InterfaceRequest<chromium::web::Frame> frame_request) + fidl::InterfaceRequest<fuchsia::web::Frame> frame_request) : web_contents_(std::move(web_contents)), + log_level_(kLogSeverityNone), context_(context), binding_(this, std::move(frame_request)), weak_factory_(this) { @@ -209,29 +245,6 @@ return zx::unowned_channel(binding_.channel()); } -bool FrameImpl::ShouldCreateWebContents( - content::WebContents* web_contents, - content::RenderFrameHost* opener, - content::SiteInstance* source_site_instance, - int32_t route_id, - int32_t main_frame_route_id, - int32_t main_frame_widget_route_id, - content::mojom::WindowContainerType window_container_type, - const GURL& opener_url, - const std::string& frame_name, - const GURL& target_url, - const std::string& partition_id, - content::SessionStorageNamespace* session_storage_namespace) { - DCHECK_EQ(web_contents, web_contents_.get()); - - // Prevent any child WebContents (popup windows, tabs, etc.) from spawning. - // TODO(crbug.com/888131): Implement support for popup windows. - NOTIMPLEMENTED() << "Ignored popup window request for URL: " - << target_url.spec(); - - return false; -} - void FrameImpl::CreateView(fuchsia::ui::views::ViewToken view_token) { // If a View to this Frame is already active then disconnect it. TearDownView(); @@ -264,85 +277,50 @@ window_tree_host_->Show(); } -void FrameImpl::CreateView2( - zx::eventpair view_token_value, - fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> incoming_services, - fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> outgoing_services) { - fuchsia::ui::views::ViewToken view_token; - view_token.value = std::move(view_token_value); - CreateView(std::move(view_token)); -} - void FrameImpl::GetNavigationController( - fidl::InterfaceRequest<chromium::web::NavigationController> controller) { + fidl::InterfaceRequest<fuchsia::web::NavigationController> controller) { controller_bindings_.AddBinding(this, std::move(controller)); } -void FrameImpl::SetJavaScriptLogLevel(chromium::web::LogLevel level) { - log_level_ = level; -} - -void FrameImpl::SetNavigationEventObserver( - fidl::InterfaceHandle<chromium::web::NavigationEventObserver> observer) { - // Reset the event buffer state. - waiting_for_navigation_event_ack_ = false; - cached_navigation_state_ = {}; - pending_navigation_event_ = {}; - pending_navigation_event_is_dirty_ = false; - - if (observer) { - navigation_observer_.Bind(std::move(observer)); - navigation_observer_.set_error_handler( - [this](zx_status_t status) { SetNavigationEventObserver(nullptr); }); - } else { - navigation_observer_.Unbind(); - } -} - -void FrameImpl::ExecuteJavaScript(std::vector<std::string> origins, - fuchsia::mem::Buffer script, - chromium::web::ExecuteMode mode, - ExecuteJavaScriptCallback callback) { - if (mode == chromium::web::ExecuteMode::ON_PAGE_LOAD) { - // TODO(https://crbug.com/946235): Remove this. - AddJavaScriptBindings(next_transitional_bindings_id_++, std::move(origins), - std::move(script), std::move(callback)); - return; - } else if (mode != chromium::web::ExecuteMode::IMMEDIATE_ONCE) { - // Unknown mode, ignored. - callback(false); - return; - } - +void FrameImpl::ExecuteJavaScriptNoResult( + std::vector<std::string> origins, + fuchsia::mem::Buffer script, + ExecuteJavaScriptNoResultCallback callback) { + fuchsia::web::Frame_ExecuteJavaScriptNoResult_Result result; if (!context_->IsJavaScriptInjectionAllowed()) { - callback(false); + result.set_err(fuchsia::web::FrameError::INTERNAL_ERROR); + callback(std::move(result)); return; } if (!IsOriginWhitelisted(web_contents_->GetLastCommittedURL(), origins)) { - callback(false); + result.set_err(fuchsia::web::FrameError::INVALID_ORIGIN); + callback(std::move(result)); return; } base::string16 script_utf16; if (!cr_fuchsia::ReadUTF8FromVMOAsUTF16(script, &script_utf16)) { - LOG(WARNING) << "Script is not valid UTF8."; - callback(false); + result.set_err(fuchsia::web::FrameError::BUFFER_NOT_UTF8); + callback(std::move(result)); return; } web_contents_->GetMainFrame()->ExecuteJavaScript(script_utf16, base::NullCallback()); - - callback(true); + result.set_response(fuchsia::web::Frame_ExecuteJavaScriptNoResult_Response()); + callback(std::move(result)); } -void FrameImpl::AddJavaScriptBindings(uint64_t id, - std::vector<std::string> origins, - fuchsia::mem::Buffer script, - AddJavaScriptBindingsCallback callback) { +void FrameImpl::AddBeforeLoadJavaScript( + uint64_t id, + std::vector<std::string> origins, + fuchsia::mem::Buffer script, + AddBeforeLoadJavaScriptCallback callback) { + fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result; if (!context_->IsJavaScriptInjectionAllowed()) { - callback(false); + result.set_err(fuchsia::web::FrameError::INTERNAL_ERROR); + callback(std::move(result)); return; } @@ -350,18 +328,14 @@ // it can be efficiently shared with multiple renderer processes. base::string16 script_utf16; if (!cr_fuchsia::ReadUTF8FromVMOAsUTF16(script, &script_utf16)) { - callback(false); + result.set_err(fuchsia::web::FrameError::BUFFER_NOT_UTF8); + callback(std::move(result)); return; } // Create a read-only VMO from |script|. fuchsia::mem::Buffer script_buffer = cr_fuchsia::MemBufferFromString16(script_utf16); - if (!script_buffer.vmo) { - LOG(WARNING) << "Couldn't read script contents from VMO."; - callback(false); - return; - } // Wrap the VMO into a read-only shared-memory container that Mojo can work // with. @@ -382,69 +356,108 @@ before_load_scripts_[id] = OriginScopedScript(origins, std::move(script_region_mojo)); - callback(true); + result.set_response(fuchsia::web::Frame_AddBeforeLoadJavaScript_Response()); + callback(std::move(result)); } -void FrameImpl::RemoveJavaScriptBindings( - uint64_t id, - RemoveJavaScriptBindingsCallback callback) { +void FrameImpl::RemoveBeforeLoadJavaScript(uint64_t id) { before_load_scripts_.erase(id); for (auto script_id_iter = before_load_scripts_order_.begin(); script_id_iter != before_load_scripts_order_.end(); ++script_id_iter) { if (*script_id_iter == id) { before_load_scripts_order_.erase(script_id_iter); - callback(true); return; } } - - callback(false); } -void FrameImpl::PostMessage(chromium::web::WebMessage message, - std::string target_origin, +void FrameImpl::PostMessage(std::string origin, + fuchsia::web::WebMessage message, PostMessageCallback callback) { constexpr char kWildcardOrigin[] = "*"; - if (target_origin.empty()) { - callback(false); + fuchsia::web::Frame_PostMessage_Result result; + if (origin.empty()) { + result.set_err(fuchsia::web::FrameError::INVALID_ORIGIN); + callback(std::move(result)); return; } - base::Optional<base::string16> target_origin_utf16; - if (target_origin != kWildcardOrigin) - target_origin_utf16 = base::UTF8ToUTF16(target_origin); + if (!message.has_data()) { + result.set_err(fuchsia::web::FrameError::NO_DATA_IN_MESSAGE); + callback(std::move(result)); + return; + } + + base::Optional<base::string16> origin_utf16; + if (origin != kWildcardOrigin) + origin_utf16 = base::UTF8ToUTF16(origin); base::string16 data_utf16; - if (!cr_fuchsia::ReadUTF8FromVMOAsUTF16(message.data, &data_utf16)) { - DLOG(WARNING) << "PostMessage() rejected non-UTF8 |message.data|."; - callback(false); + if (!cr_fuchsia::ReadUTF8FromVMOAsUTF16(message.data(), &data_utf16)) { + result.set_err(fuchsia::web::FrameError::BUFFER_NOT_UTF8); + callback(std::move(result)); return; } // Include outgoing MessagePorts in the message. std::vector<mojo::ScopedMessagePipeHandle> message_ports; - if (message.outgoing_transfer) { - if (!message.outgoing_transfer->is_message_port()) { - DLOG(WARNING) << "|outgoing_transfer| is not a MessagePort."; - callback(false); - return; + if (message.has_outgoing_transfer()) { + // Verify that all the Transferables are valid before we start allocating + // resources to them. + for (const fuchsia::web::OutgoingTransferable& outgoing : + message.outgoing_transfer()) { + if (!outgoing.is_message_port()) { + result.set_err(fuchsia::web::FrameError::INTERNAL_ERROR); + callback(std::move(result)); + return; + } } - mojo::ScopedMessagePipeHandle port = LegacyMessagePortBridge::FromFidl( - std::move(message.outgoing_transfer->message_port())); - if (!port) { - callback(false); - return; + for (fuchsia::web::OutgoingTransferable& outgoing : + *message.mutable_outgoing_transfer()) { + mojo::ScopedMessagePipeHandle port = + MessagePortImpl::FromFidl(std::move(outgoing.message_port())); + if (!port) { + result.set_err(fuchsia::web::FrameError::INTERNAL_ERROR); + callback(std::move(result)); + return; + } + message_ports.push_back(std::move(port)); } - message_ports.push_back(std::move(port)); } content::MessagePortProvider::PostMessageToFrame( - web_contents_.get(), base::string16(), target_origin_utf16, + web_contents_.get(), base::string16(), origin_utf16, std::move(data_utf16), std::move(message_ports)); - callback(true); + result.set_response(fuchsia::web::Frame_PostMessage_Response()); + callback(std::move(result)); +} + +void FrameImpl::SetNavigationEventListener( + fidl::InterfaceHandle<fuchsia::web::NavigationEventListener> listener) { + // Reset the event buffer state. + waiting_for_navigation_event_ack_ = false; + cached_navigation_state_ = {}; + pending_navigation_event_ = {}; + pending_navigation_event_is_dirty_ = false; + + if (listener) { + navigation_listener_.Bind(std::move(listener)); + navigation_listener_.set_error_handler( + [this](zx_status_t status) { SetNavigationEventListener(nullptr); }); + } else { + navigation_listener_.Unbind(); + } +} + +void FrameImpl::SetJavaScriptLogLevel(fuchsia::web::ConsoleLogLevel level) { + log_level_ = ConsoleLogLevelToLoggingSeverity(level); +} + +void FrameImpl::SetEnableInput(bool enable_input) { + discarding_event_filter_.set_discard_events(!enable_input); } FrameImpl::OriginScopedScript::OriginScopedScript() = default; @@ -481,9 +494,9 @@ } void FrameImpl::OnNavigationEntryChanged(content::NavigationEntry* entry) { - chromium::web::NavigationEntry entry_converted = + fuchsia::web::NavigationState entry_converted = ConvertContentNavigationEntry(entry); - pending_navigation_event_is_dirty_ |= ComputeNavigationEvent( + pending_navigation_event_is_dirty_ |= DiffNavigationEntries( cached_navigation_state_, entry_converted, &pending_navigation_event_); cached_navigation_state_ = std::move(entry_converted); base::ThreadTaskRunnerHandle::Get()->PostTask( @@ -492,7 +505,7 @@ } void FrameImpl::MaybeSendNavigationEvent() { - if (!navigation_observer_) + if (!navigation_listener_) return; if (!pending_navigation_event_is_dirty_ || @@ -505,7 +518,7 @@ // Send the event to the observer and, upon acknowledgement, revisit this // function to send another update. - navigation_observer_->OnNavigationStateChanged( + navigation_listener_->OnNavigationStateChanged( std::move(pending_navigation_event_), [this]() { waiting_for_navigation_event_ack_ = false; MaybeSendNavigationEvent(); @@ -514,21 +527,31 @@ pending_navigation_event_ = {}; } -void FrameImpl::LoadUrl(std::string url, chromium::web::LoadUrlParams params) { +void FrameImpl::LoadUrl(std::string url, + fuchsia::web::LoadUrlParams params, + LoadUrlCallback callback) { + fuchsia::web::NavigationController_LoadUrl_Result result; GURL validated_url(url); if (!validated_url.is_valid()) { - // TODO(crbug.com/934539): Add type epitaph. - DLOG(WARNING) << "Invalid URL: " << url; + result.set_err(fuchsia::web::NavigationControllerError::INVALID_URL); + callback(std::move(result)); return; } content::NavigationController::LoadURLParams params_converted(validated_url); if (params.has_headers()) { - std::vector<base::StringPiece> extra_headers; + std::vector<std::string> extra_headers; extra_headers.reserve(params.headers().size()); for (const auto& header : params.headers()) { - extra_headers.push_back(base::StringPiece( - reinterpret_cast<const char*>(header.data()), header.size())); + // TODO(crbug.com/964732): Check there is no colon in |header_name|. + base::StringPiece header_name( + reinterpret_cast<const char*>(header.name.data()), + header.name.size()); + base::StringPiece header_value( + reinterpret_cast<const char*>(header.value.data()), + header.value.size()); + extra_headers.emplace_back( + base::StrCat({header_name, ": ", header_value})); } params_converted.extra_headers = base::JoinString(extra_headers, "\n"); } @@ -543,7 +566,10 @@ } else { params_converted.was_activated = content::WasActivatedOption::kNo; } + web_contents_->GetController().LoadURLWithParams(params_converted); + result.set_response(fuchsia::web::NavigationController_LoadUrl_Response()); + callback(std::move(result)); } void FrameImpl::GoBack() { @@ -560,29 +586,88 @@ web_contents_->Stop(); } -void FrameImpl::Reload(chromium::web::ReloadType type) { +void FrameImpl::Reload(fuchsia::web::ReloadType type) { content::ReloadType internal_reload_type; switch (type) { - case chromium::web::ReloadType::PARTIAL_CACHE: + case fuchsia::web::ReloadType::PARTIAL_CACHE: internal_reload_type = content::ReloadType::NORMAL; break; - case chromium::web::ReloadType::NO_CACHE: + case fuchsia::web::ReloadType::NO_CACHE: internal_reload_type = content::ReloadType::BYPASSING_CACHE; break; } web_contents_->GetController().Reload(internal_reload_type, false); } -void FrameImpl::GetVisibleEntry(GetVisibleEntryCallback callback) { +void FrameImpl::GetVisibleEntry( + fuchsia::web::NavigationController::GetVisibleEntryCallback callback) { content::NavigationEntry* entry = web_contents_->GetController().GetVisibleEntry(); if (!entry) { - callback(nullptr); + callback({}); return; } - chromium::web::NavigationEntry output = ConvertContentNavigationEntry(entry); - callback(std::make_unique<chromium::web::NavigationEntry>(std::move(output))); + callback(ConvertContentNavigationEntry(entry)); +} + +bool FrameImpl::ShouldCreateWebContents( + content::WebContents* web_contents, + content::RenderFrameHost* opener, + content::SiteInstance* source_site_instance, + int32_t route_id, + int32_t main_frame_route_id, + int32_t main_frame_widget_route_id, + content::mojom::WindowContainerType window_container_type, + const GURL& opener_url, + const std::string& frame_name, + const GURL& target_url, + const std::string& partition_id, + content::SessionStorageNamespace* session_storage_namespace) { + DCHECK_EQ(web_contents, web_contents_.get()); + + // Prevent any child WebContents (popup windows, tabs, etc.) from spawning. + // TODO(crbug.com/888131): Implement support for popup windows. + NOTIMPLEMENTED() << "Ignored popup window request for URL: " + << target_url.spec(); + + return false; +} + +bool FrameImpl::DidAddMessageToConsole(content::WebContents* source, + int32_t level, + const base::string16& message, + int32_t line_no, + const base::string16& source_id) { + if (log_level_ > level) { + return false; + } + + std::string formatted_message = + base::StringPrintf("%s:%d : %s", base::UTF16ToUTF8(source_id).data(), + line_no, base::UTF16ToUTF8(message).data()); + switch (level) { + case logging::LOG_VERBOSE: + LOG(INFO) << "debug:" << formatted_message; + break; + case logging::LOG_INFO: + LOG(INFO) << "info:" << formatted_message; + break; + case logging::LOG_WARNING: + LOG(WARNING) << "warn:" << formatted_message; + break; + case logging::LOG_ERROR: + LOG(ERROR) << "error:" << formatted_message; + break; + default: + DLOG(WARNING) << "Unknown log level: " << level; + return false; + } + + if (console_log_message_hook_) + console_log_message_hook_.Run(formatted_message); + + return true; } void FrameImpl::DidFinishLoad(content::RenderFrameHost* render_frame_host, @@ -623,48 +708,3 @@ void FrameImpl::TitleWasSet(content::NavigationEntry* entry) { OnNavigationEntryChanged(entry); } - -bool FrameImpl::DidAddMessageToConsole(content::WebContents* source, - int32_t level, - const base::string16& message, - int32_t line_no, - const base::string16& source_id) { - if (static_cast<std::underlying_type<chromium::web::LogLevel>::type>( - log_level_) > level) { - return false; - } - - std::string formatted_message = - base::StringPrintf("%s:%d : %s", base::UTF16ToUTF8(source_id).data(), - line_no, base::UTF16ToUTF8(message).data()); - switch (level) { - case static_cast<std::underlying_type<chromium::web::LogLevel>::type>( - chromium::web::LogLevel::DEBUG): - LOG(INFO) << "debug:" << formatted_message; - break; - case static_cast<std::underlying_type<chromium::web::LogLevel>::type>( - chromium::web::LogLevel::INFO): - LOG(INFO) << "info:" << formatted_message; - break; - case static_cast<std::underlying_type<chromium::web::LogLevel>::type>( - chromium::web::LogLevel::WARN): - LOG(WARNING) << "warn:" << formatted_message; - break; - case static_cast<std::underlying_type<chromium::web::LogLevel>::type>( - chromium::web::LogLevel::ERROR): - LOG(ERROR) << "error:" << formatted_message; - break; - default: - DLOG(WARNING) << "Unknown log level: " << level; - return false; - } - - if (console_log_message_hook_) - console_log_message_hook_.Run(formatted_message); - - return true; -} - -void FrameImpl::SetEnableInput(bool enable_input) { - discarding_event_filter_.set_discard_events(!enable_input); -}
diff --git a/fuchsia/engine/browser/frame_impl.h b/fuchsia/engine/browser/frame_impl.h index f036fc5..ab527388 100644 --- a/fuchsia/engine/browser/frame_impl.h +++ b/fuchsia/engine/browser/frame_impl.h
@@ -5,6 +5,7 @@ #ifndef FUCHSIA_ENGINE_BROWSER_FRAME_IMPL_H_ #define FUCHSIA_ENGINE_BROWSER_FRAME_IMPL_H_ +#include <fuchsia/web/cpp/fidl.h> #include <lib/fidl/cpp/binding_set.h> #include <lib/zx/channel.h> #include <list> @@ -21,7 +22,6 @@ #include "content/public/browser/web_contents_observer.h" #include "fuchsia/engine/browser/discarding_event_filter.h" #include "fuchsia/engine/on_load_script_injector.mojom.h" -#include "fuchsia/fidl/chromium/web/cpp/fidl.h" #include "ui/aura/window_tree_host.h" #include "ui/wm/core/focus_controller.h" #include "url/gurl.h" @@ -36,48 +36,17 @@ class ContextImpl; -// Implementation of Frame from //fuchsia/fidl/frame.fidl. -// Implements a Frame service, which is a wrapper for a WebContents instance. -class FrameImpl : public chromium::web::Frame, - public chromium::web::NavigationController, +// Implementation of fuchsia.web.Frame based on content::WebContents. +class FrameImpl : public fuchsia::web::Frame, + public fuchsia::web::NavigationController, public content::WebContentsObserver, public content::WebContentsDelegate { public: FrameImpl(std::unique_ptr<content::WebContents> web_contents, ContextImpl* context, - fidl::InterfaceRequest<chromium::web::Frame> frame_request); + fidl::InterfaceRequest<fuchsia::web::Frame> frame_request); ~FrameImpl() override; - // chromium::web::Frame implementation. - void CreateView(fuchsia::ui::views::ViewToken view_token) override; - void CreateView2( - zx::eventpair view_token, - fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> incoming_services, - fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> outgoing_services) - override; - void GetNavigationController( - fidl::InterfaceRequest<chromium::web::NavigationController> controller) - override; - void SetJavaScriptLogLevel(chromium::web::LogLevel level) override; - void SetNavigationEventObserver( - fidl::InterfaceHandle<chromium::web::NavigationEventObserver> observer) - override; - void ExecuteJavaScript(std::vector<std::string> origins, - fuchsia::mem::Buffer script, - chromium::web::ExecuteMode mode, - ExecuteJavaScriptCallback callback) override; - void PostMessage(chromium::web::WebMessage message, - std::string target_origin, - PostMessageCallback callback) override; - void SetEnableInput(bool enable_input) override; - void AddJavaScriptBindings(uint64_t id, - std::vector<std::string> origins, - fuchsia::mem::Buffer script, - AddJavaScriptBindingsCallback callback) override; - void RemoveJavaScriptBindings( - uint64_t id, - RemoveJavaScriptBindingsCallback callback) override; - zx::unowned_channel GetBindingChannelForTest() const; content::WebContents* web_contents_for_test() { return web_contents_.get(); } bool has_view_for_test() { return window_tree_host_ != nullptr; } @@ -93,6 +62,30 @@ FRIEND_TEST_ALL_PREFIXES(FrameImplTest, ReloadFrame); FRIEND_TEST_ALL_PREFIXES(FrameImplTest, Stop); + // fuchsia::web::Frame implementation. + void CreateView(fuchsia::ui::views::ViewToken view_token) override; + void GetNavigationController( + fidl::InterfaceRequest<fuchsia::web::NavigationController> controller) + override; + void ExecuteJavaScriptNoResult( + std::vector<std::string> origins, + fuchsia::mem::Buffer script, + ExecuteJavaScriptNoResultCallback callback) override; + void AddBeforeLoadJavaScript( + uint64_t id, + std::vector<std::string> origins, + fuchsia::mem::Buffer script, + AddBeforeLoadJavaScriptCallback callback) override; + void RemoveBeforeLoadJavaScript(uint64_t id) override; + void PostMessage(std::string origin, + fuchsia::web::WebMessage message, + fuchsia::web::Frame::PostMessageCallback callback) override; + void SetNavigationEventListener( + fidl::InterfaceHandle<fuchsia::web::NavigationEventListener> listener) + override; + void SetJavaScriptLogLevel(fuchsia::web::ConsoleLogLevel level) override; + void SetEnableInput(bool enable_input) override; + class OriginScopedScript { public: OriginScopedScript(); @@ -126,12 +119,14 @@ // to be reported. void MaybeSendNavigationEvent(); - // chromium::web::NavigationController implementation. - void LoadUrl(std::string url, chromium::web::LoadUrlParams params) override; + // fuchsia::web::NavigationController implementation. + void LoadUrl(std::string url, + fuchsia::web::LoadUrlParams params, + LoadUrlCallback callback) override; void GoBack() override; void GoForward() override; void Stop() override; - void Reload(chromium::web::ReloadType type) override; + void Reload(fuchsia::web::ReloadType type) override; void GetVisibleEntry(GetVisibleEntryCallback callback) override; // content::WebContentsDelegate implementation. @@ -166,20 +161,19 @@ std::unique_ptr<wm::FocusController> focus_controller_; DiscardingEventFilter discarding_event_filter_; - chromium::web::NavigationEventObserverPtr navigation_observer_; - chromium::web::NavigationEntry cached_navigation_state_; - chromium::web::NavigationEvent pending_navigation_event_; + fuchsia::web::NavigationEventListenerPtr navigation_listener_; + fuchsia::web::NavigationState cached_navigation_state_; + fuchsia::web::NavigationState pending_navigation_event_; bool waiting_for_navigation_event_ack_; bool pending_navigation_event_is_dirty_; - chromium::web::LogLevel log_level_ = chromium::web::LogLevel::NONE; + logging::LogSeverity log_level_; std::map<uint64_t, OriginScopedScript> before_load_scripts_; std::vector<uint64_t> before_load_scripts_order_; ContextImpl* context_ = nullptr; - uint64_t next_transitional_bindings_id_ = 0x80000000; base::RepeatingCallback<void(base::StringPiece)> console_log_message_hook_; - fidl::Binding<chromium::web::Frame> binding_; - fidl::BindingSet<chromium::web::NavigationController> controller_bindings_; + fidl::Binding<fuchsia::web::Frame> binding_; + fidl::BindingSet<fuchsia::web::NavigationController> controller_bindings_; base::WeakPtrFactory<FrameImpl> weak_factory_;
diff --git a/fuchsia/engine/browser/frame_impl_browsertest.cc b/fuchsia/engine/browser/frame_impl_browsertest.cc index 84306bc..2bf2017 100644 --- a/fuchsia/engine/browser/frame_impl_browsertest.cc +++ b/fuchsia/engine/browser/frame_impl_browsertest.cc
@@ -531,7 +531,7 @@ controller->LoadUrl(url.spec(), chromium::web::LoadUrlParams()); navigation_observer_.RunUntilNavigationEquals(url, kPage1Title); - EXPECT_FALSE(*remove_result); + EXPECT_TRUE(*remove_result); } // Test JS injection by using Javascript to trigger document navigation. @@ -1221,32 +1221,3 @@ EXPECT_THAT(iter->second.headers, testing::Contains(testing::Key("X-2ExtraHeaders"))); } - -// TODO(crbug.com/931831): Remove this test once the transition is complete. -IN_PROC_BROWSER_TEST_F(RequestMonitoringFrameImplBrowserTest, - DeprecatedExtraHeaders) { - chromium::web::FramePtr frame = CreateFrame(); - - chromium::web::LoadUrlParams load_url_params; - load_url_params.set_headers({StringToUnsignedVector("X-ExtraHeaders: 1"), - StringToUnsignedVector("X-2ExtraHeaders: 2")}); - - chromium::web::NavigationControllerPtr controller; - frame->GetNavigationController(controller.NewRequest()); - - const GURL page_url(embedded_test_server()->GetURL(kPage1Path)); - - controller->LoadUrl(page_url.spec(), std::move(load_url_params)); - navigation_observer_.RunUntilNavigationEquals(page_url, kPage1Title); - - base::RunLoop().RunUntilIdle(); - - // At this point, the page should be loaded, the server should have received - // the request and the request should be in the map. - const auto iter = accumulated_requests_.find(page_url); - ASSERT_NE(iter, accumulated_requests_.end()); - EXPECT_THAT(iter->second.headers, - testing::Contains(testing::Key("X-ExtraHeaders"))); - EXPECT_THAT(iter->second.headers, - testing::Contains(testing::Key("X-2ExtraHeaders"))); -}
diff --git a/fuchsia/engine/browser/legacy_context_bridge.cc b/fuchsia/engine/browser/legacy_context_bridge.cc new file mode 100644 index 0000000..ef18ecca --- /dev/null +++ b/fuchsia/engine/browser/legacy_context_bridge.cc
@@ -0,0 +1,33 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "fuchsia/engine/browser/legacy_context_bridge.h" + +#include "base/fuchsia/fuchsia_logging.h" +#include "fuchsia/engine/browser/legacy_frame_bridge.h" + +LegacyContextBridge::LegacyContextBridge( + fidl::InterfaceRequest<chromium::web::Context> request, + fuchsia::web::ContextPtr handle) + : binding_(this, std::move(request)), context_(std::move(handle)) { + binding_.set_error_handler([this](zx_status_t status) { + ZX_LOG_IF(ERROR, status != ZX_ERR_PEER_CLOSED, status) + << " |binding_| disconnected."; + delete this; + }); + context_.set_error_handler([this](zx_status_t status) { + ZX_LOG_IF(ERROR, status != ZX_ERR_PEER_CLOSED, status) + << " |context_| disconnected."; + delete this; + }); +} + +LegacyContextBridge::~LegacyContextBridge() = default; + +void LegacyContextBridge::CreateFrame( + fidl::InterfaceRequest<chromium::web::Frame> frame) { + fuchsia::web::FramePtr fuchsia_frame; + context_->CreateFrame(fuchsia_frame.NewRequest()); + new LegacyFrameBridge(std::move(frame), std::move(fuchsia_frame)); +}
diff --git a/fuchsia/engine/browser/legacy_context_bridge.h b/fuchsia/engine/browser/legacy_context_bridge.h new file mode 100644 index 0000000..3d3996e --- /dev/null +++ b/fuchsia/engine/browser/legacy_context_bridge.h
@@ -0,0 +1,37 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FUCHSIA_ENGINE_BROWSER_LEGACY_CONTEXT_BRIDGE_H_ +#define FUCHSIA_ENGINE_BROWSER_LEGACY_CONTEXT_BRIDGE_H_ + +#include <fuchsia/web/cpp/fidl.h> +#include <lib/fidl/cpp/binding.h> + +#include "base/macros.h" +#include "fuchsia/fidl/chromium/web/cpp/fidl.h" + +// Allows chromium::web::Context clients to connect to fuchsia::web::Context +// instances. +// +// LegacyContextBridge instances are self-managed; they destroy themselves when +// the connection with either end is terminated. +class LegacyContextBridge : public chromium::web::Context { + public: + LegacyContextBridge(fidl::InterfaceRequest<chromium::web::Context> request, + fuchsia::web::ContextPtr handle); + + private: + // Non-public to ensure that only this object may destroy itself. + ~LegacyContextBridge() override; + + // chromium::web::Context implementation. + void CreateFrame(fidl::InterfaceRequest<chromium::web::Frame> frame) override; + + fidl::Binding<chromium::web::Context> binding_; + fuchsia::web::ContextPtr context_; + + DISALLOW_COPY_AND_ASSIGN(LegacyContextBridge); +}; + +#endif // FUCHSIA_ENGINE_BROWSER_LEGACY_CONTEXT_BRIDGE_H_
diff --git a/fuchsia/engine/browser/legacy_frame_bridge.cc b/fuchsia/engine/browser/legacy_frame_bridge.cc new file mode 100644 index 0000000..4bede06 --- /dev/null +++ b/fuchsia/engine/browser/legacy_frame_bridge.cc
@@ -0,0 +1,164 @@ +// 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 "fuchsia/engine/browser/legacy_frame_bridge.h" + +#include "base/fuchsia/fuchsia_logging.h" +#include "fuchsia/engine/browser/legacy_message_port_bridge.h" +#include "fuchsia/engine/browser/legacy_navigation_controller_bridge.h" +#include "fuchsia/engine/browser/legacy_navigation_event_listener_bridge.h" + +namespace { + +// All the active LegacyFrameBridge instances. Used for testing. +std::set<LegacyFrameBridge*> g_legacy_bridges; + +} // namespace + +LegacyFrameBridge::LegacyFrameBridge( + fidl::InterfaceRequest<chromium::web::Frame> request, + fuchsia::web::FramePtr handle) + : binding_(this, std::move(request)), frame_(std::move(handle)) { + binding_.set_error_handler([this](zx_status_t status) { + ZX_LOG_IF(ERROR, status != ZX_ERR_PEER_CLOSED, status) + << " |binding_| disconnected."; + delete this; + }); + frame_.set_error_handler([this](zx_status_t status) { + ZX_LOG_IF(ERROR, status != ZX_ERR_PEER_CLOSED, status) + << " |frame_| disconnected."; + delete this; + }); + g_legacy_bridges.insert(this); +} + +// static +fuchsia::web::FramePtr* LegacyFrameBridge::GetFramePtrForTest( + chromium::web::FramePtr* frame_ptr) { + // Find the LegacyFrameBridge whose channel is connected to |frame_ptr| by + // inspecting the related_koids of active LegacyFrameBridges. + zx_info_handle_basic_t handle_info; + zx_status_t status = frame_ptr->channel().get_info( + ZX_INFO_HANDLE_BASIC, &handle_info, sizeof(zx_info_handle_basic_t), + nullptr, nullptr); + ZX_CHECK(status == ZX_OK, status) << "zx_object_get_info"; + zx_handle_t client_handle_koid = handle_info.koid; + + for (LegacyFrameBridge* legacy_frame : g_legacy_bridges) { + status = legacy_frame->binding_.channel().get_info( + ZX_INFO_HANDLE_BASIC, &handle_info, sizeof(zx_info_handle_basic_t), + nullptr, nullptr); + ZX_CHECK(status == ZX_OK, status) << "zx_object_get_info"; + + if (client_handle_koid == handle_info.related_koid) + return &legacy_frame->frame_; + } + + return nullptr; +} + +LegacyFrameBridge::~LegacyFrameBridge() { + g_legacy_bridges.erase(this); +} + +void LegacyFrameBridge::CreateView(fuchsia::ui::views::ViewToken view_token) { + frame_->CreateView(std::move(view_token)); +} + +void LegacyFrameBridge::CreateView2( + zx::eventpair view_token_value, + fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> incoming_services, + fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> outgoing_services) { + fuchsia::ui::views::ViewToken view_token; + view_token.value = std::move(view_token_value); + CreateView(std::move(view_token)); +} + +void LegacyFrameBridge::GetNavigationController( + fidl::InterfaceRequest<chromium::web::NavigationController> controller) { + fuchsia::web::NavigationControllerPtr fuchsia_controller; + frame_->GetNavigationController(fuchsia_controller.NewRequest()); + new LegacyNavigationControllerBridge(std::move(controller), + std::move(fuchsia_controller)); +} + +void LegacyFrameBridge::ExecuteJavaScript(std::vector<std::string> origins, + fuchsia::mem::Buffer script, + chromium::web::ExecuteMode mode, + ExecuteJavaScriptCallback callback) { + if (mode == chromium::web::ExecuteMode::ON_PAGE_LOAD) { + AddJavaScriptBindings(next_transitional_bindings_id_++, std::move(origins), + std::move(script), std::move(callback)); + return; + } else if (mode != chromium::web::ExecuteMode::IMMEDIATE_ONCE) { + // Unknown mode, ignored. + callback(false); + return; + } + + frame_->ExecuteJavaScriptNoResult( + std::move(origins), std::move(script), + [callback = std::move(callback)]( + fuchsia::web::Frame_ExecuteJavaScriptNoResult_Result result) { + callback(result.is_response()); + }); +} + +void LegacyFrameBridge::AddJavaScriptBindings( + uint64_t id, + std::vector<std::string> origins, + fuchsia::mem::Buffer script, + AddJavaScriptBindingsCallback callback) { + frame_->AddBeforeLoadJavaScript( + id, std::move(origins), std::move(script), + [callback = std::move(callback)]( + fuchsia::web::Frame_AddBeforeLoadJavaScript_Result result) { + callback(result.is_response()); + }); +} + +void LegacyFrameBridge::RemoveJavaScriptBindings( + uint64_t id, + RemoveJavaScriptBindingsCallback callback) { + frame_->RemoveBeforeLoadJavaScript(id); + callback(true); +} + +void LegacyFrameBridge::PostMessage( + chromium::web::WebMessage message, + std::string target_origin, + chromium::web::Frame::PostMessageCallback callback) { + base::Optional<fuchsia::web::WebMessage> converted = + LegacyMessagePortBridge::ConvertFromLegacyWebMessage(message); + if (!converted) { + callback(false); + return; + } + frame_->PostMessage(std::move(target_origin), std::move(converted.value()), + [callback = std::move(callback)]( + fuchsia::web::Frame_PostMessage_Result result) { + callback(result.is_response()); + }); +} + +void LegacyFrameBridge::SetNavigationEventObserver( + fidl::InterfaceHandle<chromium::web::NavigationEventObserver> observer) { + if (observer) { + fuchsia::web::NavigationEventListenerPtr listener; + new LegacyNavigationEventListenerBridge(listener.NewRequest(), + observer.Bind()); + frame_->SetNavigationEventListener(std::move(listener)); + } else { + frame_->SetNavigationEventListener(nullptr); + } +} + +void LegacyFrameBridge::SetJavaScriptLogLevel(chromium::web::LogLevel level) { + frame_->SetJavaScriptLogLevel( + static_cast<fuchsia::web::ConsoleLogLevel>(level)); +} + +void LegacyFrameBridge::SetEnableInput(bool enable_input) { + frame_->SetEnableInput(enable_input); +}
diff --git a/fuchsia/engine/browser/legacy_frame_bridge.h b/fuchsia/engine/browser/legacy_frame_bridge.h new file mode 100644 index 0000000..d13f72f --- /dev/null +++ b/fuchsia/engine/browser/legacy_frame_bridge.h
@@ -0,0 +1,70 @@ +// 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 FUCHSIA_ENGINE_BROWSER_LEGACY_FRAME_BRIDGE_H_ +#define FUCHSIA_ENGINE_BROWSER_LEGACY_FRAME_BRIDGE_H_ + +#include <fuchsia/web/cpp/fidl.h> +#include <lib/fidl/cpp/binding.h> +#include <set> + +#include "base/containers/unique_ptr_adapters.h" +#include "base/macros.h" +#include "fuchsia/fidl/chromium/web/cpp/fidl.h" + +// Allows chromium::web::Frame clients to connect to fuchsia::web::Frame +// instances. +// +// LegacyFrameBridge instances are self-managed; they destroy themselves +// when the connection with either end is terminated. +class LegacyFrameBridge : public chromium::web::Frame { + public: + LegacyFrameBridge(fidl::InterfaceRequest<chromium::web::Frame> request, + fuchsia::web::FramePtr handle); + + static fuchsia::web::FramePtr* GetFramePtrForTest( + chromium::web::FramePtr* frame_ptr); + + private: + // Non-public to ensure that only this object may destroy itself. + ~LegacyFrameBridge() override; + + // chromium::web::Frame implementation. + void CreateView(fuchsia::ui::views::ViewToken view_token) override; + void CreateView2( + zx::eventpair view_token, + fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> incoming_services, + fidl::InterfaceHandle<fuchsia::sys::ServiceProvider> outgoing_services) + override; + void GetNavigationController( + fidl::InterfaceRequest<chromium::web::NavigationController> controller) + override; + void ExecuteJavaScript(std::vector<std::string> origins, + fuchsia::mem::Buffer script, + chromium::web::ExecuteMode mode, + ExecuteJavaScriptCallback callback) override; + void AddJavaScriptBindings(uint64_t id, + std::vector<std::string> origins, + fuchsia::mem::Buffer script, + AddJavaScriptBindingsCallback callback) override; + void RemoveJavaScriptBindings( + uint64_t id, + RemoveJavaScriptBindingsCallback callback) override; + void PostMessage(chromium::web::WebMessage message, + std::string target_origin, + PostMessageCallback callback) override; + void SetNavigationEventObserver( + fidl::InterfaceHandle<chromium::web::NavigationEventObserver> observer) + override; + void SetJavaScriptLogLevel(chromium::web::LogLevel level) override; + void SetEnableInput(bool enable_input) override; + + fidl::Binding<chromium::web::Frame> binding_; + fuchsia::web::FramePtr frame_; + uint64_t next_transitional_bindings_id_ = 0x80000000; + + DISALLOW_COPY_AND_ASSIGN(LegacyFrameBridge); +}; + +#endif // FUCHSIA_ENGINE_BROWSER_LEGACY_FRAME_BRIDGE_H_
diff --git a/fuchsia/engine/browser/legacy_message_port_bridge.cc b/fuchsia/engine/browser/legacy_message_port_bridge.cc index 5c8537d..bc089431 100644 --- a/fuchsia/engine/browser/legacy_message_port_bridge.cc +++ b/fuchsia/engine/browser/legacy_message_port_bridge.cc
@@ -7,21 +7,34 @@ #include "base/fuchsia/fuchsia_logging.h" // static -mojo::ScopedMessagePipeHandle LegacyMessagePortBridge::FromFidl( - fidl::InterfaceRequest<chromium::web::MessagePort> port) { - fuchsia::web::MessagePortPtr fuchsia_port; - mojo::ScopedMessagePipeHandle content_port = - MessagePortImpl::FromFidl(fuchsia_port.NewRequest()); +base::Optional<fuchsia::web::WebMessage> +LegacyMessagePortBridge::ConvertFromLegacyWebMessage( + chromium::web::WebMessage& message) { + fuchsia::web::WebMessage converted; + converted.set_data(std::move(message.data)); - new LegacyMessagePortBridge(std::move(port), std::move(fuchsia_port)); - return content_port; + if (message.outgoing_transfer) { + if (!message.outgoing_transfer->is_message_port()) + return base::nullopt; + + fuchsia::web::OutgoingTransferable outgoing; + fuchsia::web::MessagePortPtr fuchsia_port; + outgoing.set_message_port(fuchsia_port.NewRequest()); + new LegacyMessagePortBridge( + std::move(message.outgoing_transfer->message_port()), + std::move(fuchsia_port)); + std::vector<fuchsia::web::OutgoingTransferable> transferables; + transferables.push_back(std::move(outgoing)); + converted.set_outgoing_transfer(std::move(transferables)); + } + + return converted; } LegacyMessagePortBridge::LegacyMessagePortBridge( fidl::InterfaceRequest<chromium::web::MessagePort> request, fuchsia::web::MessagePortPtr handle) - : binding_(this), message_port_(std::move(handle)) { - binding_.Bind(std::move(request)); + : binding_(this, std::move(request)), message_port_(std::move(handle)) { binding_.set_error_handler([this](zx_status_t status) { ZX_LOG_IF(ERROR, status != ZX_ERR_PEER_CLOSED, status) << " |binding_| disconnected."; @@ -38,27 +51,15 @@ void LegacyMessagePortBridge::PostMessage(chromium::web::WebMessage message, PostMessageCallback callback) { - fuchsia::web::WebMessage converted; - converted.set_data(std::move(message.data)); - - if (message.outgoing_transfer) { - if (!message.outgoing_transfer->is_message_port()) { - callback(false); - return; - } - fuchsia::web::OutgoingTransferable outgoing; - fuchsia::web::MessagePortPtr fuchsia_port; - outgoing.set_message_port(fuchsia_port.NewRequest()); - new LegacyMessagePortBridge( - std::move(message.outgoing_transfer->message_port()), - std::move(fuchsia_port)); - std::vector<fuchsia::web::OutgoingTransferable> transferables; - transferables.push_back(std::move(outgoing)); - converted.set_outgoing_transfer(std::move(transferables)); + base::Optional<fuchsia::web::WebMessage> converted = + ConvertFromLegacyWebMessage(message); + if (!converted) { + callback(false); + return; } message_port_->PostMessage( - std::move(converted), + std::move(*converted), [callback = std::move(callback)]( fuchsia::web::MessagePort_PostMessage_Result result) { callback(result.is_response());
diff --git a/fuchsia/engine/browser/legacy_message_port_bridge.h b/fuchsia/engine/browser/legacy_message_port_bridge.h index ab5f86d0..cde670c 100644 --- a/fuchsia/engine/browser/legacy_message_port_bridge.h +++ b/fuchsia/engine/browser/legacy_message_port_bridge.h
@@ -7,20 +7,19 @@ #include <lib/fidl/cpp/binding.h> +#include "base/optional.h" #include "fuchsia/engine/browser/message_port_impl.h" #include "fuchsia/fidl/chromium/web/cpp/fidl.h" -// Bridges chromium::web::MessagePort and fuchsia::web::MessagePort calls. +// Allows chromium::web::MessagePort clients to connect to +// fuchsia::web::MessagePort instances. // // LegacyMessagePortBridge are self-managed; they destroy themselves when -// the connection with either the chromium::web::MessagePort or -// fuchsia::web::MessagePort is terminated. +// the connection with either end is terminated. class LegacyMessagePortBridge : public chromium::web::MessagePort { public: - // Creates a connected MessagePort from a FIDL MessagePort request and - // returns a handle to its peer Mojo pipe. - static mojo::ScopedMessagePipeHandle FromFidl( - fidl::InterfaceRequest<chromium::web::MessagePort> port); + static base::Optional<fuchsia::web::WebMessage> ConvertFromLegacyWebMessage( + chromium::web::WebMessage& message); private: explicit LegacyMessagePortBridge(
diff --git a/fuchsia/engine/browser/legacy_navigation_controller_bridge.cc b/fuchsia/engine/browser/legacy_navigation_controller_bridge.cc new file mode 100644 index 0000000..4ad1850 --- /dev/null +++ b/fuchsia/engine/browser/legacy_navigation_controller_bridge.cc
@@ -0,0 +1,121 @@ +// 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 "fuchsia/engine/browser/legacy_navigation_controller_bridge.h" + +#include "base/fuchsia/fuchsia_logging.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "fuchsia/engine/browser/legacy_frame_bridge.h" + +namespace { + +std::unique_ptr<chromium::web::NavigationEntry> ConvertToLegacyNavigationEntry( + const fuchsia::web::NavigationState& entry) { + chromium::web::NavigationEntry converted; + bool is_changed = false; + + if (entry.has_title()) { + converted.title = entry.title(); + is_changed = true; + } + if (entry.has_url()) { + converted.url = entry.url(); + is_changed = true; + } + if (entry.has_page_type()) { + converted.is_error = entry.page_type() == fuchsia::web::PageType::ERROR; + is_changed = true; + } + + return is_changed + ? std::make_unique<chromium::web::NavigationEntry>(converted) + : nullptr; +} + +std::vector<uint8_t> StringToUnsignedVector(base::StringPiece str) { + const uint8_t* raw_data = reinterpret_cast<const uint8_t*>(str.data()); + return std::vector<uint8_t>(raw_data, raw_data + str.length()); +} + +} // namespace + +LegacyNavigationControllerBridge::LegacyNavigationControllerBridge( + fidl::InterfaceRequest<chromium::web::NavigationController> request, + fuchsia::web::NavigationControllerPtr handle) + : binding_(this, std::move(request)), + navigation_controller_(std::move(handle)) { + binding_.set_error_handler([this](zx_status_t status) { + ZX_LOG_IF(ERROR, status != ZX_ERR_PEER_CLOSED, status) + << " |binding_| disconnected."; + delete this; + }); + navigation_controller_.set_error_handler([this](zx_status_t status) { + ZX_LOG_IF(ERROR, status != ZX_ERR_PEER_CLOSED, status) + << " |navigation_controller_| disconnected."; + delete this; + }); +} + +LegacyNavigationControllerBridge::~LegacyNavigationControllerBridge() = default; + +void LegacyNavigationControllerBridge::LoadUrl( + std::string url, + chromium::web::LoadUrlParams params) { + fuchsia::web::LoadUrlParams converted; + if (params.has_type()) + converted.set_type(static_cast<fuchsia::web::LoadUrlReason>(params.type())); + if (params.has_referrer_url()) + converted.set_referrer_url(std::move(*params.mutable_referrer_url())); + if (params.has_was_user_activated()) + converted.set_was_user_activated(params.was_user_activated()); + if (params.has_headers()) { + std::vector<fuchsia::net::http::Header> headers; + headers.reserve(params.headers().size()); + for (const auto& header : params.headers()) { + base::StringPiece full_header( + reinterpret_cast<const char*>(header.data())); + std::vector<std::string> values = base::SplitString( + full_header, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + if (values.size() != 2) { + // Badly formed header. Ignore. + continue; + } + fuchsia::net::http::Header http_header; + http_header.name = StringToUnsignedVector(values[0]); + http_header.value = StringToUnsignedVector(values[1]); + headers.emplace_back(http_header); + } + converted.set_headers(std::move(headers)); + } + + navigation_controller_->LoadUrl( + std::move(url), std::move(converted), + [](fuchsia::web::NavigationController_LoadUrl_Result) {}); +} + +void LegacyNavigationControllerBridge::GoBack() { + navigation_controller_->GoBack(); +} + +void LegacyNavigationControllerBridge::GoForward() { + navigation_controller_->GoForward(); +} + +void LegacyNavigationControllerBridge::Stop() { + navigation_controller_->Stop(); +} + +void LegacyNavigationControllerBridge::Reload(chromium::web::ReloadType type) { + navigation_controller_->Reload(static_cast<fuchsia::web::ReloadType>(type)); +} + +void LegacyNavigationControllerBridge::GetVisibleEntry( + GetVisibleEntryCallback callback) { + navigation_controller_->GetVisibleEntry( + [callback = std::move(callback)]( + fuchsia::web::NavigationState navigation_entry) { + callback(ConvertToLegacyNavigationEntry(navigation_entry)); + }); +}
diff --git a/fuchsia/engine/browser/legacy_navigation_controller_bridge.h b/fuchsia/engine/browser/legacy_navigation_controller_bridge.h new file mode 100644 index 0000000..72920881 --- /dev/null +++ b/fuchsia/engine/browser/legacy_navigation_controller_bridge.h
@@ -0,0 +1,45 @@ +// 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 FUCHSIA_ENGINE_BROWSER_LEGACY_NAVIGATION_CONTROLLER_BRIDGE_H_ +#define FUCHSIA_ENGINE_BROWSER_LEGACY_NAVIGATION_CONTROLLER_BRIDGE_H_ + +#include <fuchsia/web/cpp/fidl.h> +#include <lib/fidl/cpp/binding.h> +#include <string> + +#include "base/macros.h" +#include "fuchsia/fidl/chromium/web/cpp/fidl.h" + +// Allows chromium::web::gNavigationControllerePort clients to connect to +// fuchsia::web::NavigationController instances. +// +// LegacyNavigationControllerBridge instances are self-managed; they destroy +// themselves when the connection with either end is terminated. +class LegacyNavigationControllerBridge + : public chromium::web::NavigationController { + public: + LegacyNavigationControllerBridge( + fidl::InterfaceRequest<chromium::web::NavigationController> request, + fuchsia::web::NavigationControllerPtr handle); + + private: + // Non-public to ensure that only this object may destroy itself. + ~LegacyNavigationControllerBridge() override; + + // chromium::web::NavigationController implementation. + void LoadUrl(std::string url, chromium::web::LoadUrlParams params) override; + void GoBack() override; + void GoForward() override; + void Stop() override; + void Reload(chromium::web::ReloadType type) override; + void GetVisibleEntry(GetVisibleEntryCallback callback) override; + + fidl::Binding<chromium::web::NavigationController> binding_; + fuchsia::web::NavigationControllerPtr navigation_controller_; + + DISALLOW_COPY_AND_ASSIGN(LegacyNavigationControllerBridge); +}; + +#endif // FUCHSIA_ENGINE_BROWSER_LEGACY_NAVIGATION_CONTROLLER_BRIDGE_H_
diff --git a/fuchsia/engine/browser/legacy_navigation_event_listener_bridge.cc b/fuchsia/engine/browser/legacy_navigation_event_listener_bridge.cc new file mode 100644 index 0000000..c398d4f --- /dev/null +++ b/fuchsia/engine/browser/legacy_navigation_event_listener_bridge.cc
@@ -0,0 +1,52 @@ +// 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 "fuchsia/engine/browser/legacy_navigation_event_listener_bridge.h" + +#include "base/fuchsia/fuchsia_logging.h" + +namespace { + +chromium::web::NavigationEvent ConvertToLegacyNavigationEvent( + const fuchsia::web::NavigationState& entry) { + chromium::web::NavigationEvent converted; + + if (entry.has_title()) + converted.title = entry.title(); + if (entry.has_url()) + converted.url = entry.url(); + if (entry.has_page_type()) + converted.is_error = entry.page_type() == fuchsia::web::PageType::ERROR; + + return converted; +} + +} // namespace + +LegacyNavigationEventListenerBridge::LegacyNavigationEventListenerBridge( + fidl::InterfaceRequest<fuchsia::web::NavigationEventListener> request, + chromium::web::NavigationEventObserverPtr handle) + : binding_(this, std::move(request)), observer_(std::move(handle)) { + binding_.set_error_handler([this](zx_status_t status) { + ZX_LOG_IF(ERROR, status != ZX_ERR_PEER_CLOSED, status) + << " |binding_| disconnected."; + delete this; + }); + observer_.set_error_handler([this](zx_status_t status) { + ZX_LOG_IF(ERROR, status != ZX_ERR_PEER_CLOSED, status) + << " |observer_| disconnected."; + delete this; + }); +} + +LegacyNavigationEventListenerBridge::~LegacyNavigationEventListenerBridge() = + default; + +void LegacyNavigationEventListenerBridge::OnNavigationStateChanged( + fuchsia::web::NavigationState change, + OnNavigationStateChangedCallback callback) { + observer_->OnNavigationStateChanged(ConvertToLegacyNavigationEvent(change), + std::move(callback)); + // [callback = std::move(callback)]() { callback(); }); +}
diff --git a/fuchsia/engine/browser/legacy_navigation_event_listener_bridge.h b/fuchsia/engine/browser/legacy_navigation_event_listener_bridge.h new file mode 100644 index 0000000..c6cedf8 --- /dev/null +++ b/fuchsia/engine/browser/legacy_navigation_event_listener_bridge.h
@@ -0,0 +1,41 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FUCHSIA_ENGINE_BROWSER_LEGACY_NAVIGATION_EVENT_LISTENER_BRIDGE_H_ +#define FUCHSIA_ENGINE_BROWSER_LEGACY_NAVIGATION_EVENT_LISTENER_BRIDGE_H_ + +#include <fuchsia/web/cpp/fidl.h> +#include <lib/fidl/cpp/binding.h> + +#include "base/macros.h" +#include "fuchsia/fidl/chromium/web/cpp/fidl.h" + +// Allows fuchsia::web::NavigationEventListener clients to connect to +// chromium::web::NavigationEventObserver instances. +// +// LegacyNavigationEventListenerBridge instances are self-managed; they destroy +// themselves when the connection with either end is terminated. +class LegacyNavigationEventListenerBridge + : public fuchsia::web::NavigationEventListener { + public: + LegacyNavigationEventListenerBridge( + fidl::InterfaceRequest<fuchsia::web::NavigationEventListener> request, + chromium::web::NavigationEventObserverPtr handle); + + private: + // Non-public to ensure that only this object may destroy itself. + ~LegacyNavigationEventListenerBridge() override; + + // fuchsia::web::NavigationEventListener implementation. + void OnNavigationStateChanged( + fuchsia::web::NavigationState change, + OnNavigationStateChangedCallback callback) override; + + fidl::Binding<fuchsia::web::NavigationEventListener> binding_; + chromium::web::NavigationEventObserverPtr observer_; + + DISALLOW_COPY_AND_ASSIGN(LegacyNavigationEventListenerBridge); +}; + +#endif // FUCHSIA_ENGINE_BROWSER_LEGACY_NAVIGATION_EVENT_LISTENER_BRIDGE_H_
diff --git a/fuchsia/engine/browser/web_engine_browser_main_parts.cc b/fuchsia/engine/browser/web_engine_browser_main_parts.cc index ad40fc259..5021c69 100644 --- a/fuchsia/engine/browser/web_engine_browser_main_parts.cc +++ b/fuchsia/engine/browser/web_engine_browser_main_parts.cc
@@ -12,6 +12,7 @@ #include "base/logging.h" #include "content/public/browser/render_frame_host.h" #include "fuchsia/engine/browser/context_impl.h" +#include "fuchsia/engine/browser/legacy_context_bridge.h" #include "fuchsia/engine/browser/web_engine_browser_context.h" #include "fuchsia/engine/browser/web_engine_screen.h" #include "fuchsia/engine/common.h" @@ -46,9 +47,12 @@ context_service_ = std::make_unique<ContextImpl>(browser_context_.get()); - context_binding_ = std::make_unique<fidl::Binding<chromium::web::Context>>( - context_service_.get(), fidl::InterfaceRequest<chromium::web::Context>( - std::move(context_channel_))); + fuchsia::web::ContextPtr fuchsia_context; + context_binding_ = std::make_unique<fidl::Binding<fuchsia::web::Context>>( + context_service_.get(), fuchsia_context.NewRequest()); + new LegacyContextBridge(fidl::InterfaceRequest<chromium::web::Context>( + std::move(context_channel_)), + std::move(fuchsia_context)); // Quit the browser main loop when the Context connection is dropped. context_binding_->set_error_handler([this](zx_status_t status) {
diff --git a/fuchsia/engine/browser/web_engine_browser_main_parts.h b/fuchsia/engine/browser/web_engine_browser_main_parts.h index 3418b262..35a1933b 100644 --- a/fuchsia/engine/browser/web_engine_browser_main_parts.h +++ b/fuchsia/engine/browser/web_engine_browser_main_parts.h
@@ -5,6 +5,7 @@ #ifndef FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_BROWSER_MAIN_PARTS_H_ #define FUCHSIA_ENGINE_BROWSER_WEB_ENGINE_BROWSER_MAIN_PARTS_H_ +#include <fuchsia/web/cpp/fidl.h> #include <lib/fidl/cpp/binding.h> #include <memory> @@ -13,7 +14,6 @@ #include "content/public/browser/browser_main_parts.h" #include "fuchsia/engine/browser/context_impl.h" #include "fuchsia/engine/browser/web_engine_browser_context.h" -#include "fuchsia/fidl/chromium/web/cpp/fidl.h" namespace display { class Screen; @@ -40,7 +40,7 @@ std::unique_ptr<display::Screen> screen_; std::unique_ptr<WebEngineBrowserContext> browser_context_; std::unique_ptr<ContextImpl> context_service_; - std::unique_ptr<fidl::Binding<chromium::web::Context>> context_binding_; + std::unique_ptr<fidl::Binding<fuchsia::web::Context>> context_binding_; base::OnceClosure quit_closure_;
diff --git a/fuchsia/fidl/web/frame.fidl b/fuchsia/fidl/web/frame.fidl index 8533fb1..58648d32 100644 --- a/fuchsia/fidl/web/frame.fidl +++ b/fuchsia/fidl/web/frame.fidl
@@ -99,7 +99,7 @@ fuchsia.mem.Buffer script) -> (bool success); /// Removes a previously added JavaScript snippet identified by |id|. - /// Returns |true| if the script was found and removed. + /// Always returns |true|, it is safe to ignore the return value. RemoveJavaScriptBindings(uint64 id) -> (bool removed); /// Posts a message to the frame's onMessage handler.
diff --git a/gpu/ipc/service/direct_composition_child_surface_win.cc b/gpu/ipc/service/direct_composition_child_surface_win.cc index 16726c5b..edbd2c3 100644 --- a/gpu/ipc/service/direct_composition_child_surface_win.cc +++ b/gpu/ipc/service/direct_composition_child_surface_win.cc
@@ -59,14 +59,13 @@ return false; } Microsoft::WRL::ComPtr<IDXGIDevice> dxgi_device; - d3d11_device.CopyTo(dxgi_device.GetAddressOf()); + d3d11_device.As(&dxgi_device); DCHECK(dxgi_device); Microsoft::WRL::ComPtr<IDXGIAdapter> dxgi_adapter; - dxgi_device->GetAdapter(dxgi_adapter.GetAddressOf()); + dxgi_device->GetAdapter(&dxgi_adapter); DCHECK(dxgi_adapter); Microsoft::WRL::ComPtr<IDXGIFactory5> dxgi_factory; - if (FAILED(dxgi_adapter->GetParent( - IID_PPV_ARGS(dxgi_factory.GetAddressOf())))) { + if (FAILED(dxgi_adapter->GetParent(IID_PPV_ARGS(&dxgi_factory)))) { DLOG(ERROR) << "Not using swap chain tearing because failed to retrieve " "IDXGIFactory5 interface"; return false; @@ -166,7 +165,7 @@ // may flicker black when it's first presented. first_swap_ = false; Microsoft::WRL::ComPtr<IDXGIDevice2> dxgi_device2; - d3d11_device_.CopyTo(dxgi_device2.GetAddressOf()); + d3d11_device_.As(&dxgi_device2); DCHECK(dxgi_device2); base::WaitableEvent event( base::WaitableEvent::ResetPolicy::AUTOMATIC, @@ -294,7 +293,7 @@ // become transparent. HRESULT hr = dcomp_device_->CreateSurface( size_.width(), size_.height(), output_format, - DXGI_ALPHA_MODE_PREMULTIPLIED, dcomp_surface_.GetAddressOf()); + DXGI_ALPHA_MODE_PREMULTIPLIED, &dcomp_surface_); if (FAILED(hr)) { DLOG(ERROR) << "CreateSurface failed with error " << std::hex << hr; return false; @@ -307,13 +306,13 @@ DXGI_ALPHA_MODE alpha_mode = has_alpha_ ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE; Microsoft::WRL::ComPtr<IDXGIDevice> dxgi_device; - d3d11_device_.CopyTo(dxgi_device.GetAddressOf()); + d3d11_device_.As(&dxgi_device); DCHECK(dxgi_device); Microsoft::WRL::ComPtr<IDXGIAdapter> dxgi_adapter; - dxgi_device->GetAdapter(dxgi_adapter.GetAddressOf()); + dxgi_device->GetAdapter(&dxgi_adapter); DCHECK(dxgi_adapter); Microsoft::WRL::ComPtr<IDXGIFactory2> dxgi_factory; - dxgi_adapter->GetParent(IID_PPV_ARGS(dxgi_factory.GetAddressOf())); + dxgi_adapter->GetParent(IID_PPV_ARGS(&dxgi_factory)); DCHECK(dxgi_factory); DXGI_SWAP_CHAIN_DESC1 desc = {}; @@ -330,7 +329,7 @@ desc.Flags = IsSwapChainTearingSupported() ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0; HRESULT hr = dxgi_factory->CreateSwapChainForComposition( - d3d11_device_.Get(), &desc, nullptr, swap_chain_.GetAddressOf()); + d3d11_device_.Get(), &desc, nullptr, &swap_chain_); first_swap_ = true; if (FAILED(hr)) { DLOG(ERROR) << "CreateSwapChainForComposition failed with error " @@ -345,15 +344,15 @@ if (dcomp_surface_) { POINT update_offset; const RECT rect = rectangle.ToRECT(); - HRESULT hr = dcomp_surface_->BeginDraw( - &rect, IID_PPV_ARGS(draw_texture_.GetAddressOf()), &update_offset); + HRESULT hr = dcomp_surface_->BeginDraw(&rect, IID_PPV_ARGS(&draw_texture_), + &update_offset); if (FAILED(hr)) { DLOG(ERROR) << "BeginDraw failed with error " << std::hex << hr; return false; } draw_offset_ = gfx::Point(update_offset) - rectangle.origin(); } else { - swap_chain_->GetBuffer(0, IID_PPV_ARGS(draw_texture_.GetAddressOf())); + swap_chain_->GetBuffer(0, IID_PPV_ARGS(&draw_texture_)); } DCHECK(draw_texture_);
diff --git a/gpu/ipc/service/direct_composition_surface_win.cc b/gpu/ipc/service/direct_composition_surface_win.cc index 7404e5d0..d8470b1 100644 --- a/gpu/ipc/service/direct_composition_surface_win.cc +++ b/gpu/ipc/service/direct_composition_surface_win.cc
@@ -182,20 +182,20 @@ } Microsoft::WRL::ComPtr<IDXGIDevice> dxgi_device; - if (FAILED(d3d11_device.CopyTo(dxgi_device.GetAddressOf()))) { + if (FAILED(d3d11_device.As(&dxgi_device))) { DLOG(ERROR) << "Failed to retrieve DXGI device"; return; } Microsoft::WRL::ComPtr<IDXGIAdapter> dxgi_adapter; - if (FAILED(dxgi_device->GetAdapter(dxgi_adapter.GetAddressOf()))) { + if (FAILED(dxgi_device->GetAdapter(&dxgi_adapter))) { DLOG(ERROR) << "Failed to retrieve DXGI adapter"; return; } // This will fail if the D3D device is "Microsoft Basic Display Adapter". Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device; - if (FAILED(d3d11_device.CopyTo(video_device.GetAddressOf()))) { + if (FAILED(d3d11_device.As(&video_device))) { DLOG(ERROR) << "Failed to retrieve video device"; return; } @@ -204,11 +204,11 @@ unsigned int i = 0; while (true) { Microsoft::WRL::ComPtr<IDXGIOutput> output; - if (FAILED(dxgi_adapter->EnumOutputs(i++, output.GetAddressOf()))) + if (FAILED(dxgi_adapter->EnumOutputs(i++, &output))) break; DCHECK(output); Microsoft::WRL::ComPtr<IDXGIOutput3> output3; - if (FAILED(output.CopyTo(output3.GetAddressOf()))) + if (FAILED(output.As(&output3))) continue; DCHECK(output3); @@ -224,7 +224,7 @@ if (info.overlay_format == OverlayFormat::kNV12) { UINT color_space_support_flags = 0; Microsoft::WRL::ComPtr<IDXGIOutput4> output4; - if (FAILED(output.CopyTo(output4.GetAddressOf()))) + if (FAILED(output.As(&output4))) continue; if (FAILED(output4->CheckOverlayColorSpaceSupport( @@ -338,28 +338,10 @@ Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device, Microsoft::WRL::ComPtr<IDCompositionDevice2> dcomp_device); - // Information about the back buffer surface. Cached on every frame to check - // if back buffer changed from previous frame. Back buffer uses either a swap - // chain, or a direct composition surface depending on whether layers are used - // or not (see DirectCompositionSurfaceChildWin). - struct BackbufferInfo { - // Set if backbuffer is using a swap chain currently. - Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain; - - // Set if backbuffer is using a direct composition surface currently. - Microsoft::WRL::ComPtr<IDCompositionSurface> dcomp_surface; - uint64_t dcomp_surface_serial; - - bool operator!=(const BackbufferInfo& other) const { - return std::tie(swap_chain, dcomp_surface, dcomp_surface_serial) != - std::tie(other.swap_chain, other.dcomp_surface, - other.dcomp_surface_serial); - } - }; // Present pending overlay layers, and perform a direct composition commit if - // necessary using provided backbuffer info for creating backbuffer visual. - // Returns true if presentation and commit succeeded. - bool CommitAndClearPendingOverlays(BackbufferInfo backbuffer_info); + // necessary. Returns true if presentation and commit succeeded. + bool CommitAndClearPendingOverlays( + DirectCompositionChildSurfaceWin* root_surface); // Schedule an overlay layer for the next CommitAndClearPendingOverlays call. bool ScheduleDCLayer(const ui::DCRendererLayerParams& params); @@ -371,6 +353,8 @@ bool InitializeVideoProcessor(const gfx::Size& input_size, const gfx::Size& output_size); + void SetNeedsCommit() { needs_commit_ = true; } + const Microsoft::WRL::ComPtr<ID3D11VideoDevice>& video_device() const { return video_device_; } @@ -396,10 +380,6 @@ private: class SwapChainPresenter; - // Update backbuffer visual with provided info. Returns true if the visual - // changed, and a direct composition commit is needed. - bool UpdateBackbufferVisual(BackbufferInfo info); - const GpuDriverBugWorkarounds workarounds_; Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_; @@ -418,14 +398,21 @@ gfx::Size video_input_size_; gfx::Size video_output_size_; - // Direct composition visual for window. - Microsoft::WRL::ComPtr<IDCompositionVisual2> root_visual_; + // Set to true if a direct composition commit is needed. + bool needs_commit_ = false; - // Direct composition for backbuffer surface. - Microsoft::WRL::ComPtr<IDCompositionVisual2> backbuffer_visual_; + // Set if root surface is using a swap chain currently. + Microsoft::WRL::ComPtr<IDXGISwapChain1> root_swap_chain_; - // Cached backbuffer info for last frame. - BackbufferInfo backbuffer_info_; + // Set if root surface is using a direct composition surface currently. + Microsoft::WRL::ComPtr<IDCompositionSurface> root_dcomp_surface_; + uint64_t root_dcomp_surface_serial_; + + // Direct composition visual for root surface. + Microsoft::WRL::ComPtr<IDCompositionVisual2> root_surface_visual_; + + // Root direct composition visual for window dcomp target. + Microsoft::WRL::ComPtr<IDCompositionVisual2> dcomp_root_visual_; // List of pending overlay layers from ScheduleDCLayer(). std::vector<std::unique_ptr<ui::DCRendererLayerParams>> pending_overlays_; @@ -446,11 +433,8 @@ Microsoft::WRL::ComPtr<IDCompositionDevice2> dcomp_device); ~SwapChainPresenter(); - // Present the given overlay to swap chain. |needs_commit| is true if direct - // composition visuals changed, and a commit is needed. Returns true on - // success. - bool PresentToSwapChain(const ui::DCRendererLayerParams& overlay, - bool* needs_commit); + // Present the given overlay to swap chain. Returns true on success. + bool PresentToSwapChain(const ui::DCRendererLayerParams& overlay); const Microsoft::WRL::ComPtr<IDXGISwapChain1>& swap_chain() const { return swap_chain_; @@ -516,18 +500,23 @@ // Returns optimal swap chain size for given layer. gfx::Size CalculateSwapChainSize(const ui::DCRendererLayerParams& params); - // Update direct composition visuals for layer with given swap chain size, and - // returns true if a commit is needed. - bool UpdateVisuals(const ui::DCRendererLayerParams& params, + // Update direct composition visuals for layer with given swap chain size. + void UpdateVisuals(const ui::DCRendererLayerParams& params, const gfx::Size& swap_chain_size); + // Try presenting to a decode swap chain based on various conditions such as + // global state (e.g. finch, NV12 support), texture flags, and transform. + // Returns true on success. See PresentToDecodeSwapChain() for more info. + bool TryPresentToDecodeSwapChain(gl::GLImageDXGI* image_dxgi, + const gfx::Rect& content_rect, + const gfx::Size& swap_chain_size); + // Present to a decode swap chain created from compatible video decoder // buffers using given |image_dxgi| with destination size |swap_chain_size|. - // Sets |needs_commit| to true if a commit is needed. Returns true on success. + // Returns true on success. bool PresentToDecodeSwapChain(gl::GLImageDXGI* image_dxgi, const gfx::Rect& content_rect, - const gfx::Size& swap_chain_size, - bool* needs_commit); + const gfx::Size& swap_chain_size); // Records presentation statistics in UMA and traces (for pixel tests) for the // current swap chain which could either be a regular flip swap chain or a @@ -623,24 +612,24 @@ dcomp_device_ = std::move(dcomp_device); Microsoft::WRL::ComPtr<IDCompositionDesktopDevice> desktop_device; - dcomp_device_.CopyTo(desktop_device.GetAddressOf()); + dcomp_device_.As(&desktop_device); DCHECK(desktop_device); - HRESULT hr = desktop_device->CreateTargetForHwnd( - window, TRUE, dcomp_target_.GetAddressOf()); + HRESULT hr = + desktop_device->CreateTargetForHwnd(window, TRUE, &dcomp_target_); if (FAILED(hr)) { DLOG(ERROR) << "CreateTargetForHwnd failed with error 0x" << std::hex << hr; return false; } - dcomp_device_->CreateVisual(root_visual_.GetAddressOf()); - DCHECK(root_visual_); - dcomp_target_->SetRoot(root_visual_.Get()); + dcomp_device_->CreateVisual(&dcomp_root_visual_); + DCHECK(dcomp_root_visual_); + dcomp_target_->SetRoot(dcomp_root_visual_.Get()); // A visual inherits the interpolation mode of the parent visual by default. // If no visuals set the interpolation mode, the default for the entire visual // tree is nearest neighbor interpolation. // Set the interpolation mode to Linear to get a better upscaling quality. - root_visual_->SetBitmapInterpolationMode( + dcomp_root_visual_->SetBitmapInterpolationMode( DCOMPOSITION_BITMAP_INTERPOLATION_MODE_LINEAR); return true; @@ -650,16 +639,16 @@ const gfx::Size& output_size) { if (!video_device_) { // This can fail if the D3D device is "Microsoft Basic Display Adapter". - if (FAILED(d3d11_device_.CopyTo(video_device_.GetAddressOf()))) { + if (FAILED(d3d11_device_.As(&video_device_))) { DLOG(ERROR) << "Failed to retrieve video device from D3D11 device"; return false; } DCHECK(video_device_); Microsoft::WRL::ComPtr<ID3D11DeviceContext> context; - d3d11_device_->GetImmediateContext(context.GetAddressOf()); + d3d11_device_->GetImmediateContext(&context); DCHECK(context); - context.CopyTo(video_context_.GetAddressOf()); + context.As(&video_context_); DCHECK(video_context_); } @@ -683,7 +672,7 @@ desc.OutputHeight = output_size.height(); desc.Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL; HRESULT hr = video_device_->CreateVideoProcessorEnumerator( - &desc, video_processor_enumerator_.GetAddressOf()); + &desc, &video_processor_enumerator_); if (FAILED(hr)) { DLOG(ERROR) << "CreateVideoProcessorEnumerator failed with error 0x" << std::hex << hr; @@ -691,7 +680,7 @@ } hr = video_device_->CreateVideoProcessor(video_processor_enumerator_.Get(), 0, - video_processor_.GetAddressOf()); + &video_processor_); if (FAILED(hr)) { DLOG(ERROR) << "CreateVideoProcessor failed with error 0x" << std::hex << hr; @@ -799,8 +788,8 @@ desc.MiscFlags = 0; desc.SampleDesc.Count = 1; Microsoft::WRL::ComPtr<ID3D11Texture2D> texture; - HRESULT hr = d3d11_device_->CreateTexture2D( - &desc, nullptr, staging_texture_.GetAddressOf()); + HRESULT hr = + d3d11_device_->CreateTexture2D(&desc, nullptr, &staging_texture_); if (FAILED(hr)) { DLOG(ERROR) << "Creating D3D11 video upload texture failed: " << std::hex << hr; @@ -811,7 +800,7 @@ } Microsoft::WRL::ComPtr<ID3D11DeviceContext> context; - d3d11_device_->GetImmediateContext(context.GetAddressOf()); + d3d11_device_->GetImmediateContext(&context); // TODO(crbug.com/890227): Temporary CHECK for debugging. CHECK(context); @@ -917,19 +906,17 @@ return swap_chain_size; } -bool DCLayerTree::SwapChainPresenter::UpdateVisuals( +void DCLayerTree::SwapChainPresenter::UpdateVisuals( const ui::DCRendererLayerParams& params, const gfx::Size& swap_chain_size) { - bool needs_commit = false; - if (!content_visual_) { DCHECK(!clip_visual_); - dcomp_device_->CreateVisual(clip_visual_.GetAddressOf()); + dcomp_device_->CreateVisual(&clip_visual_); DCHECK(clip_visual_); - dcomp_device_->CreateVisual(content_visual_.GetAddressOf()); + dcomp_device_->CreateVisual(&content_visual_); DCHECK(content_visual_); clip_visual_->AddVisual(content_visual_.Get(), FALSE, nullptr); - needs_commit = true; + layer_tree_->SetNeedsCommit(); } // Visual offset is applied before transform so it behaves similar to how the @@ -951,13 +938,13 @@ if (visual_info_.offset != offset || visual_info_.transform != transform) { visual_info_.offset = offset; visual_info_.transform = transform; - needs_commit = true; + layer_tree_->SetNeedsCommit(); content_visual_->SetOffsetX(offset.x()); content_visual_->SetOffsetY(offset.y()); Microsoft::WRL::ComPtr<IDCompositionMatrixTransform> dcomp_transform; - dcomp_device_->CreateMatrixTransform(dcomp_transform.GetAddressOf()); + dcomp_device_->CreateMatrixTransform(&dcomp_transform); DCHECK(dcomp_transform); // SkMatrix44 is column-major, but D2D_MATRIX_3x2_F is row-major. D2D_MATRIX_3X2_F d2d_matrix = { @@ -972,13 +959,13 @@ visual_info_.clip_rect != params.clip_rect) { visual_info_.is_clipped = params.is_clipped; visual_info_.clip_rect = params.clip_rect; - needs_commit = true; + layer_tree_->SetNeedsCommit(); // DirectComposition clips happen in the pre-transform visual space, while // cc/ clips happen post-transform. So the clip needs to go on a separate // parent visual that's untransformed. if (params.is_clipped) { Microsoft::WRL::ComPtr<IDCompositionRectangleClip> clip; - dcomp_device_->CreateRectangleClip(clip.GetAddressOf()); + dcomp_device_->CreateRectangleClip(&clip); DCHECK(clip); clip->SetLeft(params.clip_rect.x()); clip->SetRight(params.clip_rect.right()); @@ -989,14 +976,85 @@ clip_visual_->SetClip(nullptr); } } - return needs_commit; +} + +bool DCLayerTree::SwapChainPresenter::TryPresentToDecodeSwapChain( + gl::GLImageDXGI* image_dxgi, + const gfx::Rect& content_rect, + const gfx::Size& swap_chain_size) { + if (!base::FeatureList::IsEnabled( + features::kDirectCompositionUseNV12DecodeSwapChain)) + return false; + + auto not_used_reason = DecodeSwapChainNotUsedReason::kFailedToPresent; + + bool nv12_supported = g_overlay_format_used == OverlayFormat::kNV12; + // TODO(sunnyps): Try using decode swap chain for uploaded video images. + if (image_dxgi && nv12_supported && !failed_to_present_decode_swapchain_) { + D3D11_TEXTURE2D_DESC texture_desc = {}; + image_dxgi->texture()->GetDesc(&texture_desc); + + bool is_decoder_texture = texture_desc.BindFlags & D3D11_BIND_DECODER; + + // Decode swap chains do not support shared resources. + // TODO(sunnyps): Find a workaround for when the decoder moves to its own + // thread and D3D device. See https://crbug.com/911847 + bool is_shared_texture = + texture_desc.MiscFlags & + (D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | + D3D11_RESOURCE_MISC_SHARED_NTHANDLE); + + // Rotated videos are not promoted to overlays. We plan to implement + // rotation using video processor instead of via direct composition. Also + // check for skew and any downscaling specified to direct composition. + bool is_overlay_supported_transform = + visual_info_.transform.IsPositiveScaleOrTranslation(); + + // Downscaled video isn't promoted to hardware overlays. We prefer to + // blit into the smaller size so that it can be promoted to a hardware + // overlay. + float swap_chain_scale_x = + swap_chain_size.width() * 1.0f / content_rect.width(); + float swap_chain_scale_y = + swap_chain_size.height() * 1.0f / content_rect.height(); + + is_overlay_supported_transform = is_overlay_supported_transform && + (swap_chain_scale_x >= 1.0f) && + (swap_chain_scale_y >= 1.0f); + + if (is_decoder_texture && !is_shared_texture && + is_overlay_supported_transform) { + if (PresentToDecodeSwapChain(image_dxgi, content_rect, swap_chain_size)) + return true; + ReleaseSwapChainResources(); + failed_to_present_decode_swapchain_ = true; + not_used_reason = DecodeSwapChainNotUsedReason::kFailedToPresent; + DLOG(ERROR) + << "Present to decode swap chain failed - falling back to blit"; + } else if (!is_decoder_texture) { + not_used_reason = DecodeSwapChainNotUsedReason::kNonDecoderTexture; + } else if (is_shared_texture) { + not_used_reason = DecodeSwapChainNotUsedReason::kSharedTexture; + } else if (!is_overlay_supported_transform) { + not_used_reason = DecodeSwapChainNotUsedReason::kIncompatibleTransform; + } + } else if (!image_dxgi) { + not_used_reason = DecodeSwapChainNotUsedReason::kSoftwareFrame; + } else if (!nv12_supported) { + not_used_reason = DecodeSwapChainNotUsedReason::kNv12NotSupported; + } else if (failed_to_present_decode_swapchain_) { + not_used_reason = DecodeSwapChainNotUsedReason::kFailedToPresent; + } + + UMA_HISTOGRAM_ENUMERATION( + "GPU.DirectComposition.DecodeSwapChainNotUsedReason", not_used_reason); + return false; } bool DCLayerTree::SwapChainPresenter::PresentToDecodeSwapChain( gl::GLImageDXGI* image_dxgi, const gfx::Rect& content_rect, - const gfx::Size& swap_chain_size, - bool* needs_commit) { + const gfx::Size& swap_chain_size) { DCHECK(!swap_chain_size.IsEmpty()); Microsoft::WRL::ComPtr<IDXGIResource> decode_resource; @@ -1074,7 +1132,7 @@ DCHECK(decode_surface_); content_visual_->SetContent(decode_surface_.Get()); - *needs_commit = true; + layer_tree_->SetNeedsCommit(); } else if (last_y_image_ == image_dxgi && last_uv_image_ == image_dxgi && swap_chain_size_ == swap_chain_size) { // Early out if we're presenting the same image again. @@ -1136,10 +1194,7 @@ } bool DCLayerTree::SwapChainPresenter::PresentToSwapChain( - const ui::DCRendererLayerParams& params, - bool* needs_commit) { - *needs_commit = false; - + const ui::DCRendererLayerParams& params) { gl::GLImageDXGI* image_dxgi = gl::GLImageDXGI::FromGLImage(params.y_image.get()); gl::GLImageMemory* y_image_memory = @@ -1160,80 +1215,16 @@ if (swap_chain_) { ReleaseSwapChainResources(); content_visual_->SetContent(nullptr); - *needs_commit = true; + layer_tree_->SetNeedsCommit(); } return true; } - if (UpdateVisuals(params, swap_chain_size)) - *needs_commit = true; + UpdateVisuals(params, swap_chain_size); - if (base::FeatureList::IsEnabled( - features::kDirectCompositionUseNV12DecodeSwapChain)) { - auto not_used_reason = DecodeSwapChainNotUsedReason::kFailedToPresent; - - bool nv12_supported = g_overlay_format_used == OverlayFormat::kNV12; - // TODO(sunnyps): Try using decode swap chain for uploaded video images. - if (image_dxgi && nv12_supported && !failed_to_present_decode_swapchain_) { - D3D11_TEXTURE2D_DESC texture_desc = {}; - image_dxgi->texture()->GetDesc(&texture_desc); - - bool is_decoder_texture = texture_desc.BindFlags & D3D11_BIND_DECODER; - - // Decode swap chains do not support shared resources. - // TODO(sunnyps): Find a workaround for when the decoder moves to its own - // thread and D3D device. See https://crbug.com/911847 - bool is_shared_texture = - texture_desc.MiscFlags & - (D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | - D3D11_RESOURCE_MISC_SHARED_NTHANDLE); - - // Rotated videos are not promoted to overlays. We plan to implement - // rotation using video processor instead of via direct composition. Also - // check for skew and any downscaling specified to direct composition. - bool is_overlay_supported_transform = - visual_info_.transform.IsPositiveScaleOrTranslation(); - - // Downscaled video isn't promoted to hardware overlays. We prefer to - // blit into the smaller size so that it can be promoted to a hardware - // overlay. - float swap_chain_scale_x = - swap_chain_size.width() * 1.0f / params.content_rect.width(); - float swap_chain_scale_y = - swap_chain_size.height() * 1.0f / params.content_rect.height(); - - is_overlay_supported_transform = is_overlay_supported_transform && - (swap_chain_scale_x >= 1.0f) && - (swap_chain_scale_y >= 1.0f); - - if (is_decoder_texture && !is_shared_texture && - is_overlay_supported_transform) { - if (PresentToDecodeSwapChain(image_dxgi, params.content_rect, - swap_chain_size, needs_commit)) { - return true; - } - ReleaseSwapChainResources(); - failed_to_present_decode_swapchain_ = true; - not_used_reason = DecodeSwapChainNotUsedReason::kFailedToPresent; - DLOG(ERROR) - << "Present to decode swap chain failed - falling back to blit"; - } else if (!is_decoder_texture) { - not_used_reason = DecodeSwapChainNotUsedReason::kNonDecoderTexture; - } else if (is_shared_texture) { - not_used_reason = DecodeSwapChainNotUsedReason::kSharedTexture; - } else if (!is_overlay_supported_transform) { - not_used_reason = DecodeSwapChainNotUsedReason::kIncompatibleTransform; - } - } else if (!image_dxgi) { - not_used_reason = DecodeSwapChainNotUsedReason::kSoftwareFrame; - } else if (!nv12_supported) { - not_used_reason = DecodeSwapChainNotUsedReason::kNv12NotSupported; - } else if (failed_to_present_decode_swapchain_) { - not_used_reason = DecodeSwapChainNotUsedReason::kFailedToPresent; - } - - UMA_HISTOGRAM_ENUMERATION( - "GPU.DirectComposition.DecodeSwapChainNotUsedReason", not_used_reason); + if (TryPresentToDecodeSwapChain(image_dxgi, params.content_rect, + swap_chain_size)) { + return true; } bool swap_chain_resized = swap_chain_size_ != swap_chain_size; @@ -1251,7 +1242,7 @@ return false; } content_visual_->SetContent(swap_chain_.Get()); - *needs_commit = true; + layer_tree_->SetNeedsCommit(); } else if (last_y_image_ == params.y_image && last_uv_image_ == params.uv_image) { // The swap chain is presenting the same images as last swap, which means @@ -1313,13 +1304,13 @@ // first Present() after this needs to have SyncInterval > 0, or else the // workaround doesn't help. Microsoft::WRL::ComPtr<ID3D11Texture2D> dest_texture; - swap_chain_->GetBuffer(0, IID_PPV_ARGS(dest_texture.GetAddressOf())); + swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dest_texture)); DCHECK(dest_texture); Microsoft::WRL::ComPtr<ID3D11Texture2D> src_texture; - hr = swap_chain_->GetBuffer(1, IID_PPV_ARGS(src_texture.GetAddressOf())); + hr = swap_chain_->GetBuffer(1, IID_PPV_ARGS(&src_texture)); DCHECK(src_texture); Microsoft::WRL::ComPtr<ID3D11DeviceContext> context; - d3d11_device_->GetImmediateContext(context.GetAddressOf()); + d3d11_device_->GetImmediateContext(&context); DCHECK(context); context->CopyResource(dest_texture.Get(), src_texture.Get()); @@ -1327,7 +1318,7 @@ // there still may be a black flicker when presenting expensive content // (e.g. 4k video). Microsoft::WRL::ComPtr<IDXGIDevice2> dxgi_device2; - d3d11_device_.CopyTo(dxgi_device2.GetAddressOf()); + d3d11_device_.As(&dxgi_device2); DCHECK(dxgi_device2); base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); @@ -1429,8 +1420,8 @@ Microsoft::WRL::ComPtr<IDXGISwapChain3> swap_chain3; Microsoft::WRL::ComPtr<ID3D11VideoContext1> context1; - if (SUCCEEDED(swap_chain_.CopyTo(swap_chain3.GetAddressOf())) && - SUCCEEDED(video_context.CopyTo(context1.GetAddressOf()))) { + if (SUCCEEDED(swap_chain_.As(&swap_chain3)) && + SUCCEEDED(video_context.As(&context1))) { DCHECK(swap_chain3); DCHECK(context1); // Set input color space. @@ -1487,7 +1478,7 @@ Microsoft::WRL::ComPtr<ID3D11VideoProcessorInputView> input_view; HRESULT hr = video_device->CreateVideoProcessorInputView( input_texture.Get(), video_processor_enumerator.Get(), &input_desc, - input_view.GetAddressOf()); + &input_view); if (FAILED(hr)) { DLOG(ERROR) << "CreateVideoProcessorInputView failed with error 0x" << std::hex << hr; @@ -1512,7 +1503,7 @@ if (!output_view_) { Microsoft::WRL::ComPtr<ID3D11Texture2D> swap_chain_buffer; - swap_chain_->GetBuffer(0, IID_PPV_ARGS(swap_chain_buffer.GetAddressOf())); + swap_chain_->GetBuffer(0, IID_PPV_ARGS(&swap_chain_buffer)); D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC output_desc = {}; output_desc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D; @@ -1520,7 +1511,7 @@ hr = video_device->CreateVideoProcessorOutputView( swap_chain_buffer.Get(), video_processor_enumerator.Get(), - &output_desc, output_view_.GetAddressOf()); + &output_desc, &output_view_); if (FAILED(hr)) { DLOG(ERROR) << "CreateVideoProcessorOutputView failed with error 0x" << std::hex << hr; @@ -1601,13 +1592,13 @@ ReleaseSwapChainResources(); Microsoft::WRL::ComPtr<IDXGIDevice> dxgi_device; - d3d11_device_.CopyTo(dxgi_device.GetAddressOf()); + d3d11_device_.As(&dxgi_device); DCHECK(dxgi_device); Microsoft::WRL::ComPtr<IDXGIAdapter> dxgi_adapter; - dxgi_device->GetAdapter(dxgi_adapter.GetAddressOf()); + dxgi_device->GetAdapter(&dxgi_adapter); DCHECK(dxgi_adapter); Microsoft::WRL::ComPtr<IDXGIFactoryMedia> media_factory; - dxgi_adapter->GetParent(IID_PPV_ARGS(media_factory.GetAddressOf())); + dxgi_adapter->GetParent(IID_PPV_ARGS(&media_factory)); DCHECK(media_factory); // The composition surface handle is only used to create YUV swap chains since @@ -1648,7 +1639,7 @@ if (use_yuv_swap_chain) { HRESULT hr = media_factory->CreateSwapChainForCompositionSurfaceHandle( d3d11_device_.Get(), swap_chain_handle_.Get(), &desc, nullptr, - swap_chain_.GetAddressOf()); + &swap_chain_); is_yuv_swapchain_ = SUCCEEDED(hr); failed_to_create_yuv_swapchain_ = !is_yuv_swapchain_; @@ -1677,7 +1668,7 @@ HRESULT hr = media_factory->CreateSwapChainForCompositionSurfaceHandle( d3d11_device_.Get(), swap_chain_handle_.Get(), &desc, nullptr, - swap_chain_.GetAddressOf()); + &swap_chain_); base::UmaHistogramSparse(kSwapChainCreationResultByFormatUmaPrefix + OverlayFormatToString(OverlayFormat::kBGRA), @@ -1696,46 +1687,42 @@ return true; } -bool DCLayerTree::UpdateBackbufferVisual(BackbufferInfo info) { - bool needs_commit = false; - - if (!backbuffer_visual_) { - dcomp_device_->CreateVisual(backbuffer_visual_.GetAddressOf()); - needs_commit = true; - } - - if (backbuffer_info_ != info) { - backbuffer_info_ = std::move(info); - backbuffer_visual_->SetContent( - backbuffer_info_.dcomp_surface - ? static_cast<IUnknown*>(backbuffer_info_.dcomp_surface.Get()) - : static_cast<IUnknown*>(backbuffer_info_.swap_chain.Get())); - needs_commit = true; - } - - return needs_commit; -} - bool DCLayerTree::CommitAndClearPendingOverlays( - BackbufferInfo backbuffer_info) { - bool needs_commit = false; + DirectCompositionChildSurfaceWin* root_surface) { + DCHECK(!needs_commit_); + // Check if root surface visual needs a commit first. + if (!root_surface_visual_) { + dcomp_device_->CreateVisual(&root_surface_visual_); + needs_commit_ = true; + } - // Check if backbuffer visual needs a commit first. - if (UpdateBackbufferVisual(std::move(backbuffer_info))) - needs_commit = true; + if (root_surface->swap_chain() != root_swap_chain_ || + root_surface->dcomp_surface() != root_dcomp_surface_ || + root_surface->dcomp_surface_serial() != root_dcomp_surface_serial_) { + root_swap_chain_ = root_surface->swap_chain(); + root_dcomp_surface_ = root_surface->dcomp_surface(); + root_dcomp_surface_serial_ = root_surface->dcomp_surface_serial(); + root_surface_visual_->SetContent( + root_swap_chain_ ? static_cast<IUnknown*>(root_swap_chain_.Get()) + : static_cast<IUnknown*>(root_dcomp_surface_.Get())); + needs_commit_ = true; + } + + std::vector<std::unique_ptr<ui::DCRendererLayerParams>> overlays; + std::swap(pending_overlays_, overlays); // Sort layers by z-order. - std::sort(pending_overlays_.begin(), pending_overlays_.end(), + std::sort(overlays.begin(), overlays.end(), [](const auto& a, const auto& b) -> bool { return a->z_order < b->z_order; }); // If we need to grow or shrink swap chain presenters, we'll need to add or // remove visuals. - if (video_swap_chains_.size() != pending_overlays_.size()) { + if (video_swap_chains_.size() != overlays.size()) { // Grow or shrink list of swap chain presenters to match pending overlays. std::vector<std::unique_ptr<SwapChainPresenter>> new_video_swap_chains; - for (size_t i = 0; i < pending_overlays_.size(); ++i) { + for (size_t i = 0; i < overlays.size(); ++i) { // TODO(sunnyps): Try to find a matching swap chain based on size, type of // swap chain, gl image, etc. if (i < video_swap_chains_.size()) { @@ -1746,46 +1733,43 @@ } } video_swap_chains_.swap(new_video_swap_chains); - needs_commit = true; + needs_commit_ = true; } // Present to each swap chain. - for (size_t i = 0; i < pending_overlays_.size(); ++i) { + for (size_t i = 0; i < overlays.size(); ++i) { auto& video_swap_chain = video_swap_chains_[i]; - bool video_needs_commit = false; - if (!video_swap_chain->PresentToSwapChain(*pending_overlays_[i], - &video_needs_commit)) { + if (!video_swap_chain->PresentToSwapChain(*overlays[i])) { DLOG(ERROR) << "PresentToSwapChain failed"; return false; } - needs_commit = needs_commit || video_needs_commit; } // Rebuild visual tree and commit if any visual changed. - if (needs_commit) { - root_visual_->RemoveAllVisuals(); + if (needs_commit_) { + needs_commit_ = false; + dcomp_root_visual_->RemoveAllVisuals(); // Add layers with negative z-order first. size_t i = 0; - for (; i < pending_overlays_.size() && pending_overlays_[i]->z_order < 0; - ++i) { + for (; i < overlays.size() && overlays[i]->z_order < 0; ++i) { IDCompositionVisual2* visual = video_swap_chains_[i]->visual().Get(); // We call AddVisual with insertAbove FALSE and referenceVisual nullptr // which is equivalent to saying that the visual should be below no other // visual, or in other words it should be above all other visuals. - root_visual_->AddVisual(visual, FALSE, nullptr); + dcomp_root_visual_->AddVisual(visual, FALSE, nullptr); } - // Add backbuffer visual at z-order 0. - root_visual_->AddVisual(backbuffer_visual_.Get(), FALSE, nullptr); + // Add root surface visual at z-order 0. + dcomp_root_visual_->AddVisual(root_surface_visual_.Get(), FALSE, nullptr); // Add visuals with positive z-order. - for (; i < pending_overlays_.size(); ++i) { + for (; i < overlays.size(); ++i) { // There shouldn't be a layer with z-order 0. Otherwise, we can't tell - // its order with respect to backbuffer. - DCHECK_GT(pending_overlays_[i]->z_order, 0); + // its order with respect to root surface. + DCHECK_GT(overlays[i]->z_order, 0); IDCompositionVisual2* visual = video_swap_chains_[i]->visual().Get(); - root_visual_->AddVisual(visual, FALSE, nullptr); + dcomp_root_visual_->AddVisual(visual, FALSE, nullptr); } HRESULT hr = dcomp_device_->Commit(); @@ -1795,7 +1779,6 @@ } } - pending_overlays_.clear(); return true; } @@ -1854,7 +1837,7 @@ // This will fail if the D3D device is "Microsoft Basic Display Adapter". Microsoft::WRL::ComPtr<ID3D11VideoDevice> video_device; - if (FAILED(d3d11_device.CopyTo(video_device.GetAddressOf()))) { + if (FAILED(d3d11_device.As(&video_device))) { DLOG(ERROR) << "Failed to retrieve video device"; return false; } @@ -1925,7 +1908,7 @@ HRESULT hr = S_OK; Microsoft::WRL::ComPtr<IDXGIFactory> factory; - hr = CreateDXGIFactory(IID_PPV_ARGS(factory.GetAddressOf())); + hr = CreateDXGIFactory(IID_PPV_ARGS(&factory)); if (FAILED(hr)) { DLOG(ERROR) << "Failed to create DXGI factory."; return false; @@ -1934,7 +1917,7 @@ bool hdr_monitor_found = false; for (UINT adapter_index = 0;; ++adapter_index) { Microsoft::WRL::ComPtr<IDXGIAdapter> adapter; - hr = factory->EnumAdapters(adapter_index, adapter.GetAddressOf()); + hr = factory->EnumAdapters(adapter_index, &adapter); if (hr == DXGI_ERROR_NOT_FOUND) break; if (FAILED(hr)) { @@ -1944,7 +1927,7 @@ for (UINT output_index = 0;; ++output_index) { Microsoft::WRL::ComPtr<IDXGIOutput> output; - hr = adapter->EnumOutputs(output_index, output.GetAddressOf()); + hr = adapter->EnumOutputs(output_index, &output); if (hr == DXGI_ERROR_NOT_FOUND) break; if (FAILED(hr)) { @@ -1953,7 +1936,7 @@ } Microsoft::WRL::ComPtr<IDXGIOutput6> output6; - hr = output->QueryInterface(IID_PPV_ARGS(output6.GetAddressOf())); + hr = output->QueryInterface(IID_PPV_ARGS(&output6)); if (FAILED(hr)) { DLOG(WARNING) << "IDXGIOutput6 is required for HDR detection."; continue; @@ -2049,12 +2032,7 @@ gfx::SwapResult::SWAP_FAILED) succeeded = false; - DCLayerTree::BackbufferInfo backbuffer_info = { - root_surface_->swap_chain().Get(), - root_surface_->dcomp_surface().Get(), - root_surface_->dcomp_surface_serial(), - }; - if (!layer_tree_->CommitAndClearPendingOverlays(std::move(backbuffer_info))) + if (!layer_tree_->CommitAndClearPendingOverlays(root_surface_.get())) succeeded = false; auto swap_result =
diff --git a/gpu/ipc/service/direct_composition_surface_win_unittest.cc b/gpu/ipc/service/direct_composition_surface_win_unittest.cc index aca23603..88a3195 100644 --- a/gpu/ipc/service/direct_composition_surface_win_unittest.cc +++ b/gpu/ipc/service/direct_composition_surface_win_unittest.cc
@@ -140,8 +140,7 @@ data.SysMemPitch = size.width(); Microsoft::WRL::ComPtr<ID3D11Texture2D> texture; - HRESULT hr = - d3d11_device->CreateTexture2D(&desc, &data, texture.GetAddressOf()); + HRESULT hr = d3d11_device->CreateTexture2D(&desc, &data, &texture); CHECK(SUCCEEDED(hr)); return texture; } @@ -896,7 +895,7 @@ Microsoft::WRL::ComPtr<ID3D11Texture2D> texture = CreateNV12Texture(d3d11_device, texture_size, true); Microsoft::WRL::ComPtr<IDXGIResource1> resource; - texture.CopyTo(resource.GetAddressOf()); + texture.As(&resource); HANDLE handle = 0; resource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr, &handle); @@ -947,7 +946,7 @@ Microsoft::WRL::ComPtr<ID3D11Texture2D> texture = CreateNV12Texture(d3d11_device, texture_size, true); Microsoft::WRL::ComPtr<IDXGIResource1> resource; - texture.CopyTo(resource.GetAddressOf()); + texture.As(&resource); HANDLE handle = 0; resource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr, &handle); @@ -1003,7 +1002,7 @@ Microsoft::WRL::ComPtr<ID3D11Texture2D> texture = CreateNV12Texture(d3d11_device, texture_size, true); Microsoft::WRL::ComPtr<IDXGIResource1> resource; - texture.CopyTo(resource.GetAddressOf()); + texture.As(&resource); HANDLE handle = 0; resource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr, &handle); @@ -1058,7 +1057,7 @@ Microsoft::WRL::ComPtr<ID3D11Texture2D> texture = CreateNV12Texture(d3d11_device, texture_size, true); Microsoft::WRL::ComPtr<IDXGIResource1> resource; - texture.CopyTo(resource.GetAddressOf()); + texture.As(&resource); HANDLE handle = 0; resource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr, &handle); @@ -1124,7 +1123,7 @@ Microsoft::WRL::ComPtr<ID3D11Texture2D> texture = CreateNV12Texture(d3d11_device, texture_size, true); Microsoft::WRL::ComPtr<IDXGIResource1> resource; - texture.CopyTo(resource.GetAddressOf()); + texture.As(&resource); HANDLE handle = 0; resource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr, &handle); @@ -1192,7 +1191,7 @@ Microsoft::WRL::ComPtr<ID3D11Texture2D> texture = CreateNV12Texture(d3d11_device, texture_size, true); Microsoft::WRL::ComPtr<IDXGIResource1> resource; - texture.CopyTo(resource.GetAddressOf()); + texture.As(&resource); HANDLE handle = 0; resource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr, &handle);
diff --git a/infra/config/cr-buildbucket.cfg b/infra/config/cr-buildbucket.cfg index 3345a58..a9d1609a 100644 --- a/infra/config/cr-buildbucket.cfg +++ b/infra/config/cr-buildbucket.cfg
@@ -437,6 +437,12 @@ } builder_mixins { + name: "mac-dawn-ci" + mixins: "mac" + mixins: "dawn-ci" +} + +builder_mixins { name: "memory-ci" mixins: "goma-many-jobs-for-ci" recipe { @@ -2043,6 +2049,18 @@ mixins: "win-dawn-ci" } + # chromium.dawn Mac bots (to be folded in to the section above once working) + builders { + name: "Dawn Mac x64 Builder" + mixins: "mac-dawn-ci" + } + builders { + name: "Dawn Mac x64 Release (AMD)" + # Note the use of linux-dawn-ci for this Mac bot. We are attempting to use + # a thin Linux VM for the tester. + mixins: "linux-dawn-ci" + } + # Code coverage reports generation bots. builders { name: "ios-simulator-code-coverage"
diff --git a/infra/config/luci-milo.cfg b/infra/config/luci-milo.cfg index 79a77ad..aa2f085 100644 --- a/infra/config/luci-milo.cfg +++ b/infra/config/luci-milo.cfg
@@ -3407,6 +3407,16 @@ short_name: "x64" } builders { + name: "buildbucket/luci.chromium.ci/Dawn Mac x64 Builder" + category: "ToT|Mac|Builder" + short_name: "x64" + } + builders { + name: "buildbucket/luci.chromium.ci/Dawn Mac x64 Release (AMD)" + category: "ToT|Mac|AMD" + short_name: "x64" + } + builders { name: "buildbucket/luci.chromium.ci/Dawn Linux x64 DEPS Builder" category: "DEPS|Linux|Builder" short_name: "x64"
diff --git a/infra/config/luci-scheduler.cfg b/infra/config/luci-scheduler.cfg index e456176..39ab2d6 100644 --- a/infra/config/luci-scheduler.cfg +++ b/infra/config/luci-scheduler.cfg
@@ -145,6 +145,7 @@ triggers: "CrWinGomaStaging" triggers: "Dawn Linux x64 Builder" triggers: "Dawn Linux x64 DEPS Builder" + triggers: "Dawn Mac x64 Builder" triggers: "Dawn Win10 x64 Builder" triggers: "Dawn Win10 x64 DEPS Builder" triggers: "Dawn Win10 x86 Builder" @@ -2049,6 +2050,27 @@ } job { + id: "Dawn Mac x64 Builder" + acl_sets: "default" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "Dawn Mac x64 Builder" + } +} + +job { + id: "Dawn Mac x64 Release (AMD)" + # Triggered by "Dawn Mac x64 Builder" + acl_sets: "triggered-by-parent-builders" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "Dawn Mac x64 Release (AMD)" + } +} + +job { id: "GPU FYI Mac Builder" acl_sets: "default" buildbucket: {
diff --git a/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm b/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm index d957e70..efdd1b3 100644 --- a/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm +++ b/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm
@@ -152,9 +152,10 @@ self.dispatcher = static_cast<id<ApplicationCommands>>(_commandDispatcher); } -- (BOOL)presentingInfobarBanner { +- (BOOL)isPresentingInfobarBanner { DCHECK(IsInfobarUIRebootEnabled()); - return self.infobarViewController ? YES : NO; + _presentingInfobarBanner = self.infobarViewController ? YES : NO; + return _presentingInfobarBanner; } #pragma mark - InfobarConsumer
diff --git a/ios/web/find_in_page/find_in_page_manager_impl.h b/ios/web/find_in_page/find_in_page_manager_impl.h index 5620ce8d..9265b1e 100644 --- a/ios/web/find_in_page/find_in_page_manager_impl.h +++ b/ios/web/find_in_page/find_in_page_manager_impl.h
@@ -31,6 +31,7 @@ // FindInPageManager overrides void Find(NSString* query, FindInPageOptions options) override; void StopFinding() override; + bool CanSearchContent() override; FindInPageManagerDelegate* GetDelegate() override; void SetDelegate(FindInPageManagerDelegate* delegate) override;
diff --git a/ios/web/find_in_page/find_in_page_manager_impl.mm b/ios/web/find_in_page/find_in_page_manager_impl.mm index 65d7fd8..55260a5 100644 --- a/ios/web/find_in_page/find_in_page_manager_impl.mm +++ b/ios/web/find_in_page/find_in_page_manager_impl.mm
@@ -224,6 +224,8 @@ } void FindInPageManagerImpl::Find(NSString* query, FindInPageOptions options) { + DCHECK(CanSearchContent()); + switch (options) { case FindInPageOptions::FindInPageSearch: DCHECK(query); @@ -277,6 +279,10 @@ void FindInPageManagerImpl::StopFinding() {} +bool FindInPageManagerImpl::CanSearchContent() { + return web_state_->ContentIsHTML(); +} + void FindInPageManagerImpl::ProcessFindInPageResult(const std::string& frame_id, const int unique_id, const base::Value* result) {
diff --git a/ios/web/find_in_page/find_in_page_manger_impl_unittest.mm b/ios/web/find_in_page/find_in_page_manger_impl_unittest.mm index 0014e5ff..05393ffd 100644 --- a/ios/web/find_in_page/find_in_page_manger_impl_unittest.mm +++ b/ios/web/find_in_page/find_in_page_manger_impl_unittest.mm
@@ -591,4 +591,16 @@ })); } +// Tests that Find in Page SetContentIsHTML() returns true if the web state's +// content is HTML and returns false if the web state's content is not HTML. +TEST_F(FindInPageManagerImplTest, FindInPageCanSearchContent) { + test_web_state_->SetContentIsHTML(false); + + EXPECT_FALSE(GetFindInPageManager()->CanSearchContent()); + + test_web_state_->SetContentIsHTML(true); + + EXPECT_TRUE(GetFindInPageManager()->CanSearchContent()); +} + } // namespace web
diff --git a/ios/web/public/find_in_page/find_in_page_manager.h b/ios/web/public/find_in_page/find_in_page_manager.h index 2e5bae1..1bd01d0 100644 --- a/ios/web/public/find_in_page/find_in_page_manager.h +++ b/ios/web/public/find_in_page/find_in_page_manager.h
@@ -18,8 +18,7 @@ enum class FindInPageOptions { // Searches for a string. Highlights all matches. Selects and scrolls to the // first result if string is found. Selecting refers to highlighting in a - // unique manner different from the other matches. TODO(crbug.com/925149): - // Does not support strings with non-ascii. + // unique manner different from the other matches. FindInPageSearch = 1, // Selects and scrolls to the next result if there is one. Otherwise, nothing // will change. Loop back to the first result if currently on last result. If @@ -38,6 +37,7 @@ // on |options|. |query| must not be null if |options| is |FindInPageSearch|. // |query| is ignored if |options| is not |FindInPageSearch|. If new search is // started before previous search finishes, old request will be discarded. + // Check CanSearchContent() before calling Find(). // // FindInPageManagerDelegate::DidHighlightMatches() will be called to return // the total matches found if FindInPageSearch is passed, assuming it hasn't @@ -50,6 +50,10 @@ // FindInPageOptions::FindInPageSearch is never called. virtual void StopFinding() = 0; + // Returns false if page content can not be searched (for example: an image) + // or if search is not supported (for example: PDF files). + virtual bool CanSearchContent() = 0; + virtual FindInPageManagerDelegate* GetDelegate() = 0; virtual void SetDelegate(FindInPageManagerDelegate* delegate) = 0;
diff --git a/ios/web/public/web_state/ui/crw_web_view_proxy.h b/ios/web/public/web_state/ui/crw_web_view_proxy.h index ec1a1430..3b6f02d 100644 --- a/ios/web/public/web_state/ui/crw_web_view_proxy.h +++ b/ios/web/public/web_state/ui/crw_web_view_proxy.h
@@ -64,6 +64,7 @@ - (void)addSubview:(UIView*)view; // Returns YES if it makes sense to search for text right now. +// TODO(crbug.com/949651): Remove once JSFindInPageManager is removed. - (BOOL)hasSearchableTextContent; // Returns the currently visible keyboard accessory, or nil.
diff --git a/ios/web/web_state/js/find_in_page_js_unittest.mm b/ios/web/web_state/js/find_in_page_js_unittest.mm index 250ceec..9bf26c4 100644 --- a/ios/web/web_state/js/find_in_page_js_unittest.mm +++ b/ios/web/web_state/js/find_in_page_js_unittest.mm
@@ -346,4 +346,31 @@ @"document.getElementsByClassName('find_selected').length")); } +// Tests that FindInPage works when searching for strings with non-ascii +// characters. +TEST_F(FindInPageJsTest, SearchForNonAscii) { + ASSERT_TRUE(LoadHtml("<span>école francais</span>")); + base::TimeDelta kCallJavascriptFunctionTimeout = + base::TimeDelta::FromSeconds(kWaitForJSCompletionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return frames_manager()->GetAllWebFrames().size() == 1; + })); + __block bool message_received = false; + std::vector<base::Value> params; + params.push_back(base::Value("école")); + params.push_back(base::Value(kPumpSearchTimeout)); + main_web_frame()->CallJavaScriptFunction( + kFindInPageSearch, params, base::BindOnce(^(const base::Value* result) { + ASSERT_TRUE(result); + ASSERT_TRUE(result->is_double()); + double count = result->GetDouble(); + ASSERT_EQ(1.0, count); + message_received = true; + }), + kCallJavascriptFunctionTimeout); + ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^{ + return message_received; + })); +} + } // namespace web
diff --git a/media/audio/audio_manager_unittest.cc b/media/audio/audio_manager_unittest.cc index aec1d2a..27cb93f 100644 --- a/media/audio/audio_manager_unittest.cc +++ b/media/audio/audio_manager_unittest.cc
@@ -56,7 +56,7 @@ #if defined(USE_CRAS) #include "chromeos/audio/audio_devices_pref_handler_stub.h" #include "chromeos/audio/cras_audio_handler.h" -#include "chromeos/dbus/fake_cras_audio_client.h" +#include "chromeos/dbus/audio/fake_cras_audio_client.h" #include "media/audio/cras/audio_manager_cras.h" #endif // defined(USE_CRAS)
diff --git a/media/audio/cras/cras_input_unittest.cc b/media/audio/cras/cras_input_unittest.cc index 08bd484..fc1ce1b2 100644 --- a/media/audio/cras/cras_input_unittest.cc +++ b/media/audio/cras/cras_input_unittest.cc
@@ -15,7 +15,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "chromeos/audio/cras_audio_handler.h" -#include "chromeos/dbus/fake_cras_audio_client.h" +#include "chromeos/dbus/audio/fake_cras_audio_client.h" #include "media/audio/audio_device_description.h" #include "media/audio/cras/audio_manager_cras.h" #include "media/audio/fake_audio_log_factory.h"
diff --git a/media/audio/cras/cras_unified_unittest.cc b/media/audio/cras/cras_unified_unittest.cc index a811cd4..9f036f6 100644 --- a/media/audio/cras/cras_unified_unittest.cc +++ b/media/audio/cras/cras_unified_unittest.cc
@@ -15,7 +15,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "chromeos/audio/cras_audio_handler.h" -#include "chromeos/dbus/cras_audio_client.h" +#include "chromeos/dbus/audio/cras_audio_client.h" #include "media/audio/audio_device_description.h" #include "media/audio/cras/audio_manager_cras.h" #include "media/audio/fake_audio_log_factory.h"
diff --git a/media/capture/video/OWNERS b/media/capture/video/OWNERS index 8b3d667..ea5ac3b3 100644 --- a/media/capture/video/OWNERS +++ b/media/capture/video/OWNERS
@@ -1,9 +1,7 @@ emircan@chromium.org chfremer@chromium.org +mcasas@chromium.org tommi@chromium.org -# Original (legacy) owner. -mcasas@chromium.org - +# TEAM: media-capture-and-streams@grotations.appspotmail.com # COMPONENT: Blink>GetUserMedia>WebCam -# TEAM: webrtc-dev@chromium.org
diff --git a/media/capture/video/android/java/src/org/chromium/media/OWNERS b/media/capture/video/android/java/src/org/chromium/media/OWNERS index 939f3d261..e34b150738 100644 --- a/media/capture/video/android/java/src/org/chromium/media/OWNERS +++ b/media/capture/video/android/java/src/org/chromium/media/OWNERS
@@ -1,7 +1,5 @@ +mcasas@chromium.org qinmin@chromium.org -# Original (legacy) owner. -mcasas@chromium.org - +# media-capture-and-streams@grotations.appspotmail.com # COMPONENT: Blink>GetUserMedia>WebCam -# TEAM: webrtc-dev@chromium.org
diff --git a/media/learning/common/learning_task.h b/media/learning/common/learning_task.h index 3c24aca8..0e4eb5a 100644 --- a/media/learning/common/learning_task.h +++ b/media/learning/common/learning_task.h
@@ -30,6 +30,9 @@ enum class Model { kExtraTrees, kLookupTable, + + // For the fuzzer. + kMaxValue = kLookupTable }; enum class Ordering { @@ -44,6 +47,9 @@ // ints that represent the number of elapsed milliseconds are numerically // ordered in a meaningful way. kNumeric, + + // For the fuzzer. + kMaxValue = kNumeric }; enum class PrivacyMode { @@ -53,6 +59,9 @@ // Value does not represent private information, such as video width. kPublic, + + // For the fuzzer. + kMaxValue = kPublic }; // Description of how a Value should be interpreted.
diff --git a/media/learning/impl/BUILD.gn b/media/learning/impl/BUILD.gn index 1400eee1..27ed8c2 100644 --- a/media/learning/impl/BUILD.gn +++ b/media/learning/impl/BUILD.gn
@@ -2,10 +2,13 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//testing/libfuzzer/fuzzer_test.gni") + component("impl") { output_name = "learning_impl" visibility = [ "//media/learning/impl:unit_tests", + "//media/learning/impl:learning_fuzzer", # Actual clients. "//content/browser", @@ -82,3 +85,14 @@ "//testing/gtest", ] } + +fuzzer_test("learning_fuzzer") { + sources = [ + "learning_fuzzertest.cc", + ] + deps = [ + ":impl", + "//base", + "//base/test:test_support", + ] +}
diff --git a/media/learning/impl/learning_fuzzertest.cc b/media/learning/impl/learning_fuzzertest.cc new file mode 100644 index 0000000..122d031a --- /dev/null +++ b/media/learning/impl/learning_fuzzertest.cc
@@ -0,0 +1,72 @@ +// 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 "base/test/fuzzed_data_provider.h" +#include "base/test/scoped_task_environment.h" +#include "media/learning/impl/learning_task_controller_impl.h" + +using media::learning::FeatureValue; +using media::learning::FeatureVector; +using media::learning::LearningTask; +using ValueDescription = media::learning::LearningTask::ValueDescription; +using media::learning::LearningTaskControllerImpl; +using media::learning::ObservationCompletion; +using media::learning::TargetValue; + +ValueDescription ConsumeValueDescription(base::FuzzedDataProvider* provider) { + ValueDescription desc; + desc.name = provider->ConsumeRandomLengthString(100); + desc.ordering = provider->ConsumeEnum<LearningTask::Ordering>(); + desc.privacy_mode = provider->ConsumeEnum<LearningTask::PrivacyMode>(); + return desc; +} + +double ConsumeDouble(base::FuzzedDataProvider* provider) { + std::vector<uint8_t> v = provider->ConsumeBytes(sizeof(double)); + if (v.size() == sizeof(double)) + return reinterpret_cast<double*>(v.data())[0]; + + return 0; +} + +FeatureVector ConsumeFeatureVector(base::FuzzedDataProvider* provider) { + FeatureVector features; + int n = provider->ConsumeIntegralInRange(0, 100); + while (n-- > 0) + features.push_back(FeatureValue(ConsumeDouble(provider))); + + return features; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + base::test::ScopedTaskEnvironment scoped_task_environment; + base::FuzzedDataProvider provider(data, size); + + LearningTask task; + task.name = provider.ConsumeRandomLengthString(100); + task.model = provider.ConsumeEnum<LearningTask::Model>(); + task.use_one_hot_conversion = provider.ConsumeBool(); + task.uma_hacky_confusion_matrix = provider.ConsumeRandomLengthString(10); + int n_features = provider.ConsumeIntegralInRange(0, 100); + int subset_size = provider.ConsumeIntegralInRange<uint8_t>(0, n_features); + if (subset_size) + task.feature_subset_size = subset_size; + for (int i = 0; i < n_features; i++) + task.feature_descriptions.push_back(ConsumeValueDescription(&provider)); + task.target_description = ConsumeValueDescription(&provider); + + LearningTaskControllerImpl controller(task); + + // Build random examples. + while (provider.remaining_bytes() > 0) { + base::UnguessableToken id = base::UnguessableToken::Create(); + controller.BeginObservation(id, ConsumeFeatureVector(&provider)); + controller.CompleteObservation( + id, ObservationCompletion(TargetValue(ConsumeDouble(&provider)), + ConsumeDouble(&provider))); + scoped_task_environment.RunUntilIdle(); + } + + return 0; +}
diff --git a/media/learning/impl/learning_task_controller_helper.cc b/media/learning/impl/learning_task_controller_helper.cc index 82d0165..01c8972e 100644 --- a/media/learning/impl/learning_task_controller_helper.cc +++ b/media/learning/impl/learning_task_controller_helper.cc
@@ -44,7 +44,8 @@ base::UnguessableToken id, const ObservationCompletion& completion) { auto iter = pending_examples_.find(id); - DCHECK(iter != pending_examples_.end()); + if (iter == pending_examples_.end()) + return; iter->second.example.target_value = completion.target_value; iter->second.example.weight = completion.weight; @@ -55,8 +56,8 @@ void LearningTaskControllerHelper::CancelObservation( base::UnguessableToken id) { auto iter = pending_examples_.find(id); - // If the example has already been completed, then we shouldn't be called. - DCHECK(iter != pending_examples_.end()); + if (iter == pending_examples_.end()) + return; // This would have to check for pending predictions, if we supported them, and // defer destruction until the features arrive.
diff --git a/media/learning/impl/learning_task_controller_impl.cc b/media/learning/impl/learning_task_controller_impl.cc index fc4597a..c663f5b 100644 --- a/media/learning/impl/learning_task_controller_impl.cc +++ b/media/learning/impl/learning_task_controller_impl.cc
@@ -21,18 +21,19 @@ SequenceBoundFeatureProvider feature_provider) : task_(task), training_data_(std::make_unique<TrainingData>()), - reporter_(std::move(reporter)) { + reporter_(std::move(reporter)), + helper_(std::make_unique<LearningTaskControllerHelper>( + task, + base::BindRepeating(&LearningTaskControllerImpl::AddFinishedExample, + AsWeakPtr()), + std::move(feature_provider))), + expected_feature_count_(task_.feature_descriptions.size()) { + // Note that |helper_| uses the full set of features. + // TODO(liberato): Make this compositional. FeatureSubsetTaskController? if (task_.feature_subset_size) DoFeatureSubsetSelection(); - // Now that we have the updated task, create a helper for it. - helper_ = std::make_unique<LearningTaskControllerHelper>( - task, - base::BindRepeating(&LearningTaskControllerImpl::AddFinishedExample, - AsWeakPtr()), - std::move(feature_provider)); - switch (task_.model) { case LearningTask::Model::kExtraTrees: trainer_ = std::make_unique<ExtraTreesTrainer>(); @@ -48,30 +49,49 @@ void LearningTaskControllerImpl::BeginObservation( base::UnguessableToken id, const FeatureVector& features) { - // Copy just the subset we care about. - FeatureVector new_features; - if (task_.feature_subset_size) { - for (auto& iter : feature_indices_) - new_features.push_back(features[iter]); - } else { - // Use them all. - new_features = features; - } + // TODO(liberato): Should we enforce that the right number of features are + // present here? Right now, we allow it to be shorter, so that features from + // a FeatureProvider may be omitted. Of course, they have to be at the end in + // that case. If we start enforcing it here, make sure that LearningHelper + // starts adding the placeholder features. + if (!trainer_) + return; - helper_->BeginObservation(id, new_features); + helper_->BeginObservation(id, features); } void LearningTaskControllerImpl::CompleteObservation( base::UnguessableToken id, const ObservationCompletion& completion) { + if (!trainer_) + return; helper_->CompleteObservation(id, completion); } void LearningTaskControllerImpl::CancelObservation(base::UnguessableToken id) { + if (!trainer_) + return; helper_->CancelObservation(id); } void LearningTaskControllerImpl::AddFinishedExample(LabelledExample example) { + // Verify that we have a trainer and that we got the right number of features. + // We don't compare to |task_.feature_descriptions.size()| since that has been + // adjusted to the subset size already. We expect the original count. + if (!trainer_ || example.features.size() != expected_feature_count_) + return; + + // Now that we have the whole set of features, select the subset we want. + FeatureVector new_features; + if (task_.feature_subset_size) { + for (auto& iter : feature_indices_) + new_features.push_back(example.features[iter]); + example.features = std::move(new_features); + } // else use them all. + + // The features should now match the task. + DCHECK_EQ(example.features.size(), task_.feature_descriptions.size()); + if (training_data_->size() >= task_.max_data_set_size) { // Replace a random example. We don't necessarily want to replace the // oldest, since we don't necessarily want to enforce an ad-hoc recency @@ -156,7 +176,8 @@ task_.feature_descriptions = adjusted_descriptions; - reporter_->SetFeatureSubset(feature_indices_); + if (reporter_) + reporter_->SetFeatureSubset(feature_indices_); } } // namespace learning
diff --git a/media/learning/impl/learning_task_controller_impl.h b/media/learning/impl/learning_task_controller_impl.h index 86f007baf..ea9d95e 100644 --- a/media/learning/impl/learning_task_controller_impl.h +++ b/media/learning/impl/learning_task_controller_impl.h
@@ -91,6 +91,9 @@ // randomly chosen subset of features. std::set<int> feature_indices_; + // Number of features that we expect in each observation. + size_t expected_feature_count_; + friend class LearningTaskControllerImplTest; };
diff --git a/media/learning/impl/learning_task_controller_impl_unittest.cc b/media/learning/impl/learning_task_controller_impl_unittest.cc index 1b5f6c5..fdabda3 100644 --- a/media/learning/impl/learning_task_controller_impl_unittest.cc +++ b/media/learning/impl/learning_task_controller_impl_unittest.cc
@@ -191,6 +191,7 @@ TEST_F(LearningTaskControllerImplTest, FeatureProviderIsUsed) { // If a FeatureProvider factory is provided, make sure that it's used to // adjust new examples. + task_.feature_descriptions.push_back({"AddedByFeatureProvider"}); SequenceBoundFeatureProvider feature_provider = base::SequenceBound<FakeFeatureProvider>( base::SequencedTaskRunnerHandle::Get());
diff --git a/media/muxers/OWNERS b/media/muxers/OWNERS index 92570f5..2198557 100644 --- a/media/muxers/OWNERS +++ b/media/muxers/OWNERS
@@ -1,7 +1,4 @@ +mcasas@chromium.org miu@chromium.org -# Original (legacy) owner. -mcasas@chromium.org - # COMPONENT: Blink>MediaRecording -# TEAM: webrtc-dev@chromium.org
diff --git a/mojo/core/channel_mac.cc b/mojo/core/channel_mac.cc index 0043335..450bd17e 100644 --- a/mojo/core/channel_mac.cc +++ b/mojo/core/channel_mac.cc
@@ -528,6 +528,12 @@ } OnError(Error::kDisconnected); return; + } else if (header->msgh_id == MACH_NOTIFY_SEND_ONCE) { + // Notification of an extant send-once right being destroyed. This is + // sent for the right allocated in RequestSendDeadNameNotification(), + // and no action needs to be taken. Since it is ignored, the kernel + // audit token need not be checked. + return; } if (header->msgh_size < sizeof(mach_msg_base_t)) {
diff --git a/mojo/public/cpp/bindings/lib/message.cc b/mojo/public/cpp/bindings/lib/message.cc index da2238e0..fa28aa4 100644 --- a/mojo/public/cpp/bindings/lib/message.cc +++ b/mojo/public/cpp/bindings/lib/message.cc
@@ -93,16 +93,14 @@ } } -void CreateSerializedMessageObject( - uint32_t name, - uint32_t flags, - uint32_t trace_id, - size_t payload_size, - size_t payload_interface_id_count, - std::vector<ScopedHandle>* handles, - const std::vector<MojoAppendMessageDataHandleOptions>* handle_options, - ScopedMessageHandle* out_handle, - internal::Buffer* out_buffer) { +void CreateSerializedMessageObject(uint32_t name, + uint32_t flags, + uint32_t trace_id, + size_t payload_size, + size_t payload_interface_id_count, + std::vector<ScopedHandle>* handles, + ScopedMessageHandle* out_handle, + internal::Buffer* out_buffer) { TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("toplevel.flow"), "mojo::Message Send", MANGLE_MESSAGE_ID(trace_id), TRACE_EVENT_FLAG_FLOW_OUT); @@ -112,12 +110,6 @@ DCHECK_EQ(MOJO_RESULT_OK, rv); DCHECK(handle.is_valid()); - MojoAppendMessageDataOptions append_options = {0}; - append_options.struct_size = sizeof(append_options); - append_options.flags = MOJO_APPEND_MESSAGE_DATA_FLAG_NONE; - if (handle_options) - append_options.handle_options = handle_options->data(); - void* buffer; uint32_t buffer_size; size_t total_size = internal::ComputeSerializedMessageSize( @@ -128,8 +120,8 @@ rv = MojoAppendMessageData( handle->value(), static_cast<uint32_t>(total_size), handles ? reinterpret_cast<MojoHandle*>(handles->data()) : nullptr, - handles ? static_cast<uint32_t>(handles->size()) : 0, &append_options, - &buffer, &buffer_size); + handles ? static_cast<uint32_t>(handles->size()) : 0, nullptr, &buffer, + &buffer_size); DCHECK_EQ(MOJO_RESULT_OK, rv); if (handles) { // Handle ownership has been taken by MojoAppendMessageData. @@ -242,24 +234,10 @@ uint32_t flags, size_t payload_size, size_t payload_interface_id_count, - std::vector<ScopedHandle>* handles) - : Message(name, - flags, - payload_size, - payload_interface_id_count, - handles, - nullptr) {} - -Message::Message( - uint32_t name, - uint32_t flags, - size_t payload_size, - size_t payload_interface_id_count, - std::vector<ScopedHandle>* handles, - const std::vector<MojoAppendMessageDataHandleOptions>* handle_options) { + std::vector<ScopedHandle>* handles) { CreateSerializedMessageObject(name, flags, GetTraceId(this), payload_size, - payload_interface_id_count, handles, - handle_options, &handle_, &payload_buffer_); + payload_interface_id_count, handles, &handle_, + &payload_buffer_); transferable_ = true; serialized_ = true; } @@ -387,8 +365,7 @@ return; } - if (context->associated_endpoint_handles()->empty() && - !context->has_handles_with_shared_message_order()) { + if (context->associated_endpoint_handles()->empty()) { // Attaching only non-associated handles is easier since we don't have to // modify the message header. Faster path for that. payload_buffer_.AttachHandles(context->mutable_handles()); @@ -404,8 +381,7 @@ uint32_t payload_size = payload_num_bytes(); mojo::Message new_message(name(), header()->flags, payload_size, context->associated_endpoint_handles()->size(), - context->mutable_handles(), - context->handle_options()); + context->mutable_handles()); std::swap(*context->mutable_associated_endpoint_handles(), new_message.associated_endpoint_handles_); memcpy(new_message.payload_buffer()->AllocateAndGet(payload_size), payload(),
diff --git a/mojo/public/cpp/bindings/lib/serialization_context.cc b/mojo/public/cpp/bindings/lib/serialization_context.cc index 5085327..267b541 100644 --- a/mojo/public/cpp/bindings/lib/serialization_context.cc +++ b/mojo/public/cpp/bindings/lib/serialization_context.cc
@@ -25,16 +25,6 @@ DCHECK_LT(handles_.size(), std::numeric_limits<uint32_t>::max()); out_data->value = static_cast<uint32_t>(handles_.size()); handles_.emplace_back(std::move(handle)); - - MojoAppendMessageDataHandleOptions options = {0}; - options.struct_size = sizeof(options); - options.flags = share_message_order_for_new_handles_ - ? MOJO_APPEND_MESSAGE_DATA_HANDLE_FLAG_SPLICE - : MOJO_APPEND_MESSAGE_DATA_HANDLE_FLAG_NONE; - handle_options_.push_back(options); - - if (share_message_order_for_new_handles_) - has_handles_with_shared_message_order_ = true; } }
diff --git a/mojo/public/cpp/bindings/lib/serialization_context.h b/mojo/public/cpp/bindings/lib/serialization_context.h index 7491190a..0e3c0788 100644 --- a/mojo/public/cpp/bindings/lib/serialization_context.h +++ b/mojo/public/cpp/bindings/lib/serialization_context.h
@@ -29,14 +29,6 @@ SerializationContext(); ~SerializationContext(); - void set_share_message_order_for_new_handles(bool share) { - share_message_order_for_new_handles_ = share; - } - - bool has_handles_with_shared_message_order() const { - return has_handles_with_shared_message_order_; - } - // Adds a handle to the handle list and outputs its serialized form in // |*out_data|. void AddHandle(mojo::ScopedHandle handle, Handle_Data* out_data); @@ -62,11 +54,6 @@ const std::vector<mojo::ScopedHandle>* handles() { return &handles_; } std::vector<mojo::ScopedHandle>* mutable_handles() { return &handles_; } - const std::vector<MojoAppendMessageDataHandleOptions>* handle_options() - const { - return &handle_options_; - } - const std::vector<ScopedInterfaceEndpointHandle>* associated_endpoint_handles() const { return &associated_endpoint_handles_; @@ -94,22 +81,11 @@ const AssociatedEndpointHandle_Data& encoded_handle); private: - // Whenever this is |true|, newly added interface handles are marked for - // splicing into the sendng interface pipe upon message transmission. - bool share_message_order_for_new_handles_ = false; - - // Indicates whether any handles were added to this context while - // |share_message_order_for_new_handles_| was |true|. - bool has_handles_with_shared_message_order_ = false; - // Handles owned by this object. Used during serialization to hold onto // handles accumulated during pre-serialization, and used during // deserialization to hold onto handles extracted from a message. std::vector<mojo::ScopedHandle> handles_; - // Options for each of the attached handles. - std::vector<MojoAppendMessageDataHandleOptions> handle_options_; - // Stashes ScopedInterfaceEndpointHandles encoded in a message by index. std::vector<ScopedInterfaceEndpointHandle> associated_endpoint_handles_;
diff --git a/mojo/public/cpp/bindings/message.h b/mojo/public/cpp/bindings/message.h index 7117e70b..791cb53b 100644 --- a/mojo/public/cpp/bindings/message.h +++ b/mojo/public/cpp/bindings/message.h
@@ -68,16 +68,6 @@ size_t payload_interface_id_count, std::vector<ScopedHandle>* handles); - // Same as above, but with additional per-handle options to control how - // each handle in |handles| is attached. - Message( - uint32_t name, - uint32_t flags, - size_t payload_size, - size_t payload_interface_id_count, - std::vector<ScopedHandle>* handles, - const std::vector<MojoAppendMessageDataHandleOptions>* handle_options); - // Constructs a new serialized Message object from an existing // ScopedMessageHandle; e.g., one read from a message pipe. //
diff --git a/mojo/public/cpp/bindings/tests/BUILD.gn b/mojo/public/cpp/bindings/tests/BUILD.gn index 1d82337d..a73a8736 100644 --- a/mojo/public/cpp/bindings/tests/BUILD.gn +++ b/mojo/public/cpp/bindings/tests/BUILD.gn
@@ -37,7 +37,6 @@ "router_test_util.h", "sample_service_unittest.cc", "serialization_warning_unittest.cc", - "share_message_order_unittest.cc", "struct_unittest.cc", "sync_handle_registry_unittest.cc", "sync_method_unittest.cc", @@ -53,11 +52,9 @@ ":mojo_public_bindings_test_utils", "//base/test:test_support", "//mojo/core/embedder", - "//mojo/core/test:test_support", "//mojo/public/cpp/bindings", "//mojo/public/cpp/system", "//mojo/public/cpp/test_support:test_utils", - "//mojo/public/interfaces/bindings/tests:cpp_only_test_interfaces", "//mojo/public/interfaces/bindings/tests:other_test_interfaces", "//mojo/public/interfaces/bindings/tests:test_associated_interfaces", "//mojo/public/interfaces/bindings/tests:test_export_component",
diff --git a/mojo/public/cpp/bindings/tests/share_message_order_unittest.cc b/mojo/public/cpp/bindings/tests/share_message_order_unittest.cc deleted file mode 100644 index 753e036..0000000 --- a/mojo/public/cpp/bindings/tests/share_message_order_unittest.cc +++ /dev/null
@@ -1,254 +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 <algorithm> -#include <memory> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/macros.h" -#include "base/optional.h" -#include "base/run_loop.h" -#include "base/test/scoped_task_environment.h" -#include "mojo/core/test/mojo_test_base.h" -#include "mojo/public/cpp/bindings/receiver.h" -#include "mojo/public/cpp/bindings/receiver_set.h" -#include "mojo/public/cpp/bindings/remote.h" -#include "mojo/public/interfaces/bindings/tests/share_message_order.test-mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace test { -namespace share_message_order { - -using ShareMessageOrderTest = mojo::core::test::MojoTestBase; - -class CounterObserverImpl : public mojom::CounterObserver { - public: - CounterObserverImpl() = default; - ~CounterObserverImpl() override = default; - - uint32_t counter_value() const { return counter_value_; } - - PendingRemote<mojom::CounterObserver> MakeRemote() { - return receiver_.BindNewPipeAndPassRemote(); - } - - void WaitForNextIncrement() { - if (!wait_loop_) - wait_loop_.emplace(); - wait_loop_->Run(); - wait_loop_.reset(); - } - - // mojom::CounterObserver: - void OnIncrement(uint32_t value) override { - counter_value_ = value; - if (wait_loop_) - wait_loop_->Quit(); - } - - private: - uint32_t counter_value_ = 0; - Receiver<mojom::CounterObserver> receiver_{this}; - base::Optional<base::RunLoop> wait_loop_; - - DISALLOW_COPY_AND_ASSIGN(CounterObserverImpl); -}; - -class CounterImpl : public mojom::Counter, public mojom::Doubler { - public: - explicit CounterImpl(PendingReceiver<mojom::Counter> receiver) - : receiver_(this, std::move(receiver)) { - receiver_.set_disconnect_handler(wait_for_disconnect_loop_.QuitClosure()); - } - - ~CounterImpl() override = default; - - void WaitForDisconnect() { wait_for_disconnect_loop_.Run(); } - - private: - // mojom::Counter: - void Increment(IncrementCallback callback) override { - ++value_; - std::move(callback).Run(); - for (const auto& observer : observers_) - observer->OnIncrement(value_); - } - - void AddObserver(PendingRemote<mojom::CounterObserver> observer) override { - observers_.emplace_back(std::move(observer)); - } - - void AddDoubler(PendingReceiver<mojom::Doubler> receiver) override { - doubler_receiver_.Bind(std::move(receiver)); - } - - // mojom::Doubler: - void Double() override { value_ *= 2; } - - base::RunLoop wait_for_disconnect_loop_; - uint32_t value_ = 0; - Receiver<mojom::Counter> receiver_; - Receiver<mojom::Doubler> doubler_receiver_{this}; - std::vector<Remote<mojom::CounterObserver>> observers_; - - DISALLOW_COPY_AND_ASSIGN(CounterImpl); -}; - -TEST_F(ShareMessageOrderTest, Ordering) { - // Setup two child processes, one for a CounterImpl and one for its client. - // They will use additional interfaces with shared message ordering. We use - // a multi-process test environment because it introduces sufficient internal - // timing variations to exercise our ordering constraints. - RunTestClient("CounterImpl", [&](MojoHandle h) { - MojoHandle receiver_handle, remote_handle; - CreateMessagePipe(&receiver_handle, &remote_handle); - - WriteMessageWithHandles(h, "hi", &receiver_handle, 1); - RunTestClient("CounterClient", [&](MojoHandle h) { - WriteMessageWithHandles(h, "hi", &remote_handle, 1); - EXPECT_EQ("ok", ReadMessage(h)); - WriteMessage(h, "bye"); - }); - }); -} - -DEFINE_TEST_CLIENT_TEST_WITH_PIPE(CounterImpl, ShareMessageOrderTest, h) { - base::test::ScopedTaskEnvironment task_environment; - - MojoHandle receiver_handle; - EXPECT_EQ("hi", ReadMessageWithHandles(h, &receiver_handle, 1)); - - CounterImpl counter_impl{PendingReceiver<mojom::Counter>( - ScopedMessagePipeHandle(MessagePipeHandle(receiver_handle)))}; - counter_impl.WaitForDisconnect(); -} - -DEFINE_TEST_CLIENT_TEST_WITH_PIPE(CounterClient, ShareMessageOrderTest, h) { - base::test::ScopedTaskEnvironment task_environment; - - MojoHandle remote_handle; - EXPECT_EQ("hi", ReadMessageWithHandles(h, &remote_handle, 1)); - - Remote<mojom::Counter> counter{PendingRemote<mojom::Counter>( - ScopedMessagePipeHandle(MessagePipeHandle(remote_handle)), 0)}; - - // By the mojom definition of AddDoubler, the Doubler's own pipe will share - // message ordering with the Counter's pipe once this message is sent. - Remote<mojom::Doubler> doubler; - counter->AddDoubler(doubler.BindNewPipeAndPassReceiver()); - - // And the CounterObserver's pipe will share messaging ordering as well, - // specifically its received messages will be ordered with replies received - // by our Remote<mojom::Counter>. - CounterObserverImpl observer; - counter->AddObserver(observer.MakeRemote()); - - { - base::RunLoop loop; - counter->Increment(loop.QuitClosure()); - loop.Run(); - } - - // The observer should not have dispatched an observed event yet, since it - // must arrive after the reply which just terminated our RunLoop. - // - // If there are ordering violations, this may flakily fail with an unexpected - // value of 1. - EXPECT_EQ(0u, observer.counter_value()); - observer.WaitForNextIncrement(); - - EXPECT_EQ(1u, observer.counter_value()); - - // Also verify ordering of messages on the Doubler. - - { - base::RunLoop loop; - counter->Increment(base::DoNothing()); // Increment to 2 - doubler->Double(); // Double to 4 - counter->Increment(loop.QuitClosure()); // Increment to 5 - loop.Run(); - } - - // Because of strict message ordering constraints, at this point the observer - // should have seen the increment to 2 above, but not the increment to 5. - // - // If there are ordering violations, this may flakily fail with an unexpected - // value of 2, 3, or 4. - EXPECT_EQ(2u, observer.counter_value()); - - observer.WaitForNextIncrement(); - - // If there are ordering violations, this may flakily fail with an unexpected - // value of 3 or 4. - EXPECT_EQ(5u, observer.counter_value()); - - WriteMessage(h, "ok"); - EXPECT_EQ("bye", ReadMessage(h)); -} - -class SyncPingImpl : public mojom::SyncPing { - public: - SyncPingImpl(mojo::PendingReceiver<mojom::SyncPing> receiver) - : receiver_(this, std::move(receiver)) {} - ~SyncPingImpl() override = default; - - // mojom::SyncPing: - void PingAsync(PingCallback callback) override { std::move(callback).Run(); } - void Ping(PingCallback callback) override { std::move(callback).Run(); } - - private: - mojo::Receiver<mojom::SyncPing> receiver_; - - DISALLOW_COPY_AND_ASSIGN(SyncPingImpl); -}; - -class SyncEchoImpl : public mojom::SyncEcho { - public: - SyncEchoImpl(mojo::PendingReceiver<mojom::SyncEcho> receiver) - : receiver_(this, std::move(receiver)) {} - ~SyncEchoImpl() override = default; - - // mojom::SyncEcho: - void PingThenEcho(mojo::PendingRemote<mojom::SyncPing> remote_ping, - const std::string& x, - PingThenEchoCallback callback) override { - mojo::Remote<mojom::SyncPing> ping(std::move(remote_ping)); - - base::RunLoop loop; - ping->PingAsync(loop.QuitClosure()); - loop.Run(); - - CHECK(ping->Ping()); - - std::move(callback).Run(x); - } - - private: - mojo::Receiver<mojom::SyncEcho> receiver_; - - DISALLOW_COPY_AND_ASSIGN(SyncEchoImpl); -}; - -TEST_F(ShareMessageOrderTest, NestedSyncCall) { - base::test::ScopedTaskEnvironment task_environment; - - mojo::PendingRemote<mojom::SyncPing> ping; - SyncPingImpl ping_impl(ping.InitWithNewPipeAndPassReceiver()); - - mojo::Remote<mojom::SyncEcho> echo; - SyncEchoImpl echo_impl(echo.BindNewPipeAndPassReceiver()); - - const std::string kTestString = "ok hello"; - std::string echoed_string; - EXPECT_TRUE(echo->PingThenEcho(std::move(ping), kTestString, &echoed_string)); - EXPECT_EQ(kTestString, echoed_string); -} - -} // namespace share_message_order -} // namespace test -} // namespace mojo
diff --git a/mojo/public/interfaces/bindings/tests/BUILD.gn b/mojo/public/interfaces/bindings/tests/BUILD.gn index aa238a6..a5efd42 100644 --- a/mojo/public/interfaces/bindings/tests/BUILD.gn +++ b/mojo/public/interfaces/bindings/tests/BUILD.gn
@@ -493,14 +493,6 @@ ] } -mojom("cpp_only_test_interfaces") { - testonly = true - cpp_only = true - sources = [ - "share_message_order.test-mojom", - ] -} - # Ensure that some target forces JS and Java bindings generation when all # targets are built. This provides a basic generation smoke test for new # endpoint types in mojom.
diff --git a/mojo/public/interfaces/bindings/tests/share_message_order.test-mojom b/mojo/public/interfaces/bindings/tests/share_message_order.test-mojom deleted file mode 100644 index 5807e32..0000000 --- a/mojo/public/interfaces/bindings/tests/share_message_order.test-mojom +++ /dev/null
@@ -1,40 +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. - -module mojo.test.share_message_order.mojom; - -interface CounterObserver { - // Called every time the associated Counter has its value incremented. - OnIncrement(uint32 value); -}; - -interface Doubler { - // Requests that the Doubler's associated Counter double its current count. - Double(); -}; - -interface Counter { - Increment() => (); - - // Adds an observer which will be notified after every invocation of - // |Increment()|. Observers are always notified *after* the Increment response - // is sent. - AddObserver([ShareMessageOrder] pending_remote<CounterObserver> observer); - - // Gets an interface which can be used to double the current count retained by - // this Counter. - AddDoubler([ShareMessageOrder] pending_receiver<Doubler> receiver); -}; - -interface SyncPing { - PingAsync() => (); - [Sync] Ping() => (); -}; - -interface SyncEcho { - [Sync] PingThenEcho([ShareMessageOrder] pending_remote<SyncPing> ping, - string x) - => (string x); -}; -
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl index e0bd720..7c6b9cd 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl
@@ -25,10 +25,6 @@ {%- set kind = pf.field.kind %} {%- set serializer_type = kind|unmapped_type_for_serializer %} -{%- if pf.field|share_message_order %} - ({{context}})->set_share_message_order_for_new_handles(true); -{%- endif %} - {%- if kind|is_object_kind or kind|is_any_handle_or_interface_kind %} {%- set original_input_field = input_field_pattern|format(name) %} {%- set input_field = "in_%s"|format(name) if input_may_be_temp @@ -90,11 +86,6 @@ {%- else %} {{writer}}->{{name}} = {{input_field}}; {%- endif %} - -{%- if pf.field|share_message_order %} - ({{context}})->set_share_message_order_for_new_handles(false); -{%- endif %} - {%- endfor %} {%- endmacro -%}
diff --git a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py index 1d1fbe5..b8070e6 100644 --- a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py +++ b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -368,7 +368,6 @@ "is_typemapped_kind": self._IsTypemappedKind, "is_union_kind": mojom.IsUnionKind, "passes_associated_kinds": mojom.PassesAssociatedKinds, - "share_message_order": mojom.FieldOrParamSharesMessageOrder, "struct_constructors": self._GetStructConstructors, "under_to_camel": generator.ToCamel, "unmapped_type_for_serializer": self._GetUnmappedTypeForSerializer, @@ -751,8 +750,7 @@ # TODO(crbug.com/753433): Support lazy serialization for methods which pass # associated handles. - if mojom.MethodPassesAssociatedKinds(method) or \ - mojom.MethodParametersShareMessageOrder(method): + if mojom.MethodPassesAssociatedKinds(method): return False return not any(self._KindMustBeSerialized(param.kind) for param in
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/module.py b/mojo/public/tools/bindings/pylib/mojom/generate/module.py index b1201f97..18a4101 100644 --- a/mojo/public/tools/bindings/pylib/mojom/generate/module.py +++ b/mojo/public/tools/bindings/pylib/mojom/generate/module.py
@@ -221,7 +221,6 @@ ATTRIBUTE_MIN_VERSION = 'MinVersion' ATTRIBUTE_EXTENSIBLE = 'Extensible' ATTRIBUTE_SYNC = 'Sync' -ATTRIBUTE_SHARE_MESSAGE_ORDER = 'ShareMessageOrder' class NamedValue(object): @@ -302,11 +301,6 @@ return self.attributes.get(ATTRIBUTE_MIN_VERSION) \ if self.attributes else None - @property - def share_message_order(self): - return self.attributes.get(ATTRIBUTE_SHARE_MESSAGE_ORDER, False) \ - if self.attributes else False - class StructField(Field): pass @@ -571,11 +565,6 @@ return self.attributes.get(ATTRIBUTE_MIN_VERSION) \ if self.attributes else None - @property - def share_message_order(self): - return self.attributes.get(ATTRIBUTE_SHARE_MESSAGE_ORDER, False) \ - if self.attributes else False - class Method(object): def __init__(self, interface, mojom_name, ordinal=None, attributes=None): @@ -874,11 +863,6 @@ def IsAssociatedInterfaceRequestKind(kind): return isinstance(kind, AssociatedInterfaceRequest) - -def FieldOrParamSharesMessageOrder(field_or_param): - return field_or_param.share_message_order - - def IsPendingRemoteKind(kind): return isinstance(kind, PendingRemote) @@ -953,7 +937,7 @@ return False -def _AnyParameterKindRecursive(method, predicate, visited_kinds=None): +def _AnyMethodParameterRecursive(method, predicate, visited_kinds=None): def _HasProperty(kind): if kind in visited_kinds: # No need to examine the kind again. @@ -985,53 +969,16 @@ return False -def _AnyFieldRecursive(fields_or_params, predicate, visited_kinds=None): - if not fields_or_params: - return False - - def _HasProperty(kind): - if kind in visited_kinds: - return False - if IsStructKind(kind) or IsUnionKind(kind): - visited_kinds.add(kind) - return _AnyFieldRecursive(kind.fields, predicate, visited_kinds) - if IsArrayKind(kind): - return _HasProperty(kind.kind) - if IsMapKind(kind): - if _HasProperty(kind.key_kind) or _HasProperty(kind.value_kind): - return True - return False - - if visited_kinds is None: - visited_kinds = set() - - for field_or_param in fields_or_params: - if predicate(field_or_param): - return True - if _HasProperty(field_or_param.kind): - return True - - return False - - # Finds out whether a method passes associated interfaces and associated # interface requests. def MethodPassesAssociatedKinds(method, visited_kinds=None): - return _AnyParameterKindRecursive(method, IsAssociatedKind, + return _AnyMethodParameterRecursive(method, IsAssociatedKind, visited_kinds=visited_kinds) # Determines whether a method passes interfaces. def MethodPassesInterfaces(method): - return _AnyParameterKindRecursive(method, IsInterfaceKind) - - -def MethodParametersShareMessageOrder(method, visited_kinds=None): - return _AnyFieldRecursive(method.parameters, FieldOrParamSharesMessageOrder, - visited_kinds=visited_kinds) or \ - _AnyFieldRecursive(method.response_parameters, - FieldOrParamSharesMessageOrder, - visited_kinds=visited_kinds) + return _AnyMethodParameterRecursive(method, IsInterfaceKind) def HasSyncMethods(interface):
diff --git a/net/dns/BUILD.gn b/net/dns/BUILD.gn index d6fb54bd..a3bdb220 100644 --- a/net/dns/BUILD.gn +++ b/net/dns/BUILD.gn
@@ -75,10 +75,24 @@ "serial_worker.h", ] - if (is_posix || is_fuchsia) { - sources += [ "dns_config_service_posix.cc" ] + if (is_fuchsia) { + sources += [ + "dns_config_service_fuchsia.cc", + "dns_config_service_fuchsia.h", + ] + } - if (enable_built_in_dns) { + if (is_posix) { + sources += [ + "dns_config_service_posix.cc", + "dns_config_service_posix.h", + ] + } + + if (enable_built_in_dns) { + sources += [ "dns_client.cc" ] + + if (is_posix || is_fuchsia) { sources += [ "address_sorter_posix.cc", "address_sorter_posix.h", @@ -86,10 +100,6 @@ } } - if (enable_built_in_dns) { - sources += [ "dns_client.cc" ] - } - if (enable_mdns) { sources += [ "mdns_cache.cc", @@ -374,7 +384,7 @@ "serial_worker_unittest.cc", ] - if (is_posix || is_fuchsia) { + if (is_posix) { sources += [ "dns_config_service_posix_unittest.cc" ] }
diff --git a/net/dns/dns_config_service_fuchsia.cc b/net/dns/dns_config_service_fuchsia.cc new file mode 100644 index 0000000..d4fca47 --- /dev/null +++ b/net/dns/dns_config_service_fuchsia.cc
@@ -0,0 +1,36 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/dns/dns_config_service_fuchsia.h" + +#include <memory> + +#include "net/dns/dns_config.h" +#include "net/dns/dns_hosts.h" + +namespace net { +namespace internal { + +DnsConfigServiceFuchsia::DnsConfigServiceFuchsia() = default; +DnsConfigServiceFuchsia::~DnsConfigServiceFuchsia() = default; + +void DnsConfigServiceFuchsia::ReadNow() { + // TODO(crbug.com/950717): Implement this method. + OnConfigRead(DnsConfig()); + OnHostsRead(DnsHosts()); +} + +bool DnsConfigServiceFuchsia::StartWatching() { + // TODO(crbug.com/950717): Implement this method. + return false; +} + +} // namespace internal + +// static +std::unique_ptr<DnsConfigService> DnsConfigService::CreateSystemService() { + return std::make_unique<internal::DnsConfigServiceFuchsia>(); +} + +} // namespace net \ No newline at end of file
diff --git a/net/dns/dns_config_service_fuchsia.h b/net/dns/dns_config_service_fuchsia.h new file mode 100644 index 0000000..79488e66 --- /dev/null +++ b/net/dns/dns_config_service_fuchsia.h
@@ -0,0 +1,34 @@ +// 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 NET_DNS_DNS_CONFIG_SERVICE_FUCHSIA_H_ +#define NET_DNS_DNS_CONFIG_SERVICE_FUCHSIA_H_ + +#include "base/macros.h" +#include "net/dns/dns_config_service.h" + +namespace net { +namespace internal { + +// DnsConfigService implementation for Fuchsia. Currently is a stub that returns +// an empty config (which means DNS resolver always falls back to +// getaddrinfo()). +class NET_EXPORT_PRIVATE DnsConfigServiceFuchsia : public DnsConfigService { + public: + DnsConfigServiceFuchsia(); + ~DnsConfigServiceFuchsia() override; + + protected: + // DnsConfigService overrides. + void ReadNow() override; + bool StartWatching() override; + + private: + DISALLOW_COPY_AND_ASSIGN(DnsConfigServiceFuchsia); +}; + +} // namespace internal +} // namespace net + +#endif // NET_DNS_DNS_CONFIG_SERVICE_FUCHSIA_H_
diff --git a/net/ssl/client_cert_identity.cc b/net/ssl/client_cert_identity.cc index 19878813..fcb9f13 100644 --- a/net/ssl/client_cert_identity.cc +++ b/net/ssl/client_cert_identity.cc
@@ -4,6 +4,8 @@ #include "net/ssl/client_cert_identity.h" +#include <utility> + #include "base/bind.h" #include "net/cert/x509_util.h" #include "net/ssl/ssl_private_key.h" @@ -14,10 +16,9 @@ void IdentityOwningPrivateKeyCallback( std::unique_ptr<ClientCertIdentity> identity, - const base::Callback<void(scoped_refptr<SSLPrivateKey>)>& - private_key_callback, + base::OnceCallback<void(scoped_refptr<SSLPrivateKey>)> private_key_callback, scoped_refptr<SSLPrivateKey> private_key) { - private_key_callback.Run(std::move(private_key)); + std::move(private_key_callback).Run(std::move(private_key)); } } // namespace @@ -29,13 +30,13 @@ // static void ClientCertIdentity::SelfOwningAcquirePrivateKey( std::unique_ptr<ClientCertIdentity> self, - const base::Callback<void(scoped_refptr<SSLPrivateKey>)>& + base::OnceCallback<void(scoped_refptr<SSLPrivateKey>)> private_key_callback) { ClientCertIdentity* self_ptr = self.get(); auto wrapped_private_key_callback = - base::Bind(&IdentityOwningPrivateKeyCallback, base::Passed(&self), - private_key_callback); - self_ptr->AcquirePrivateKey(wrapped_private_key_callback); + base::BindOnce(&IdentityOwningPrivateKeyCallback, std::move(self), + std::move(private_key_callback)); + self_ptr->AcquirePrivateKey(std::move(wrapped_private_key_callback)); } void ClientCertIdentity::SetIntermediates(
diff --git a/net/ssl/client_cert_identity.h b/net/ssl/client_cert_identity.h index 6848217..155786f9 100644 --- a/net/ssl/client_cert_identity.h +++ b/net/ssl/client_cert_identity.h
@@ -36,7 +36,7 @@ // run synchronously or asynchronously. The caller is responsible for // keeping the ClientCertIdentity alive until the callback is run. virtual void AcquirePrivateKey( - const base::Callback<void(scoped_refptr<SSLPrivateKey>)>& + base::OnceCallback<void(scoped_refptr<SSLPrivateKey>)> private_key_callback) = 0; #if defined(OS_MACOSX) @@ -49,7 +49,7 @@ // are the same as for AcquirePrivateKey above. static void SelfOwningAcquirePrivateKey( std::unique_ptr<ClientCertIdentity> identity, - const base::Callback<void(scoped_refptr<SSLPrivateKey>)>& + base::OnceCallback<void(scoped_refptr<SSLPrivateKey>)> private_key_callback); // Sets the intermediates of |certificate()| to |intermediates|. Note that
diff --git a/net/ssl/client_cert_identity_mac.cc b/net/ssl/client_cert_identity_mac.cc index 34c27156..c9f62fa 100644 --- a/net/ssl/client_cert_identity_mac.cc +++ b/net/ssl/client_cert_identity_mac.cc
@@ -17,12 +17,12 @@ ClientCertIdentityMac::~ClientCertIdentityMac() = default; void ClientCertIdentityMac::AcquirePrivateKey( - const base::Callback<void(scoped_refptr<SSLPrivateKey>)>& + base::OnceCallback<void(scoped_refptr<SSLPrivateKey>)> private_key_callback) { // This only adds a ref to and returns the private key from identity_ so it // doesn't need to run on a worker thread. - private_key_callback.Run( - CreateSSLPrivateKeyForSecIdentity(certificate(), identity_.get())); + std::move(private_key_callback) + .Run(CreateSSLPrivateKeyForSecIdentity(certificate(), identity_.get())); } SecIdentityRef ClientCertIdentityMac::sec_identity_ref() const {
diff --git a/net/ssl/client_cert_identity_mac.h b/net/ssl/client_cert_identity_mac.h index 8ae543f..0fbbb05 100644 --- a/net/ssl/client_cert_identity_mac.h +++ b/net/ssl/client_cert_identity_mac.h
@@ -20,9 +20,8 @@ base::ScopedCFTypeRef<SecIdentityRef> sec_identity); ~ClientCertIdentityMac() override; - void AcquirePrivateKey( - const base::Callback<void(scoped_refptr<SSLPrivateKey>)>& - private_key_callback) override; + void AcquirePrivateKey(base::OnceCallback<void(scoped_refptr<SSLPrivateKey>)> + private_key_callback) override; SecIdentityRef sec_identity_ref() const override; private:
diff --git a/net/ssl/client_cert_identity_test_util.cc b/net/ssl/client_cert_identity_test_util.cc index d1cb669..32209b6 100644 --- a/net/ssl/client_cert_identity_test_util.cc +++ b/net/ssl/client_cert_identity_test_util.cc
@@ -5,6 +5,7 @@ #include "net/ssl/client_cert_identity_test_util.h" #include <memory> +#include <utility> #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -71,9 +72,9 @@ } void FakeClientCertIdentity::AcquirePrivateKey( - const base::Callback<void(scoped_refptr<SSLPrivateKey>)>& + base::OnceCallback<void(scoped_refptr<SSLPrivateKey>)> private_key_callback) { - private_key_callback.Run(key_); + std::move(private_key_callback).Run(key_); } #if defined(OS_MACOSX)
diff --git a/net/ssl/client_cert_identity_test_util.h b/net/ssl/client_cert_identity_test_util.h index 85049e1a..b7e5dfef 100644 --- a/net/ssl/client_cert_identity_test_util.h +++ b/net/ssl/client_cert_identity_test_util.h
@@ -42,9 +42,8 @@ SSLPrivateKey* ssl_private_key() const { return key_.get(); } // ClientCertIdentity implementation: - void AcquirePrivateKey( - const base::Callback<void(scoped_refptr<SSLPrivateKey>)>& - private_key_callback) override; + void AcquirePrivateKey(base::OnceCallback<void(scoped_refptr<SSLPrivateKey>)> + private_key_callback) override; #if defined(OS_MACOSX) SecIdentityRef sec_identity_ref() const override; #endif
diff --git a/net/ssl/client_cert_store.h b/net/ssl/client_cert_store.h index cbe7eed..b0c1c65 100644 --- a/net/ssl/client_cert_store.h +++ b/net/ssl/client_cert_store.h
@@ -23,14 +23,15 @@ public: virtual ~ClientCertStore() {} - using ClientCertListCallback = base::Callback<void(ClientCertIdentityList)>; + using ClientCertListCallback = + base::OnceCallback<void(ClientCertIdentityList)>; // Get client certs matching the |cert_request_info| and pass them to the // |callback|. The |callback| may be called sychronously. The caller must // ensure the ClientCertStore and |cert_request_info| remain alive until the // callback has been run. virtual void GetClientCerts(const SSLCertRequestInfo& cert_request_info, - const ClientCertListCallback& callback) = 0; + ClientCertListCallback callback) = 0; protected: ClientCertStore() {}
diff --git a/net/ssl/client_cert_store_mac.cc b/net/ssl/client_cert_store_mac.cc index a64f448..fc448f4 100644 --- a/net/ssl/client_cert_store_mac.cc +++ b/net/ssl/client_cert_store_mac.cc
@@ -394,20 +394,14 @@ ClientCertStoreMac::~ClientCertStoreMac() {} -void ClientCertStoreMac::GetClientCerts( - const SSLCertRequestInfo& request, - const ClientCertListCallback& callback) { - if (base::PostTaskAndReplyWithResult( - GetSSLPlatformKeyTaskRunner().get(), FROM_HERE, - // Caller is responsible for keeping the |request| alive - // until the callback is run, so std::cref is safe. - base::Bind(&GetClientCertsOnBackgroundThread, std::cref(request)), - callback)) { - return; - } - - // If the task could not be posted, behave as if there were no certificates. - callback.Run(ClientCertIdentityList()); +void ClientCertStoreMac::GetClientCerts(const SSLCertRequestInfo& request, + ClientCertListCallback callback) { + base::PostTaskAndReplyWithResult( + GetSSLPlatformKeyTaskRunner().get(), FROM_HERE, + // Caller is responsible for keeping the |request| alive + // until the callback is run, so std::cref is safe. + base::BindOnce(&GetClientCertsOnBackgroundThread, std::cref(request)), + std::move(callback)); } bool ClientCertStoreMac::SelectClientCertsForTesting(
diff --git a/net/ssl/client_cert_store_mac.h b/net/ssl/client_cert_store_mac.h index cc06ec60..7dc3b4c 100644 --- a/net/ssl/client_cert_store_mac.h +++ b/net/ssl/client_cert_store_mac.h
@@ -20,7 +20,7 @@ // ClientCertStore: void GetClientCerts(const SSLCertRequestInfo& cert_request_info, - const ClientCertListCallback& callback) override; + ClientCertListCallback callback) override; private: friend class ClientCertStoreMacTest;
diff --git a/net/ssl/client_cert_store_nss.cc b/net/ssl/client_cert_store_nss.cc index 0265a20a..6bb552a 100644 --- a/net/ssl/client_cert_store_nss.cc +++ b/net/ssl/client_cert_store_nss.cc
@@ -45,17 +45,17 @@ password_delegate_(std::move(password_delegate)) {} ~ClientCertIdentityNSS() override = default; - void AcquirePrivateKey( - const base::Callback<void(scoped_refptr<SSLPrivateKey>)>& - private_key_callback) override { + void AcquirePrivateKey(base::OnceCallback<void(scoped_refptr<SSLPrivateKey>)> + private_key_callback) override { // Caller is responsible for keeping the ClientCertIdentity alive until // the |private_key_callback| is run, so it's safe to use Unretained here. base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::Bind(&FetchClientCertPrivateKey, base::Unretained(certificate()), - cert_certificate_.get(), password_delegate_), - private_key_callback); + base::BindOnce(&FetchClientCertPrivateKey, + base::Unretained(certificate()), cert_certificate_.get(), + password_delegate_), + std::move(private_key_callback)); } private: @@ -72,21 +72,20 @@ ClientCertStoreNSS::~ClientCertStoreNSS() = default; -void ClientCertStoreNSS::GetClientCerts( - const SSLCertRequestInfo& request, - const ClientCertListCallback& callback) { +void ClientCertStoreNSS::GetClientCerts(const SSLCertRequestInfo& request, + ClientCertListCallback callback) { scoped_refptr<crypto::CryptoModuleBlockingPasswordDelegate> password_delegate; if (!password_delegate_factory_.is_null()) password_delegate = password_delegate_factory_.Run(request.host_and_port); base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::Bind(&ClientCertStoreNSS::GetAndFilterCertsOnWorkerThread, - // Caller is responsible for keeping the ClientCertStore - // alive until the callback is run. - base::Unretained(this), std::move(password_delegate), - base::Unretained(&request)), - callback); + base::BindOnce(&ClientCertStoreNSS::GetAndFilterCertsOnWorkerThread, + // Caller is responsible for keeping the ClientCertStore + // alive until the callback is run. + base::Unretained(this), std::move(password_delegate), + base::Unretained(&request)), + std::move(callback)); } // static
diff --git a/net/ssl/client_cert_store_nss.h b/net/ssl/client_cert_store_nss.h index 465569ec..95313553 100644 --- a/net/ssl/client_cert_store_nss.h +++ b/net/ssl/client_cert_store_nss.h
@@ -23,8 +23,9 @@ class NET_EXPORT ClientCertStoreNSS : public ClientCertStore { public: - typedef base::Callback<crypto::CryptoModuleBlockingPasswordDelegate*( - const HostPortPair& /* server */)> PasswordDelegateFactory; + typedef base::RepeatingCallback<crypto::CryptoModuleBlockingPasswordDelegate*( + const HostPortPair& /* server */)> + PasswordDelegateFactory; using CertFilter = base::RepeatingCallback<bool(CERTCertificate*)>; @@ -34,7 +35,7 @@ // ClientCertStore: void GetClientCerts(const SSLCertRequestInfo& cert_request_info, - const ClientCertListCallback& callback) override; + ClientCertListCallback callback) override; // Examines the certificates in |identities| to find all certificates that // match the client certificate request in |request|, removing any that don't.
diff --git a/net/ssl/client_cert_store_nss_unittest.cc b/net/ssl/client_cert_store_nss_unittest.cc index ded63b21..c6c7f29 100644 --- a/net/ssl/client_cert_store_nss_unittest.cc +++ b/net/ssl/client_cert_store_nss_unittest.cc
@@ -122,8 +122,8 @@ scoped_refptr<SSLPrivateKey> ssl_private_key; base::RunLoop key_loop; selected_identities[0]->AcquirePrivateKey( - base::Bind(SavePrivateKeyAndQuitCallback, &ssl_private_key, - key_loop.QuitClosure())); + base::BindOnce(SavePrivateKeyAndQuitCallback, &ssl_private_key, + key_loop.QuitClosure())); key_loop.Run(); ASSERT_TRUE(ssl_private_key); @@ -159,8 +159,8 @@ scoped_refptr<SSLPrivateKey> ssl_private_key; base::RunLoop key_loop; selected_identities[0]->AcquirePrivateKey( - base::Bind(SavePrivateKeyAndQuitCallback, &ssl_private_key, - key_loop.QuitClosure())); + base::BindOnce(SavePrivateKeyAndQuitCallback, &ssl_private_key, + key_loop.QuitClosure())); key_loop.Run(); ASSERT_TRUE(ssl_private_key); EXPECT_EQ(expected, ssl_private_key->GetAlgorithmPreferences()); @@ -232,7 +232,7 @@ scoped_refptr<SSLPrivateKey> ssl_private_key; base::RunLoop key_loop; - selected_identities[0]->AcquirePrivateKey(base::Bind( + selected_identities[0]->AcquirePrivateKey(base::BindOnce( SavePrivateKeyAndQuitCallback, &ssl_private_key, key_loop.QuitClosure())); key_loop.Run();
diff --git a/net/ssl/client_cert_store_win.cc b/net/ssl/client_cert_store_win.cc index fed21b8f..8621dbc 100644 --- a/net/ssl/client_cert_store_win.cc +++ b/net/ssl/client_cert_store_win.cc
@@ -16,6 +16,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback.h" +#include "base/callback_helpers.h" #include "base/logging.h" #include "base/numerics/safe_conversions.h" #include "base/single_thread_task_runner.h" @@ -35,34 +36,25 @@ class ClientCertIdentityWin : public ClientCertIdentity { public: - // Takes ownership of |cert_context|. ClientCertIdentityWin( scoped_refptr<net::X509Certificate> cert, - PCCERT_CONTEXT cert_context, + ScopedPCCERT_CONTEXT cert_context, scoped_refptr<base::SingleThreadTaskRunner> key_task_runner) : ClientCertIdentity(std::move(cert)), - cert_context_(cert_context), - key_task_runner_(key_task_runner) {} - ~ClientCertIdentityWin() override { - CertFreeCertificateContext(cert_context_); - } + cert_context_(std::move(cert_context)), + key_task_runner_(std::move(key_task_runner)) {} - void AcquirePrivateKey( - const base::Callback<void(scoped_refptr<SSLPrivateKey>)>& - private_key_callback) override { - if (base::PostTaskAndReplyWithResult( - key_task_runner_.get(), FROM_HERE, - base::Bind(&FetchClientCertPrivateKey, - base::Unretained(certificate()), cert_context_), - private_key_callback)) { - return; - } - // If the task could not be posted, behave as if there was no key. - private_key_callback.Run(nullptr); + void AcquirePrivateKey(base::OnceCallback<void(scoped_refptr<SSLPrivateKey>)> + private_key_callback) override { + base::PostTaskAndReplyWithResult( + key_task_runner_.get(), FROM_HERE, + base::BindOnce(&FetchClientCertPrivateKey, + base::Unretained(certificate()), cert_context_.get()), + std::move(private_key_callback)); } private: - PCCERT_CONTEXT cert_context_; + ScopedPCCERT_CONTEXT cert_context_; scoped_refptr<base::SingleThreadTaskRunner> key_task_runner_; }; @@ -155,15 +147,18 @@ PCCERT_CONTEXT cert_context = chain_context->rgpChain[0]->rgpElement[0]->pCertContext; // Copy the certificate, so that it is valid after |cert_store| is closed. - PCCERT_CONTEXT cert_context2 = nullptr; + ScopedPCCERT_CONTEXT cert_context2; + PCCERT_CONTEXT raw = nullptr; BOOL ok = CertAddCertificateContextToStore( - nullptr, cert_context, CERT_STORE_ADD_USE_EXISTING, &cert_context2); + nullptr, cert_context, CERT_STORE_ADD_USE_EXISTING, &raw); if (!ok) { NOTREACHED(); continue; } + cert_context2.reset(raw); // Grab the intermediates, if any. + std::vector<ScopedPCCERT_CONTEXT> intermediates_storage; std::vector<PCCERT_CONTEXT> intermediates; for (DWORD i = 1; i < chain_context->rgpChain[0]->cElement; ++i) { PCCERT_CONTEXT chain_intermediate = @@ -172,8 +167,10 @@ ok = CertAddCertificateContextToStore(nullptr, chain_intermediate, CERT_STORE_ADD_USE_EXISTING, &copied_intermediate); - if (ok) + if (ok) { intermediates.push_back(copied_intermediate); + intermediates_storage.emplace_back(copied_intermediate); + } } // Drop the self-signed root, if any. Match Internet Explorer in not sending @@ -185,8 +182,8 @@ // in that case, assume it is a configuration error. if (!intermediates.empty() && x509_util::IsSelfSigned(intermediates.back())) { - CertFreeCertificateContext(intermediates.back()); intermediates.pop_back(); + intermediates_storage.pop_back(); } // Allow UTF-8 inside PrintableStrings in client certificates. See @@ -195,16 +192,14 @@ options.printable_string_is_utf8 = true; scoped_refptr<X509Certificate> cert = x509_util::CreateX509CertificateFromCertContexts( - cert_context2, intermediates, options); + cert_context2.get(), intermediates, options); if (cert) { selected_identities.push_back(std::make_unique<ClientCertIdentityWin>( std::move(cert), - cert_context2, // Takes ownership of |cert_context2|. + std::move(cert_context2), // Takes ownership of |cert_context2|. current_thread)); // The key must be acquired on the same thread, as // the PCCERT_CONTEXT may not be thread safe. } - for (size_t i = 0; i < intermediates.size(); ++i) - CertFreeCertificateContext(intermediates[i]); } std::sort(selected_identities.begin(), selected_identities.end(), @@ -223,31 +218,25 @@ ClientCertStoreWin::~ClientCertStoreWin() {} -void ClientCertStoreWin::GetClientCerts( - const SSLCertRequestInfo& request, - const ClientCertListCallback& callback) { +void ClientCertStoreWin::GetClientCerts(const SSLCertRequestInfo& request, + ClientCertListCallback callback) { if (cert_store_) { // Use the existing client cert store. Note: Under some situations, // it's possible for this to return certificates that aren't usable // (see below). // When using caller provided HCERTSTORE, assume that it should be accessed // on the current thread. - callback.Run(GetClientCertsImpl(cert_store_, request)); + std::move(callback).Run(GetClientCertsImpl(cert_store_, request)); return; } - if (base::PostTaskAndReplyWithResult( - GetSSLPlatformKeyTaskRunner().get(), FROM_HERE, - // Caller is responsible for keeping the |request| alive - // until the callback is run, so std::cref is safe. - base::Bind(&ClientCertStoreWin::GetClientCertsWithMyCertStore, + base::PostTaskAndReplyWithResult( + GetSSLPlatformKeyTaskRunner().get(), FROM_HERE, + // Caller is responsible for keeping the |request| alive + // until the callback is run, so std::cref is safe. + base::BindOnce(&ClientCertStoreWin::GetClientCertsWithMyCertStore, std::cref(request)), - callback)) { - return; - } - - // If the task could not be posted, behave as if there were no certificates. - callback.Run(ClientCertIdentityList()); + std::move(callback)); } // static
diff --git a/net/ssl/client_cert_store_win.h b/net/ssl/client_cert_store_win.h index 4db6d475..184ed6b 100644 --- a/net/ssl/client_cert_store_win.h +++ b/net/ssl/client_cert_store_win.h
@@ -28,7 +28,7 @@ // will use that. Otherwise it will use the current user's "MY" cert store // instead. void GetClientCerts(const SSLCertRequestInfo& cert_request_info, - const ClientCertListCallback& callback) override; + ClientCertListCallback callback) override; private: using ScopedHCERTSTORE = crypto::ScopedCAPIHandle<
diff --git a/net/tools/cert_verify_tool/cert_verify_tool.cc b/net/tools/cert_verify_tool/cert_verify_tool.cc index 5129002..57c200c 100644 --- a/net/tools/cert_verify_tool/cert_verify_tool.cc +++ b/net/tools/cert_verify_tool/cert_verify_tool.cc
@@ -284,7 +284,7 @@ base::FilePath target_path = base::FilePath(args[0]); base::FilePath crlset_path = command_line.GetSwitchValuePath("crlset"); - scoped_refptr<net::CRLSet> crl_set; + scoped_refptr<net::CRLSet> crl_set = net::CRLSet::BuiltinCRLSet(); if (!crlset_path.empty()) { std::string crl_set_bytes; if (!ReadFromFile(crlset_path, &crl_set_bytes))
diff --git a/remoting/host/token_validator_base.cc b/remoting/host/token_validator_base.cc index d78637ea..041f7fb 100644 --- a/remoting/host/token_validator_base.cc +++ b/remoting/host/token_validator_base.cc
@@ -219,8 +219,9 @@ // give it a WeakPtr for |this|, and ownership of the other parameters. client_cert_store->GetClientCerts( *cert_request_info, - base::Bind(&TokenValidatorBase::OnCertificatesSelected, - weak_factory_.GetWeakPtr(), base::Owned(client_cert_store))); + base::BindOnce(&TokenValidatorBase::OnCertificatesSelected, + weak_factory_.GetWeakPtr(), + base::Owned(client_cert_store))); } void TokenValidatorBase::OnCertificatesSelected( @@ -246,8 +247,8 @@ (*best_match_position)->certificate(); net::ClientCertIdentity::SelfOwningAcquirePrivateKey( std::move(*best_match_position), - base::Bind(&TokenValidatorBase::ContinueWithCertificate, - weak_factory_.GetWeakPtr(), std::move(cert))); + base::BindOnce(&TokenValidatorBase::ContinueWithCertificate, + weak_factory_.GetWeakPtr(), std::move(cert))); } }
diff --git a/services/device/geolocation/OWNERS b/services/device/geolocation/OWNERS index 2596b2d..2ce1e4a 100644 --- a/services/device/geolocation/OWNERS +++ b/services/device/geolocation/OWNERS
@@ -1,8 +1,6 @@ mattreynolds@chromium.org - -# Original (legacy) owners. mcasas@chromium.org timvolodine@chromium.org -# COMPONENT: Blink>Geolocation # TEAM: device-dev@chromium.org +# COMPONENT: Blink>Location
diff --git a/services/shape_detection/OWNERS b/services/shape_detection/OWNERS index 7a97495..0e57d5f 100644 --- a/services/shape_detection/OWNERS +++ b/services/shape_detection/OWNERS
@@ -1,7 +1,5 @@ -reillyg@chromium.org - -# Original (legacy) owner. -mcasas@chromium.org - # COMPONENT: Blink>ImageCapture -# TEAM: device-dev@chromium.org +# TEAM: media-dev@chromium.org + +mcasas@chromium.org +reillyg@chromium.org
diff --git a/services/tracing/public/cpp/perfetto/perfetto_config.cc b/services/tracing/public/cpp/perfetto/perfetto_config.cc index 2d73c53..b21ba02a 100644 --- a/services/tracing/public/cpp/perfetto/perfetto_config.cc +++ b/services/tracing/public/cpp/perfetto/perfetto_config.cc
@@ -76,6 +76,9 @@ perfetto_config.add_data_sources()->mutable_config(); trace_metadata_config->set_name(tracing::mojom::kMetaDataSourceName); trace_metadata_config->set_target_buffer(0); + auto* metadata_chrome_config = trace_metadata_config->mutable_chrome_config(); + metadata_chrome_config->set_trace_config(chrome_config_string); + // TODO(ssid): Also set privacy_filtering_enabled here. return perfetto_config; }
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc index f13da240..32a58a48 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
@@ -23,6 +23,7 @@ #include "services/tracing/public/cpp/perfetto/thread_local_event_sink.h" #include "services/tracing/public/cpp/perfetto/traced_value_proto_writer.h" #include "services/tracing/public/cpp/perfetto/track_event_thread_local_event_sink.h" +#include "services/tracing/public/cpp/trace_event_args_whitelist.h" #include "services/tracing/public/mojom/constants.mojom.h" #include "third_party/perfetto/include/perfetto/tracing/core/shared_memory_arbiter.h" #include "third_party/perfetto/include/perfetto/tracing/core/startup_trace_writer.h" @@ -42,7 +43,11 @@ TraceEventMetadataSource::TraceEventMetadataSource() : DataSourceBase(mojom::kMetaDataSourceName), - origin_task_runner_(base::SequencedTaskRunnerHandle::Get()) {} + origin_task_runner_(base::SequencedTaskRunnerHandle::Get()) { + AddGeneratorFunction(base::BindRepeating( + &TraceEventMetadataSource::GenerateTraceConfigMetadataDict, + base::Unretained(this))); +} TraceEventMetadataSource::~TraceEventMetadataSource() = default; @@ -52,6 +57,30 @@ generator_functions_.push_back(generator); } +std::unique_ptr<base::DictionaryValue> +TraceEventMetadataSource::GenerateTraceConfigMetadataDict() { + if (chrome_config_.empty()) { + return nullptr; + } + + base::trace_event::TraceConfig parsed_chrome_config(chrome_config_); + + auto metadata_dict = std::make_unique<base::DictionaryValue>(); + // If argument filtering is enabled, we need to check if the trace config is + // whitelisted before emitting it. + // TODO(eseckler): Figure out a way to solve this without calling directly + // into IsMetadataWhitelisted(). + if (!parsed_chrome_config.IsArgumentFilterEnabled() || + IsMetadataWhitelisted("trace-config")) { + metadata_dict->SetString("trace-config", chrome_config_); + } else { + metadata_dict->SetString("trace-config", "__stripped__"); + } + + chrome_config_ = std::string(); + return metadata_dict; +} + void TraceEventMetadataSource::GenerateMetadata( std::unique_ptr<perfetto::TraceWriter> trace_writer) { DCHECK(origin_task_runner_->RunsTasksInCurrentSequence()); @@ -91,6 +120,7 @@ // sense to emit the metadata on startup, so the UI can display it right away. privacy_filtering_enabled_ = data_source_config.chrome_config().privacy_filtering_enabled(); + chrome_config_ = data_source_config.chrome_config().trace_config(); trace_writer_ = producer_client->CreateTraceWriter(data_source_config.target_buffer()); } @@ -107,6 +137,7 @@ std::move(stop_complete_callback)); } else { trace_writer_.reset(); + chrome_config_ = std::string(); std::move(stop_complete_callback).Run(); } }
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.h b/services/tracing/public/cpp/perfetto/trace_event_data_source.h index f316150..0d9a9a02 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source.h +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.h
@@ -51,11 +51,13 @@ private: void GenerateMetadata(std::unique_ptr<perfetto::TraceWriter> trace_writer); + std::unique_ptr<base::DictionaryValue> GenerateTraceConfigMetadataDict(); std::vector<MetadataGeneratorFunction> generator_functions_; scoped_refptr<base::SequencedTaskRunner> origin_task_runner_; std::unique_ptr<perfetto::TraceWriter> trace_writer_; bool privacy_filtering_enabled_ = false; + std::string chrome_config_; DISALLOW_COPY_AND_ASSIGN(TraceEventMetadataSource); };
diff --git a/services/video_capture/OWNERS b/services/video_capture/OWNERS index 495d7a5..c3dbbd03 100644 --- a/services/video_capture/OWNERS +++ b/services/video_capture/OWNERS
@@ -1,8 +1,6 @@ +# TEAM: media-capture-and-streams@grotations.appspotmail.com +# COMPONENT: Blink>GetUserMedia + chfremer@chromium.org emircan@chromium.org - -# Original (legacy) owner. -per-file *video*=mcasas@chromium.org - -# COMPONENT: Blink>GetUserMedia -# TEAM: webrtc-dev@chromium.org +mcasas@chromium.org
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h index 9a3d3be..5cc162df 100644 --- a/skia/config/SkUserConfig.h +++ b/skia/config/SkUserConfig.h
@@ -169,6 +169,10 @@ #define SK_SUPPORT_LEGACY_AAA_CHOICE #endif +#ifndef SK_SUPPORT_LEGACY_COLORFILTER_FACTORIES +#define SK_SUPPORT_LEGACY_COLORFILTER_FACTORIES +#endif + #ifndef SK_ENABLE_LEGACY_TEXT_COLOR #define SK_ENABLE_LEGACY_TEXT_COLOR #endif
diff --git a/testing/buildbot/chromium.dawn.json b/testing/buildbot/chromium.dawn.json index d545aea8..0c1caf8 100644 --- a/testing/buildbot/chromium.dawn.json +++ b/testing/buildbot/chromium.dawn.json
@@ -159,6 +159,30 @@ } ] }, + "Dawn Mac x64 Builder": {}, + "Dawn Mac x64 Release (AMD)": { + "gtest_tests": [ + { + "args": [ + "--use-gpu-in-tests", + "--test-launcher-retry-limit=0" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "1002:6821", + "hidpi": "1", + "os": "Mac-10.13.6", + "pool": "Chrome-GPU" + } + ], + "shards": 4 + }, + "test": "dawn_end2end_tests" + } + ] + }, "Dawn Win10 x64 Builder": {}, "Dawn Win10 x64 DEPS Builder": {}, "Dawn Win10 x64 DEPS Release (Intel HD 630)": {
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 5a01153..5440ddf 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -10850,7 +10850,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -10858,7 +10858,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] }, @@ -10877,7 +10877,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -10885,7 +10885,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -10905,7 +10905,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -10913,7 +10913,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -10930,7 +10930,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -10938,7 +10938,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] }, @@ -10956,7 +10956,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -10964,7 +10964,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -10980,7 +10980,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -10988,7 +10988,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11004,7 +11004,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11012,7 +11012,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11025,7 +11025,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11033,7 +11033,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11050,7 +11050,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11058,7 +11058,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11071,7 +11071,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11079,7 +11079,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11105,7 +11105,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11114,7 +11114,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11137,7 +11137,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11146,7 +11146,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11169,7 +11169,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11178,7 +11178,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11201,7 +11201,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11210,7 +11210,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11237,7 +11237,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11246,7 +11246,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11276,7 +11276,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11285,7 +11285,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11323,7 +11323,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11332,7 +11332,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11356,7 +11356,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11365,7 +11365,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11388,7 +11388,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11397,7 +11397,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11422,7 +11422,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11431,7 +11431,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] }, @@ -11455,7 +11455,7 @@ "dimension_sets": [ { "gpu": "1002:6821", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11464,7 +11464,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] }, @@ -11486,7 +11486,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11494,7 +11494,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] }, @@ -11513,7 +11513,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11521,7 +11521,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11541,7 +11541,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11549,7 +11549,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11566,7 +11566,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11574,7 +11574,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] }, @@ -11592,7 +11592,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11600,7 +11600,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11616,7 +11616,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11624,7 +11624,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11640,7 +11640,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11648,7 +11648,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11661,7 +11661,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11669,7 +11669,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11686,7 +11686,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11694,7 +11694,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11707,7 +11707,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11715,7 +11715,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11741,7 +11741,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11750,7 +11750,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11773,7 +11773,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11782,7 +11782,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11805,7 +11805,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11814,7 +11814,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11837,7 +11837,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11846,7 +11846,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11873,7 +11873,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11882,7 +11882,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11912,7 +11912,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11921,7 +11921,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11959,7 +11959,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -11968,7 +11968,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -11992,7 +11992,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12001,7 +12001,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12024,7 +12024,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12033,7 +12033,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12058,7 +12058,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12067,7 +12067,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] }, @@ -12091,7 +12091,7 @@ "dimension_sets": [ { "gpu": "8086:0a2e", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12100,7 +12100,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] }, @@ -12122,7 +12122,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12130,7 +12130,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] }, @@ -12149,7 +12149,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12157,7 +12157,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12177,7 +12177,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12185,7 +12185,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12202,7 +12202,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12210,7 +12210,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] }, @@ -12228,7 +12228,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12236,7 +12236,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12252,7 +12252,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12260,7 +12260,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12276,7 +12276,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12284,7 +12284,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12297,7 +12297,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12305,7 +12305,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12322,7 +12322,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12330,7 +12330,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12343,7 +12343,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12351,7 +12351,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12377,7 +12377,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12386,7 +12386,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12409,7 +12409,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12418,7 +12418,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12441,7 +12441,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12450,7 +12450,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12473,7 +12473,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12482,7 +12482,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12509,7 +12509,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12518,7 +12518,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12548,7 +12548,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12557,7 +12557,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12595,7 +12595,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12604,7 +12604,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12628,7 +12628,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12637,7 +12637,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12660,7 +12660,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12669,7 +12669,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] } @@ -12694,7 +12694,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12703,7 +12703,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] }, @@ -12727,7 +12727,7 @@ "dimension_sets": [ { "gpu": "10de:0fe9", - "os": "Mac-10.14.3", + "os": "Mac-10.14.4", "pool": "Chrome-GPU" } ], @@ -12736,7 +12736,7 @@ "optional_dimensions": { "600": [ { - "os": "Mac-10.14.4" + "os": "Mac-10.14.3" } ] }, @@ -16453,32 +16453,6 @@ ], "idempotent": false } - }, - { - "args": [ - "webgl_conformance", - "--show-stdout", - "--browser=debug", - "--passthrough", - "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" - ], - "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl_conformance_tests", - "should_retry_with_patch": false, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:0fe9", - "hidpi": "1", - "os": "Mac-10.13.6", - "pool": "Chrome-GPU" - } - ], - "idempotent": false, - "shards": 2 - } } ] },
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index 9d0e449..8919d21 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -331,14 +331,14 @@ 'mac_10.14': { 'swarming': { 'dimensions': { - 'os': 'Mac-10.14.3', + 'os': 'Mac-10.14.4', }, 'optional_dimensions': { # Wait 10 minutes for 10.14.4, then fall back to 10.14.3. # The format for optional dimensions is: expiration: [{key, value}, ..]. 600: [ { - 'os': 'Mac-10.14.4', + 'os': 'Mac-10.14.3', }, ], },
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 528592e..e995d343 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1523,6 +1523,11 @@ ] }, }, + 'remove_from': [ + # Too slow on this configuration, which is severely hardware + # constrained. crbug.com/950690 + 'Mac FYI Retina Debug (NVIDIA)', + ], }, 'webgl_conformance_vulkan_passthrough_tests': { 'remove_from': [
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index ad46626..cd922fa 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -1050,6 +1050,17 @@ 'gtest_tests': 'gpu_dawn_gtests', }, }, + 'Dawn Mac x64 Builder' : {}, + 'Dawn Mac x64 Release (AMD)': { + 'os_type': 'mac', + 'browser_config': 'release', + 'mixins': [ + 'mac_retina_amd_gpu', + ], + 'test_suites': { + 'gtest_tests': 'gpu_dawn_gtests', + }, + }, 'Dawn Win10 x64 Builder' : {}, 'Dawn Win10 x64 DEPS Builder' : {}, 'Dawn Win10 x64 DEPS Release (Intel HD 630)': {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 6b34d2f..6506460 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -3311,6 +3311,7 @@ "OmniboxRichEntitySuggestions", "OmniboxTailSuggestions", "OmniboxUIExperimentMaxAutocompleteMatches", + "QueryInOmnibox", "ZeroSuggestRedirectToChrome", "ZeroSuggestSwapTitleAndUrl" ]
diff --git a/third_party/blink/common/mediastream/OWNERS b/third_party/blink/common/mediastream/OWNERS index 7f3f570..ed7be739 100644 --- a/third_party/blink/common/mediastream/OWNERS +++ b/third_party/blink/common/mediastream/OWNERS
@@ -4,5 +4,5 @@ per-file *_mojom_traits*.*=set noparent per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS -# TEAM: webrtc-dev@chromium.org +# TEAM: media-capture-and-streams@grotations.appspotmail.com # COMPONENT: Blink>GetUserMedia
diff --git a/third_party/blink/public/common/mediastream/OWNERS b/third_party/blink/public/common/mediastream/OWNERS index f247c7f..155e1a8b 100644 --- a/third_party/blink/public/common/mediastream/OWNERS +++ b/third_party/blink/public/common/mediastream/OWNERS
@@ -6,5 +6,5 @@ per-file *.typemap=set noparent per-file *.typemap=file://ipc/SECURITY_OWNERS -# TEAM: webrtc-dev@chromium.org +# TEAM: media-capture-and-streams@grotations.appspotmail.com # COMPONENT: Blink>GetUserMedia
diff --git a/third_party/blink/public/mojom/mediastream/OWNERS b/third_party/blink/public/mojom/mediastream/OWNERS index 1ec01e1..ff62c9c4 100644 --- a/third_party/blink/public/mojom/mediastream/OWNERS +++ b/third_party/blink/public/mojom/mediastream/OWNERS
@@ -4,5 +4,5 @@ per-file *.mojom=set noparent per-file *.mojom=file://ipc/SECURITY_OWNERS -# TEAM: webrtc-dev@chromium.org +# TEAM: media-capture-and-streams@grotations.appspotmail.com # COMPONENT: Blink>GetUserMedia
diff --git a/third_party/blink/public/platform/modules/mediastream/OWNERS b/third_party/blink/public/platform/modules/mediastream/OWNERS index 32889cc..c205d4f9 100644 --- a/third_party/blink/public/platform/modules/mediastream/OWNERS +++ b/third_party/blink/public/platform/modules/mediastream/OWNERS
@@ -2,5 +2,5 @@ per-file media_stream_audio_processor*=aluebs@chromium.org -# TEAM: webrtc-dev@chromium.org +# TEAM: media-capture-and-streams@grotations.appspotmail.com # COMPONENT: Blink>GetUserMedia
diff --git a/third_party/blink/public/web/modules/mediastream/OWNERS b/third_party/blink/public/web/modules/mediastream/OWNERS index 9d70184..4d93338 100644 --- a/third_party/blink/public/web/modules/mediastream/OWNERS +++ b/third_party/blink/public/web/modules/mediastream/OWNERS
@@ -1,4 +1,4 @@ file://third_party/blink/common/mediastream/OWNERS -# TEAM: webrtc-dev@chromium.org +# TEAM: media-capture-and-streams@grotations.appspotmail.com # COMPONENT: Blink>GetUserMedia
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc index de5a461..b0bfc8a 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
@@ -44,7 +44,8 @@ ~SourceStream() override = default; // Called by V8 on a background thread. Should block until we can return - // some data. + // some data. Ownership of the |src| data buffer is passed to the caller, + // unless |src| is null. size_t GetMoreData(const uint8_t** src) override { DCHECK(!IsMainThread()); CHECK(ready_to_run_.IsSet()); @@ -61,7 +62,11 @@ if (initial_data_) { CHECK_GT(initial_data_len_, 0u); - *src = initial_data_.release(); + if (src) { + *src = initial_data_.release(); + } else { + initial_data_.reset(); + } size_t len = initial_data_len_; initial_data_len_ = 0; return len; @@ -83,8 +88,12 @@ // num_bytes could only be 0 if the handle was being read elsewhere. CHECK_GT(num_bytes, 0u); - auto copy_for_script_stream = std::make_unique<uint8_t[]>(num_bytes); - memcpy(copy_for_script_stream.get(), buffer, num_bytes); + if (src) { + auto copy_for_script_stream = + std::make_unique<uint8_t[]>(num_bytes); + memcpy(copy_for_script_stream.get(), buffer, num_bytes); + *src = copy_for_script_stream.release(); + } // TODO(leszeks): It would be nice to get rid of this second copy, and // either share ownership of the chunks, or only give chunks back to @@ -100,7 +109,6 @@ result = data_pipe_->EndReadData(num_bytes); CHECK_EQ(result, MOJO_RESULT_OK); - *src = copy_for_script_stream.release(); return num_bytes; } @@ -152,8 +160,7 @@ if (!finished_) { // Keep reading data until we finish (returning 0). It won't be streaming // compiled any more, but it will continue being forwarded to the client. - const uint8_t* ignored_data; - while (GetMoreData(&ignored_data) != 0) { + while (GetMoreData(nullptr) != 0) { } } CHECK(finished_);
diff --git a/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_individual.py b/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_individual.py index 992d4db..0bafc86 100755 --- a/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_individual.py +++ b/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_individual.py
@@ -112,22 +112,22 @@ return posixpath.join(relative_dir, output_file_basename + '.h') -def get_implements_from_definitions(definitions, definition_name): - left_interfaces = [] - right_interfaces = [] - for implement in definitions.implements: - if definition_name == implement.left_interface: - right_interfaces.append(implement.right_interface) - elif definition_name == implement.right_interface: - left_interfaces.append(implement.left_interface) +def get_includes_from_definitions(definitions, definition_name): + interfaces = [] + mixins = [] + for include in definitions.includes: + if definition_name == include.interface: + mixins.append(include.mixin) + elif definition_name == include.mixin: + interfaces.append(include.interface) else: raise IdlBadFilenameError( - 'implements statement found in unrelated IDL file.\n' + 'includes statement found in unrelated IDL file.\n' 'Statement is:\n' - ' %s implements %s;\n' + ' %s includes %s;\n' 'but filename is unrelated "%s.idl"' % - (implement.left_interface, implement.right_interface, definition_name)) - return left_interfaces, right_interfaces + (include.interface, include.mixin, definition_name)) + return interfaces, mixins def get_put_forward_interfaces_from_definition(definition): @@ -298,11 +298,10 @@ {'cpp_includes': {component: set([this_include_path])}}) return - # 'implements' statements can be included in either the file for the - # implement*ing* interface (lhs of 'implements') or implement*ed* interface - # (rhs of 'implements'). Store both for now, then merge to implement*ing* - # interface later. - left_interfaces, right_interfaces = get_implements_from_definitions( + # 'includes' statements can be included in either the file for the + # interface (lhs of 'includes') or mixin (rhs of 'includes'). Store both + # for now, then merge to the interface later. + includes_interfaces, includes_mixins = get_includes_from_definitions( definitions, definition.name) interface_info.update({ @@ -310,8 +309,8 @@ 'full_path': full_path, 'union_types': this_union_types, 'implemented_as': implemented_as, - 'implemented_by_interfaces': left_interfaces, - 'implements_interfaces': right_interfaces, + 'included_by_interfaces': includes_interfaces, + 'including_mixins': includes_mixins, 'include_path': this_include_path, # FIXME: temporary private field, while removing old treatement of # 'implements': http://crbug.com/360435
diff --git a/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_overall.py b/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_overall.py index 10dabe7..449aad69 100755 --- a/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_overall.py +++ b/third_party/blink/renderer/bindings/scripts/compute_interfaces_info_overall.py
@@ -50,7 +50,7 @@ Current keys are: * dependencies: - 'implements_interfaces': targets of 'implements' statements + 'including_mixins': targets of 'includes' statements 'referenced_interfaces': reference interfaces that are introspected (currently just targets of [PutForwards]) @@ -111,7 +111,7 @@ class IdlInterfaceFileNotFoundError(Exception): - """Raised if the IDL file implementing an interface cannot be found.""" + """Raised if an IDL file that contains the mixin cannot be found.""" pass @@ -226,17 +226,17 @@ compute_inheritance_info(interface_name) # Compute dependencies - # Move implements info from implement*ed* interface (rhs of 'implements') - # to implement*ing* interface (lhs of 'implements'). - # Note that moving an 'implements' statement between implementing and - # implemented files does not change the info (or hence cause a rebuild)! - for right_interface_name, interface_info in interfaces_info.iteritems(): - for left_interface_name in interface_info['implemented_by_interfaces']: - interfaces_info[left_interface_name]['implements_interfaces'].append(right_interface_name) - del interface_info['implemented_by_interfaces'] + # Move includes info from mixin (rhs of 'includes') to interface (lhs of + # 'includes'). + # Note that moving an 'includes' statement between files does not change the + # info itself (or hence cause a rebuild)! + for mixin_name, interface_info in interfaces_info.iteritems(): + for interface_name in interface_info['included_by_interfaces']: + interfaces_info[interface_name]['including_mixins'].append(mixin_name) + del interface_info['included_by_interfaces'] # An IDL file's dependencies are partial interface files that extend it, - # and files for other interfaces that this interfaces implements. + # and files for other interfaces that this interfaces include. for interface_name, interface_info in interfaces_info.iteritems(): partial_interface_paths = partial_interface_files[interface_name] partial_interfaces_full_paths = partial_interface_paths['full_paths'] @@ -244,29 +244,24 @@ # implemented in separate classes from the main interface. partial_interfaces_include_paths = partial_interface_paths['include_paths'] - implemented_interfaces = interface_info['implements_interfaces'] + mixins = interface_info['including_mixins'] try: - implemented_interfaces_info = [ - interfaces_info[interface] - for interface in implemented_interfaces] + mixins_info = [interfaces_info[mixin] for mixin in mixins] except KeyError as key_name: - raise IdlInterfaceFileNotFoundError('Could not find the IDL file where the following implemented interface is defined: %s' % key_name) - implemented_interfaces_full_paths = [ - implemented_interface_info['full_path'] - for implemented_interface_info in implemented_interfaces_info] - # Implemented interfaces don't need includes, as this is handled in - # the Blink implementation (they are implemented on |impl| itself, - # hence header is included in implementing class). - # However, they are needed for legacy implemented interfaces that - # are being treated as partial interfaces, until we remove these. - # http://crbug.com/360435 - implemented_interfaces_include_paths = [ - implemented_interface_info['include_path'] - for implemented_interface_info in implemented_interfaces_info - if implemented_interface_info['is_legacy_treat_as_partial_interface']] + raise IdlInterfaceFileNotFoundError('Could not find the IDL file where the following mixin is defined: %s' % key_name) + mixins_full_paths = [mixin_info['full_path'] for mixin_info in mixins_info] + # Mixins don't need include files, as this is handled in the Blink + # implementation (they are implemented on |impl| itself, hence header + # declaration is included in the interface class). + # However, they are needed for legacy mixins that are being treated as + # partial interfaces, until we remove these. + # https://crbug.com/360435 + mixins_include_paths = [ + mixin_info['include_path'] for mixin_info in mixins_info + if mixin_info['is_legacy_treat_as_partial_interface']] - dependencies_full_paths = implemented_interfaces_full_paths - dependencies_include_paths = implemented_interfaces_include_paths + dependencies_full_paths = mixins_full_paths + dependencies_include_paths = mixins_include_paths dependencies_other_component_full_paths = [] dependencies_other_component_include_paths = []
diff --git a/third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py b/third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py index 6e4950e..9eb6063 100755 --- a/third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py +++ b/third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py
@@ -68,10 +68,10 @@ def read_idl_file(reader, idl_filename): definitions = reader.read_idl_file(idl_filename) interfaces = definitions.interfaces - implements = definitions.implements + includes = definitions.includes # There should only be a single interface defined in an IDL file. Return it. assert len(interfaces) == 1 - return (interfaces.values()[0], implements) + return (interfaces.values()[0], includes) def interface_is_global(interface): @@ -90,40 +90,32 @@ """ features_for_type = defaultdict(set) types_for_feature = defaultdict(set) - includes = set() - - # Gather interfaces which are implemented by other interfaces. - implemented_interfaces = set() - for name, interface_info in info_provider.interfaces_info.iteritems(): - # Skip special entries such as 'dictionaries' or 'ancestors'. - if name.lower() == name: - continue - implemented_interfaces.update(interface_info.get('implements_interfaces')) + include_files = set() for idl_filename in idl_filenames: - interface, implements = read_idl_file(reader, idl_filename) + interface, includes = read_idl_file(reader, idl_filename) feature_names = get_origin_trial_feature_names_from_interface(interface) - # If this interface is implemented by other interfaces, we don't generate - # V8 bindings code for it. - if interface.name in implemented_interfaces: + # If this interface is a mixin, we don't generate V8 bindings code for + # it. + if interface.is_mixin: continue - # If this interface implements another one, + # If this interface include another one, # it inherits any conditional features from it. - for implement in implements: - assert implement.left_interface == interface.name - implemented_interface, _ = read_idl_file( + for include in includes: + assert include.interface == interface.name + mixin, _ = read_idl_file( reader, - info_provider.interfaces_info[implement.right_interface].get('full_path')) - feature_names |= get_origin_trial_feature_names_from_interface(implemented_interface) + info_provider.interfaces_info[include.mixin].get('full_path')) + feature_names |= get_origin_trial_feature_names_from_interface(mixin) feature_names = list(feature_names) if feature_names: is_global = interface_is_global(interface) if interface.is_partial: # For partial interfaces, we need to generate different - # includes if the parent interface is in a different + # |include_files| if the parent interface is in a different # component. parent_interface_info = info_provider.interfaces_info[interface.name] parent_interface, _ = read_idl_file( @@ -132,13 +124,13 @@ parent_component = idl_filename_to_component( parent_interface_info.get('full_path')) if interface.is_partial and target_component != parent_component: - includes.add('bindings/%s/v8/%s' % - (parent_component, binding_header_filename(interface.name))) - includes.add('bindings/%s/v8/%s' % - (target_component, binding_header_filename(interface.name + 'Partial'))) + include_files.add('bindings/%s/v8/%s' % + (parent_component, binding_header_filename(interface.name))) + include_files.add('bindings/%s/v8/%s' % + (target_component, binding_header_filename(interface.name + 'Partial'))) else: - includes.add('bindings/%s/v8/%s' % - (target_component, binding_header_filename(interface.name))) + include_files.add('bindings/%s/v8/%s' % + (target_component, binding_header_filename(interface.name))) # If this is a partial interface in the same component as # its parent, then treat it as a non-partial interface. interface.is_partial = False @@ -151,17 +143,17 @@ features_for_type[interface_info].add(feature_name) types_for_feature[feature_name].add(interface_info) - return features_for_type, types_for_feature, includes + return features_for_type, types_for_feature, include_files def origin_trial_features_context(generator_name, feature_info): context = {'code_generator': generator_name} # Unpack the feature info tuple. - features_for_type, types_for_feature, includes = feature_info + features_for_type, types_for_feature, include_files = feature_info # Add includes needed for cpp code and normalize. - includes.update([ + include_files.update([ 'core/context_features/context_feature_settings.h', 'core/execution_context/execution_context.h', 'core/frame/frame.h', @@ -174,7 +166,7 @@ # here because the ContextFeatureSettings code needs it. 'bindings/core/v8/v8_window.h', ]) - context['includes'] = normalize_and_sort_includes(includes) + context['includes'] = normalize_and_sort_includes(include_files) # For each interface, collect a list of bindings installation functions to # call, organized by conditional feature.
diff --git a/third_party/blink/renderer/bindings/scripts/idl_definitions.py b/third_party/blink/renderer/bindings/scripts/idl_definitions.py index c83c71f..58d091b 100644 --- a/third_party/blink/renderer/bindings/scripts/idl_definitions.py +++ b/third_party/blink/renderer/bindings/scripts/idl_definitions.py
@@ -98,7 +98,7 @@ self.callback_functions = {} self.dictionaries = {} self.enumerations = {} - self.implements = [] + self.includes = [] self.interfaces = {} self.first_name = None self.typedefs = {} @@ -124,8 +124,8 @@ elif child_class == 'Callback': callback_function = IdlCallbackFunction(child) self.callback_functions[callback_function.name] = callback_function - elif child_class == 'Implements' or child_class == 'Includes': - self.implements.append(IdlImplement(child)) + elif child_class == 'Includes': + self.includes.append(IdlIncludes(child)) elif child_class == 'Dictionary': dictionary = IdlDictionary(child) self.dictionaries[dictionary.name] = dictionary @@ -144,8 +144,8 @@ dictionary.accept(visitor) for enumeration in self.enumerations.itervalues(): enumeration.accept(visitor) - for implement in self.implements: - implement.accept(visitor) + for include in self.includes: + include.accept(visitor) for typedef in self.typedefs.itervalues(): typedef.accept(visitor) @@ -752,20 +752,16 @@ ################################################################################ -# Implement statements / includes statements +# Includes statements ################################################################################ -class IdlImplement(object): - """ - IdlImplement class represents an implements statement or an includes - statement. - """ +class IdlIncludes(object): def __init__(self, node): - self.left_interface = node.GetName() - self.right_interface = node.GetProperty('REFERENCE') + self.interface = node.GetName() + self.mixin = node.GetProperty('REFERENCE') def accept(self, visitor): - visitor.visit_implement(self) + visitor.visit_include(self) ################################################################################ @@ -1023,7 +1019,7 @@ def visit_enumeration(self, enumeration): pass - def visit_implement(self, implement): + def visit_include(self, include): pass def visit_interface(self, interface):
diff --git a/third_party/blink/renderer/bindings/scripts/interface_dependency_resolver.py b/third_party/blink/renderer/bindings/scripts/interface_dependency_resolver.py index 318f9e6b..7e81deb 100644 --- a/third_party/blink/renderer/bindings/scripts/interface_dependency_resolver.py +++ b/third_party/blink/renderer/bindings/scripts/interface_dependency_resolver.py
@@ -29,7 +29,7 @@ """Resolve interface dependencies, producing a merged IdlDefinitions object. This library computes interface dependencies (partial interfaces and -implements), reads the dependency files, and merges them to the IdlDefinitions +includes), reads the dependency files, and merges them to the IdlDefinitions for the main IDL file, producing an IdlDefinitions object representing the entire interface. @@ -68,13 +68,13 @@ """Resolve dependencies, merging them into IDL definitions of main file. Dependencies consist of 'partial interface' for the same interface as - in the main file, and other interfaces that this interface 'implements'. + in the main file, and mixins that this interface 'includes'. These are merged into the main IdlInterface, as the main IdlInterface implements all these members. - Referenced interfaces are added to IdlDefinitions, but not merged into - the main IdlInterface, as these are only referenced (their members are - introspected, but not implemented in this interface). + Partial interfaces and mixins are added to IdlDefinitions, but not + merged into the main IdlInterface, as these are only referenced (their + members are introspected, but not implemented in this interface). Inherited extended attributes are also added to the main IdlInterface. @@ -96,8 +96,8 @@ or a given IdlDefinitions object has incorrect referenced interfaces. """ - # FIXME: we need to resolve dependency when we implement partial - # dictionary. + # TODO(crbug.com/579896): we need to resolve dependency when we + # support partial dictionary. if not definitions.interfaces: raise Exception('No need to resolve any dependencies of ' 'this definition: %s, because this should ' @@ -222,7 +222,7 @@ # - An interface defined in core cannot include an interface mixin # defined in modules. if not dependency_interface.is_mixin: - raise Exception('The interface:%s cannot implement ' + raise Exception('The interface:%s cannot include ' 'the non-mixin interface: %s.' % ( target_interface.name, dependency_interface.name)) @@ -236,9 +236,9 @@ dependency_component)) resolved_definitions[component].update(dependency_definitions) # merges partial interfaces - # Implemented interfaces (non-partial dependencies) are also merged - # into the target interface, so Code Generator can just iterate - # over one list (and not need to handle 'implements' itself). + # Mixins are also merged into the target interface, so Code + # Generator can just iterate over one list (and not need to handle + # 'includes' itself). target_interface.merge(dependency_interface) return resolved_definitions @@ -282,9 +282,7 @@ # which class implemented interfaces are implemented. # # Currently [LegacyTreatAsPartialInterface] can be used to have partial - # interface behavior on implemented interfaces, but this is being removed - # as legacy cruft: - # FIXME: Remove [LegacyTreatAsPartialInterface] + # interface behavior on mixins, but this is being removed as legacy cruft: # http://crbug.com/360435 # # Note that [ImplementedAs] is used with different meanings on interfaces
diff --git a/third_party/blink/renderer/core/animation/element_animation.idl b/third_party/blink/renderer/core/animation/element_animation.idl index 3e56e3d..1c596d3 100644 --- a/third_party/blink/renderer/core/animation/element_animation.idl +++ b/third_party/blink/renderer/core/animation/element_animation.idl
@@ -32,7 +32,7 @@ // https://drafts.csswg.org/web-animations/#extensions-to-the-element-interface // TODO(dstockwell): This should be an Animatable interface, where Element -// implements Animatable. +// includes Animatable. [ ImplementedAs=ElementAnimation
diff --git a/third_party/blink/renderer/core/dom/accessibility_role.idl b/third_party/blink/renderer/core/dom/accessibility_role.idl index 22454d63..3685a82 100644 --- a/third_party/blink/renderer/core/dom/accessibility_role.idl +++ b/third_party/blink/renderer/core/dom/accessibility_role.idl
@@ -10,4 +10,4 @@ [CEReactions, Reflect] attribute DOMString? role; }; -Element implements AccessibilityRole; +Element includes AccessibilityRole;
diff --git a/third_party/blink/renderer/core/dom/aria_attributes.idl b/third_party/blink/renderer/core/dom/aria_attributes.idl index e4271c3..d0ad259 100644 --- a/third_party/blink/renderer/core/dom/aria_attributes.idl +++ b/third_party/blink/renderer/core/dom/aria_attributes.idl
@@ -53,4 +53,4 @@ [CEReactions, Reflect=aria_valuetext] attribute DOMString? ariaValueText; }; -Element implements AriaAttributes; +Element includes AriaAttributes;
diff --git a/third_party/blink/renderer/core/dom/character_data.idl b/third_party/blink/renderer/core/dom/character_data.idl index 30b22212..40df5dd 100644 --- a/third_party/blink/renderer/core/dom/character_data.idl +++ b/third_party/blink/renderer/core/dom/character_data.idl
@@ -29,5 +29,5 @@ [RaisesException] void replaceData(unsigned long offset, unsigned long count, DOMString data); }; -CharacterData implements ChildNode; -CharacterData implements NonDocumentTypeChildNode; +CharacterData includes ChildNode; +CharacterData includes NonDocumentTypeChildNode;
diff --git a/third_party/blink/renderer/core/dom/document.idl b/third_party/blink/renderer/core/dom/document.idl index c28eba7..53d4e05 100644 --- a/third_party/blink/renderer/core/dom/document.idl +++ b/third_party/blink/renderer/core/dom/document.idl
@@ -208,9 +208,9 @@ attribute EventHandler onvisibilitychange; }; -Document implements GlobalEventHandlers; -Document implements DocumentAndElementEventHandlers; -Document implements ParentNode; -Document implements NonElementParentNode; -Document implements DocumentOrShadowRoot; -Document implements FontFaceSource; +Document includes GlobalEventHandlers; +Document includes DocumentAndElementEventHandlers; +Document includes ParentNode; +Document includes NonElementParentNode; +Document includes DocumentOrShadowRoot; +Document includes FontFaceSource;
diff --git a/third_party/blink/renderer/core/dom/document_fragment.idl b/third_party/blink/renderer/core/dom/document_fragment.idl index ab728d2..892a8fbc 100644 --- a/third_party/blink/renderer/core/dom/document_fragment.idl +++ b/third_party/blink/renderer/core/dom/document_fragment.idl
@@ -25,5 +25,5 @@ ] interface DocumentFragment : Node { }; -DocumentFragment implements ParentNode; -DocumentFragment implements NonElementParentNode; +DocumentFragment includes ParentNode; +DocumentFragment includes NonElementParentNode;
diff --git a/third_party/blink/renderer/core/dom/document_type.idl b/third_party/blink/renderer/core/dom/document_type.idl index 1b7f4112..836148a 100644 --- a/third_party/blink/renderer/core/dom/document_type.idl +++ b/third_party/blink/renderer/core/dom/document_type.idl
@@ -25,4 +25,4 @@ readonly attribute DOMString systemId; }; -DocumentType implements ChildNode; +DocumentType includes ChildNode;
diff --git a/third_party/blink/renderer/core/dom/element.idl b/third_party/blink/renderer/core/dom/element.idl index df946e6a..39aeb5b 100644 --- a/third_party/blink/renderer/core/dom/element.idl +++ b/third_party/blink/renderer/core/dom/element.idl
@@ -144,6 +144,6 @@ [RuntimeEnabled=DisplayLocking, ImplementedAs=getDisplayLockForBindings] readonly attribute DisplayLockContext displayLock; }; -Element implements ParentNode; -Element implements ChildNode; -Element implements NonDocumentTypeChildNode; +Element includes ParentNode; +Element includes ChildNode; +Element includes NonDocumentTypeChildNode;
diff --git a/third_party/blink/renderer/core/dom/processing_instruction.idl b/third_party/blink/renderer/core/dom/processing_instruction.idl index e4662081..a58cfbf 100644 --- a/third_party/blink/renderer/core/dom/processing_instruction.idl +++ b/third_party/blink/renderer/core/dom/processing_instruction.idl
@@ -23,7 +23,7 @@ interface ProcessingInstruction : CharacterData { readonly attribute DOMString target; - // ProcessingInstruction implements LinkStyle + // ProcessingInstruction includes LinkStyle // https://drafts.csswg.org/cssom/#requirements-on-user-agents-implementing-the-xml-stylesheet-processing-instruction readonly attribute StyleSheet? sheet; };
diff --git a/third_party/blink/renderer/core/dom/shadow_root.idl b/third_party/blink/renderer/core/dom/shadow_root.idl index 1fb0c53..851c72e 100644 --- a/third_party/blink/renderer/core/dom/shadow_root.idl +++ b/third_party/blink/renderer/core/dom/shadow_root.idl
@@ -33,4 +33,4 @@ readonly attribute boolean delegatesFocus; }; -ShadowRoot implements DocumentOrShadowRoot; +ShadowRoot includes DocumentOrShadowRoot;
diff --git a/third_party/blink/renderer/core/fetch/request.idl b/third_party/blink/renderer/core/fetch/request.idl index 0e5f9c14..7459022 100644 --- a/third_party/blink/renderer/core/fetch/request.idl +++ b/third_party/blink/renderer/core/fetch/request.idl
@@ -54,4 +54,4 @@ [RaisesException, CallWith=ScriptState, DoNotTestNewObject, NewObject] Request clone(); }; -Request implements Body; +Request includes Body;
diff --git a/third_party/blink/renderer/core/fetch/response.idl b/third_party/blink/renderer/core/fetch/response.idl index 0b5cdb7..dac40e5 100644 --- a/third_party/blink/renderer/core/fetch/response.idl +++ b/third_party/blink/renderer/core/fetch/response.idl
@@ -30,4 +30,4 @@ [MeasureAs=FetchBodyStream] readonly attribute ReadableStream? body; }; -Response implements Body; +Response includes Body;
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc index 5fc087b..b661fab5 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -1477,35 +1477,6 @@ WebWindowFeatures window_features = GetWindowFeaturesFromString(features); - FrameLoadRequest frame_request(active_document, - ResourceRequest(completed_url), - target.IsEmpty() ? "_blank" : target); - frame_request.SetNavigationPolicy( - NavigationPolicyForCreateWindow(window_features)); - frame_request.SetFeaturesForWindowOpen(window_features); - frame_request.SetShouldSetOpener(window_features.noopener ? kNeverSetOpener - : kMaybeSetOpener); - - // Normally, FrameLoader would take care of setting the referrer for a - // navigation that is triggered from javascript. However, creating a window - // goes through sufficient processing that it eventually enters FrameLoader as - // an embedder-initiated navigation. FrameLoader assumes no responsibility - // for generating an embedder-initiated navigation's referrer, so we need to - // ensure the proper referrer is set now. - // TODO(domfarolino): Stop setting ResourceRequest's HTTP Referrer and store - // this is a separate member. See https://crbug.com/850813. - frame_request.GetResourceRequest().SetHttpReferrer( - SecurityPolicy::GenerateReferrer(active_document->GetReferrerPolicy(), - completed_url, - active_document->OutgoingReferrer())); - - frame_request.GetResourceRequest().SetHasUserGesture( - LocalFrame::HasTransientUserActivation(GetFrame())); - GetFrame()->MaybeLogAdClickNavigation(); - - if (const WebInputEvent* input_event = CurrentInputEvent::Get()) - frame_request.SetInputStartTime(input_event->TimeStamp()); - // Get the target frame for the special cases of _top and _parent. // In those cases, we schedule a location change right now and return early. Frame* target_frame = nullptr; @@ -1533,23 +1504,25 @@ } } - bool created = false; - if (!target_frame) - target_frame = CreateNewWindow(*GetFrame(), frame_request, created); - if (!target_frame) - return nullptr; + if (!target_frame) { + return CreateWindow(completed_url, target, window_features, + *incumbent_window, *GetFrame()); + } if (!active_document->GetFrame() || !active_document->GetFrame()->CanNavigate(*target_frame)) { return nullptr; } - if ((!completed_url.IsEmpty() || created) && + if (!url_string.IsEmpty() && !target_frame->DomWindow()->IsInsecureScriptAccess(*incumbent_window, completed_url)) { - frame_request.SetFrameName("_self"); - frame_request.SetNavigationPolicy(kNavigationPolicyCurrentTab); - target_frame->Navigate(frame_request, WebFrameLoadType::kStandard); + FrameLoadRequest request(active_document, ResourceRequest(completed_url)); + request.GetResourceRequest().SetHasUserGesture( + LocalFrame::HasTransientUserActivation(GetFrame())); + if (const WebInputEvent* input_event = CurrentInputEvent::Get()) + request.SetInputStartTime(input_event->TimeStamp()); + target_frame->Navigate(request, WebFrameLoadType::kStandard); } // TODO(japhet): window-open-noopener.html?_top and several tests in @@ -1565,8 +1538,7 @@ if (window_features.noopener) return nullptr; - if (!created) - target_frame->Client()->SetOpener(GetFrame()); + target_frame->Client()->SetOpener(GetFrame()); return target_frame->DomWindow(); }
diff --git a/third_party/blink/renderer/core/frame/navigator.idl b/third_party/blink/renderer/core/frame/navigator.idl index 9b1c330..a309bef4 100644 --- a/third_party/blink/renderer/core/frame/navigator.idl +++ b/third_party/blink/renderer/core/frame/navigator.idl
@@ -32,11 +32,11 @@ [HighEntropy, MeasureAs=NavigatorVendor] readonly attribute DOMString vendor; }; -Navigator implements NavigatorConcurrentHardware; -Navigator implements NavigatorCookies; -Navigator implements NavigatorDeviceMemory; -Navigator implements NavigatorID; -Navigator implements NavigatorLanguage; -Navigator implements NavigatorOnLine; -Navigator implements NavigatorAutomationInformation; -Navigator implements NavigatorUserAgent; +Navigator includes NavigatorConcurrentHardware; +Navigator includes NavigatorCookies; +Navigator includes NavigatorDeviceMemory; +Navigator includes NavigatorID; +Navigator includes NavigatorLanguage; +Navigator includes NavigatorOnLine; +Navigator includes NavigatorAutomationInformation; +Navigator includes NavigatorUserAgent;
diff --git a/third_party/blink/renderer/core/frame/window.idl b/third_party/blink/renderer/core/frame/window.idl index e681b67b..9f3ed35 100644 --- a/third_party/blink/renderer/core/frame/window.idl +++ b/third_party/blink/renderer/core/frame/window.idl
@@ -218,6 +218,6 @@ [OriginTrialEnabled=TrustedDOMTypes, Unforgeable] readonly attribute TrustedTypePolicyFactory TrustedTypes; }; -Window implements GlobalEventHandlers; -Window implements WindowEventHandlers; -Window implements WindowOrWorkerGlobalScope; +Window includes GlobalEventHandlers; +Window includes WindowEventHandlers; +Window includes WindowOrWorkerGlobalScope;
diff --git a/third_party/blink/renderer/core/html/html_anchor_element.idl b/third_party/blink/renderer/core/html/html_anchor_element.idl index 2cd0d37..96902d9 100644 --- a/third_party/blink/renderer/core/html/html_anchor_element.idl +++ b/third_party/blink/renderer/core/html/html_anchor_element.idl
@@ -42,4 +42,4 @@ [CEReactions, Reflect] attribute DOMString shape; }; -HTMLAnchorElement implements HTMLHyperlinkElementUtils; +HTMLAnchorElement includes HTMLHyperlinkElementUtils;
diff --git a/third_party/blink/renderer/core/html/html_area_element.idl b/third_party/blink/renderer/core/html/html_area_element.idl index 468cda2..a6d1728c 100644 --- a/third_party/blink/renderer/core/html/html_area_element.idl +++ b/third_party/blink/renderer/core/html/html_area_element.idl
@@ -36,4 +36,4 @@ [CEReactions, Reflect] attribute boolean noHref; }; -HTMLAreaElement implements HTMLHyperlinkElementUtils; +HTMLAreaElement includes HTMLHyperlinkElementUtils;
diff --git a/third_party/blink/renderer/core/html/html_attribute_names.json5 b/third_party/blink/renderer/core/html/html_attribute_names.json5 index 5d34a3e..3ff9569 100644 --- a/third_party/blink/renderer/core/html/html_attribute_names.json5 +++ b/third_party/blink/renderer/core/html/html_attribute_names.json5
@@ -118,7 +118,7 @@ "leftmargin", "link", "list", - "load", + "loading", "longdesc", "loop", "low",
diff --git a/third_party/blink/renderer/core/html/html_body_element.idl b/third_party/blink/renderer/core/html/html_body_element.idl index da075c8..c616fb17 100644 --- a/third_party/blink/renderer/core/html/html_body_element.idl +++ b/third_party/blink/renderer/core/html/html_body_element.idl
@@ -31,7 +31,7 @@ [CEReactions, Reflect] attribute DOMString background; // TODO(foolip): These event handler attributes should be inherited from - // HTMLElement (which implements GlobalEventHandlers), but have different + // HTMLElement (which includes GlobalEventHandlers), but have different // behavior. See https://www.w3.org/Bugs/Public/show_bug.cgi?id=28166 attribute EventHandler onblur; attribute EventHandler onerror; @@ -45,4 +45,4 @@ [RuntimeEnabled=OrientationEvent] attribute EventHandler onorientationchange; }; -HTMLBodyElement implements WindowEventHandlers; +HTMLBodyElement includes WindowEventHandlers;
diff --git a/third_party/blink/renderer/core/html/html_element.idl b/third_party/blink/renderer/core/html/html_element.idl index cb792372..181d3f3 100644 --- a/third_party/blink/renderer/core/html/html_element.idl +++ b/third_party/blink/renderer/core/html/html_element.idl
@@ -40,7 +40,7 @@ [CEReactions] attribute boolean spellcheck; [Measure] attribute DOMString autocapitalize; - // HTMLElement implements ElementContentEditable + // HTMLElement includes ElementContentEditable // https://html.spec.whatwg.org/C/#contenteditable [CEReactions, CustomElementCallbacks, RaisesException=Setter] attribute DOMString contentEditable; [ImplementedAs=isContentEditableForBinding] readonly attribute boolean isContentEditable; @@ -67,6 +67,6 @@ [Affects=Nothing, CEReactions, CustomElementCallbacks, RaisesException=Setter, MeasureAs=HTMLElementOuterText] attribute [TreatNullAs=EmptyString] DOMString outerText; }; -HTMLElement implements GlobalEventHandlers; -HTMLElement implements DocumentAndElementEventHandlers; -HTMLElement implements NoncedElement; +HTMLElement includes GlobalEventHandlers; +HTMLElement includes DocumentAndElementEventHandlers; +HTMLElement includes NoncedElement;
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.cc b/third_party/blink/renderer/core/html/html_frame_owner_element.cc index 2e4b86d..4065bb9 100644 --- a/third_party/blink/renderer/core/html/html_frame_owner_element.cc +++ b/third_party/blink/renderer/core/html/html_frame_owner_element.cc
@@ -385,14 +385,14 @@ const KURL& url, const AtomicString& frame_name, bool replace_current_item) { - // Update the |should_lazy_load_children_| value according to the "lazyload" + // Update the |should_lazy_load_children_| value according to the "loading" // attribute immediately, so that it still gets respected even if the "src" - // attribute gets parsed in ParseAttribute() before the "lazyload" attribute + // attribute gets parsed in ParseAttribute() before the "loading" attribute // does. Note that when the *feature policy* for "lazyload" is disabled, the - // attribute value "off" for "lazyload" is ignored (i.e., interpreted as + // attribute value loading="eager" is ignored (i.e., interpreted as // "auto" instead). if (should_lazy_load_children_ && - EqualIgnoringASCIICase(FastGetAttribute(html_names::kLoadAttr), + EqualIgnoringASCIICase(FastGetAttribute(html_names::kLoadingAttr), "eager") && !GetDocument().IsLazyLoadPolicyEnforced()) { should_lazy_load_children_ = false; @@ -446,10 +446,11 @@ request.SetSkipServiceWorker(true); if (!lazy_load_frame_observer_ && - IsFrameLazyLoadable(GetDocument(), url, - EqualIgnoringASCIICase( - FastGetAttribute(html_names::kLoadAttr), "lazy"), - should_lazy_load_children_)) { + IsFrameLazyLoadable( + GetDocument(), url, + EqualIgnoringASCIICase(FastGetAttribute(html_names::kLoadingAttr), + "lazy"), + should_lazy_load_children_)) { // By default, avoid deferring subresources inside a lazily loaded frame. // This will make it possible for subresources in hidden frames to load that // will never be visible, as well as make it so that deferred frames that @@ -496,9 +497,9 @@ void HTMLFrameOwnerElement::ParseAttribute( const AttributeModificationParams& params) { - if (params.name == html_names::kLoadAttr) { + if (params.name == html_names::kLoadingAttr) { // Note that when the *feature policy* for "lazyload" is disabled, the - // attribute value "off" for "lazyload" is ignored (i.e., interpreted as + // attribute value loading="eager" is ignored (i.e., interpreted as // "auto" instead). if (EqualIgnoringASCIICase(params.new_value, "eager") && !GetDocument().IsLazyLoadPolicyEnforced()) {
diff --git a/third_party/blink/renderer/core/html/html_frame_set_element.idl b/third_party/blink/renderer/core/html/html_frame_set_element.idl index 54a4bcb0..6a6733ed 100644 --- a/third_party/blink/renderer/core/html/html_frame_set_element.idl +++ b/third_party/blink/renderer/core/html/html_frame_set_element.idl
@@ -29,7 +29,7 @@ [CEReactions, Reflect] attribute DOMString rows; // TODO(foolip): These event handler attributes should be inherited from - // HTMLElement (which implements GlobalEventHandlers), but have different + // HTMLElement (which includes GlobalEventHandlers), but have different // behavior. See https://www.w3.org/Bugs/Public/show_bug.cgi?id=28166 attribute EventHandler onblur; attribute EventHandler onerror; @@ -42,4 +42,4 @@ [RuntimeEnabled=OrientationEvent] attribute EventHandler onorientationchange; }; -HTMLFrameSetElement implements WindowEventHandlers; +HTMLFrameSetElement includes WindowEventHandlers;
diff --git a/third_party/blink/renderer/core/html/html_iframe_element.idl b/third_party/blink/renderer/core/html/html_iframe_element.idl index cbb6e27..9532b1d 100644 --- a/third_party/blink/renderer/core/html/html_iframe_element.idl +++ b/third_party/blink/renderer/core/html/html_iframe_element.idl
@@ -46,7 +46,7 @@ // https://w3c.github.io/webappsec-feature-policy/#the-policy-object [RuntimeEnabled=FeaturePolicyJavaScriptInterface] readonly attribute FeaturePolicy featurePolicy; - [RuntimeEnabled=LazyFrameLoading, CEReactions, Reflect, ReflectOnly=("lazy", "eager", "auto"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString load; + [RuntimeEnabled=LazyFrameLoading, CEReactions, Reflect, ReflectOnly=("lazy", "eager", "auto"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString loading; // obsolete members // https://html.spec.whatwg.org/C/#HTMLIFrameElement-partial
diff --git a/third_party/blink/renderer/core/html/html_image_element.cc b/third_party/blink/renderer/core/html/html_image_element.cc index eca9ea1f..b8af2cc 100644 --- a/third_party/blink/renderer/core/html/html_image_element.cc +++ b/third_party/blink/renderer/core/html/html_image_element.cc
@@ -314,7 +314,7 @@ if (intrinsic_size_changed && GetLayoutObject() && GetLayoutObject()->IsLayoutImage()) ToLayoutImage(GetLayoutObject())->IntrinsicSizeChanged(); - } else if (name == kLoadAttr && + } else if (name == kLoadingAttr && EqualIgnoringASCIICase(params.new_value, "eager") && !GetDocument().IsLazyLoadPolicyEnforced()) { GetImageLoader().LoadDeferredImage(referrer_policy_);
diff --git a/third_party/blink/renderer/core/html/html_image_element.idl b/third_party/blink/renderer/core/html/html_image_element.idl index 560705b..f7f066d 100644 --- a/third_party/blink/renderer/core/html/html_image_element.idl +++ b/third_party/blink/renderer/core/html/html_image_element.idl
@@ -44,7 +44,7 @@ [CEReactions, MeasureAs=PriorityHints, OriginTrialEnabled=PriorityHints, Reflect, ReflectOnly=("low", "auto", "high"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString importance; // https://github.com/ojanvafai/intrinsicsize-attribute/blob/master/README.md [RuntimeEnabled=ExperimentalProductivityFeatures, CEReactions, Reflect] attribute DOMString intrinsicSize; - [RuntimeEnabled=LazyImageLoading, CEReactions, Reflect, ReflectOnly=("lazy", "eager", "auto"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString load; + [RuntimeEnabled=LazyImageLoading, CEReactions, Reflect, ReflectOnly=("lazy", "eager", "auto"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString loading; // obsolete members // https://html.spec.whatwg.org/C/#HTMLImageElement-partial
diff --git a/third_party/blink/renderer/core/html/html_link_element.idl b/third_party/blink/renderer/core/html/html_link_element.idl index 8f9737f..2390dbb 100644 --- a/third_party/blink/renderer/core/html/html_link_element.idl +++ b/third_party/blink/renderer/core/html/html_link_element.idl
@@ -45,7 +45,7 @@ [CEReactions, Reflect] attribute DOMString rev; [CEReactions, Reflect] attribute DOMString target; - // HTMLLinkElement implements LinkStyle + // HTMLLinkElement includes LinkStyle // https://drafts.csswg.org/cssom/#the-linkstyle-interface readonly attribute StyleSheet? sheet;
diff --git a/third_party/blink/renderer/core/html/html_style_element.idl b/third_party/blink/renderer/core/html/html_style_element.idl index 143638e..f2134900 100644 --- a/third_party/blink/renderer/core/html/html_style_element.idl +++ b/third_party/blink/renderer/core/html/html_style_element.idl
@@ -27,7 +27,7 @@ [CEReactions, Reflect] attribute DOMString media; [CEReactions, Reflect] attribute DOMString type; - // HTMLStyleElement implements LinkStyle + // HTMLStyleElement includes LinkStyle // https://drafts.csswg.org/cssom/#the-linkstyle-interface readonly attribute StyleSheet? sheet; };
diff --git a/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc b/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc index ebff844..bd2622e 100644 --- a/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc +++ b/third_party/blink/renderer/core/html/lazy_load_frame_observer_test.cc
@@ -750,7 +750,7 @@ <body onload='console.log("main body onload");'> <div style='height: %dpx;'></div> <iframe src='https://crossorigin.com/subframe.html' - style='width: 200px; height: 200px;' load='eager' + style='width: 200px; height: 200px;' loading='eager' onload='console.log("child frame element onload");'></iframe> </body>)HTML", kViewportHeight + GetLoadingDistanceThreshold() + 100)); @@ -798,7 +798,7 @@ <body onload='console.log("main body onload");'> <div style='height: %dpx;'></div> <iframe src='https://example.com/subframe.html' - style='width: 400px; height: 400px;' load='lazy' + style='width: 400px; height: 400px;' loading='lazy' onload='console.log("child frame element onload");'></iframe> </body>)HTML", kViewportHeight + GetLoadingDistanceThreshold() + 100)); @@ -916,7 +916,7 @@ Element* child_frame_element = GetDocument().getElementById("child_frame"); ASSERT_TRUE(child_frame_element); - child_frame_element->setAttribute(html_names::kLoadAttr, "eager"); + child_frame_element->setAttribute(html_names::kLoadingAttr, "eager"); ExpectInitialDeferralActionHistogramSamplesIfApplicable( LazyLoadFrameObserver::FrameInitialDeferralAction::kDeferred, 1); @@ -962,14 +962,14 @@ // There's another nested cross origin iframe inside the first child frame, // even further down such that it's not near the viewport. If LazyLoad is // enabled, it should be deferred even though it's nested inside a frame that - // was previously deferred, because it has the attribute load=lazy. + // was previously deferred, because it has the attribute loading=lazy. base::Optional<SimRequest> nested_frame_resource; if (!RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) nested_frame_resource.emplace("https://test.com/", "text/html"); child_frame_resource->Complete( String::Format("<div style='height: %dpx;'></div>" - "<iframe src='https://test.com/' load='lazy'" + "<iframe src='https://test.com/' loading='lazy'" " style='width: 200px; height: 200px;'>" "</iframe>", kViewportHeight + GetLoadingDistanceThreshold() + 100)); @@ -1001,7 +1001,7 @@ <body onload='console.log("main body onload");'> <div style='height: %dpx;'></div> <iframe src='https://crossorigin.com/subframe.html' - style='width: 200px; height: 200px;' load='eager' + style='width: 200px; height: 200px;' loading='eager' onload='console.log("child frame element onload");'></iframe> </body>)HTML", kViewportHeight + GetLoadingDistanceThreshold() + 100)); @@ -1011,15 +1011,16 @@ // There's another nested cross origin iframe inside the first child frame, // even further down such that it's not near the viewport. If LazyLoad is - // enabled, it should be deferred because it has the attribute load=lazy, - // even though it's nested inside a frame that has the attribute load=eager. + // enabled, it should be deferred because it has the attribute loading=lazy, + // even though it's nested inside a frame that has the attribute + // loading=eager. base::Optional<SimRequest> nested_frame_resource; if (!RuntimeEnabledFeatures::LazyFrameLoadingEnabled()) nested_frame_resource.emplace("https://test.com/", "text/html"); child_frame_resource.Complete( String::Format("<div style='height: %dpx;'></div>" - "<iframe src='https://test.com/' load='lazy'" + "<iframe src='https://test.com/' loading='lazy'" " style='width: 200px; height: 200px;'>" "</iframe>", kViewportHeight + GetLoadingDistanceThreshold() + 100)); @@ -1051,7 +1052,7 @@ <body onload='console.log("main body onload");'> <div style='height: %dpx;'></div> <iframe src='https://crossorigin.com/subframe.html' - style='width: 200px; height: 200px;' load='eager' + style='width: 200px; height: 200px;' loading='eager' onload='console.log("child frame element onload");'></iframe> </body>)HTML", kViewportHeight + GetLoadingDistanceThreshold() + 100)); @@ -1061,14 +1062,14 @@ // There's another nested cross origin iframe inside the first child frame, // even further down such that it's not near the viewport. Since it has the - // attribute load=eager, it shouldn't be deferred. Note that this also + // attribute loading=eager, it shouldn't be deferred. Note that this also // matches the default behavior that would happen if the load attribute was // omitted on the nested iframe entirely. SimRequest nested_frame_resource("https://test.com/", "text/html"); child_frame_resource.Complete( String::Format("<div style='height: %dpx;'></div>" - "<iframe src='https://test.com/' load='eager'" + "<iframe src='https://test.com/' loading='eager'" " style='width: 200px; height: 200px;'>" "</iframe>", kViewportHeight + GetLoadingDistanceThreshold() + 100)); @@ -1211,7 +1212,7 @@ ScopedRestrictLazyFrameLoadingToDataSaverForTest scoped_restrict_lazy_frame_loading_to_data_saver_for_test_(false); - TestCrossOriginFrameIsImmediatelyLoaded("load='eager'"); + TestCrossOriginFrameIsImmediatelyLoaded("loading='eager'"); } TEST_F(LazyLoadFramesTest, LazyLoadWhenDataSaverDisabledAndRestricted) { @@ -1231,7 +1232,7 @@ GetNetworkStateNotifier().SetSaveDataEnabled(true); WebView().GetPage()->GetSettings().SetDataSaverHoldbackWebApi(true); - TestCrossOriginFrameIsLazilyLoaded("load='lazy'"); + TestCrossOriginFrameIsLazilyLoaded("loading='lazy'"); TestCrossOriginFrameIsImmediatelyLoaded(""); } @@ -1254,7 +1255,7 @@ WebView().GetPage()->GetSettings().SetDataSaverHoldbackWebApi(false); // Even when restricted to data saver, the attribute should be respected. - TestCrossOriginFrameIsLazilyLoaded("load='lazy'"); + TestCrossOriginFrameIsLazilyLoaded("loading='lazy'"); TestCrossOriginFrameIsImmediatelyLoaded(""); }
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc index c9b55ed..b814db9 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
@@ -150,7 +150,7 @@ referrer_policy_(network::mojom::ReferrerPolicy::kDefault), integrity_attr_set_(false), integrity_features_(features), - load_attr_value_(LoadAttrValue::kAuto), + loading_attr_value_(LoadingAttrValue::kAuto), width_attr_small_absolute_(false), height_attr_small_absolute_(false), inline_style_dimensions_small_(false), @@ -288,10 +288,10 @@ request->SetCharset(Charset()); request->SetDefer(defer_); - // If the 'lazyload' feature policy is enforced, the attribute value "lazy" - // for the 'load' attribute is considered as 'auto'. - if (load_attr_value_ != LoadAttrValue::kLazy && - ((load_attr_value_ == LoadAttrValue::kEager && + // If the 'lazyload' feature policy is enforced, the attribute value + // loading='lazy' is considered as 'auto'. + if (loading_attr_value_ != LoadingAttrValue::kLazy && + ((loading_attr_value_ == LoadingAttrValue::kEager && !document_parameters.lazyload_policy_enforced) || (width_attr_small_absolute_ && height_attr_small_absolute_) || inline_style_dimensions_small_)) { @@ -310,7 +310,7 @@ } private: - enum class LoadAttrValue { kAuto, kLazy, kEager }; + enum class LoadingAttrValue { kAuto, kLazy, kEager }; template <typename NameType> void ProcessScriptAttribute(const NameType& attribute_name, @@ -368,14 +368,15 @@ Match(attribute_name, kImportanceAttr) && priority_hints_origin_trial_enabled_) { SetImportance(attribute_value); - } else if (load_attr_value_ == LoadAttrValue::kAuto && - Match(attribute_name, kLoadAttr) && + } else if (loading_attr_value_ == LoadingAttrValue::kAuto && + Match(attribute_name, kLoadingAttr) && RuntimeEnabledFeatures::LazyImageLoadingEnabled()) { - load_attr_value_ = EqualIgnoringASCIICase(attribute_value, "eager") - ? LoadAttrValue::kEager - : EqualIgnoringASCIICase(attribute_value, "lazy") - ? LoadAttrValue::kLazy - : LoadAttrValue::kAuto; + loading_attr_value_ = + EqualIgnoringASCIICase(attribute_value, "eager") + ? LoadingAttrValue::kEager + : EqualIgnoringASCIICase(attribute_value, "lazy") + ? LoadingAttrValue::kLazy + : LoadingAttrValue::kAuto; } else if (!width_attr_small_absolute_ && Match(attribute_name, kWidthAttr) && RuntimeEnabledFeatures::LazyImageLoadingEnabled()) { @@ -697,7 +698,7 @@ bool integrity_attr_set_; IntegrityMetadataSet integrity_metadata_; SubresourceIntegrity::IntegrityFeatures integrity_features_; - LoadAttrValue load_attr_value_; + LoadingAttrValue loading_attr_value_; bool width_attr_small_absolute_; bool height_attr_small_absolute_; bool inline_style_dimensions_small_;
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc index 6131a3f..f6473aa 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
@@ -1231,12 +1231,12 @@ TEST_F(HTMLPreloadScannerTest, LazyImageLoadAttributePassed) { ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); LazyImageLoadTestCase test_cases[] = { - {"<img src='foo.jpg' load='auto'>", false}, - {"<img src='foo.jpg' load='lazy'>", false}, - {"<img src='foo.jpg' load='eager'>", true}, - // load=lazy should override other conditions. - {"<img src='foo.jpg' style='height: 1px;' load='lazy'>", false}, - {"<img src='foo.jpg' style='height: 1px; width: 1px' load='lazy'>", + {"<img src='foo.jpg' loading='auto'>", false}, + {"<img src='foo.jpg' loading='lazy'>", false}, + {"<img src='foo.jpg' loading='eager'>", true}, + // loading=lazy should override other conditions. + {"<img src='foo.jpg' style='height: 1px;' loading='lazy'>", false}, + {"<img src='foo.jpg' style='height: 1px; width: 1px' loading='lazy'>", false}, }; for (const auto& test_case : test_cases)
diff --git a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc index 5a80930..8cdfb10 100644 --- a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc +++ b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc
@@ -294,8 +294,7 @@ *GetLayoutGrid(), child, child_block_direction)) { SetOverrideContainingBlockContentSizeForChild(child, child_block_direction, LayoutUnit(-1)); - child.SetNeedsLayout(layout_invalidation_reason::kGridChanged, - kMarkOnlyThis); + child.SetSelfNeedsLayoutForAvailableSpace(true); } child.LayoutIfNeeded(); @@ -325,8 +324,7 @@ if (UpdateOverrideContainingBlockContentSizeForChild( child, child_inline_direction)) { - child.SetNeedsLayout(layout_invalidation_reason::kGridChanged, - kMarkOnlyThis); + child.SetSelfNeedsLayoutForAvailableSpace(true); } return LogicalHeightForChild(child); } @@ -350,8 +348,7 @@ if (UpdateOverrideContainingBlockContentSizeForChild( child, child_inline_direction)) { - child.SetNeedsLayout(layout_invalidation_reason::kGridChanged, - kMarkOnlyThis); + child.SetSelfNeedsLayoutForAvailableSpace(true); } return LogicalHeightForChild(child); } @@ -540,8 +537,7 @@ LayoutBox& child, bool override_size_has_changed) const { if (override_size_has_changed) { - child.SetNeedsLayout(layout_invalidation_reason::kGridChanged, - kMarkOnlyThis); + child.SetSelfNeedsLayoutForAvailableSpace(true); child.LayoutIfNeeded(); } } @@ -583,8 +579,7 @@ LayoutBox& child, bool override_size_has_changed) const { if (override_size_has_changed && Direction() != kForColumns) { - child.SetNeedsLayout(layout_invalidation_reason::kGridChanged, - kMarkOnlyThis); + child.SetSelfNeedsLayoutForAvailableSpace(true); child.LayoutIfNeeded(); } }
diff --git a/third_party/blink/renderer/core/layout/layout_grid.cc b/third_party/blink/renderer/core/layout/layout_grid.cc index 3b11250..21ba0e0 100644 --- a/third_party/blink/renderer/core/layout/layout_grid.cc +++ b/third_party/blink/renderer/core/layout/layout_grid.cc
@@ -156,7 +156,7 @@ *child) || SelfAlignmentChangedSize(kGridColumnAxis, *old_style, new_style, *child)) { - child->SetNeedsLayout(layout_invalidation_reason::kGridChanged); + child->SetSelfNeedsLayoutForAvailableSpace(true); } } } @@ -1220,8 +1220,7 @@ OverrideSizeChanged(child, kForRows, grid_area_logical_size); if (grid_area_width_changed || (grid_area_height_changed && HasRelativeBlockAxisSize(*this, child))) { - child.SetNeedsLayout(layout_invalidation_reason::kGridChanged, - kMarkOnlyThis); + child.SetSelfNeedsLayoutForAvailableSpace(true); } child.SetOverrideContainingBlockContentLogicalWidth( @@ -1507,7 +1506,7 @@ // TODO (lajava): Can avoid laying out here in some cases. See // https://webkit.org/b/87905. child.SetLogicalHeight(LayoutUnit()); - child.SetNeedsLayout(layout_invalidation_reason::kGridChanged); + child.SetSelfNeedsLayoutForAvailableSpace(true); } } }
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index b8659aed..4a61837 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -120,6 +120,20 @@ namespace { +// In order for an image to be rendered from the content property, there can be +// at most one piece of image content data, followed by some optional +// alternative text. +bool ShouldUseContentData(const ContentData* content_data) { + if (!content_data) + return false; + if (!content_data->IsImage()) + return false; + if (content_data->Next() && !content_data->Next()->IsAltText()) + return false; + + return true; +} + template <typename Predicate> LayoutObject* FindAncestorByPredicate(const LayoutObject* descendant, LayoutObject::AncestorSkipInfo* skip_info, @@ -213,16 +227,16 @@ DCHECK(IsAllowedToModifyLayoutTreeStructure(element->GetDocument())); // Minimal support for content properties replacing an entire element. - // Works only if we have exactly one piece of content and it's a URL. - // Otherwise acts as if we didn't support this feature. + // Works only if we have exactly one piece of content and it's a URL, with + // some optional alternative text. Otherwise acts as if we didn't support this + // feature. const ContentData* content_data = style.GetContentData(); - if (content_data && !content_data->Next() && content_data->IsImage() && - !element->IsPseudoElement()) { + if (!element->IsPseudoElement() && ShouldUseContentData(content_data)) { LayoutImage* image = new LayoutImage(element); - // LayoutImageResourceStyleImage requires a style being present on the image - // but we don't want to trigger a style change now as the node is not fully - // attached. Moving this code to style change doesn't make sense as it - // should be run once at layoutObject creation. + // LayoutImageResourceStyleImage requires a style being present on the + // image but we don't want to trigger a style change now as the node is + // not fully attached. Moving this code to style change doesn't make sense + // as it should be run once at layoutObject creation. image->SetStyleInternal(const_cast<ComputedStyle*>(&style)); if (const StyleImage* style_image = To<ImageContentData>(content_data)->GetImage()) {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc index f74eb42..ee045cad 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -233,6 +233,11 @@ scoped_refptr<const NGLayoutResult> layout_result = box_->CachedLayoutResult(constraint_space, break_token); if (layout_result) { + // We may have to update the margins on box_; we reuse the layout result + // even if a percentage margin may have changed. + if (UNLIKELY(Style().MayHaveMargin() && !IsTableCell())) + box_->SetMargin(ComputePhysicalMargins(constraint_space, Style())); + // TODO(layoutng): Figure out why these two call can't be inside the // !constraint_space.IsIntermediateLayout() block below. UpdateShapeOutsideInfoIfNeeded(
diff --git a/third_party/blink/renderer/core/loader/frame_load_request.h b/third_party/blink/renderer/core/loader/frame_load_request.h index b8e69efa..fdb5216 100644 --- a/third_party/blink/renderer/core/loader/frame_load_request.h +++ b/third_party/blink/renderer/core/loader/frame_load_request.h
@@ -29,7 +29,6 @@ #include "services/network/public/mojom/request_context_frame_type.mojom-shared.h" #include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h" #include "third_party/blink/public/web/web_triggering_event_info.h" -#include "third_party/blink/public/web/web_window_features.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/frame_types.h" #include "third_party/blink/renderer/core/loader/frame_loader_types.h" @@ -147,15 +146,6 @@ base::TimeTicks GetInputStartTime() const { return input_start_time_; } - const WebWindowFeatures& GetWindowFeatures() const { - return window_features_; - } - void SetFeaturesForWindowOpen(const WebWindowFeatures& features) { - window_features_ = features; - is_window_open_ = true; - } - bool IsWindowOpen() const { return is_window_open_; } - private: Member<Document> origin_document_; ResourceRequest resource_request_; @@ -175,8 +165,6 @@ base::TimeTicks input_start_time_; network::mojom::RequestContextFrameType frame_type_ = network::mojom::RequestContextFrameType::kNone; - WebWindowFeatures window_features_; - bool is_window_open_ = false; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index b735a3bf..cec7e21 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -797,32 +797,22 @@ if (!PrepareRequestForThisFrame(request)) return; - SetReferrerForFrameRequest(request); + Frame* target_frame = frame_->FindFrameForNavigation( + AtomicString(request.FrameName()), *frame_, url); - // A GetNavigationPolicy() value other than kNavigationPolicyCurrentTab at - // this point indicates that a user event modified the navigation policy - // (e.g., a ctrl-click). Let the user's action override any target attribute. - if (request.GetNavigationPolicy() == kNavigationPolicyCurrentTab) { - Frame* target_frame = frame_->FindFrameForNavigation( - AtomicString(request.FrameName()), *frame_, url); - if (!target_frame) { - request.SetNavigationPolicy(kNavigationPolicyNewForegroundTab); - bool created = false; - target_frame = CreateNewWindow(*frame_.Get(), request, created); - if (!target_frame) - return; - } + // Downloads and navigations which specifically target a *new* frame + // (e.g. because of a ctrl-click) should ignore the target. + bool should_navigate_target_frame = + request.GetNavigationPolicy() == kNavigationPolicyCurrentTab; - if (target_frame != frame_) { - bool was_in_same_page = target_frame->GetPage() == frame_->GetPage(); - request.SetFrameName("_self"); - request.SetNavigationPolicy(kNavigationPolicyCurrentTab); - target_frame->Navigate(request, frame_load_type); - Page* page = target_frame->GetPage(); - if (!was_in_same_page && page) - page->GetChromeClient().Focus(frame_); - return; - } + if (target_frame && target_frame != frame_ && should_navigate_target_frame) { + bool was_in_same_page = target_frame->GetPage() == frame_->GetPage(); + request.SetFrameName("_self"); + target_frame->Navigate(request, frame_load_type); + Page* page = target_frame->GetPage(); + if (!was_in_same_page && page) + page->GetChromeClient().Focus(frame_); + return; } // Block renderer-initiated loads of data: and filesystem: URLs in the top @@ -847,6 +837,16 @@ return; } + SetReferrerForFrameRequest(request); + + if (!target_frame && !request.FrameName().IsEmpty() && + should_navigate_target_frame) { + request.SetFrameType(network::mojom::RequestContextFrameType::kAuxiliary); + request.SetNavigationPolicy(kNavigationPolicyNewForegroundTab); + CreateWindowForRequest(request, *frame_); + return; // Navigation will be handled by the new frame/window. + } + // TODO(dgozman): merge page dismissal check and FrameNavigationDisabler. if (!frame_->IsNavigationAllowed() || frame_->GetDocument()->PageDismissalEventBeingDispatched() !=
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc index 5cfff2c..89635e0b 100644 --- a/third_party/blink/renderer/core/loader/image_loader.cc +++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -75,7 +75,7 @@ return false; if (EqualIgnoringASCIICase( - html_image->FastGetAttribute(html_names::kLoadAttr), "lazy")) + html_image->FastGetAttribute(html_names::kLoadingAttr), "lazy")) return true; // Do not lazyload image elements created from javascript. @@ -83,7 +83,7 @@ return false; if (EqualIgnoringASCIICase( - html_image->FastGetAttribute(html_names::kLoadAttr), "eager") && + html_image->FastGetAttribute(html_names::kLoadingAttr), "eager") && !frame->GetDocument()->IsLazyLoadPolicyEnforced()) { return false; }
diff --git a/third_party/blink/renderer/core/page/create_window.cc b/third_party/blink/renderer/core/page/create_window.cc index dab84de..023516a 100644 --- a/third_party/blink/renderer/core/page/create_window.cc +++ b/third_party/blink/renderer/core/page/create_window.cc
@@ -33,15 +33,19 @@ #include "third_party/blink/public/common/dom_storage/session_storage_namespace_id.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/frame/from_ad_state.h" +#include "third_party/blink/public/platform/web_input_event.h" +#include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/public/web/web_view_client.h" #include "third_party/blink/public/web/web_window_features.h" #include "third_party/blink/renderer/core/core_initializer.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/events/current_input_event.h" #include "third_party/blink/renderer/core/exported/web_view_impl.h" #include "third_party/blink/renderer/core/frame/ad_tracker.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/frame_client.h" #include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/loader/frame_load_request.h" #include "third_party/blink/renderer/core/page/chrome_client.h" @@ -49,6 +53,8 @@ #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/weborigin/security_origin.h" +#include "third_party/blink/renderer/platform/weborigin/security_policy.h" namespace blink { @@ -201,43 +207,20 @@ } } -Frame* CreateNewWindow(LocalFrame& opener_frame, - FrameLoadRequest& request, - bool& created) { +static Frame* CreateNewWindow(LocalFrame& opener_frame, + const FrameLoadRequest& request, + const WebWindowFeatures& features, + bool& created) { DCHECK(request.GetResourceRequest().RequestorOrigin() || opener_frame.GetDocument()->Url().IsEmpty()); - - // Exempting window.open() from this check here is necessary to support a - // special policy that will be removed in Chrome 82. - // See https://crbug.com/937569 - if (!request.IsWindowOpen() && - opener_frame.GetDocument()->PageDismissalEventBeingDispatched() != - Document::kNoDismissal) { - return nullptr; - } - - request.SetFrameType(network::mojom::RequestContextFrameType::kAuxiliary); + DCHECK_EQ(request.GetFrameType(), + network::mojom::RequestContextFrameType::kAuxiliary); const KURL& url = request.GetResourceRequest().Url(); - if (url.ProtocolIsJavaScript() && - opener_frame.GetDocument()->GetContentSecurityPolicy() && - !ContentSecurityPolicy::ShouldBypassMainWorld( - opener_frame.GetDocument())) { - String script_source = DecodeURLEscapeSequences( - url.GetString(), DecodeURLMode::kUTF8OrIsomorphic); - - if (!opener_frame.GetDocument()->GetContentSecurityPolicy()->AllowInline( - ContentSecurityPolicy::InlineType::kNavigation, - nullptr /* element */, script_source, String() /* nonce */, - opener_frame.GetDocument()->Url(), OrdinalNumber())) { - return nullptr; - } - } - - const WebWindowFeatures& features = request.GetWindowFeatures(); probe::WindowOpen(opener_frame.GetDocument(), url, request.FrameName(), features, LocalFrame::HasTransientUserActivation(&opener_frame)); + created = false; // Sandboxed frames cannot open new auxiliary browsing contexts. if (opener_frame.GetDocument()->IsSandboxed(WebSandboxFlags::kPopups)) { @@ -282,16 +265,6 @@ if (!page) return nullptr; - auto* new_local_frame = DynamicTo<LocalFrame>(page->MainFrame()); - if (request.GetShouldSendReferrer() == kMaybeSendReferrer) { - // TODO(japhet): Does network::mojom::ReferrerPolicy need to be proagated - // for RemoteFrames? - if (new_local_frame) { - new_local_frame->GetDocument()->SetReferrerPolicy( - opener_frame.GetDocument()->GetReferrerPolicy()); - } - } - if (page == old_page) { Frame* frame = &opener_frame.Tree().Top(); if (!opener_frame.CanNavigate(*frame)) @@ -326,4 +299,122 @@ return &frame; } +DOMWindow* CreateWindow(const KURL& completed_url, + const AtomicString& frame_name, + const WebWindowFeatures& window_features, + LocalDOMWindow& incumbent_window, + LocalFrame& opener_frame) { + LocalFrame* active_frame = incumbent_window.GetFrame(); + DCHECK(active_frame); + + if (completed_url.ProtocolIsJavaScript() && + opener_frame.GetDocument()->GetContentSecurityPolicy() && + !ContentSecurityPolicy::ShouldBypassMainWorld( + opener_frame.GetDocument())) { + String script_source = DecodeURLEscapeSequences( + completed_url.GetString(), DecodeURLMode::kUTF8OrIsomorphic); + + if (!opener_frame.GetDocument()->GetContentSecurityPolicy()->AllowInline( + ContentSecurityPolicy::InlineType::kNavigation, + nullptr /* element */, script_source, String() /* nonce */, + opener_frame.GetDocument()->Url(), OrdinalNumber())) { + return nullptr; + } + } + + FrameLoadRequest frame_request(incumbent_window.document(), + ResourceRequest(completed_url), frame_name); + frame_request.SetNavigationPolicy( + NavigationPolicyForCreateWindow(window_features)); + frame_request.SetShouldSetOpener(window_features.noopener ? kNeverSetOpener + : kMaybeSetOpener); + frame_request.SetFrameType( + network::mojom::RequestContextFrameType::kAuxiliary); + + // Normally, FrameLoader would take care of setting the referrer for a + // navigation that is triggered from javascript. However, creating a window + // goes through sufficient processing that it eventually enters FrameLoader as + // an embedder-initiated navigation. FrameLoader assumes no responsibility + // for generating an embedder-initiated navigation's referrer, so we need to + // ensure the proper referrer is set now. + // TODO(domfarolino): Stop setting ResourceRequest's HTTP Referrer and store + // this is a separate member. See https://crbug.com/850813. + frame_request.GetResourceRequest().SetHttpReferrer( + SecurityPolicy::GenerateReferrer( + active_frame->GetDocument()->GetReferrerPolicy(), completed_url, + active_frame->GetDocument()->OutgoingReferrer())); + + // Records HasUserGesture before the value is invalidated inside + // createWindow(LocalFrame& openerFrame, ...). + // This value will be set in ResourceRequest loaded in a new LocalFrame. + bool has_user_gesture = LocalFrame::HasTransientUserActivation(&opener_frame); + opener_frame.MaybeLogAdClickNavigation(); + + // We pass the opener frame for the lookupFrame in case the active frame is + // different from the opener frame, and the name references a frame relative + // to the opener frame. + bool created; + Frame* new_frame = + CreateNewWindow(opener_frame, frame_request, window_features, created); + if (!new_frame) + return nullptr; + if (new_frame->DomWindow()->IsInsecureScriptAccess(incumbent_window, + completed_url)) + return window_features.noopener ? nullptr : new_frame->DomWindow(); + + if (created || !completed_url.IsEmpty()) { + FrameLoadRequest request(incumbent_window.document(), + ResourceRequest(completed_url)); + request.GetResourceRequest().SetHasUserGesture(has_user_gesture); + if (const WebInputEvent* input_event = CurrentInputEvent::Get()) { + request.SetInputStartTime(input_event->TimeStamp()); + } + new_frame->Navigate(request, WebFrameLoadType::kStandard); + } + return window_features.noopener ? nullptr : new_frame->DomWindow(); +} + +void CreateWindowForRequest(const FrameLoadRequest& request, + LocalFrame& opener_frame) { + DCHECK(request.GetResourceRequest().RequestorOrigin() || + (opener_frame.GetDocument() && + opener_frame.GetDocument()->Url().IsEmpty())); + + if (opener_frame.GetDocument()->PageDismissalEventBeingDispatched() != + Document::kNoDismissal) + return; + + if (opener_frame.GetDocument() && + opener_frame.GetDocument()->IsSandboxed(WebSandboxFlags::kPopups)) + return; + + WebWindowFeatures features; + features.noopener = request.GetShouldSetOpener() == kNeverSetOpener; + bool created; + Frame* new_frame = CreateNewWindow(opener_frame, request, features, created); + if (!new_frame) + return; + auto* new_local_frame = DynamicTo<LocalFrame>(new_frame); + if (request.GetShouldSendReferrer() == kMaybeSendReferrer) { + // TODO(japhet): Does network::mojom::ReferrerPolicy need to be proagated + // for RemoteFrames? + if (new_local_frame) { + new_local_frame->GetDocument()->SetReferrerPolicy( + opener_frame.GetDocument()->GetReferrerPolicy()); + } + } + + // TODO(japhet): Form submissions on RemoteFrames don't work yet. + FrameLoadRequest new_request(nullptr, request.GetResourceRequest()); + new_request.SetForm(request.Form()); + if (const WebInputEvent* input_event = CurrentInputEvent::Get()) { + new_request.SetInputStartTime(input_event->TimeStamp()); + } + auto blob_url_token = request.GetBlobURLToken(); + if (blob_url_token) + new_request.SetBlobURLToken(std::move(blob_url_token)); + if (new_local_frame) + new_local_frame->Loader().StartNavigation(new_request); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/page/create_window.h b/third_party/blink/renderer/core/page/create_window.h index d11a26b..11e635ae4 100644 --- a/third_party/blink/renderer/core/page/create_window.h +++ b/third_party/blink/renderer/core/page/create_window.h
@@ -28,17 +28,23 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_CREATE_WINDOW_H_ #include "third_party/blink/public/web/web_window_features.h" -#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +// To avoid conflicts with the CreateWindow macro from the Windows SDK... +#undef CreateWindow + namespace blink { -class Frame; class LocalFrame; struct FrameLoadRequest; -Frame* CreateNewWindow(LocalFrame& opener_frame, - FrameLoadRequest&, - bool& created); +DOMWindow* CreateWindow(const KURL& completed_url, + const AtomicString& frame_name, + const WebWindowFeatures&, + LocalDOMWindow& incumbent_window, + LocalFrame& opener_frame); + +void CreateWindowForRequest(const FrameLoadRequest&, LocalFrame& opener_frame); CORE_EXPORT WebWindowFeatures GetWindowFeaturesFromString(const String&);
diff --git a/third_party/blink/renderer/core/page/spatial_navigation.cc b/third_party/blink/renderer/core/page/spatial_navigation.cc index 5da6a2b..7c018421 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation.cc +++ b/third_party/blink/renderer/core/page/spatial_navigation.cc
@@ -49,10 +49,7 @@ static void DeflateIfOverlapped(LayoutRect&, LayoutRect&); FocusCandidate::FocusCandidate(Node* node, SpatialNavigationDirection direction) - : visible_node(nullptr), - focusable_node(nullptr), - is_offscreen(true), - is_offscreen_after_scrolling(true) { + : visible_node(nullptr), focusable_node(nullptr), is_offscreen(true) { DCHECK(node); DCHECK(node->IsElementNode()); @@ -73,8 +70,6 @@ focusable_node = node; is_offscreen = IsOffscreen(visible_node); - is_offscreen_after_scrolling = - IsOffscreenAfterFrameScroll(visible_node, direction); } bool IsSpatialNavigationEnabled(const LocalFrame* frame) {
diff --git a/third_party/blink/renderer/core/page/spatial_navigation.h b/third_party/blink/renderer/core/page/spatial_navigation.h index 44c0c02..eccdac7 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation.h +++ b/third_party/blink/renderer/core/page/spatial_navigation.h
@@ -51,10 +51,7 @@ public: FocusCandidate() - : visible_node(nullptr), - focusable_node(nullptr), - is_offscreen(true), - is_offscreen_after_scrolling(true) {} + : visible_node(nullptr), focusable_node(nullptr), is_offscreen(true) {} FocusCandidate(Node*, SpatialNavigationDirection); explicit FocusCandidate(HTMLAreaElement*, SpatialNavigationDirection); @@ -71,13 +68,10 @@ Member<Node> focusable_node; LayoutRect rect_in_root_frame; bool is_offscreen; - bool is_offscreen_after_scrolling; }; CORE_EXPORT bool HasRemoteFrame(const Node*); CORE_EXPORT bool IsOffscreen(const Node*); -CORE_EXPORT bool IsOffscreenAfterFrameScroll(const Node*, - SpatialNavigationDirection); bool ScrollInDirection(Node* container, SpatialNavigationDirection); CORE_EXPORT bool IsScrollableNode(const Node* node); CORE_EXPORT bool IsScrollableAreaOrDocument(const Node*);
diff --git a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc index 3f4cd49..7b2b3b94 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc +++ b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
@@ -81,7 +81,7 @@ // Ignore off-screen focusables that are not exposed after one "scroll step" // in the direction. - if (candidate.is_offscreen && candidate.is_offscreen_after_scrolling) + if (candidate.is_offscreen) return; double distance =
diff --git a/third_party/blink/renderer/core/svg/svg_a_element.idl b/third_party/blink/renderer/core/svg/svg_a_element.idl index c8a8956a..29e46a3 100644 --- a/third_party/blink/renderer/core/svg/svg_a_element.idl +++ b/third_party/blink/renderer/core/svg/svg_a_element.idl
@@ -29,4 +29,4 @@ [ImplementedAs=svgTarget, Measure] readonly attribute SVGAnimatedString target; }; -SVGAElement implements SVGURIReference; +SVGAElement includes SVGURIReference;
diff --git a/third_party/blink/renderer/core/svg/svg_animation_element.idl b/third_party/blink/renderer/core/svg/svg_animation_element.idl index a56ef3d..23be2805 100644 --- a/third_party/blink/renderer/core/svg/svg_animation_element.idl +++ b/third_party/blink/renderer/core/svg/svg_animation_element.idl
@@ -43,4 +43,4 @@ [MeasureAs=SVGSMILBeginEndAnimationElement] void endElementAt(float offset); }; -SVGAnimationElement implements SVGTests; +SVGAnimationElement includes SVGTests;
diff --git a/third_party/blink/renderer/core/svg/svg_element.idl b/third_party/blink/renderer/core/svg/svg_element.idl index c98affb..57a07d3 100644 --- a/third_party/blink/renderer/core/svg/svg_element.idl +++ b/third_party/blink/renderer/core/svg/svg_element.idl
@@ -36,6 +36,6 @@ void blur(); }; -SVGElement implements GlobalEventHandlers; -SVGElement implements DocumentAndElementEventHandlers; -SVGElement implements NoncedElement; +SVGElement includes GlobalEventHandlers; +SVGElement includes DocumentAndElementEventHandlers; +SVGElement includes NoncedElement;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_blend_element.idl b/third_party/blink/renderer/core/svg/svg_fe_blend_element.idl index 5f7487b..a59c5700 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_blend_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_blend_element.idl
@@ -53,4 +53,4 @@ [MeasureAs=SVG1DOMFilter] readonly attribute SVGAnimatedEnumeration mode; }; -SVGFEBlendElement implements SVGFilterPrimitiveStandardAttributes; +SVGFEBlendElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.idl b/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.idl index c39f3cc..48a98cd 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.idl
@@ -40,4 +40,4 @@ [MeasureAs=SVG1DOMFilter] readonly attribute SVGAnimatedNumberList values; }; -SVGFEColorMatrixElement implements SVGFilterPrimitiveStandardAttributes; +SVGFEColorMatrixElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.idl b/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.idl index b8cd25b..dcb417db5 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.idl
@@ -29,4 +29,4 @@ [MeasureAs=SVG1DOMFilter] readonly attribute SVGAnimatedString in1; }; -SVGFEComponentTransferElement implements SVGFilterPrimitiveStandardAttributes; +SVGFEComponentTransferElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_composite_element.idl b/third_party/blink/renderer/core/svg/svg_fe_composite_element.idl index af2826ce..4723b018 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_composite_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_composite_element.idl
@@ -46,4 +46,4 @@ [MeasureAs=SVG1DOMFilter] readonly attribute SVGAnimatedNumber k4; }; -SVGFECompositeElement implements SVGFilterPrimitiveStandardAttributes; +SVGFECompositeElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.idl b/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.idl index e628d4a..d1b8c08 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.idl
@@ -48,4 +48,4 @@ [Measure] readonly attribute SVGAnimatedBoolean preserveAlpha; }; -SVGFEConvolveMatrixElement implements SVGFilterPrimitiveStandardAttributes; +SVGFEConvolveMatrixElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.idl b/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.idl index a7dd44b..b03edec 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.idl
@@ -33,4 +33,4 @@ [MeasureAs=SVG1DOMFilter] readonly attribute SVGAnimatedNumber kernelUnitLengthY; }; -SVGFEDiffuseLightingElement implements SVGFilterPrimitiveStandardAttributes; +SVGFEDiffuseLightingElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.idl b/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.idl index 4c765273..c2879c4c 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.idl
@@ -42,4 +42,4 @@ [MeasureAs=SVG1DOMFilter] readonly attribute SVGAnimatedEnumeration yChannelSelector; }; -SVGFEDisplacementMapElement implements SVGFilterPrimitiveStandardAttributes; +SVGFEDisplacementMapElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.idl b/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.idl index 801e5de9..d07d5b45 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.idl
@@ -29,4 +29,4 @@ [MeasureAs=SVG1DOMFilter] void setStdDeviation(float stdDeviationX, float stdDeviationY); }; -SVGFEDropShadowElement implements SVGFilterPrimitiveStandardAttributes; +SVGFEDropShadowElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_flood_element.idl b/third_party/blink/renderer/core/svg/svg_fe_flood_element.idl index 08924a0d..973cc2e 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_flood_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_flood_element.idl
@@ -28,4 +28,4 @@ interface SVGFEFloodElement : SVGElement { }; -SVGFEFloodElement implements SVGFilterPrimitiveStandardAttributes; +SVGFEFloodElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.idl b/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.idl index 02487e2..a0fc0861 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.idl
@@ -33,4 +33,4 @@ [MeasureAs=SVG1DOMFilter] void setStdDeviation(float stdDeviationX, float stdDeviationY); }; -SVGFEGaussianBlurElement implements SVGFilterPrimitiveStandardAttributes; +SVGFEGaussianBlurElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_image_element.idl b/third_party/blink/renderer/core/svg/svg_fe_image_element.idl index 585f4b9..b9c4661 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_image_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_image_element.idl
@@ -29,5 +29,5 @@ [MeasureAs=SVG1DOMFilter] readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio; }; -SVGFEImageElement implements SVGFilterPrimitiveStandardAttributes; -SVGFEImageElement implements SVGURIReference; +SVGFEImageElement includes SVGFilterPrimitiveStandardAttributes; +SVGFEImageElement includes SVGURIReference;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_merge_element.idl b/third_party/blink/renderer/core/svg/svg_fe_merge_element.idl index ab157b85..d53acda 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_merge_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_merge_element.idl
@@ -28,4 +28,4 @@ interface SVGFEMergeElement : SVGElement { }; -SVGFEMergeElement implements SVGFilterPrimitiveStandardAttributes; +SVGFEMergeElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_morphology_element.idl b/third_party/blink/renderer/core/svg/svg_fe_morphology_element.idl index 185408d..9187763 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_morphology_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_morphology_element.idl
@@ -39,4 +39,4 @@ [MeasureAs=SVG1DOMFilter] readonly attribute SVGAnimatedNumber radiusY; }; -SVGFEMorphologyElement implements SVGFilterPrimitiveStandardAttributes; +SVGFEMorphologyElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_offset_element.idl b/third_party/blink/renderer/core/svg/svg_fe_offset_element.idl index 02f3c46..5278f274 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_offset_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_offset_element.idl
@@ -31,4 +31,4 @@ [MeasureAs=SVG1DOMFilter] readonly attribute SVGAnimatedNumber dy; }; -SVGFEOffsetElement implements SVGFilterPrimitiveStandardAttributes; +SVGFEOffsetElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.idl b/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.idl index c9a5924..56470b1e 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.idl
@@ -34,4 +34,4 @@ [MeasureAs=SVG1DOMFilter] readonly attribute SVGAnimatedNumber kernelUnitLengthY; }; -SVGFESpecularLightingElement implements SVGFilterPrimitiveStandardAttributes; +SVGFESpecularLightingElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_tile_element.idl b/third_party/blink/renderer/core/svg/svg_fe_tile_element.idl index 703b2ff..39cd920 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_tile_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_tile_element.idl
@@ -29,4 +29,4 @@ [MeasureAs=SVG1DOMFilter] readonly attribute SVGAnimatedString in1; }; -SVGFETileElement implements SVGFilterPrimitiveStandardAttributes; +SVGFETileElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.idl b/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.idl index b7049138..6259e4bb 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.idl +++ b/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.idl
@@ -46,4 +46,4 @@ [MeasureAs=SVG1DOMFilter] readonly attribute SVGAnimatedEnumeration type; }; -SVGFETurbulenceElement implements SVGFilterPrimitiveStandardAttributes; +SVGFETurbulenceElement includes SVGFilterPrimitiveStandardAttributes;
diff --git a/third_party/blink/renderer/core/svg/svg_filter_element.idl b/third_party/blink/renderer/core/svg/svg_filter_element.idl index e7fd4458..598013f 100644 --- a/third_party/blink/renderer/core/svg/svg_filter_element.idl +++ b/third_party/blink/renderer/core/svg/svg_filter_element.idl
@@ -35,5 +35,5 @@ [MeasureAs=SVG1DOMFilter] readonly attribute SVGAnimatedLength height; }; -SVGFilterElement implements SVGURIReference; -// SVGFilterElement implements SVGUnitTypes; +SVGFilterElement includes SVGURIReference; +// SVGFilterElement includes SVGUnitTypes;
diff --git a/third_party/blink/renderer/core/svg/svg_gradient_element.idl b/third_party/blink/renderer/core/svg/svg_gradient_element.idl index d3abb19..5fb065d 100644 --- a/third_party/blink/renderer/core/svg/svg_gradient_element.idl +++ b/third_party/blink/renderer/core/svg/svg_gradient_element.idl
@@ -39,5 +39,5 @@ [MeasureAs=SVG1DOMPaintServer] readonly attribute SVGAnimatedEnumeration spreadMethod; }; -SVGGradientElement implements SVGURIReference; -// SVGGradientElement implements SVGUnitTypes; +SVGGradientElement includes SVGURIReference; +// SVGGradientElement includes SVGUnitTypes;
diff --git a/third_party/blink/renderer/core/svg/svg_graphics_element.idl b/third_party/blink/renderer/core/svg/svg_graphics_element.idl index f27e75d..5f9b1d6e 100644 --- a/third_party/blink/renderer/core/svg/svg_graphics_element.idl +++ b/third_party/blink/renderer/core/svg/svg_graphics_element.idl
@@ -44,4 +44,4 @@ [MeasureAs=SVGLocatableFarthestViewportElement] readonly attribute SVGElement farthestViewportElement; }; -SVGGraphicsElement implements SVGTests; +SVGGraphicsElement includes SVGTests;
diff --git a/third_party/blink/renderer/core/svg/svg_image_element.idl b/third_party/blink/renderer/core/svg/svg_image_element.idl index b4339886..951eee16 100644 --- a/third_party/blink/renderer/core/svg/svg_image_element.idl +++ b/third_party/blink/renderer/core/svg/svg_image_element.idl
@@ -41,4 +41,4 @@ [CallWith=ScriptState, RaisesException] Promise<void> decode(); }; -SVGImageElement implements SVGURIReference; +SVGImageElement includes SVGURIReference;
diff --git a/third_party/blink/renderer/core/svg/svg_marker_element.idl b/third_party/blink/renderer/core/svg/svg_marker_element.idl index 610dfaf..edd8c75 100644 --- a/third_party/blink/renderer/core/svg/svg_marker_element.idl +++ b/third_party/blink/renderer/core/svg/svg_marker_element.idl
@@ -50,4 +50,4 @@ [MeasureAs=SVG1DOMMarkerElement] void setOrientToAngle(SVGAngle angle); }; -SVGMarkerElement implements SVGFitToViewBox; +SVGMarkerElement includes SVGFitToViewBox;
diff --git a/third_party/blink/renderer/core/svg/svg_mask_element.idl b/third_party/blink/renderer/core/svg/svg_mask_element.idl index 471df3da..6cb896b 100644 --- a/third_party/blink/renderer/core/svg/svg_mask_element.idl +++ b/third_party/blink/renderer/core/svg/svg_mask_element.idl
@@ -34,7 +34,7 @@ [MeasureAs=SVG1DOMMaskElement] readonly attribute SVGAnimatedLength height; }; -// SVGMaskElement implements SVGUnitTypes; +// SVGMaskElement includes SVGUnitTypes; // TODO(foolip): The following is not part of any spec. https://crbug.com/701893 -SVGMaskElement implements SVGTests; +SVGMaskElement includes SVGTests;
diff --git a/third_party/blink/renderer/core/svg/svg_mpath_element.idl b/third_party/blink/renderer/core/svg/svg_mpath_element.idl index 7889bbb..332e69aa 100644 --- a/third_party/blink/renderer/core/svg/svg_mpath_element.idl +++ b/third_party/blink/renderer/core/svg/svg_mpath_element.idl
@@ -28,4 +28,4 @@ interface SVGMPathElement : SVGElement { }; -SVGMPathElement implements SVGURIReference; +SVGMPathElement includes SVGURIReference;
diff --git a/third_party/blink/renderer/core/svg/svg_pattern_element.idl b/third_party/blink/renderer/core/svg/svg_pattern_element.idl index fba4f7b..121f9b0 100644 --- a/third_party/blink/renderer/core/svg/svg_pattern_element.idl +++ b/third_party/blink/renderer/core/svg/svg_pattern_element.idl
@@ -35,10 +35,10 @@ [MeasureAs=SVG1DOMPaintServer] readonly attribute SVGAnimatedLength height; }; -SVGPatternElement implements SVGFitToViewBox; -SVGPatternElement implements SVGURIReference; -// SVGPatternElement implements SVGUnitTypes; +SVGPatternElement includes SVGFitToViewBox; +SVGPatternElement includes SVGURIReference; +// SVGPatternElement includes SVGUnitTypes; // TODO(foolip): The following was part of SVG 1.1. https://crbug.com/701893 // http://www.w3.org/TR/SVG11/pservers.html#InterfaceSVGPatternElement -SVGPatternElement implements SVGTests; +SVGPatternElement includes SVGTests;
diff --git a/third_party/blink/renderer/core/svg/svg_script_element.idl b/third_party/blink/renderer/core/svg/svg_script_element.idl index 52d84e7..8ab0ade 100644 --- a/third_party/blink/renderer/core/svg/svg_script_element.idl +++ b/third_party/blink/renderer/core/svg/svg_script_element.idl
@@ -29,4 +29,4 @@ [Reflect] attribute DOMString type; }; -SVGScriptElement implements SVGURIReference; +SVGScriptElement includes SVGURIReference;
diff --git a/third_party/blink/renderer/core/svg/svg_style_element.idl b/third_party/blink/renderer/core/svg/svg_style_element.idl index 47965340..59fe6ac 100644 --- a/third_party/blink/renderer/core/svg/svg_style_element.idl +++ b/third_party/blink/renderer/core/svg/svg_style_element.idl
@@ -31,7 +31,7 @@ attribute DOMString media; [MeasureAs=SVGStyleElementTitle] attribute DOMString title; - // SVGStyleElement implements LinkStyle + // SVGStyleElement includes LinkStyle // https://drafts.csswg.org/cssom/#the-linkstyle-interface readonly attribute StyleSheet? sheet;
diff --git a/third_party/blink/renderer/core/svg/svg_svg_element.idl b/third_party/blink/renderer/core/svg/svg_svg_element.idl index 0643aed..898a11c 100644 --- a/third_party/blink/renderer/core/svg/svg_svg_element.idl +++ b/third_party/blink/renderer/core/svg/svg_svg_element.idl
@@ -66,5 +66,5 @@ [MeasureAs=SVGSMILCurrentTime] void setCurrentTime(float seconds); }; -SVGSVGElement implements SVGFitToViewBox; -SVGSVGElement implements SVGZoomAndPan; +SVGSVGElement includes SVGFitToViewBox; +SVGSVGElement includes SVGZoomAndPan;
diff --git a/third_party/blink/renderer/core/svg/svg_symbol_element.idl b/third_party/blink/renderer/core/svg/svg_symbol_element.idl index f2c657ba..7b5298a8 100644 --- a/third_party/blink/renderer/core/svg/svg_symbol_element.idl +++ b/third_party/blink/renderer/core/svg/svg_symbol_element.idl
@@ -28,4 +28,4 @@ interface SVGSymbolElement : SVGElement { }; -SVGSymbolElement implements SVGFitToViewBox; +SVGSymbolElement includes SVGFitToViewBox;
diff --git a/third_party/blink/renderer/core/svg/svg_text_path_element.idl b/third_party/blink/renderer/core/svg/svg_text_path_element.idl index 8aee74f..2aea585 100644 --- a/third_party/blink/renderer/core/svg/svg_text_path_element.idl +++ b/third_party/blink/renderer/core/svg/svg_text_path_element.idl
@@ -41,5 +41,5 @@ [MeasureAs=SVG1DOMText] readonly attribute SVGAnimatedEnumeration spacing; }; -SVGTextPathElement implements SVGURIReference; -//SVGTextPathElement implements SVGAnimatedPathData; +SVGTextPathElement includes SVGURIReference; +//SVGTextPathElement includes SVGAnimatedPathData;
diff --git a/third_party/blink/renderer/core/svg/svg_use_element.idl b/third_party/blink/renderer/core/svg/svg_use_element.idl index b096a2f9..487f78ad 100644 --- a/third_party/blink/renderer/core/svg/svg_use_element.idl +++ b/third_party/blink/renderer/core/svg/svg_use_element.idl
@@ -32,4 +32,4 @@ [MeasureAs=SVG1DOMUseElement] readonly attribute SVGAnimatedLength height; }; -SVGUseElement implements SVGURIReference; +SVGUseElement includes SVGURIReference;
diff --git a/third_party/blink/renderer/core/svg/svg_view_element.idl b/third_party/blink/renderer/core/svg/svg_view_element.idl index 731a978..53626f2 100644 --- a/third_party/blink/renderer/core/svg/svg_view_element.idl +++ b/third_party/blink/renderer/core/svg/svg_view_element.idl
@@ -28,5 +28,5 @@ interface SVGViewElement : SVGElement { }; -SVGViewElement implements SVGFitToViewBox; -SVGViewElement implements SVGZoomAndPan; +SVGViewElement includes SVGFitToViewBox; +SVGViewElement includes SVGZoomAndPan;
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index 6a8ddc20..9fe4d52 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -174,7 +174,7 @@ #include "third_party/blink/renderer/platform/testing/url_test_helpers.h" #include "third_party/blink/renderer/platform/text/layout_locale.h" #include "third_party/blink/renderer/platform/weborigin/scheme_registry.h" -#include "third_party/blink/renderer/platform/wtf/dtoa.h" +#include "third_party/blink/renderer/platform/wtf/dtoa/dtoa.h" #include "third_party/blink/renderer/platform/wtf/text/string_buffer.h" #include "third_party/blink/renderer/platform/wtf/text/text_encoding_registry.h" #include "v8/include/v8.h"
diff --git a/third_party/blink/renderer/core/workers/shared_worker.idl b/third_party/blink/renderer/core/workers/shared_worker.idl index 3f54076..74008ed 100644 --- a/third_party/blink/renderer/core/workers/shared_worker.idl +++ b/third_party/blink/renderer/core/workers/shared_worker.idl
@@ -44,4 +44,4 @@ readonly attribute MessagePort port; }; -SharedWorker implements AbstractWorker; +SharedWorker includes AbstractWorker;
diff --git a/third_party/blink/renderer/core/workers/worker.idl b/third_party/blink/renderer/core/workers/worker.idl index e66dd1cd..a0e36b3 100644 --- a/third_party/blink/renderer/core/workers/worker.idl +++ b/third_party/blink/renderer/core/workers/worker.idl
@@ -42,4 +42,4 @@ attribute EventHandler onmessage; }; -Worker implements AbstractWorker; +Worker includes AbstractWorker;
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.cc b/third_party/blink/renderer/core/workers/worker_global_scope.cc index 3378eca..9817b5b 100644 --- a/third_party/blink/renderer/core/workers/worker_global_scope.cc +++ b/third_party/blink/renderer/core/workers/worker_global_scope.cc
@@ -254,9 +254,9 @@ ErrorEvent* error_event = nullptr; SingleCachedMetadataHandler* handler( CreateWorkerScriptCachedMetadataHandler(complete_url, - cached_meta_data.get())); + std::move(cached_meta_data))); ReportingProxy().WillEvaluateImportedClassicScript( - source_code.length(), cached_meta_data ? cached_meta_data->size() : 0); + source_code.length(), handler ? handler->GetCodeCacheSize() : 0); ScriptController()->Evaluate( ScriptSourceCode(source_code, ScriptSourceLocationType::kUnknown, handler, response_url), @@ -404,11 +404,10 @@ DCHECK(IsContextThread()); SingleCachedMetadataHandler* handler = CreateWorkerScriptCachedMetadataHandler(script_url, - cached_meta_data.get()); + std::move(cached_meta_data)); DCHECK(!source_code.IsNull()); ReportingProxy().WillEvaluateClassicScript( - source_code.length(), - cached_meta_data.get() ? cached_meta_data->size() : 0); + source_code.length(), handler ? handler->GetCodeCacheSize() : 0); // Cross-origin workers are disallowed, so use // SanitizeScriptErrors::kDoNotSanitize. bool success = ScriptController()->Evaluate(
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.h b/third_party/blink/renderer/core/workers/worker_global_scope.h index 8626df0..c72cfc599 100644 --- a/third_party/blink/renderer/core/workers/worker_global_scope.h +++ b/third_party/blink/renderer/core/workers/worker_global_scope.h
@@ -79,7 +79,7 @@ // Returns null if caching is not supported. virtual SingleCachedMetadataHandler* CreateWorkerScriptCachedMetadataHandler( const KURL& script_url, - const Vector<uint8_t>* meta_data) { + std::unique_ptr<Vector<uint8_t>> meta_data) { return nullptr; }
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.idl b/third_party/blink/renderer/core/workers/worker_global_scope.idl index ea15aa0..8d18ae2 100644 --- a/third_party/blink/renderer/core/workers/worker_global_scope.idl +++ b/third_party/blink/renderer/core/workers/worker_global_scope.idl
@@ -79,6 +79,6 @@ [RuntimeEnabled=OffscreenCanvasText] readonly attribute FontFaceSet fonts; }; -WorkerGlobalScope implements WindowOrWorkerGlobalScope; +WorkerGlobalScope includes WindowOrWorkerGlobalScope; // TODO(fserb): this needs to be enabled once we get out of RuntimeEnabled. -//WorkerGlobalScope implements FontFaceSource; +//WorkerGlobalScope includes FontFaceSource;
diff --git a/third_party/blink/renderer/core/workers/worker_navigator.idl b/third_party/blink/renderer/core/workers/worker_navigator.idl index 1fa072d4..a0fe35b 100644 --- a/third_party/blink/renderer/core/workers/worker_navigator.idl +++ b/third_party/blink/renderer/core/workers/worker_navigator.idl
@@ -33,8 +33,8 @@ ] interface WorkerNavigator { }; -WorkerNavigator implements NavigatorConcurrentHardware; -WorkerNavigator implements NavigatorDeviceMemory; -WorkerNavigator implements NavigatorID; -WorkerNavigator implements NavigatorLanguage; -WorkerNavigator implements NavigatorOnLine; +WorkerNavigator includes NavigatorConcurrentHardware; +WorkerNavigator includes NavigatorDeviceMemory; +WorkerNavigator includes NavigatorID; +WorkerNavigator includes NavigatorLanguage; +WorkerNavigator includes NavigatorOnLine;
diff --git a/third_party/blink/renderer/devtools/front_end/timeline/TimelineFlameChartNetworkDataProvider.js b/third_party/blink/renderer/devtools/front_end/timeline/TimelineFlameChartNetworkDataProvider.js index f098af8..f67649ab 100644 --- a/third_party/blink/renderer/devtools/front_end/timeline/TimelineFlameChartNetworkDataProvider.js +++ b/third_party/blink/renderer/devtools/front_end/timeline/TimelineFlameChartNetworkDataProvider.js
@@ -199,7 +199,7 @@ const /** @const */ minBarWidthPx = 2; const beginTime = request.beginTime(); - const startTime = request.startTime; + const startTime = Math.min(request.startTime, request.timing && request.timing.requestTime * 1000 || Infinity); const endTime = request.endTime; const requestTime = request.timing.requestTime * 1000; const sendStart = Math.max(timeToPixel(requestTime + request.timing.sendStart), unclippedBarX); @@ -208,8 +208,10 @@ const start = timeToPixel(startTime); const end = Math.max(timeToPixel(endTime), finish); + // Draw waiting time. context.fillStyle = 'hsla(0, 100%, 100%, 0.8)'; context.fillRect(sendStart + 0.5, barY + 0.5, headersEnd - sendStart - 0.5, barHeight - 2); + // Clear portions of initial rect to prepare for the ticks. context.fillStyle = UI.themeSupport.patchColorText('white', UI.ThemeSupport.ColorUsage.Background); context.fillRect(barX, barY - 0.5, sendStart - barX, barHeight); context.fillRect(finish, barY - 0.5, barX + barWidth - finish, barHeight);
diff --git a/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js b/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js index d0665b7..fba0085 100644 --- a/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js +++ b/third_party/blink/renderer/devtools/front_end/timeline_model/TimelineModel.js
@@ -1563,7 +1563,9 @@ * @return {number} */ beginTime() { - return Math.min(this.startTime, this.timing && this.timing.pushStart * 1000 || Infinity); + return Math.min( + this.startTime, this.timing && this.timing.requestTime * 1000 || Infinity, + this.timing && this.timing.pushStart * 1000 || Infinity); } };
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc index bf07487..cd8cf29 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -187,13 +187,26 @@ // |layout_object| and |node| correspond to an AXLayoutObject. |alt_text| is an // output parameter that will be populated if the AXLayoutObject is for a pseudo // element and contained the alternative text -base::Optional<String> GetPseudoElementAltText(Node* node) { - if (node && node->IsPseudoElement()) { +base::Optional<String> GetCSSAltText(Node* node) { + if (node && node->GetComputedStyle() && + node->GetComputedStyle()->GetContentData()) { const ComputedStyle* style = node->GetComputedStyle(); - for (const ContentData* content_data = style->GetContentData(); - content_data; content_data = content_data->Next()) { - if (content_data->IsAltText()) - return To<AltTextContentData>(content_data)->GetText(); + // If the content property is used on a non-pseudo element, match the + // behaviour of LayoutObject::CreateObject and only honour the style if + // there is exactly one piece of content, which is an image. + if (node->IsPseudoElement()) { + for (const ContentData* content_data = style->GetContentData(); + content_data; content_data = content_data->Next()) { + if (content_data->IsAltText()) + return To<AltTextContentData>(content_data)->GetText(); + } + return base::nullopt; + } + + const ContentData* content_data = style->GetContentData(); + if (content_data && content_data->IsImage() && content_data->Next() && + content_data->Next()->IsAltText()) { + return To<AltTextContentData>(content_data->Next())->GetText(); } } return base::nullopt; @@ -259,7 +272,7 @@ ax::mojom::Role AXLayoutObject::DetermineAccessibilityRole() { if (!layout_object_) return ax::mojom::Role::kUnknown; - if (GetPseudoElementAltText(GetNode())) { + if (GetCSSAltText(GetNode())) { const ComputedStyle* style = GetNode()->GetComputedStyle(); ContentData* content_data = style->GetContentData(); @@ -856,7 +869,7 @@ !GetAttribute(kTitleAttr).IsEmpty()) return false; - base::Optional<String> alt_text = GetPseudoElementAltText(GetNode()); + base::Optional<String> alt_text = GetCSSAltText(GetNode()); if (alt_text) return alt_text->IsEmpty(); @@ -1401,8 +1414,11 @@ break; } - if (!result && ParentObject()) - result = ParentObject()->NextOnLine(); + if (!result) { + AXObject* computed_parent = ComputeParent(); + if (computed_parent) + result = computed_parent->NextOnLine(); + } } // For consistency between the forward and backward directions, try to always @@ -1471,8 +1487,11 @@ break; } - if (!result && ParentObject()) - result = ParentObject()->PreviousOnLine(); + if (!result) { + AXObject* computed_parent = ComputeParent(); + if (computed_parent) + result = computed_parent->PreviousOnLine(); + } } // For consistency between the forward and backward directions, try to always @@ -1558,8 +1577,7 @@ AXRelatedObjectVector* related_objects, NameSources* name_sources) const { if (layout_object_) { - base::Optional<String> text_alternative = - GetPseudoElementAltText(GetNode()); + base::Optional<String> text_alternative = GetCSSAltText(GetNode()); bool found_text_alternative = false; if (text_alternative) { if (name_sources) { @@ -2057,6 +2075,9 @@ return parent; } + if (GetNode()) + return AXNodeObject::ComputeParent(); + LayoutObject* parent_layout_obj = ParentLayoutObject(layout_object_); if (parent_layout_obj) return AXObjectCache().GetOrCreate(parent_layout_obj); @@ -2085,6 +2106,9 @@ return parent; } + if (GetNode()) + return AXNodeObject::ComputeParentIfExists(); + LayoutObject* parent_layout_obj = ParentLayoutObject(layout_object_); if (parent_layout_obj) return AXObjectCache().Get(parent_layout_obj); @@ -2102,9 +2126,19 @@ if (IsDetached()) return; - if (IsHTMLCanvasElement(GetNode())) - return AXNodeObject::AddChildren(); - + if (GetNode() && GetNode()->IsElementNode()) { + Element* element = ToElement(GetNode()); + if (!IsHTMLMapElement(*element) && // Handled in AddImageMapChildren (img) + !IsHTMLRubyElement(*element) && // Special layout handling + !IsHTMLTableElement(*element) && // thead/tfoot move around + !element->IsPseudoElement()) { // Not visited in layout traversal + AXNodeObject::AddChildren(); + return; + } + } + Element* element = nullptr; + if (GetNode() && GetNode()->IsElementNode()) + element = ToElement(GetNode()); // If the need to add more children in addition to existing children arises, // childrenChanged should have been called, leaving the object with no // children. @@ -2123,7 +2157,6 @@ AddHiddenChildren(); AddPopupChildren(); - AddImageMapChildren(); AddRemoteSVGChildren(); AddTableChildren(); AddInlineTextBoxChildren(false); @@ -2142,7 +2175,7 @@ bool AXLayoutObject::CanHaveChildren() const { if (!layout_object_) return false; - if (GetPseudoElementAltText(GetNode())) + if (GetCSSAltText(GetNode())) return false; return AXNodeObject::CanHaveChildren(); } @@ -3586,6 +3619,26 @@ } } +void AXLayoutObject::AddListMarker() { + if (!CanHaveChildren() || !GetLayoutObject() || + !GetLayoutObject()->IsListItemIncludingNG()) { + return; + } + if (GetLayoutObject()->IsLayoutNGListItem()) { + LayoutNGListItem* list_item = ToLayoutNGListItem(GetLayoutObject()); + LayoutObject* list_marker = list_item->Marker(); + AXObject* list_marker_obj = AXObjectCache().GetOrCreate(list_marker); + if (list_marker_obj) + children_.push_back(list_marker_obj); + return; + } + LayoutListItem* list_item = ToLayoutListItem(GetLayoutObject()); + LayoutObject* list_marker = list_item->Marker(); + AXObject* list_marker_obj = AXObjectCache().GetOrCreate(list_marker); + if (list_marker_obj) + children_.push_back(list_marker_obj); +} + void AXLayoutObject::AddPopupChildren() { if (!IsHTMLInputElement(GetNode())) return;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.h b/third_party/blink/renderer/modules/accessibility/ax_layout_object.h index c458081..d3d05a9 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.h
@@ -163,6 +163,10 @@ AXObject* RawFirstChild() const override; AXObject* RawNextSibling() const override; void AddChildren() override; + void AddListMarker() override; + void AddInlineTextBoxChildren(bool force) override; + void AddImageMapChildren() override; + void AddHiddenChildren() override; bool CanHaveChildren() const override; // Properties of the object's owning document or page. @@ -213,18 +217,14 @@ bool IsValidSelectionBound(const AXObject*) const; AXObject* AccessibilityImageMapHitTest(HTMLAreaElement*, const IntPoint&) const; - LayoutObject* LayoutParentObject() const; bool IsSVGImage() const; void DetachRemoteSVGRoot(); AXSVGRoot* RemoteSVGRootElement() const; AXObject* RemoteSVGElementHitTest(const IntPoint&) const; void OffsetBoundingBoxForRemoteSVGElement(LayoutRect&) const; - void AddHiddenChildren(); - void AddImageMapChildren(); void AddPopupChildren(); void AddRemoteSVGChildren(); void AddTableChildren(); - void AddInlineTextBoxChildren(bool force); void AddValidationMessageChild(); ax::mojom::Role DetermineTableCellRole() const; ax::mojom::Role DetermineTableRowRole() const;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc b/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc index 3fe05dbe..d9330ea 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc
@@ -58,15 +58,16 @@ } bool AXListBoxOption::IsParentPresentationalRole() const { - AXObject* parent = ParentObject(); + LayoutObject* parent_layout_object = GetLayoutObject()->Parent(); + if (!parent_layout_object) + return false; + + AXObject* parent = AXObjectCache().GetOrCreate(parent_layout_object); if (!parent) return false; - LayoutObject* layout_object = parent->GetLayoutObject(); - if (!layout_object) - return false; - - if (layout_object->IsListBox() && parent->HasInheritedPresentationalRole()) + if (parent_layout_object->IsListBox() && + parent->HasInheritedPresentationalRole()) return true; return false;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc b/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc index c892b88..cdd8977 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
@@ -73,19 +73,19 @@ AXObjectCacheImpl& cache = AXObjectCache(); - AXObject* list = cache.GetOrCreate(ax::mojom::Role::kMenuListPopup); - if (!list) + AXObject* popup = cache.GetOrCreate(ax::mojom::Role::kMenuListPopup); + if (!popup) return; - ToAXMockObject(list)->SetParent(this); - if (list->AccessibilityIsIgnored()) { - cache.Remove(list->AXObjectID()); + ToAXMockObject(popup)->SetParent(this); + if (popup->AccessibilityIsIgnored()) { + cache.Remove(popup->AXObjectID()); return; } - children_.push_back(list); + children_.push_back(popup); - list->AddChildren(); + popup->AddChildren(); } bool AXMenuList::IsCollapsed() const {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index dbccf1c9..c63fd43b 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -33,6 +33,7 @@ #include "third_party/blink/renderer/core/aom/accessible_node.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" +#include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h" #include "third_party/blink/renderer/core/dom/node_traversal.h" #include "third_party/blink/renderer/core/dom/qualified_name.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" @@ -311,9 +312,9 @@ return ax::mojom::Role::kDetails; if (IsHTMLSummaryElement(*GetNode())) { - ContainerNode* parent = FlatTreeTraversal::Parent(*GetNode()); + ContainerNode* parent = LayoutTreeBuilderTraversal::Parent(*GetNode()); if (parent && IsHTMLSlotElement(parent)) - parent = FlatTreeTraversal::Parent(*parent); + parent = LayoutTreeBuilderTraversal::Parent(*parent); if (parent && IsHTMLDetailsElement(parent)) return ax::mojom::Role::kDisclosureTriangle; return ax::mojom::Role::kUnknown; @@ -661,13 +662,15 @@ if (!parent) return nullptr; - for (Element* sibling = ElementTraversal::FirstChild(*parent); sibling; - sibling = ElementTraversal::NextSibling(*sibling)) { + for (Node* sibling = LayoutTreeBuilderTraversal::FirstChild(*parent); sibling; + sibling = LayoutTreeBuilderTraversal::NextSibling(*sibling)) { + if (!sibling->IsElementNode()) + continue; const AtomicString& sibling_aria_role = - AccessibleNode::GetPropertyOrARIAAttribute(sibling, + AccessibleNode::GetPropertyOrARIAAttribute(ToElement(sibling), AOMStringProperty::kRole); if (EqualIgnoringASCIICase(sibling_aria_role, role)) - return sibling; + return ToElement(sibling); } return nullptr; @@ -2080,17 +2083,7 @@ if (!node) return nullptr; - Node* parent_node = nullptr; - - // Skip over <optgroup> and consider the <select> the immediate parent of an - // <option>. - if (auto* option = ToHTMLOptionElementOrNull(node)) - parent_node = option->OwnerSelectElement(); - - if (!parent_node) - parent_node = node->parentNode(); - - return parent_node; + return LayoutTreeBuilderTraversal::Parent(*node); } AXObject* AXNodeObject::ComputeParent() const { @@ -2112,7 +2105,7 @@ if (!GetNode()) return nullptr; - Node* first_child = GetNode()->firstChild(); + Node* first_child = LayoutTreeBuilderTraversal::FirstChild(*GetNode()); if (!first_child) return nullptr; @@ -2124,7 +2117,7 @@ if (!GetNode()) return nullptr; - Node* next_sibling = GetNode()->nextSibling(); + Node* next_sibling = LayoutTreeBuilderTraversal::NextSibling(*GetNode()); if (!next_sibling) return nullptr; @@ -2141,34 +2134,38 @@ DCHECK(!have_children_); have_children_ = true; - // The only time we add children from the DOM tree to a node with a - // layoutObject is when it's a canvas. - if (GetLayoutObject() && !IsHTMLCanvasElement(*node_)) - return; - AXObjectVector owned_children; ComputeAriaOwnsChildren(owned_children); - for (Node& child : NodeTraversal::ChildrenOf(*node_)) { - AXObject* child_obj = AXObjectCache().GetOrCreate(&child); + AddListMarker(); + + for (Node* child = LayoutTreeBuilderTraversal::FirstChild(*node_); child; + child = LayoutTreeBuilderTraversal::NextSibling(*child)) { + AXObject* child_obj = AXObjectCache().GetOrCreate(child); if (child_obj && !AXObjectCache().IsAriaOwned(child_obj)) AddChild(child_obj); } + AddHiddenChildren(); + AddImageMapChildren(); + AddInlineTextBoxChildren(false); + AddAccessibleNodeChildren(); + + for (const auto& child : children_) { + if (!child->CachedParentObject()) + child->SetParent(this); + } + for (const auto& owned_child : owned_children) AddChild(owned_child); - - for (const auto& child : children_) - child->SetParent(this); - - AddAccessibleNodeChildren(); } void AXNodeObject::AddChild(AXObject* child) { - InsertChild(child, children_.size()); + unsigned index = children_.size(); + InsertChild(child, index); } -void AXNodeObject::InsertChild(AXObject* child, unsigned index) { +void AXNodeObject::InsertChild(AXObject* child, unsigned& index) { if (!child) return; @@ -2182,11 +2179,13 @@ if (child->AccessibilityIsIgnored()) { const auto& children = child->Children(); wtf_size_t length = children.size(); - for (wtf_size_t i = 0; i < length; ++i) - children_.insert(index + i, children[i]); - } else { - DCHECK_EQ(child->ParentObject(), this); + for (wtf_size_t i = 0; i < length; ++i) { + InsertChild(children[i], index); + } + } else if (!child->IsMenuListOption()) { + // MenuListOptions must only added in AXMenuListPopup::AddChildren children_.insert(index, child); + index++; } }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.h b/third_party/blink/renderer/modules/accessibility/ax_node_object.h index 368c220a..b25675f 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.h
@@ -188,9 +188,14 @@ AXObject* RawFirstChild() const override; AXObject* RawNextSibling() const override; void AddChildren() override; + virtual void AddListMarker() {} + virtual void AddInlineTextBoxChildren(bool force) {} + virtual void AddImageMapChildren() {} + virtual void AddHiddenChildren() {} + bool CanHaveChildren() const override; void AddChild(AXObject*); - void InsertChild(AXObject*, unsigned index); + void InsertChild(AXObject*, unsigned& index); void ClearChildren() override; bool NeedsToUpdateChildren() const override { return children_dirty_; } void SetNeedsToUpdateChildren() override { children_dirty_ = true; }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index b09feae4..1f8b70a 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -1645,6 +1645,7 @@ String result = RecursiveTextAlternative( *ax_element, in_aria_labelledby_traversal, visited); + visited.insert(ax_element); local_related_objects.push_back( MakeGarbageCollected<NameSourceRelatedObject>(ax_element, result)); if (!result.IsEmpty()) {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc index 12e4718..f34adac 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -455,7 +455,7 @@ if (node->GetLayoutObject() && !IsHTMLAreaElement(node)) return GetOrCreate(node->GetLayoutObject()); - if (!node->parentElement()) + if (!LayoutTreeBuilderTraversal::Parent(*node)) return nullptr; if (IsHTMLHeadElement(node)) @@ -500,7 +500,11 @@ new_obj->Init(); new_obj->SetLastKnownIsIgnoredValue(new_obj->AccessibilityIsIgnored()); if (node) { - node_object_mapping_.Set(node, axid); + AXID prev_axid = node_object_mapping_.at(node); + if (prev_axid != 0 && prev_axid != axid) { + Remove(node); + node_object_mapping_.Set(node, axid); + } MaybeNewRelationTarget(node, new_obj); } @@ -763,6 +767,10 @@ if (!node) return; + // Something about the call chain for this method seems to leave distribution + // in a dirty state - update it before we call GetOrCreate so that we don't + // crash. + node->UpdateDistributionForFlatTreeTraversal(); AXObject* ax_object = GetOrCreate(node); if (ax_object) ax_object->SelectionChanged(); @@ -973,9 +981,9 @@ PostPlatformNotification(obj, notification); if (notification == ax::mojom::Event::kChildrenChanged && - obj->ParentObjectIfExists() && + obj->CachedParentObject() && obj->LastKnownIsIgnoredValue() != obj->AccessibilityIsIgnored()) - ChildrenChanged(obj->ParentObject()); + ChildrenChanged(obj->CachedParentObject()); } }
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.cc index a7d066c..f7b235b 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.cc
@@ -54,10 +54,10 @@ Gradient::ColorInterpolation::kUnpremultiplied, Gradient::DegenerateHandling::kDisallow)) {} -void CanvasGradient::addColorStop(float value, +void CanvasGradient::addColorStop(double value, const String& color_string, ExceptionState& exception_state) { - if (!(value >= 0 && value <= 1.0f)) { + if (!(value >= 0 && value <= 1.0)) { exception_state.ThrowDOMException(DOMExceptionCode::kIndexSizeError, "The provided value (" + String::Number(value) +
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.h index c2d056cf..ec19265 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.h +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.h
@@ -49,7 +49,7 @@ Gradient* GetGradient() const { return gradient_.get(); } - void addColorStop(float value, const String& color, ExceptionState&); + void addColorStop(double value, const String& color, ExceptionState&); private: scoped_refptr<Gradient> gradient_;
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.idl b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.idl index df921082..70731e4 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.idl +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.idl
@@ -23,10 +23,13 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +// https://html.spec.whatwg.org/multipage/canvas.html#canvasgradient + [ Exposed(Worker OffscreenCanvas, Window StableBlinkFeatures) ] interface CanvasGradient { - [RaisesException] void addColorStop(float offset, DOMString color); + [RaisesException] void addColorStop(double offset, DOMString color); };
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc index c3770835..772c8b2 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc
@@ -35,6 +35,7 @@ #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h" +#include "base/numerics/safe_conversions.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/transforms/affine_transform.h" @@ -42,6 +43,9 @@ namespace blink { +// TODO(crbug.com/940846): Consider using double-type without casting and +// DoublePoint & DoubleRect instead of FloatPoint & FloatRect. + void CanvasPath::closePath() { if (path_.IsEmpty()) return; @@ -51,7 +55,9 @@ path_.CloseSubpath(); } -void CanvasPath::moveTo(float x, float y) { +void CanvasPath::moveTo(double double_x, double double_y) { + float x = base::saturated_cast<float>(double_x); + float y = base::saturated_cast<float>(double_y); if (!std::isfinite(x) || !std::isfinite(y)) return; if (!IsTransformInvertible()) { @@ -61,7 +67,9 @@ path_.MoveTo(FloatPoint(x, y)); } -void CanvasPath::lineTo(float x, float y) { +void CanvasPath::lineTo(double double_x, double double_y) { + float x = base::saturated_cast<float>(double_x); + float y = base::saturated_cast<float>(double_y); if (!std::isfinite(x) || !std::isfinite(y)) return; FloatPoint p1 = FloatPoint(x, y); @@ -76,7 +84,15 @@ path_.AddLineTo(p1); } -void CanvasPath::quadraticCurveTo(float cpx, float cpy, float x, float y) { +void CanvasPath::quadraticCurveTo(double double_cpx, + double double_cpy, + double double_x, + double double_y) { + float cpx = base::saturated_cast<float>(double_cpx); + float cpy = base::saturated_cast<float>(double_cpy); + float x = base::saturated_cast<float>(double_x); + float y = base::saturated_cast<float>(double_y); + if (!std::isfinite(cpx) || !std::isfinite(cpy) || !std::isfinite(x) || !std::isfinite(y)) return; @@ -94,12 +110,18 @@ path_.AddQuadCurveTo(cp, p1); } -void CanvasPath::bezierCurveTo(float cp1x, - float cp1y, - float cp2x, - float cp2y, - float x, - float y) { +void CanvasPath::bezierCurveTo(double double_cp1x, + double double_cp1y, + double double_cp2x, + double double_cp2y, + double double_x, + double double_y) { + float cp1x = base::saturated_cast<float>(double_cp1x); + float cp1y = base::saturated_cast<float>(double_cp1y); + float cp2x = base::saturated_cast<float>(double_cp2x); + float cp2y = base::saturated_cast<float>(double_cp2y); + float x = base::saturated_cast<float>(double_x); + float y = base::saturated_cast<float>(double_y); if (!std::isfinite(cp1x) || !std::isfinite(cp1y) || !std::isfinite(cp2x) || !std::isfinite(cp2y) || !std::isfinite(x) || !std::isfinite(y)) return; @@ -119,12 +141,17 @@ path_.AddBezierCurveTo(cp1, cp2, p1); } -void CanvasPath::arcTo(float x1, - float y1, - float x2, - float y2, - float r, +void CanvasPath::arcTo(double double_x1, + double double_y1, + double double_x2, + double double_y2, + double double_r, ExceptionState& exception_state) { + float x1 = base::saturated_cast<float>(double_x1); + float y1 = base::saturated_cast<float>(double_y1); + float x2 = base::saturated_cast<float>(double_x2); + float y2 = base::saturated_cast<float>(double_y2); + float r = base::saturated_cast<float>(double_r); if (!std::isfinite(x1) || !std::isfinite(y1) || !std::isfinite(x2) || !std::isfinite(y2) || !std::isfinite(r)) return; @@ -313,13 +340,18 @@ } // namespace -void CanvasPath::arc(float x, - float y, - float radius, - float start_angle, - float end_angle, +void CanvasPath::arc(double double_x, + double double_y, + double double_radius, + double double_start_angle, + double double_end_angle, bool anticlockwise, ExceptionState& exception_state) { + float x = base::saturated_cast<float>(double_x); + float y = base::saturated_cast<float>(double_y); + float radius = base::saturated_cast<float>(double_radius); + float start_angle = base::saturated_cast<float>(double_start_angle); + float end_angle = base::saturated_cast<float>(double_end_angle); if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(radius) || !std::isfinite(start_angle) || !std::isfinite(end_angle)) return; @@ -345,15 +377,22 @@ AdjustEndAngle(start_angle, end_angle, anticlockwise)); } -void CanvasPath::ellipse(float x, - float y, - float radius_x, - float radius_y, - float rotation, - float start_angle, - float end_angle, +void CanvasPath::ellipse(double double_x, + double double_y, + double double_radius_x, + double double_radius_y, + double double_rotation, + double double_start_angle, + double double_end_angle, bool anticlockwise, ExceptionState& exception_state) { + float x = base::saturated_cast<float>(double_x); + float y = base::saturated_cast<float>(double_y); + float radius_x = base::saturated_cast<float>(double_radius_x); + float radius_y = base::saturated_cast<float>(double_radius_y); + float rotation = base::saturated_cast<float>(double_rotation); + float start_angle = base::saturated_cast<float>(double_start_angle); + float end_angle = base::saturated_cast<float>(double_end_angle); if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(radius_x) || !std::isfinite(radius_y) || !std::isfinite(rotation) || !std::isfinite(start_angle) || !std::isfinite(end_angle)) @@ -392,7 +431,14 @@ adjusted_end_angle); } -void CanvasPath::rect(float x, float y, float width, float height) { +void CanvasPath::rect(double double_x, + double double_y, + double double_width, + double double_height) { + float x = base::saturated_cast<float>(double_x); + float y = base::saturated_cast<float>(double_y); + float width = base::saturated_cast<float>(double_width); + float height = base::saturated_cast<float>(double_height); if (!IsTransformInvertible()) return;
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h index 357ad28..38ede735 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h
@@ -46,38 +46,44 @@ virtual ~CanvasPath() = default; void closePath(); - void moveTo(float x, float y); - void lineTo(float x, float y); - void quadraticCurveTo(float cpx, float cpy, float x, float y); - void bezierCurveTo(float cp1x, - float cp1y, - float cp2x, - float cp2y, - float x, - float y); - void arcTo(float x0, - float y0, - float x1, - float y1, - float radius, + void moveTo(double double_x, double double_y); + void lineTo(double double_x, double double_y); + void quadraticCurveTo(double double_cpx, + double double_cpy, + double double_x, + double double_y); + void bezierCurveTo(double double_cp1x, + double double_cp1y, + double double_cp2x, + double double_cp2y, + double double_x, + double double_y); + void arcTo(double double_x1, + double double_y1, + double double_x2, + double double_y2, + double double_radius, ExceptionState&); - void arc(float x, - float y, - float radius, - float start_angle, - float end_angle, + void arc(double double_x, + double double_y, + double double_radius, + double double_start_angle, + double double_end_angle, bool anticlockwise, ExceptionState&); - void ellipse(float x, - float y, - float radius_x, - float radius_y, - float rotation, - float start_angle, - float end_angle, + void ellipse(double double_x, + double double_y, + double double_radius_x, + double double_radius_y, + double double_rotation, + double double_start_angle, + double double_end_angle, bool anticlockwise, ExceptionState&); - void rect(float x, float y, float width, float height); + void rect(double double_x, + double double_y, + double double_width, + double double_height); virtual bool IsTransformInvertible() const { return true; } virtual AffineTransform Transform() const {
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl index 81a279a2..0317df56 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl
@@ -7,12 +7,12 @@ interface mixin CanvasPath { // shared path API methods void closePath(); - void moveTo(unrestricted float x, unrestricted float y); - void lineTo(unrestricted float x, unrestricted float y); - void quadraticCurveTo(unrestricted float cpx, unrestricted float cpy, unrestricted float x, unrestricted float y); - void bezierCurveTo(unrestricted float cp1x, unrestricted float cp1y, unrestricted float cp2x, unrestricted float cp2y, unrestricted float x, unrestricted float y); - [RaisesException] void arcTo(unrestricted float x1, unrestricted float y1, unrestricted float x2, unrestricted float y2, unrestricted float radius); - void rect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height); - [RaisesException] void arc(unrestricted float x, unrestricted float y, unrestricted float radius, unrestricted float startAngle, unrestricted float endAngle, optional boolean anticlockwise = false); - [RaisesException] void ellipse(unrestricted float x, unrestricted float y, unrestricted float radiusX, unrestricted float radiusY, unrestricted float rotation, unrestricted float startAngle, unrestricted float endAngle, optional boolean anticlockwise = false); + void moveTo(unrestricted double x, unrestricted double y); + void lineTo(unrestricted double x, unrestricted double y); + void quadraticCurveTo(unrestricted double cpx, unrestricted double cpy, unrestricted double x, unrestricted double y); + void bezierCurveTo(unrestricted double cp1x, unrestricted double cp1y, unrestricted double cp2x, unrestricted double cp2y, unrestricted double x, unrestricted double y); + [RaisesException] void arcTo(unrestricted double x1, unrestricted double y1, unrestricted double x2, unrestricted double y2, unrestricted double radius); + void rect(unrestricted double x, unrestricted double y, unrestricted double width, unrestricted double height); + [RaisesException] void arc(unrestricted double x, unrestricted double y, unrestricted double radius, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false); + [RaisesException] void ellipse(unrestricted double x, unrestricted double y, unrestricted double radiusX, unrestricted double radiusY, unrestricted double rotation, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false); };
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl index 8253c607..3e62a53 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl
@@ -160,4 +160,4 @@ }; -CanvasRenderingContext2D implements CanvasPath; +CanvasRenderingContext2D includes CanvasPath;
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl b/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl index f2b4429..82032cca 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl +++ b/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl
@@ -35,4 +35,4 @@ [RaisesException] void addPath(Path2D path, optional DOMMatrix2DInit transform); }; -Path2D implements CanvasPath; +Path2D includes CanvasPath;
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl index 416eb4cb..2c77305 100644 --- a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl +++ b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl
@@ -106,4 +106,4 @@ [RuntimeEnabled=OffscreenCanvasText] attribute DOMString direction; // "inherit", "rtl", "ltr" (default: "inherit") }; -OffscreenCanvasRenderingContext2D implements CanvasPath; +OffscreenCanvasRenderingContext2D includes CanvasPath;
diff --git a/third_party/blink/renderer/modules/credentialmanager/federated_credential.idl b/third_party/blink/renderer/modules/credentialmanager/federated_credential.idl index efd7e22b..ac5d3021c0 100644 --- a/third_party/blink/renderer/modules/credentialmanager/federated_credential.idl +++ b/third_party/blink/renderer/modules/credentialmanager/federated_credential.idl
@@ -15,4 +15,4 @@ // TODO(mkwst): We don't really support this yet; it always returns ''. readonly attribute DOMString? protocol; }; -FederatedCredential implements CredentialUserData; +FederatedCredential includes CredentialUserData;
diff --git a/third_party/blink/renderer/modules/credentialmanager/password_credential.idl b/third_party/blink/renderer/modules/credentialmanager/password_credential.idl index 5aa501bd..4838796d 100644 --- a/third_party/blink/renderer/modules/credentialmanager/password_credential.idl +++ b/third_party/blink/renderer/modules/credentialmanager/password_credential.idl
@@ -12,4 +12,4 @@ ] interface PasswordCredential : Credential { readonly attribute DOMString password; }; -PasswordCredential implements CredentialUserData; +PasswordCredential includes CredentialUserData;
diff --git a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl index a9a9f03..0f22522 100644 --- a/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl +++ b/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl
@@ -80,4 +80,4 @@ sequence<unrestricted double> getLineDash(); attribute unrestricted double lineDashOffset; }; -PaintRenderingContext2D implements CanvasPath; +PaintRenderingContext2D includes CanvasPath;
diff --git a/third_party/blink/renderer/modules/geolocation/OWNERS b/third_party/blink/renderer/modules/geolocation/OWNERS index 2dbeb1a..51b1f3e2 100644 --- a/third_party/blink/renderer/modules/geolocation/OWNERS +++ b/third_party/blink/renderer/modules/geolocation/OWNERS
@@ -1,7 +1,5 @@ mattreynolds@chromium.org - -# Original (legacy) owner. mcasas@chromium.org # TEAM: device-dev@chromium.org -# COMPONENT: Blink>Geolocation +# COMPONENT: Blink>Location
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc b/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc index 5ac71bf5..dcaa915 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc
@@ -28,7 +28,7 @@ #include "third_party/blink/public/common/indexeddb/web_idb_types.h" #include "third_party/blink/renderer/platform/wtf/ascii_ctype.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" -#include "third_party/blink/renderer/platform/wtf/dtoa.h" +#include "third_party/blink/renderer/platform/wtf/dtoa/dtoa.h" #include "third_party/blink/renderer/platform/wtf/text/character_names.h" #include "third_party/blink/renderer/platform/wtf/text/unicode.h"
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/OWNERS b/third_party/blink/renderer/modules/mediacapturefromelement/OWNERS index 49f3612..14affd71 100644 --- a/third_party/blink/renderer/modules/mediacapturefromelement/OWNERS +++ b/third_party/blink/renderer/modules/mediacapturefromelement/OWNERS
@@ -1,7 +1,5 @@ emircan@chromium.org - -# Original (legacy) owner. mcasas@chromium.org -# TEAM: webrtc-dev@chromium.org +# TEAM: media-capture-and-streams@grotations.appspotmail.com # COMPONENT: Blink>MediaStream>CaptureFromElement
diff --git a/third_party/blink/renderer/modules/mediarecorder/OWNERS b/third_party/blink/renderer/modules/mediarecorder/OWNERS index 5f88414..c824512 100644 --- a/third_party/blink/renderer/modules/mediarecorder/OWNERS +++ b/third_party/blink/renderer/modules/mediarecorder/OWNERS
@@ -1,7 +1,5 @@ +mcasas@chromium.org peter@chromium.org -# Original (legacy) owner. -mcasas@chromium.org - # COMPONENT: Blink>MediaRecording -# TEAM: webrtc-dev@chromium.org +# TEAM: media-dev@chromium.org
diff --git a/third_party/blink/renderer/modules/mediastream/OWNERS b/third_party/blink/renderer/modules/mediastream/OWNERS index 77d16fa..fa857a6 100644 --- a/third_party/blink/renderer/modules/mediastream/OWNERS +++ b/third_party/blink/renderer/modules/mediastream/OWNERS
@@ -2,5 +2,5 @@ hbos@chromium.org tommi@chromium.org -# TEAM: webrtc-dev@chromium.org +# TEAM: media-capture-and-streams@grotations.appspotmail.com # COMPONENT: Blink>GetUserMedia
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker.idl b/third_party/blink/renderer/modules/service_worker/service_worker.idl index 8ee3e02..ab4fbd7 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker.idl +++ b/third_party/blink/renderer/modules/service_worker/service_worker.idl
@@ -52,4 +52,4 @@ attribute EventHandler onstatechange; }; -ServiceWorker implements AbstractWorker; +ServiceWorker includes AbstractWorker;
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 f78a6e4..f05841d 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
@@ -594,9 +594,9 @@ SingleCachedMetadataHandler* ServiceWorkerGlobalScope::CreateWorkerScriptCachedMetadataHandler( const KURL& script_url, - const Vector<uint8_t>* meta_data) { + std::unique_ptr<Vector<uint8_t>> meta_data) { return ServiceWorkerScriptCachedMetadataHandler::Create(this, script_url, - meta_data); + std::move(meta_data)); } ScriptPromise ServiceWorkerGlobalScope::fetch(ScriptState* script_state,
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h index 04d38a0e..16f79d1 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
@@ -186,7 +186,7 @@ ExceptionState&) override; SingleCachedMetadataHandler* CreateWorkerScriptCachedMetadataHandler( const KURL& script_url, - const Vector<uint8_t>* meta_data) override; + std::unique_ptr<Vector<uint8_t>> meta_data) override; void ExceptionThrown(ErrorEvent*) override; void DidReceiveResponseForClassicScript(
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc b/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc index fc05eac..cc88766 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc
@@ -15,11 +15,12 @@ ServiceWorkerScriptCachedMetadataHandler( WorkerGlobalScope* worker_global_scope, const KURL& script_url, - const Vector<uint8_t>* meta_data) + std::unique_ptr<Vector<uint8_t>> meta_data) : worker_global_scope_(worker_global_scope), script_url_(script_url) { - if (meta_data) - cached_metadata_ = CachedMetadata::CreateFromSerializedData( - meta_data->data(), meta_data->size()); + if (meta_data) { + cached_metadata_ = + CachedMetadata::CreateFromSerializedData(std::move(*meta_data)); + } } ServiceWorkerScriptCachedMetadataHandler::
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h b/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h index d39558322..46a52fa0 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h
@@ -22,14 +22,15 @@ static ServiceWorkerScriptCachedMetadataHandler* Create( WorkerGlobalScope* worker_global_scope, const KURL& script_url, - const Vector<uint8_t>* meta_data) { + std::unique_ptr<Vector<uint8_t>> meta_data) { return MakeGarbageCollected<ServiceWorkerScriptCachedMetadataHandler>( - worker_global_scope, script_url, meta_data); + worker_global_scope, script_url, std::move(meta_data)); } - ServiceWorkerScriptCachedMetadataHandler(WorkerGlobalScope*, - const KURL& script_url, - const Vector<uint8_t>* meta_data); + ServiceWorkerScriptCachedMetadataHandler( + WorkerGlobalScope*, + const KURL& script_url, + std::unique_ptr<Vector<uint8_t>> meta_data); ~ServiceWorkerScriptCachedMetadataHandler() override; void Trace(blink::Visitor*) override; void SetCachedMetadata(uint32_t data_type_id,
diff --git a/third_party/blink/renderer/modules/shapedetection/OWNERS b/third_party/blink/renderer/modules/shapedetection/OWNERS index bb37d31..2a126b8 100644 --- a/third_party/blink/renderer/modules/shapedetection/OWNERS +++ b/third_party/blink/renderer/modules/shapedetection/OWNERS
@@ -1,10 +1,8 @@ -reillyg@chromium.org - -# Original (legacy) owner. mcasas@chromium.org +reillyg@chromium.org per-file *_type_converter*.*=set noparent per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS # COMPONENT: Blink>ImageCapture -# TEAM: device-dev@chromium.org +# TEAM: media-dev@chromium.org
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.idl b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.idl index 08e5755..402e4f1 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.idl +++ b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.idl
@@ -6,6 +6,6 @@ DoNotCheckConstants, Exposed(Worker WebGL2ComputeContext, Window WebGL2ComputeContext) ] interface WebGL2ComputeRenderingContext { }; -WebGL2ComputeRenderingContext implements WebGLRenderingContextBase; -WebGL2ComputeRenderingContext implements WebGL2RenderingContextBase; -WebGL2ComputeRenderingContext implements WebGL2ComputeRenderingContextBase; +WebGL2ComputeRenderingContext includes WebGLRenderingContextBase; +WebGL2ComputeRenderingContext includes WebGL2RenderingContextBase; +WebGL2ComputeRenderingContext includes WebGL2ComputeRenderingContextBase;
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl index fedeb6c7..e039327 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl +++ b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl
@@ -102,5 +102,5 @@ void memoryBarrier(GLbitfield barriers); void memoryBarrierByRegion(GLbitfield barriers); }; -WebGL2ComputeRenderingContextBase implements WebGLRenderingContextBase; -WebGL2ComputeRenderingContextBase implements WebGL2RenderingContextBase; +WebGL2ComputeRenderingContextBase includes WebGLRenderingContextBase; +WebGL2ComputeRenderingContextBase includes WebGL2RenderingContextBase;
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.idl b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.idl index 7951887..0092b94 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.idl +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.idl
@@ -8,5 +8,5 @@ DoNotCheckConstants, Exposed(Worker OffscreenCanvas, Window StableBlinkFeatures) ] interface WebGL2RenderingContext { }; -WebGL2RenderingContext implements WebGLRenderingContextBase; -WebGL2RenderingContext implements WebGL2RenderingContextBase; +WebGL2RenderingContext includes WebGLRenderingContextBase; +WebGL2RenderingContext includes WebGL2RenderingContextBase;
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.idl b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.idl index 060d0be..1d3f5504 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.idl +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.idl
@@ -535,4 +535,4 @@ void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, [AllowShared] ArrayBufferView dstData, GLintptr offset); void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLintptr offset); }; -WebGL2RenderingContextBase implements WebGLRenderingContextBase; +WebGL2RenderingContextBase includes WebGLRenderingContextBase;
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context.idl b/third_party/blink/renderer/modules/webgl/webgl_rendering_context.idl index f8ac61a..f165428 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context.idl +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context.idl
@@ -29,4 +29,4 @@ DoNotCheckConstants, Exposed(Worker OffscreenCanvas, Window StableBlinkFeatures) ] interface WebGLRenderingContext { }; -WebGLRenderingContext implements WebGLRenderingContextBase; +WebGLRenderingContext includes WebGLRenderingContextBase;
diff --git a/third_party/blink/renderer/platform/exported/mediastream/OWNERS b/third_party/blink/renderer/platform/exported/mediastream/OWNERS index 32889cc..c205d4f9 100644 --- a/third_party/blink/renderer/platform/exported/mediastream/OWNERS +++ b/third_party/blink/renderer/platform/exported/mediastream/OWNERS
@@ -2,5 +2,5 @@ per-file media_stream_audio_processor*=aluebs@chromium.org -# TEAM: webrtc-dev@chromium.org +# TEAM: media-capture-and-streams@grotations.appspotmail.com # COMPONENT: Blink>GetUserMedia
diff --git a/third_party/blink/renderer/platform/graphics/color.cc b/third_party/blink/renderer/platform/graphics/color.cc index b2e5039..1a59ce5 100644 --- a/third_party/blink/renderer/platform/graphics/color.cc +++ b/third_party/blink/renderer/platform/graphics/color.cc
@@ -29,7 +29,7 @@ #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/decimal.h" -#include "third_party/blink/renderer/platform/wtf/dtoa.h" +#include "third_party/blink/renderer/platform/wtf/dtoa/dtoa.h" #include "third_party/blink/renderer/platform/wtf/hex_number.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
diff --git a/third_party/blink/renderer/platform/graphics/gradient.cc b/third_party/blink/renderer/platform/graphics/gradient.cc index 8e93a5a..9fbdaee 100644 --- a/third_party/blink/renderer/platform/graphics/gradient.cc +++ b/third_party/blink/renderer/platform/graphics/gradient.cc
@@ -98,14 +98,14 @@ void Gradient::FillSkiaStops(ColorBuffer& colors, OffsetBuffer& pos) const { if (stops_.IsEmpty()) { // A gradient with no stops must be transparent black. - pos.push_back(WebCoreFloatToSkScalar(0)); + pos.push_back(WebCoreDoubleToSkScalar(0)); colors.push_back(SK_ColorTRANSPARENT); } else if (stops_.front().stop > 0) { // Copy the first stop to 0.0. The first stop position may have a slight // rounding error, but we don't care in this float comparison, since // 0.0 comes through cleanly and people aren't likely to want a gradient // with a stop at (0 + epsilon). - pos.push_back(WebCoreFloatToSkScalar(0)); + pos.push_back(WebCoreDoubleToSkScalar(0)); if (color_filter_) { colors.push_back( color_filter_->filterColor(MakeSkColor(stops_.front().color))); @@ -115,7 +115,7 @@ } for (const auto& stop : stops_) { - pos.push_back(WebCoreFloatToSkScalar(stop.stop)); + pos.push_back(WebCoreDoubleToSkScalar(stop.stop)); if (color_filter_) colors.push_back(color_filter_->filterColor(MakeSkColor(stop.color))); else @@ -126,7 +126,7 @@ // comparison. DCHECK(!pos.IsEmpty()); if (pos.back() < 1) { - pos.push_back(WebCoreFloatToSkScalar(1)); + pos.push_back(WebCoreDoubleToSkScalar(1)); colors.push_back(colors.back()); } }
diff --git a/third_party/blink/renderer/platform/graphics/gradient.h b/third_party/blink/renderer/platform/graphics/gradient.h index 53eec6b..714b534e 100644 --- a/third_party/blink/renderer/platform/graphics/gradient.h +++ b/third_party/blink/renderer/platform/graphics/gradient.h
@@ -95,13 +95,13 @@ struct ColorStop { DISALLOW_NEW(); - float stop; + double stop; Color color; - ColorStop(float s, const Color& c) : stop(s), color(c) {} + ColorStop(double s, const Color& c) : stop(s), color(c) {} }; void AddColorStop(const ColorStop&); - void AddColorStop(float value, const Color& color) { + void AddColorStop(double value, const Color& color) { AddColorStop(ColorStop(value, color)); } void AddColorStops(const Vector<Gradient::ColorStop>&);
diff --git a/third_party/blink/renderer/platform/loader/fetch/cached_metadata.cc b/third_party/blink/renderer/platform/loader/fetch/cached_metadata.cc index 0da3bd5..677c2e0 100644 --- a/third_party/blink/renderer/platform/loader/fetch/cached_metadata.cc +++ b/third_party/blink/renderer/platform/loader/fetch/cached_metadata.cc
@@ -11,29 +11,35 @@ scoped_refptr<CachedMetadata> CachedMetadata::CreateFromSerializedData( const uint8_t* data, size_t size) { - // Ensure the data is big enough, otherwise discard the data. - if (size < kCachedMetaDataStart || - size > std::numeric_limits<wtf_size_t>::max()) { + if (size > std::numeric_limits<wtf_size_t>::max()) return nullptr; - } + Vector<uint8_t> copied_data; + copied_data.Append(data, static_cast<wtf_size_t>(size)); + return CreateFromSerializedData(std::move(copied_data)); +} + +scoped_refptr<CachedMetadata> CachedMetadata::CreateFromSerializedData( + Vector<uint8_t> data) { + // Ensure the data is big enough, otherwise discard the data. + if (data.size() < kCachedMetaDataStart) + return nullptr; // Ensure the marker matches, otherwise discard the data. - if (*reinterpret_cast<const uint32_t*>(data) != + if (*reinterpret_cast<const uint32_t*>(data.data()) != CachedMetadataHandler::kSingleEntry) { return nullptr; } - return base::AdoptRef( - new CachedMetadata(data, static_cast<wtf_size_t>(size))); + return base::AdoptRef(new CachedMetadata(std::move(data))); } -CachedMetadata::CachedMetadata(const uint8_t* data, wtf_size_t size) { + +CachedMetadata::CachedMetadata(Vector<uint8_t> data) { // Serialized metadata should have non-empty data. - DCHECK_GT(size, kCachedMetaDataStart); - DCHECK(data); + DCHECK_GT(data.size(), kCachedMetaDataStart); + DCHECK(!data.IsEmpty()); // Make sure that the first int in the data is the single entry marker. - CHECK_EQ(*reinterpret_cast<const uint32_t*>(data), + CHECK_EQ(*reinterpret_cast<const uint32_t*>(data.data()), CachedMetadataHandler::kSingleEntry); - serialized_data_.ReserveInitialCapacity(size); - serialized_data_.Append(data, size); + serialized_data_ = std::move(data); } CachedMetadata::CachedMetadata(uint32_t data_type_id,
diff --git a/third_party/blink/renderer/platform/loader/fetch/cached_metadata.h b/third_party/blink/renderer/platform/loader/fetch/cached_metadata.h index 2c1aeb1..8f7a5aa1 100644 --- a/third_party/blink/renderer/platform/loader/fetch/cached_metadata.h +++ b/third_party/blink/renderer/platform/loader/fetch/cached_metadata.h
@@ -65,6 +65,8 @@ static scoped_refptr<CachedMetadata> CreateFromSerializedData( const uint8_t* data, size_t); + static scoped_refptr<CachedMetadata> CreateFromSerializedData( + Vector<uint8_t> data); ~CachedMetadata() = default; @@ -87,7 +89,7 @@ } private: - CachedMetadata(const uint8_t* data, wtf_size_t); + CachedMetadata(Vector<uint8_t> data); CachedMetadata(uint32_t data_type_id, const uint8_t* data, wtf_size_t); // Since the serialization format supports random access, storing it in
diff --git a/third_party/blink/renderer/platform/wtf/BUILD.gn b/third_party/blink/renderer/platform/wtf/BUILD.gn index f4a73898..a8837798 100644 --- a/third_party/blink/renderer/platform/wtf/BUILD.gn +++ b/third_party/blink/renderer/platform/wtf/BUILD.gn
@@ -56,8 +56,6 @@ "decimal.h", "deque.h", "doubly_linked_list.h", - "dtoa.cc", - "dtoa.h", "dtoa/bignum-dtoa.cc", "dtoa/bignum-dtoa.h", "dtoa/bignum.cc", @@ -69,6 +67,8 @@ "dtoa/double-conversion.cc", "dtoa/double-conversion.h", "dtoa/double.h", + "dtoa/dtoa.cc", + "dtoa/dtoa.h", "dtoa/fast-dtoa.cc", "dtoa/fast-dtoa.h", "dtoa/fixed-dtoa.cc",
diff --git a/third_party/blink/renderer/platform/wtf/dtoa.cc b/third_party/blink/renderer/platform/wtf/dtoa/dtoa.cc similarity index 98% rename from third_party/blink/renderer/platform/wtf/dtoa.cc rename to third_party/blink/renderer/platform/wtf/dtoa/dtoa.cc index 25ea1e6..0e47ce5 100644 --- a/third_party/blink/renderer/platform/wtf/dtoa.cc +++ b/third_party/blink/renderer/platform/wtf/dtoa/dtoa.cc
@@ -33,7 +33,7 @@ * file. */ -#include "third_party/blink/renderer/platform/wtf/dtoa.h" +#include "third_party/blink/renderer/platform/wtf/dtoa/dtoa.h" #include <string.h> #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
diff --git a/third_party/blink/renderer/platform/wtf/dtoa.h b/third_party/blink/renderer/platform/wtf/dtoa/dtoa.h similarity index 96% rename from third_party/blink/renderer/platform/wtf/dtoa.h rename to third_party/blink/renderer/platform/wtf/dtoa/dtoa.h index 86bec2e..4ebfc70 100644 --- a/third_party/blink/renderer/platform/wtf/dtoa.h +++ b/third_party/blink/renderer/platform/wtf/dtoa/dtoa.h
@@ -18,8 +18,8 @@ * */ -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_DTOA_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_DTOA_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_DTOA_DTOA_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_DTOA_DTOA_H_ #include "third_party/blink/renderer/platform/wtf/ascii_ctype.h" #include "third_party/blink/renderer/platform/wtf/dtoa/double-conversion.h" @@ -77,10 +77,10 @@ } // namespace WTF -using WTF::NumberToStringBuffer; -using WTF::NumberToString; using WTF::NumberToFixedPrecisionString; using WTF::NumberToFixedWidthString; +using WTF::NumberToString; +using WTF::NumberToStringBuffer; using WTF::ParseDouble; #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_DTOA_H_
diff --git a/third_party/blink/renderer/platform/wtf/dtoa_test.cc b/third_party/blink/renderer/platform/wtf/dtoa_test.cc index f00c2885..eb60c54 100644 --- a/third_party/blink/renderer/platform/wtf/dtoa_test.cc +++ b/third_party/blink/renderer/platform/wtf/dtoa_test.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/platform/wtf/dtoa.h" +#include "third_party/blink/renderer/platform/wtf/dtoa/dtoa.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/third_party/blink/renderer/platform/wtf/text/atomic_string.cc b/third_party/blink/renderer/platform/wtf/text/atomic_string.cc index b66101ad..ddd988b 100644 --- a/third_party/blink/renderer/platform/wtf/text/atomic_string.cc +++ b/third_party/blink/renderer/platform/wtf/text/atomic_string.cc
@@ -23,7 +23,7 @@ #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" -#include "third_party/blink/renderer/platform/wtf/dtoa.h" +#include "third_party/blink/renderer/platform/wtf/dtoa/dtoa.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string_table.h" #include "third_party/blink/renderer/platform/wtf/text/string_impl.h"
diff --git a/third_party/blink/renderer/platform/wtf/text/string_builder.cc b/third_party/blink/renderer/platform/wtf/text/string_builder.cc index d2482d0..40288c2 100644 --- a/third_party/blink/renderer/platform/wtf/text/string_builder.cc +++ b/third_party/blink/renderer/platform/wtf/text/string_builder.cc
@@ -28,7 +28,7 @@ #include <algorithm> #include "base/optional.h" -#include "third_party/blink/renderer/platform/wtf/dtoa.h" +#include "third_party/blink/renderer/platform/wtf/dtoa/dtoa.h" #include "third_party/blink/renderer/platform/wtf/text/integer_to_string_conversion.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/third_party/blink/renderer/platform/wtf/text/string_to_number.cc b/third_party/blink/renderer/platform/wtf/text/string_to_number.cc index a3d4dd9..7136eb9e 100644 --- a/third_party/blink/renderer/platform/wtf/text/string_to_number.cc +++ b/third_party/blink/renderer/platform/wtf/text/string_to_number.cc
@@ -6,7 +6,7 @@ #include <type_traits> #include "third_party/blink/renderer/platform/wtf/ascii_ctype.h" -#include "third_party/blink/renderer/platform/wtf/dtoa.h" +#include "third_party/blink/renderer/platform/wtf/dtoa/dtoa.h" #include "third_party/blink/renderer/platform/wtf/text/string_impl.h" namespace WTF {
diff --git a/third_party/blink/renderer/platform/wtf/text/wtf_string.cc b/third_party/blink/renderer/platform/wtf/text/wtf_string.cc index 5dd32b4..8112baa1 100644 --- a/third_party/blink/renderer/platform/wtf/text/wtf_string.cc +++ b/third_party/blink/renderer/platform/wtf/text/wtf_string.cc
@@ -28,7 +28,7 @@ #include "base/strings/string_util.h" #include "build/build_config.h" #include "third_party/blink/renderer/platform/wtf/ascii_ctype.h" -#include "third_party/blink/renderer/platform/wtf/dtoa.h" +#include "third_party/blink/renderer/platform/wtf/dtoa/dtoa.h" #include "third_party/blink/renderer/platform/wtf/hex_number.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" #include "third_party/blink/renderer/platform/wtf/text/character_names.h"
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG index 8379690..0417bf17 100644 --- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
@@ -301,12 +301,13 @@ crbug.com/591099 fast/backgrounds/quirks-mode-line-box-backgrounds.html [ Failure ] crbug.com/591099 fast/block/float/4145535Crash.html [ Pass ] crbug.com/591099 fast/borders/inline-mask-overlay-image-outset-vertical-rl.html [ Failure ] -crbug.com/591099 fast/canvas/OffscreenCanvas-copyImage.html [ Pass ] +crbug.com/591099 fast/canvas/OffscreenCanvas-copyImage.html [ Failure Pass ] crbug.com/591099 fast/css-intrinsic-dimensions/height-css-tables-collapsed.html [ Failure Pass ] crbug.com/591099 fast/css-intrinsic-dimensions/height-positioned.html [ Pass ] -crbug.com/591099 fast/css-intrinsic-dimensions/height-tables.html [ Failure Pass ] +crbug.com/591099 fast/css-intrinsic-dimensions/height-tables.html [ Pass ] crbug.com/591099 fast/css/absolute-inline-alignment-2.html [ Pass ] crbug.com/835484 fast/css/outline-narrowLine.html [ Failure ] +crbug.com/591099 fast/css/outline-offset-large.html [ Failure ] crbug.com/855279 fast/css/text-overflow-ellipsis-vertical-hittest.html [ Pass ] crbug.com/591099 fast/css3-text/css3-text-decoration/text-underline-position/text-underline-position-under.html [ Failure ] crbug.com/591099 fast/events/before-unload-return-value-from-listener.html [ Pass ] @@ -329,13 +330,12 @@ crbug.com/591099 fast/writing-mode/table-percent-width-quirk.html [ Pass ] crbug.com/591099 http/tests/appcache/non-html.xhtml [ Crash Pass ] crbug.com/591099 http/tests/csspaint/invalidation-border-image.html [ Pass ] -crbug.com/591099 http/tests/devtools/elements/highlight/highlight-css-grid.js [ Failure ] crbug.com/591099 http/tests/devtools/sources/debugger-frameworks/frameworks-jquery.js [ Crash Pass ] crbug.com/591099 http/tests/devtools/sources/debugger/debugger-proto-property.js [ Pass ] crbug.com/591099 http/tests/devtools/tracing-session-id.js [ Pass ] crbug.com/591099 http/tests/devtools/tracing/console-timeline.js [ Pass ] crbug.com/591099 http/tests/html/validation-bubble-oopif-clip.html [ Pass ] -crbug.com/591099 http/tests/media/autoplay/document-user-activation-cross-origin-feature-policy-disabled.html [ Failure ] +crbug.com/591099 http/tests/media/autoplay/document-user-activation-cross-origin-feature-policy-disabled.html [ Failure Pass ] crbug.com/591099 http/tests/media/video-load-metadata-decode-error.html [ Pass ] crbug.com/591099 http/tests/security/inactive-document-with-empty-security-origin.html [ Pass ] crbug.com/591099 http/tests/security/upgrade-insecure-requests/iframe-upgrade.https.html [ Crash ] @@ -357,7 +357,7 @@ crbug.com/916511 virtual/composite-after-paint/paint/background/scrolling-background-with-negative-z-child.html [ Crash ] crbug.com/591099 virtual/composite-after-paint/paint/invalidation/box/margin.html [ Failure Pass ] Bug(none) virtual/disable-blink-gen-property-trees/ [ Skip ] -crbug.com/917392 virtual/display-lock/display-lock/lock-after-append/acquire-after-resize.html [ Failure Pass ] +crbug.com/917392 virtual/display-lock/display-lock/lock-after-append/acquire-after-resize.html [ Failure ] crbug.com/591099 virtual/display-lock/display-lock/lock-after-append/measure-forced-layout-after-commit.html [ Failure ] crbug.com/591099 virtual/display-lock/display-lock/lock-after-append/measure-forced-layout.html [ Failure ] crbug.com/591099 virtual/display-lock/display-lock/lock-after-append/measure-updated-layout.html [ Failure ] @@ -381,7 +381,6 @@ crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/compositor-touch-hit-rects-list-translate.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/compositor-touch-hit-rects.html [ Failure ] crbug.com/591099 virtual/new-remote-playback-pipeline/ [ Skip ] -crbug.com/591099 virtual/nobinary-for-devtools/http/tests/devtools/elements/highlight/highlight-css-grid.js [ Failure ] crbug.com/591099 virtual/nobinary-for-devtools/http/tests/devtools/sources/debugger-frameworks/frameworks-jquery.js [ Crash Pass ] crbug.com/591099 virtual/nobinary-for-devtools/http/tests/devtools/tracing-session-id.js [ Pass ] crbug.com/591099 virtual/nobinary-for-devtools/http/tests/devtools/tracing/console-timeline.js [ Pass ] @@ -400,6 +399,6 @@ crbug.com/591099 virtual/user-activation-v2/fast/events/touch/compositor-touch-hit-rects.html [ Failure ] crbug.com/591099 virtual/video-surface-layer/media/W3C/video/networkState/networkState_during_progress.html [ Pass ] crbug.com/591099 virtual/video-surface-layer/media/color-profile-video-seek-filter.html [ Pass ] -crbug.com/591099 virtual/video-surface-layer/media/stable/video-object-fit-stable.html [ Pass ] +crbug.com/591099 virtual/video-surface-layer/media/stable/video-object-fit-stable.html [ Failure Pass ] crbug.com/591099 virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCIceTransport-extension.https.html [ Failure Pass ] crbug.com/591099 vr/getFrameData_oneframeupdate.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index b9763d9..fe99636 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -429,6 +429,27 @@ crbug.com/417223 external/wpt/css/css-position/position-relative-table-tr-top-absolute-child.html [ Failure ] crbug.com/417223 external/wpt/css/css-position/position-relative-table-tr-top.html [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-color-001.xht [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-position-above-left-001.xht [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-position-above-left-002.xht [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-position-above-right-001.xht [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-position-above-right-002.xht [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-position-below-left-001.xht [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-position-below-left-002.xht [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-position-below-right-001.xht [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-position-below-right-002.xht [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-style-002.html [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-style-006.html [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-style-007.html [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-style-008.html [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-style-010.html [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-style-012.html [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-style-021.html [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-style-filled-001.xht [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-style-open-001.xht [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-style-shape-001.xht [ Failure ] +crbug.com/949909 external/wpt/css/css-text-decor/text-emphasis-style-string-001.xht [ Failure ] + crbug.com/722825 media/controls/video-enter-exit-fullscreen-while-hovering-shows-controls.html [ Timeout Pass ] crbug.com/722825 virtual/video-surface-layer/media/controls/video-enter-exit-fullscreen-while-hovering-shows-controls.html [ Timeout Pass ] crbug.com/876050 virtual/video-surface-layer/media/controls/text-track-menu-pointer-selection.html [ Pass Failure ] @@ -2158,27 +2179,6 @@ crbug.com/905315 external/wpt/css/css-text/word-break/word-break-break-word-overflow-wrap-interactions.html [ Skip ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-color-001.xht [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-position-above-left-001.xht [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-position-above-left-002.xht [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-position-above-right-001.xht [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-position-above-right-002.xht [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-position-below-left-001.xht [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-position-below-left-002.xht [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-position-below-right-001.xht [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-position-below-right-002.xht [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-style-002.html [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-style-006.html [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-style-007.html [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-style-008.html [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-style-010.html [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-style-012.html [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-style-021.html [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-style-filled-001.xht [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-style-open-001.xht [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-style-shape-001.xht [ Failure ] -crbug.com/666657 external/wpt/css/css-text-decor/text-emphasis-style-string-001.xht [ Failure ] - # These are added to W3CImportExpectations as Skip, remove when next import is done. crbug.com/666657 external/wpt/css/css-text/hanging-punctuation [ Skip ]
diff --git a/third_party/blink/web_tests/accessibility/css-alt-text.html b/third_party/blink/web_tests/accessibility/css-alt-text.html index 796eb38d..8dd7e9ef 100644 --- a/third_party/blink/web_tests/accessibility/css-alt-text.html +++ b/third_party/blink/web_tests/accessibility/css-alt-text.html
@@ -198,3 +198,66 @@ }, "Pseudo elements that don't support the content property should not impact the accessibility tree if the property and alt text is supplied."); </script> + +<div id="divcontent">Div text content</div> +<style> +#divcontent { + content: url(bullet.png) / "alt"; +} +</style> + +<script> + +test(function(t) { + var domAXNode = accessibilityController.accessibleElementById("divcontent"); + assert_equals(domAXNode.role, "AXRole: AXImage"); + assert_equals(domAXNode.name, "alt"); +},"Non pseudo elements which support the content property should have the alt text applied to the image that replaces their content."); + +</script> + +<!--- The following test cases are merely here to test that the addition of alt text support has not altered the default behaviour if the content property is incorrectly supplied --> + +<div id="divdoubleimage">DOM Text</div> + +<style> +#divdoubleimage { + content: url(bullet.png) url(bullet.png) / "alt"; +} +</style> + +<script> + +test(function(t) { + var domAXNode = accessibilityController.accessibleElementById("divdoubleimage"); + assert_equals(domAXNode.role, "AXRole: AXGenericContainer"); + assert_equals(domAXNode.childrenCount, 1); + + var childAXNode = domAXNode.childAtIndex(0); + assert_equals(childAXNode.role, "AXRole: AXStaticText"); + assert_equals(childAXNode.name, "DOM Text"); +},"A DOM Node with more than one image and alternative text should not impact the accessibility tree."); + +</script> + +<div id="divtextcontent">DOM Text</div> + +<style> +#divtextcontent { + content: "text content replacement" / "alt"; +} +</style> + +<script> + +test(function(t) { + var domAXNode = accessibilityController.accessibleElementById("divtextcontent"); + assert_equals(domAXNode.role, "AXRole: AXGenericContainer"); + assert_equals(domAXNode.childrenCount, 1); + + var childAXNode = domAXNode.childAtIndex(0); + assert_equals(childAXNode.role, "AXRole: AXStaticText"); + assert_equals(childAXNode.name, "DOM Text"); +},"A DOM Node with text replacement content and alt text should not impact the accessibility tree."); + +</script>
diff --git a/third_party/blink/web_tests/accessibility/editable-anonymous-block.html b/third_party/blink/web_tests/accessibility/editable-anonymous-block.html index e4dfa764..833a949f 100644 --- a/third_party/blink/web_tests/accessibility/editable-anonymous-block.html +++ b/third_party/blink/web_tests/accessibility/editable-anonymous-block.html
@@ -14,13 +14,11 @@ assert_not_equals(editable, null); assert_equals(editable.childrenCount, 2); - let anonymousBlock = editable.childAtIndex(0); - assert_not_equals(anonymousBlock, null); - assert_equals(anonymousBlock.childrenCount, 1); - assert_equals(anonymousBlock.childAtIndex(0).role, 'AXRole: AXStaticText'); - assert_equals(anonymousBlock.childAtIndex(0).name, 'Hello'); - - assert_true(anonymousBlock.isEditable); - assert_true(anonymousBlock.isRichlyEditable); - }, 'Ensure that anonymous blocks inside content editables are not ignored and are marked as editable.'); + let staticText = editable.childAtIndex(0); + assert_not_equals(staticText, null); + assert_equals(staticText.role, 'AXRole: AXStaticText'); + assert_equals(staticText.name, 'Hello'); + assert_true(staticText.isEditable); + assert_true(staticText.isRichlyEditable); + }, 'This no longer really tests anything'); </script>
diff --git a/third_party/blink/web_tests/accessibility/scroll-div-horiz-sends-notification.html b/third_party/blink/web_tests/accessibility/scroll-div-horiz-sends-notification.html index 144b5b2f..b96bbf4 100644 --- a/third_party/blink/web_tests/accessibility/scroll-div-horiz-sends-notification.html +++ b/third_party/blink/web_tests/accessibility/scroll-div-horiz-sends-notification.html
@@ -35,22 +35,25 @@ <script> async_test_after_layout_and_paint((t) => { - var container = document.getElementById('container'); + var container = document.getElementById('container'); - accessibilityController.addNotificationListener(function (target, notification) { - if (target.role == 'AXRole: AXGenericContainer') { - console.log('Got notification on container div'); - assert_equals(container.scrollLeft, 500); - t.done(); - } - }); + accessibilityController.addNotificationListener(t.step_func((target, notification) => { + if (target.role == 'AXRole: AXGenericContainer') { + console.log('Got notification on container div'); + assert_equals(container.scrollLeft, 500); + t.done(); + } + })); - window.setTimeout(function() { - container.scrollLeft = 500; - }, 0); + window.setTimeout(function() { + container.scrollLeft = 500; + }, 0); + + window.setTimeout(t.step_func_done(() => { + assert_unreached(); + }), 200); }, "This test ensures that scrolling the window sends a notification."); - </script> </body>
diff --git a/third_party/blink/web_tests/accessibility/scroll-div-sends-notification.html b/third_party/blink/web_tests/accessibility/scroll-div-sends-notification.html index 30ed8c2..987ba4a4 100644 --- a/third_party/blink/web_tests/accessibility/scroll-div-sends-notification.html +++ b/third_party/blink/web_tests/accessibility/scroll-div-sends-notification.html
@@ -1,9 +1,9 @@ <!DOCTYPE HTML> <html> <head> - <script src="../resources/testharness.js"></script> - <script src="../resources/testharnessreport.js"></script> - <script src="../resources/run-after-layout-and-paint.js"></script> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script src="../resources/run-after-layout-and-paint.js"></script> <style> .container { padding: 100px; @@ -30,22 +30,25 @@ <script> async_test_after_layout_and_paint((t) => { - var container = document.getElementById('container'); + var container = document.getElementById('container'); - accessibilityController.addNotificationListener(function (target, notification) { - if (target.role == 'AXRole: AXGenericContainer') { - console.log('Got notification on container div'); - assert_equals(container.scrollTop, 500); - t.done(); - } - }); + accessibilityController.addNotificationListener(t.step_func((target, notification) => { + if (target.role == 'AXRole: AXGenericContainer') { + console.log('Got notification on container div'); + assert_equals(container.scrollTop, 500); + accessibilityController.removeNotificationListener(); + t.done(); + } + })); - window.setTimeout(function() { - container.scrollTop = 500; - }, 0); + window.setTimeout(function() { + container.scrollTop = 500; + }, 0); + window.setTimeout(t.step_func_done(() => { + assert_unreached(); + }), 200); }, "This test ensures that scrolling the window sends a notification."); - </script> </body>
diff --git a/third_party/blink/web_tests/accessibility/scroll-window-horiz-sends-notification.html b/third_party/blink/web_tests/accessibility/scroll-window-horiz-sends-notification.html index 6fd610d9..625aab5 100644 --- a/third_party/blink/web_tests/accessibility/scroll-window-horiz-sends-notification.html +++ b/third_party/blink/web_tests/accessibility/scroll-window-horiz-sends-notification.html
@@ -1,9 +1,9 @@ <!DOCTYPE HTML> <html> <head> - <script src="../resources/testharness.js"></script> - <script src="../resources/testharnessreport.js"></script> - <script src="../resources/run-after-layout-and-paint.js"></script> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script src="../resources/run-after-layout-and-paint.js"></script> <style> .bigbutton { display:block; @@ -21,21 +21,24 @@ <script> async_test_after_layout_and_paint((t) => { + window.scrollTo(0, 0); + assert_equals(window.pageXOffset, 0); - window.scrollTo(0, 0); - assert_equals(window.pageXOffset, 0); + accessibilityController.addNotificationListener(t.step_func((target, notification) => { + if (target.role == 'AXRole: AXWebArea' && notification == 'ScrollPositionChanged') { + console.log('Got notification on web area'); + accessibilityController.removeNotificationListener(); + assert_equals(window.pageXOffset, 500); + t.done(); + } + })); - accessibilityController.addNotificationListener(function (target, notification) { - if (target.role == 'AXRole: AXWebArea' && notification == 'ScrollPositionChanged') { - console.log('Got notification on web area'); - assert_equals(window.pageXOffset, 500); - t.done()(); - } - }); - - window.setTimeout(function() { - window.scrollTo(500, 0); - }, 0); + window.setTimeout(function() { + window.scrollTo(500, 0); + }, 0); + window.setTimeout(t.step_func_done(() => { + assert_unreached(); + }), 200); }, "This test ensures that scrolling the window sends a notification."); </script>
diff --git a/third_party/blink/web_tests/accessibility/scroll-window-sends-notification.html b/third_party/blink/web_tests/accessibility/scroll-window-sends-notification.html index 4a21da6..084f0fa 100644 --- a/third_party/blink/web_tests/accessibility/scroll-window-sends-notification.html +++ b/third_party/blink/web_tests/accessibility/scroll-window-sends-notification.html
@@ -1,9 +1,9 @@ <!DOCTYPE HTML> <html> <head> - <script src="../resources/testharness.js"></script> - <script src="../resources/testharnessreport.js"></script> - <script src="../resources/run-after-layout-and-paint.js"></script> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script src="../resources/run-after-layout-and-paint.js"></script> <style> .bigbutton { display:block; @@ -22,23 +22,27 @@ <script> async_test_after_layout_and_paint((t) => { - window.scrollTo(0, 0); - assert_equals(window.pageYOffset, 0); + window.scrollTo(0, 0); + assert_equals(window.pageXOffset, 0); - accessibilityController.addNotificationListener(function (target, notification) { - if (target.role == 'AXRole: AXWebArea' && notification == 'ScrollPositionChanged') { - console.log('Got notification on web area'); - assert_equals(window.pageYOffset, 500); - t.done() - } - }); + accessibilityController.addNotificationListener(t.step_func((target, notification) => { + if (target.role == 'AXRole: AXWebArea' && notification == 'ScrollPositionChanged') { + console.log('Got notification on web area'); + accessibilityController.removeNotificationListener(); + assert_equals(window.pageYOffset, 500); + t.done(); + } + })); - window.setTimeout(function() { - window.scrollTo(0, 500); - }, 0); + window.setTimeout(function() { + window.scrollTo(0, 500); + }, 0); + + window.setTimeout(t.step_func_done(() => { + assert_unreached(); + }), 500); }, "This test ensures that scrolling the window sends a notification."); - </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/common/security-features/resources/common.js b/third_party/blink/web_tests/external/wpt/common/security-features/resources/common.js index 8b9bd0d..b18097b1 100644 --- a/third_party/blink/web_tests/external/wpt/common/security-features/resources/common.js +++ b/third_party/blink/web_tests/external/wpt/common/security-features/resources/common.js
@@ -192,17 +192,62 @@ doBindEvents); } -/** - * requestVia*() functions return promises that are resolved on successful - * requests with objects of the same "type", i.e. objects that contains - * the same sets of keys that are fixed within one category of tests (e.g. - * within wpt/referrer-policy tests). - * wrapResult() (that should be defined outside this file) is used to convert - * the response bodies of subresources into the expected result objects in some - * cases, and in other cases the result objects are constructed more directly. - * TODO(https://crbug.com/906850): Clean up the semantics around this, e.g. - * use (or not use) wrapResult() consistently, unify the arguments, etc. - */ +function wrapResult(server_data) { + if (typeof(server_data) === "string") { + throw server_data; + } + return { + referrer: server_data.headers.referer, + headers: server_data.headers + } +} + +// `requestVia*()` functions return promises that are resolved on successful +// requests with objects with the following keys: +// - `headers`: HTTP request headers sent to server. +// - `referrer`: Referrer. +// - `location`: The URL of the subresource. +// +// Category 1: +// `headers`: set. +// `referrer`: set via `document.referrer`. +// `location`: set via `document.location`. +// See `template/document.html.template`. +// Category 2: +// `headers`: set. +// `referrer`: set to `headers.referer` by `wrapResult()`. +// `location`: not set. +// Category 3: +// All the keys listed above are NOT set. +// +// -------------------------------- -------- -------------------------- +// Function name Category Used in +// -------- ------- --------- +// referrer mixed- upgrade- +// policy content insecure- +// policy content request +// -------------------------------- -------- -------- ------- --------- +// requestViaAnchor 1 Y Y - +// requestViaArea 1 Y Y - +// requestViaAudio 3 - Y - +// requestViaDedicatedWorker 2 Y Y Y +// requestViaFetch 2 Y Y - +// requestViaForm 3 - Y - +// requestViaIframe 1 Y Y - +// requestViaImage 3 - Y - +// requestViaImageForReferrerPolicy 2 Y - - +// requestViaLinkPrefetch 3 - Y - +// requestViaLinkStylesheet 3 - Y - +// requestViaObject 3 - Y - +// requestViaPicture 3 - Y - +// requestViaScript 2 Y Y - +// requestViaSendBeacon 3 - Y - +// requestViaSharedWorker 2 Y - - +// requestViaVideo 3 - Y - +// requestViaWebSocket 3 - Y - +// requestViaWorklet 3 - Y Y +// requestViaXhr 2 Y Y - +// -------------------------------- -------- -------- ------- --------- /** * Creates a new iframe, binds load and error events, sets the src attribute and @@ -383,8 +428,9 @@ function dedicatedWorkerUrlThatFetches(url) { return `data:text/javascript, fetch('${url}') - .then(() => postMessage(''), - () => postMessage(''));`; + .then(r => r.json()) + .then(j => postMessage(j)) + .catch((e) => postMessage(e.message));`; } function workerUrlThatImports(url) {
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html b/third_party/blink/web_tests/external/wpt/content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html index 692db02..bf655a2 100644 --- a/third_party/blink/web_tests/external/wpt/content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html +++ b/third_party/blink/web_tests/external/wpt/content-security-policy/securitypolicyviolation/upgrade-insecure-requests-reporting.https.html
@@ -10,7 +10,7 @@ if (e.effectiveDirective == effective_directive) resolve(e); }); - }); + }); } async_test(t => { @@ -70,7 +70,7 @@ window.addEventListener("message", t.step_func(e => { if (e.source == i.contentWindow) { - if (e.data == (new URL(url)).origin) { + if (e.data.location == url) { waitForViolation(window, "frame-src") .then(t.step_func(e => { reported = true; @@ -78,7 +78,7 @@ t.done(); })); i.contentWindow.location.href = navigate_to; - } else if (e.data == (new URL(upgraded)).origin) { + } else if (e.data.location == upgraded) { loaded = true; if (reported) t.done();
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-image-tentative.sub.html b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-image-tentative.sub.html index e277d9e..a9e2b295 100644 --- a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-image-tentative.sub.html +++ b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-image-tentative.sub.html
@@ -26,7 +26,7 @@ <body> <p>Image inserted further below.</p> <div id="image-container"> - <img id="off" load="eager" src="http://{{hosts[alt][www1]}}:{{ports[http][0]}}/feature-policy/experimental-features/resources/lazyload.png"></img> + <img id="off" loading="eager" src="http://{{hosts[alt][www1]}}:{{ports[http][0]}}/feature-policy/experimental-features/resources/lazyload.png"></img> </div> <script> var img = document.querySelector("img"); @@ -35,11 +35,11 @@ target.load_complete = wait_for_load(target).then(() => target.did_load = true ); }); - // Sanity-check: Verify that when feature-policy 'lazyload' is enabled, the lazyload attribute - // value 'OFF' works as expected (images load immediately). + // Sanity-check: Verify that when feature-policy 'lazyload' is enabled, the attribute + // loading='eager' works as expected (images load immediately). promise_test( async(t) => { await window.load_complete; assert_true(img.did_load, "Image should have loaded."); - }, "When feature is enabled, load=eager works as expected."); + }, "When feature is enabled, loading=eager works as expected."); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html index ebed07b..3a2f469 100644 --- a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html +++ b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html
@@ -31,12 +31,12 @@ window.scrollTo(0, 0); - // Sanity-check: Make sure load='lazy' works as intended. + // Sanity-check: Make sure loading='lazy' works as intended. promise_test(async(t) => { - // Add a frame with load="lazy". + // Add a frame with loading="lazy". let frame_on = createIframe(document.body, { id: "ON", - load: "lazy", + loading: "lazy", src: `${cross_origin_url}?id=ON` }); // Sanity-check: The frame is not visible. @@ -48,17 +48,17 @@ await waitForMessageOrTimeout(t, "ON", load_timeout); assert_equals(msg_or_timeout_attr_on, expected_timeout_msg, - "With load='lazy', the frame should not load."); + "With loading='lazy', the frame should not load."); }, "Sanity-check: Contents do not load immediately (no eager-loading) " + - "when the load attribute is 'lazy' and frame is in viewport."); + "when the loading attribute is 'lazy' and frame is in viewport."); // When feature is enabled, a frame can turn off lazy loading by setting the // attribute to 'off'. promise_test(async(t) => { - // Add a frame with load="eager". + // Add a frame with loading="eager". let frame_off = createIframe(document.body, { id: "OFF", - load: "eager", + loading: "eager", src: `${cross_origin_url}?id=OFF` }); // Sanity-check: The frame is not visible. @@ -71,7 +71,7 @@ assert_equals(msg_or_timeout_attr_off, expected_load_msg, - "With load='eager', the frame should load."); + "With loading='eager', the frame should load."); }, "When 'lazyload' feature is enabled, a frame can avoid lazyloading by " + - "setting 'load' attribute to 'eager'"); + "setting 'loading' attribute to 'eager'"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/geolocation-API/OWNERS b/third_party/blink/web_tests/external/wpt/geolocation-API/OWNERS index 61e5876..6d678d86 100644 --- a/third_party/blink/web_tests/external/wpt/geolocation-API/OWNERS +++ b/third_party/blink/web_tests/external/wpt/geolocation-API/OWNERS
@@ -1,5 +1,3 @@ # TEAM: device-dev@chromium.org -# COMPONENT: Blink>Geolocation - -# Original (legacy) owner. +# COMPONENT: Blink>Location mcasas@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/html-media-capture/OWNERS b/third_party/blink/web_tests/external/wpt/html-media-capture/OWNERS index d96b9bf..5db6e74 100644 --- a/third_party/blink/web_tests/external/wpt/html-media-capture/OWNERS +++ b/third_party/blink/web_tests/external/wpt/html-media-capture/OWNERS
@@ -1,4 +1,4 @@ # TEAM: media-dev@chromium.org # COMPONENT: Blink>ImageCapture - rijubrata.bhaumik@intel.com +mcasas@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-record/OWNERS b/third_party/blink/web_tests/external/wpt/mediacapture-record/OWNERS index 9c7779b..681555b 100644 --- a/third_party/blink/web_tests/external/wpt/mediacapture-record/OWNERS +++ b/third_party/blink/web_tests/external/wpt/mediacapture-record/OWNERS
@@ -1,5 +1,3 @@ -# TEAM: webrtc-dev@chromium.org +# TEAM: media-dev@chromium.org # COMPONENT: Blink>MediaRecording - -# Original (legacy) owner. mcasas@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/mixed-content/generic/mixed-content-test-case.js b/third_party/blink/web_tests/external/wpt/mixed-content/generic/mixed-content-test-case.js index a50b61c7..e7b0baa 100644 --- a/third_party/blink/web_tests/external/wpt/mixed-content/generic/mixed-content-test-case.js +++ b/third_party/blink/web_tests/external/wpt/mixed-content/generic/mixed-content-test-case.js
@@ -3,11 +3,6 @@ * @author burnik@google.com (Kristijan Burnik) */ -function wrapResult(server_data) { - // Currently the returned value is not used in mixed-content tests. - return null; -} - /** * MixedContentTestCase exercises all the tests for checking browser behavior * when resources regarded as mixed-content are requested. A single run covers
diff --git a/third_party/blink/web_tests/external/wpt/portals/portals-create-orphaned.html b/third_party/blink/web_tests/external/wpt/portals/portals-create-orphaned.html new file mode 100644 index 0000000..903186ff --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/portals/portals-create-orphaned.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> + <script> + promise_test(async () => { + let waitForMessage = new Promise((resolve, reject) => { + var bc = new BroadcastChannel("portals-create-orphaned"); + bc.onmessage = e => { + bc.close(); + resolve(e.data); + } + }); + window.open("resources/portal-create-orphaned.html"); + let message = await waitForMessage; + assert_equals(message, "portal loaded"); + }, "creating a portal from an orphaned portal should succeed"); + </script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/portals/resources/portal-create-orphaned.html b/third_party/blink/web_tests/external/wpt/portals/resources/portal-create-orphaned.html new file mode 100644 index 0000000..89b927f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/portals/resources/portal-create-orphaned.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<body> + <script> + var portal = document.createElement("portal"); + portal.src = "simple-portal.html"; + let waitForMessage = new Promise((resolve, reject) => { + var bc_portal = new BroadcastChannel("simple-portal"); + bc_portal.onmessage = e => { + bc_portal.close(); + portal.activate(); + var portal2 = document.createElement("portal"); + portal2.src = "simple-portal.html"; + document.body.appendChild(portal2); + var bc2 = new BroadcastChannel("simple-portal"); + bc2.onmessage = e => { + bc2.close(); + resolve("portal loaded"); + } + } + }); + document.body.appendChild(portal); + waitForMessage.then(message => { + var bc = new BroadcastChannel("portals-create-orphaned"); + bc.postMessage(message); + bc.close(); + }); + </script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/referrer-policy/generic/referrer-policy-test-case.js b/third_party/blink/web_tests/external/wpt/referrer-policy/generic/referrer-policy-test-case.js index 6b5ae7f..6d570f1 100644 --- a/third_party/blink/web_tests/external/wpt/referrer-policy/generic/referrer-policy-test-case.js +++ b/third_party/blink/web_tests/external/wpt/referrer-policy/generic/referrer-policy-test-case.js
@@ -1,10 +1,3 @@ -function wrapResult(server_data) { - return { - referrer: server_data.headers.referer, - headers: server_data.headers - } -} - // NOTE: This method only strips the fragment and is not in accordance to the // recommended draft specification: // https://w3c.github.io/webappsec/specs/referrer-policy/#null
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/module-worker-redirect-upgrade.https-expected.txt b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/module-worker-redirect-upgrade.https-expected.txt index 0d9e1b9..bc6f2cd3 100644 --- a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/module-worker-redirect-upgrade.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/module-worker-redirect-upgrade.https-expected.txt
@@ -1,7 +1,7 @@ This is a testharness.js-based test. PASS secure/same-origin => secure/same-origin worker -FAIL insecure/same-origin => secure/same-origin worker promise_test: Unhandled rejection with value: object "SecurityError: Failed to construct 'Worker': Script at 'http://web-platform.test:8444/upgrade-insecure-requests/support/redirect-cors.py?location=https%3A%2F%2Fweb-platform.test%3A8444%2Fupgrade-insecure-requests%2Fsupport%2Fworker.js' cannot be accessed from origin 'https://web-platform.test:8444'." +FAIL insecure/same-origin => secure/same-origin worker promise_test: Unhandled rejection with value: object "SecurityError: Failed to construct 'Worker': Script at 'http://web-platform.test:8444/upgrade-insecure-requests/support/redirect-cors.py?location=https%3A%2F%2Fweb-platform.test%3A8444%2Fcommon%2Fsecurity-features%2Fsubresource%2Fworker.py' cannot be accessed from origin 'https://web-platform.test:8444'." PASS secure/same-origin => insecure/same-origin worker -FAIL insecure/same-origin => insecure/same-origin worker promise_test: Unhandled rejection with value: object "SecurityError: Failed to construct 'Worker': Script at 'http://web-platform.test:8444/upgrade-insecure-requests/support/redirect-cors.py?location=http%3A%2F%2Fweb-platform.test%3A8444%2Fupgrade-insecure-requests%2Fsupport%2Fworker.js' cannot be accessed from origin 'https://web-platform.test:8444'." +FAIL insecure/same-origin => insecure/same-origin worker promise_test: Unhandled rejection with value: object "SecurityError: Failed to construct 'Worker': Script at 'http://web-platform.test:8444/upgrade-insecure-requests/support/redirect-cors.py?location=http%3A%2F%2Fweb-platform.test%3A8444%2Fcommon%2Fsecurity-features%2Fsubresource%2Fworker.py' cannot be accessed from origin 'https://web-platform.test:8444'." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/module-worker-upgrade.https-expected.txt b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/module-worker-upgrade.https-expected.txt index 5132c62..8195596 100644 --- a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/module-worker-upgrade.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/module-worker-upgrade.https-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. PASS secure/same-origin worker -FAIL insecure/same-origin worker promise_test: Unhandled rejection with value: object "SecurityError: Failed to construct 'Worker': Script at 'http://web-platform.test:8444/upgrade-insecure-requests/support/worker.js' cannot be accessed from origin 'https://web-platform.test:8444'." +FAIL insecure/same-origin worker promise_test: Unhandled rejection with value: object "SecurityError: Failed to construct 'Worker': Script at 'http://web-platform.test:8444/common/security-features/subresource/worker.py' cannot be accessed from origin 'https://web-platform.test:8444'." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/generate.py b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/generate.py index 8c8cca21..4fb7078e 100644 --- a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/generate.py +++ b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/generate.py
@@ -33,8 +33,8 @@ ('layout-worklet', 'WORKLET'), ('paint-worklet', 'WORKLET'), ('worker', 'WORKER'), ('module-worker', 'WORKER'), - ('worker-subresource-xhr', 'IMAGE'), - ('worker-subresource-fetch', 'IMAGE')]: + ('worker-subresource-xhr', 'FETCH'), + ('worker-subresource-fetch', 'FETCH')]: sameOriginOnly = 'true' if resourceType == 'WORKER' else 'false' types = [('', 'generateTests'), ('-redirect', 'generateRedirectTests')] if name == 'module-worker' or resourceType == 'WORKLET':
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/pass.png b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/pass.png deleted file mode 100644 index 2fa1e0a..0000000 --- a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/pass.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/pass.png.headers b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/pass.png.headers deleted file mode 100644 index cb762eff..0000000 --- a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/pass.png.headers +++ /dev/null
@@ -1 +0,0 @@ -Access-Control-Allow-Origin: *
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/post-origin-to-parent.html b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/post-origin-to-parent.html deleted file mode 100644 index 4f596ef..0000000 --- a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/post-origin-to-parent.html +++ /dev/null
@@ -1,3 +0,0 @@ -<script> - parent.postMessage(window.location.origin, '*'); -</script>
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/testharness-helper.sub.js b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/testharness-helper.sub.js index 70378ed..f578e898 100644 --- a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/testharness-helper.sub.js +++ b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/testharness-helper.sub.js
@@ -1,9 +1,3 @@ -// Used by common.js. -function wrapResult(server_data) { - // Currently the returned value is not used in mixed-content tests. - return null; -} - const Host = { SAME_ORIGIN: "same-origin", CROSS_ORIGIN: "cross-origin", @@ -20,6 +14,7 @@ WORKER: "worker", WORKLET: "worklet", WEBSOCKET: "websocket", + FETCH: "fetch", }; // These tests rely on some unintuitive cleverness due to WPT's test setup: @@ -27,22 +22,24 @@ // in the form `http://[domain]:[https-port]`. If the upgrade fails, the load will fail, // as we don't serve HTTP over the secure port. function generateURL(host, protocol, resourceType) { - var url = new URL("http://{{host}}:{{ports[https][0]}}/upgrade-insecure-requests/support/"); + var url = new URL("http://{{host}}:{{ports[https][0]}}/common/security-features/subresource/"); url.protocol = protocol == Protocol.INSECURE ? "http" : "https"; url.hostname = host == Host.SAME_ORIGIN ? "{{host}}" : "{{domains[天気の良い日]}}"; if (resourceType == ResourceType.IMAGE) { - url.pathname += "pass.png"; + url.pathname += "image.py"; } else if (resourceType == ResourceType.FRAME) { - url.pathname += "post-origin-to-parent.html"; + url.pathname += "document.py"; } else if (resourceType == ResourceType.WEBSOCKET) { url.port = {{ports[wss][0]}}; url.protocol = protocol == Protocol.INSECURE ? "ws" : "wss"; url.pathname = "echo"; } else if (resourceType == ResourceType.WORKER) { - url.pathname += "worker.js"; + url.pathname += "worker.py"; } else if (resourceType == ResourceType.WORKLET) { - url.pathname = "/worklets/resources/empty-worklet-script-with-cors-header.js"; + url.pathname += "worker.py"; + } else if (resourceType == ResourceType.FETCH) { + url.pathname += "xhr.py"; } return { name: protocol + "/" + host + " " + resourceType, @@ -110,24 +107,24 @@ return tests; } -function assert_image_loads(test, url, height, width) { +function assert_image_loads(test, url) { var i = document.createElement('img'); i.onload = test.step_func_done(_ => { - assert_equals(i.naturalHeight, height, "Height."); - assert_equals(i.naturalWidth, width, "Width."); + assert_greater_than(i.naturalHeight, 0, "Height."); + assert_greater_than(i.naturalWidth, 0, "Width."); }); i.onerror = test.unreached_func(url + " should load successfully."); i.src = url; } -function assert_image_loads_in_srcdoc(test, url, height, width) { +function assert_image_loads_in_srcdoc(test, url) { var frame = document.createElement('iframe'); frame.srcdoc = "yay!"; frame.onload = _ => { var i = frame.contentDocument.createElement('img'); i.onload = test.step_func_done(_ => { - assert_equals(i.naturalHeight, height, "Height."); - assert_equals(i.naturalWidth, width, "Width."); + assert_greater_than(i.naturalHeight, 0, "Height."); + assert_greater_than(i.naturalWidth, 0, "Width."); frame.remove(); }); i.onerror = test.unreached_func(url + " should load successfully."); @@ -137,13 +134,13 @@ document.body.appendChild(frame); } -function assert_image_loads_in_blank(test, url, height, width) { +function assert_image_loads_in_blank(test, url) { var frame = document.createElement('iframe'); frame.onload = _ => { var i = frame.contentDocument.createElement('img'); i.onload = test.step_func_done(_ => { - assert_equals(i.naturalHeight, height, "Height."); - assert_equals(i.naturalWidth, width, "Width."); + assert_greater_than(i.naturalHeight, 0, "Height."); + assert_greater_than(i.naturalWidth, 0, "Width."); frame.remove(); }); i.onerror = test.unreached_func(url + " should load successfully."); @@ -153,20 +150,6 @@ document.body.appendChild(frame); } -function assert_frame_loads(test, url) { - var i = document.createElement('iframe'); - - window.addEventListener('message', test.step_func(e => { - if (e.source == i.contentWindow) { - i.remove(); - test.done(); - } - })); - - i.src = url; - document.body.appendChild(i); -} - function assert_websocket_loads(test, url) { var w = new WebSocket(url, "echo"); w.onopen = test.step_func(_ => { @@ -178,12 +161,12 @@ const testMap = { "image": test => { - async_test(t => assert_image_loads(t, test.url, 64, 168), test.name); - async_test(t => assert_image_loads_in_srcdoc(t, test.url, 64, 168), test.name + " in <iframe srcdoc>"); - async_test(t => assert_image_loads_in_blank(t, test.url, 64, 168), test.name + " in <iframe>"); + async_test(t => assert_image_loads(t, test.url), test.name); + async_test(t => assert_image_loads_in_srcdoc(t, test.url), test.name + " in <iframe srcdoc>"); + async_test(t => assert_image_loads_in_blank(t, test.url), test.name + " in <iframe>"); }, "iframe": - test => async_test(t => assert_frame_loads(t, test.url), test.name), + test => promise_test(t => requestViaIframe(test.url), test.name), "worker": test => promise_test(
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/worker.js b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/worker.js deleted file mode 100644 index 7e2168bc..0000000 --- a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/worker.js +++ /dev/null
@@ -1 +0,0 @@ -postMessage('done');
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/worker.js.headers b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/worker.js.headers deleted file mode 100644 index cb762eff..0000000 --- a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/support/worker.js.headers +++ /dev/null
@@ -1 +0,0 @@ -Access-Control-Allow-Origin: *
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-redirect-upgrade.https-expected.txt b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-redirect-upgrade.https-expected.txt index 0d9e1b9..bc6f2cd3 100644 --- a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-redirect-upgrade.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-redirect-upgrade.https-expected.txt
@@ -1,7 +1,7 @@ This is a testharness.js-based test. PASS secure/same-origin => secure/same-origin worker -FAIL insecure/same-origin => secure/same-origin worker promise_test: Unhandled rejection with value: object "SecurityError: Failed to construct 'Worker': Script at 'http://web-platform.test:8444/upgrade-insecure-requests/support/redirect-cors.py?location=https%3A%2F%2Fweb-platform.test%3A8444%2Fupgrade-insecure-requests%2Fsupport%2Fworker.js' cannot be accessed from origin 'https://web-platform.test:8444'." +FAIL insecure/same-origin => secure/same-origin worker promise_test: Unhandled rejection with value: object "SecurityError: Failed to construct 'Worker': Script at 'http://web-platform.test:8444/upgrade-insecure-requests/support/redirect-cors.py?location=https%3A%2F%2Fweb-platform.test%3A8444%2Fcommon%2Fsecurity-features%2Fsubresource%2Fworker.py' cannot be accessed from origin 'https://web-platform.test:8444'." PASS secure/same-origin => insecure/same-origin worker -FAIL insecure/same-origin => insecure/same-origin worker promise_test: Unhandled rejection with value: object "SecurityError: Failed to construct 'Worker': Script at 'http://web-platform.test:8444/upgrade-insecure-requests/support/redirect-cors.py?location=http%3A%2F%2Fweb-platform.test%3A8444%2Fupgrade-insecure-requests%2Fsupport%2Fworker.js' cannot be accessed from origin 'https://web-platform.test:8444'." +FAIL insecure/same-origin => insecure/same-origin worker promise_test: Unhandled rejection with value: object "SecurityError: Failed to construct 'Worker': Script at 'http://web-platform.test:8444/upgrade-insecure-requests/support/redirect-cors.py?location=http%3A%2F%2Fweb-platform.test%3A8444%2Fcommon%2Fsecurity-features%2Fsubresource%2Fworker.py' cannot be accessed from origin 'https://web-platform.test:8444'." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-subresource-fetch-redirect-upgrade.https.html b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-subresource-fetch-redirect-upgrade.https.html index b2ce2cf..948dd65 100644 --- a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-subresource-fetch-redirect-upgrade.https.html +++ b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-subresource-fetch-redirect-upgrade.https.html
@@ -12,7 +12,7 @@ </head> <body> <script> -const tests = generateRedirectTests(ResourceType.IMAGE, false); +const tests = generateRedirectTests(ResourceType.FETCH, false); tests.forEach(test => testMap['worker-subresource-fetch'](test)); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-subresource-fetch-upgrade.https.html b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-subresource-fetch-upgrade.https.html index 1639363..bc98b9f2 100644 --- a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-subresource-fetch-upgrade.https.html +++ b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-subresource-fetch-upgrade.https.html
@@ -12,7 +12,7 @@ </head> <body> <script> -const tests = generateTests(ResourceType.IMAGE, false); +const tests = generateTests(ResourceType.FETCH, false); tests.forEach(test => testMap['worker-subresource-fetch'](test)); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-upgrade.https-expected.txt b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-upgrade.https-expected.txt index 5132c62..8195596 100644 --- a/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-upgrade.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/upgrade-insecure-requests/worker-upgrade.https-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. PASS secure/same-origin worker -FAIL insecure/same-origin worker promise_test: Unhandled rejection with value: object "SecurityError: Failed to construct 'Worker': Script at 'http://web-platform.test:8444/upgrade-insecure-requests/support/worker.js' cannot be accessed from origin 'https://web-platform.test:8444'." +FAIL insecure/same-origin worker promise_test: Unhandled rejection with value: object "SecurityError: Failed to construct 'Worker': Script at 'http://web-platform.test:8444/common/security-features/subresource/worker.py' cannot be accessed from origin 'https://web-platform.test:8444'." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/fast/events/popup-blocked-to-post-blank-expected.txt b/third_party/blink/web_tests/fast/events/popup-blocked-to-post-blank-expected.txt index 5305a4e3..1c6ee54 100644 --- a/third_party/blink/web_tests/fast/events/popup-blocked-to-post-blank-expected.txt +++ b/third_party/blink/web_tests/fast/events/popup-blocked-to-post-blank-expected.txt
@@ -1 +1,2 @@ +CONSOLE ERROR: line 15: Not allowed to navigate top frame to data URL: data:text/html,<script>alert(window)</script>? If the POST pop-up was not blocked then there will be an ALERT containing a Window object. Otherwise, the test passes.
diff --git a/third_party/blink/web_tests/fast/frames/sandboxed-iframe-navigation-targetlink-expected.txt b/third_party/blink/web_tests/fast/frames/sandboxed-iframe-navigation-targetlink-expected.txt index 06a635cf..cbcb138 100644 --- a/third_party/blink/web_tests/fast/frames/sandboxed-iframe-navigation-targetlink-expected.txt +++ b/third_party/blink/web_tests/fast/frames/sandboxed-iframe-navigation-targetlink-expected.txt
@@ -1,6 +1,5 @@ CONSOLE ERROR: line 18: Unsafe JavaScript attempt to initiate navigation for frame with URL 'about:blank' from frame with URL 'sandboxed-iframe-navigation-targetlink.html'. The frame attempting navigation is sandboxed, and is therefore disallowed from navigating its ancestors. -CONSOLE ERROR: line 18: Blocked opening 'sandboxed-iframe-navigated.html' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set. This test verifies that a sandboxed IFrame cannot open a link in another frame using the target attribute of a link. This is done by loading ten non-sandboxed IFrames, and a single sandboxed one. In addition each of these frames have a target frame (so, 22 frames in total). Expect ten frames to be able to open a link in their corresponding target frame, but the sandboxed one to not be one of them.
diff --git a/third_party/blink/web_tests/fast/spatial-navigation/snav-iframe-with-offscreen-focusable-element.html b/third_party/blink/web_tests/fast/spatial-navigation/snav-iframe-with-offscreen-focusable-element.html index b61300e..cdcc06b 100644 --- a/third_party/blink/web_tests/fast/spatial-navigation/snav-iframe-with-offscreen-focusable-element.html +++ b/third_party/blink/web_tests/fast/spatial-navigation/snav-iframe-with-offscreen-focusable-element.html
@@ -25,6 +25,8 @@ ["Down", "frameA,1"], ["Down", "frameA,1"], ["Down", "frameA,1"], + ["Down", "frameA,1"], + ["Down", "frameA,2"], ["Down", "frameA,2"], ["Down", "end"], ["Up", "frameA,frameAbody"], @@ -35,6 +37,8 @@ ["Up", "frameA,2"], ["Up", "frameA,2"], ["Up", "frameA,2"], + ["Up", "frameA,2"], + ["Up", "frameA,1"], ["Up", "frameA,1"], ["Up", "start"], ];
diff --git a/third_party/blink/web_tests/fast/spatial-navigation/snav-media-elements.html b/third_party/blink/web_tests/fast/spatial-navigation/snav-media-elements.html index fb42a2d..4d59037b 100644 --- a/third_party/blink/web_tests/fast/spatial-navigation/snav-media-elements.html +++ b/third_party/blink/web_tests/fast/spatial-navigation/snav-media-elements.html
@@ -1,3 +1,11 @@ +<style> + p { + margin: 0; + } + video { + height: 100px; + } +</style> <p>This is a link <a id="start" href="a">start of Test</a>.</p> <video id="v1" controls tabindex="0" src="../../media/content/test.mp4"></video> <p>This is a link <a id="i2" href="a">i2</a>.</p>
diff --git a/third_party/blink/web_tests/fast/spatial-navigation/snav-navigate-visible-elements-only.html b/third_party/blink/web_tests/fast/spatial-navigation/snav-navigate-visible-elements-only.html new file mode 100644 index 0000000..fafebd8 --- /dev/null +++ b/third_party/blink/web_tests/fast/spatial-navigation/snav-navigate-visible-elements-only.html
@@ -0,0 +1,54 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/snav-testharness.js"></script> + +<style> + div { + width: 100px; + height: 100px; + background-color: green; + position: absolute; + } + + #A { + top: 601px; + } +</style> + +<div id="start" tabindex="0"></div> +<div id="A" tabindex="0"></div> + +<script> + // This test checks that focusless mode allows entering focus into an element + // with the enter key and exiting it with the escape key. + const A = document.getElementById("A"); + const start = document.getElementById("start"); + + snav.assertSnavEnabledAndTestable(); + start.focus(); + + test(() => { + assert_equals(window.scrollY, 0, "Start at 0 scroll offset.") + assert_equals(window.internals.interestedElement, + start, "Top DIV starts off focused"); + + // Down should scroll the visual viewport, since there's no targets + // availabe on screen. + snav.triggerMove('Down'); + + assert_equals(window.internals.interestedElement, + start, + "First navigation should't move interest"); + assert_greater_than(window.scrollY, 0, + "First navigation should scroll"); + assert_greater_than(window.innerHeight, + A.getBoundingClientRect().top, + "A element should now be at least partially visible"); + + snav.triggerMove('Down'); + assert_equals(window.internals.interestedElement, + A, + "Navigate to onscreen element."); + }, "Don't navigate to elements that are off screen."); +</script>
diff --git a/third_party/blink/web_tests/http/tests/lazyload/attribute.html b/third_party/blink/web_tests/http/tests/lazyload/attribute.html index 07751af..c6181504 100644 --- a/third_party/blink/web_tests/http/tests/lazyload/attribute.html +++ b/third_party/blink/web_tests/http/tests/lazyload/attribute.html
@@ -6,10 +6,10 @@ <body> <div style="height:10000px;"></div> <img id="no_attribute_img" src='../loading/resources/base-image1.png'> - <img id="auto_attribute_img" src='../loading/resources/base-image2.png' load="auto"> - <img id="invalid_attribute_img" src='../loading/resources/base-image3.png' load="invalid-value-default"> - <img id="lazy_attribute_img" src='../loading/resources/dup-image1.png' load="lazy"> - <img id="eager_attribute_img" src='../loading/resources/dup-image2.png' load="eager"> + <img id="auto_attribute_img" src='../loading/resources/base-image2.png' loading="auto"> + <img id="invalid_attribute_img" src='../loading/resources/base-image3.png' loading="invalid-value-default"> + <img id="lazy_attribute_img" src='../loading/resources/dup-image1.png' loading="lazy"> + <img id="eager_attribute_img" src='../loading/resources/dup-image2.png' loading="eager"> </body> <script> @@ -29,48 +29,48 @@ assert_false(is_image_fully_loaded(no_attribute_img)); })); lazy_attribute_img.addEventListener("load", - t.unreached_func("Load event should not be fired for below viewport image with load=lazy")); + t.unreached_func("Load event should not be fired for below viewport image with loading=lazy")); auto_attribute_img.addEventListener("load", - t.unreached_func("Load event should not be fired for below viewport image with load=auto")); + t.unreached_func("Load event should not be fired for below viewport image with loading=auto")); no_attribute_img.addEventListener("load", - t.unreached_func("Load event should not be fired for below viewport image with no load attribute")); + t.unreached_func("Load event should not be fired for below viewport image with no loading attribute")); invalid_attribute_img.addEventListener("load", - t.unreached_func("Load event should not be fired for below viewport image with invalid load attribute")); - }, "Test that <img> with load=lazy or auto or no attribute or invalid value are loaded as a placeholder"); + t.unreached_func("Load event should not be fired for below viewport image with invalid loading attribute")); + }, "Test that <img> with loading=lazy or auto or no attribute or invalid value are loaded as a placeholder"); async_test(function(t) { eager_attribute_img.addEventListener("load", t.step_func_done(function() { assert_true(is_image_fully_loaded(eager_attribute_img)); })); - }, "Test that <img> with load=eager is fully loaded, and not a placeholder"); + }, "Test that <img> with loading=eager is fully loaded, and not a placeholder"); async_test(function(t) { var complete = 0; var onload_callback = function() { if (++complete == 4) { - // The four images with load=lazy,auto or default or invalid attribute are loaded. + // The four images with loading=lazy,auto or default or invalid attribute are loaded. assert_true(is_image_fully_loaded(no_attribute_img)); assert_true(is_image_fully_loaded(lazy_attribute_img)); assert_true(is_image_fully_loaded(auto_attribute_img)); assert_true(is_image_fully_loaded(invalid_attribute_img)); t.done(); } - assert_equals("eager", this.getAttribute('load')); + assert_equals("eager", this.getAttribute('loading')); }; no_attribute_img.addEventListener("load", onload_callback); lazy_attribute_img.addEventListener("load", onload_callback); auto_attribute_img.addEventListener("load", onload_callback); invalid_attribute_img.addEventListener("load", onload_callback); window.addEventListener("load", t.step_func(function() { - assert_equals(null, no_attribute_img.getAttribute('load')); - assert_equals("lazy", lazy_attribute_img.getAttribute('load')); - assert_equals("auto", auto_attribute_img.getAttribute('load')); - assert_equals("invalid-value-default", invalid_attribute_img.getAttribute('load')); - no_attribute_img.setAttribute('load', 'eager'); - lazy_attribute_img.setAttribute('load', 'eager'); - auto_attribute_img.setAttribute('load', 'eager'); - invalid_attribute_img.setAttribute('load', 'eager'); + assert_equals(null, no_attribute_img.getAttribute('loading')); + assert_equals("lazy", lazy_attribute_img.getAttribute('loading')); + assert_equals("auto", auto_attribute_img.getAttribute('loading')); + assert_equals("invalid-value-default", invalid_attribute_img.getAttribute('loading')); + no_attribute_img.setAttribute('loading', 'eager'); + lazy_attribute_img.setAttribute('loading', 'eager'); + auto_attribute_img.setAttribute('loading', 'eager'); + invalid_attribute_img.setAttribute('loading', 'eager'); })); }, "Test that deferred <img> are fully loaded when lazyload is turned off"); </script>
diff --git a/third_party/blink/web_tests/http/tests/security/sandboxed-iframe-form-top-expected.txt b/third_party/blink/web_tests/http/tests/security/sandboxed-iframe-form-top-expected.txt index ad4c764..de8060f 100644 --- a/third_party/blink/web_tests/http/tests/security/sandboxed-iframe-form-top-expected.txt +++ b/third_party/blink/web_tests/http/tests/security/sandboxed-iframe-form-top-expected.txt
@@ -1,6 +1,5 @@ CONSOLE ERROR: line 8: Unsafe JavaScript attempt to initiate navigation for frame with URL 'http://127.0.0.1:8000/security/sandboxed-iframe-form-top.html' from frame with URL 'http://127.0.0.1:8000/security/resources/sandboxed-iframe-form-top.html'. The frame attempting navigation of the top-level window is sandboxed, but the flag of 'allow-top-navigation' or 'allow-top-navigation-by-user-activation' is not set. -CONSOLE ERROR: line 8: Blocked opening 'http://127.0.0.1:8000/security/resources/fail.html?' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set. This tests passes if the sandboxed frame cannot navigate the top frame. PASS
diff --git a/third_party/blink/web_tests/inspector-protocol/accessibility/accessibility-ignoredNodes-expected.txt b/third_party/blink/web_tests/inspector-protocol/accessibility/accessibility-ignoredNodes-expected.txt index e1ae030..a616f48 100644 --- a/third_party/blink/web_tests/inspector-protocol/accessibility/accessibility-ignoredNodes-expected.txt +++ b/third_party/blink/web_tests/inspector-protocol/accessibility/accessibility-ignoredNodes-expected.txt
@@ -152,6 +152,7 @@ *GenericContainer text "Div in list isn't presentational" checkbox "Content within label refers to label container" + button "aria-hidden false button" GenericContainer combobox { @@ -337,6 +338,7 @@ text "List item also presentational" GenericContainer checkbox "Content within label refers to label container" + button "aria-hidden false button" GenericContainer *combobox MenuListPopup
diff --git a/third_party/blink/web_tests/virtual/mouseevent_fractional/fast/events/popup-blocked-to-post-blank-expected.txt b/third_party/blink/web_tests/virtual/mouseevent_fractional/fast/events/popup-blocked-to-post-blank-expected.txt new file mode 100644 index 0000000..1c6ee54 --- /dev/null +++ b/third_party/blink/web_tests/virtual/mouseevent_fractional/fast/events/popup-blocked-to-post-blank-expected.txt
@@ -0,0 +1,2 @@ +CONSOLE ERROR: line 15: Not allowed to navigate top frame to data URL: data:text/html,<script>alert(window)</script>? +If the POST pop-up was not blocked then there will be an ALERT containing a Window object. Otherwise, the test passes.
diff --git a/third_party/blink/web_tests/virtual/user-activation-v2/fast/events/popup-blocked-to-post-blank-expected.txt b/third_party/blink/web_tests/virtual/user-activation-v2/fast/events/popup-blocked-to-post-blank-expected.txt new file mode 100644 index 0000000..1c6ee54 --- /dev/null +++ b/third_party/blink/web_tests/virtual/user-activation-v2/fast/events/popup-blocked-to-post-blank-expected.txt
@@ -0,0 +1,2 @@ +CONSOLE ERROR: line 15: Not allowed to navigate top frame to data URL: data:text/html,<script>alert(window)</script>? +If the POST pop-up was not blocked then there will be an ALERT containing a Window object. Otherwise, the test passes.
diff --git a/third_party/libcxx-pretty-printers/.style.yapf b/third_party/libcxx-pretty-printers/.style.yapf new file mode 100644 index 0000000..557fa7b --- /dev/null +++ b/third_party/libcxx-pretty-printers/.style.yapf
@@ -0,0 +1,2 @@ +[style] +based_on_style = pep8
diff --git a/third_party/libcxx-pretty-printers/README.chromium b/third_party/libcxx-pretty-printers/README.chromium index f63918a..2edbcb2 100644 --- a/third_party/libcxx-pretty-printers/README.chromium +++ b/third_party/libcxx-pretty-printers/README.chromium
@@ -1,6 +1,6 @@ Name: libcxx-pretty-printers -URL: https://github.com/LeszekSwirski/libcxx-pretty-printers -Version: dc4eb17426ce62262992d7c52aa1140f9b707c37 +URL: https://github.com/tanderson-google/libcxx-pretty-printers +Version: unknown License: GPL v3 License File: LICENSE Security Critical: no @@ -9,10 +9,10 @@ GDB Pretty Printers for libc++ of Clang/LLVM Local patches: -None +This is a fork of [1] which is a fork of [2] which is a fork of [3] which was +originally a fork of some pretty-printers for libstdc++. printers.py no longer +tracks any of these upstreams. -Upgrading: -$ git clone https://github.com/LeszekSwirski/libcxx-pretty-printers.git -$ rm -rf .git .gitignore -* Add README.chromium -* Add OWNERS +[1] https://github.com/tanderson-google/libcxx-pretty-printers +[2] https://github.com/LeszekSwirski/libcxx-pretty-printers +[3] https://github.com/koutheir/libcxx-pretty-printers
diff --git a/third_party/libcxx-pretty-printers/README.md b/third_party/libcxx-pretty-printers/README.md deleted file mode 100644 index 5433b0e..0000000 --- a/third_party/libcxx-pretty-printers/README.md +++ /dev/null
@@ -1,4 +0,0 @@ -libcxx-pretty-printers -====================== - -GDB Pretty Printers for libc++ of Clang/LLVM
diff --git a/third_party/libcxx-pretty-printers/src/libcxx/v1/printers.py b/third_party/libcxx-pretty-printers/printers.py similarity index 71% rename from third_party/libcxx-pretty-printers/src/libcxx/v1/printers.py rename to third_party/libcxx-pretty-printers/printers.py index 3c43aaa5..e59493f1 100644 --- a/third_party/libcxx-pretty-printers/src/libcxx/v1/printers.py +++ b/third_party/libcxx-pretty-printers/printers.py
@@ -63,6 +63,10 @@ pass +def make_type_re(typename): + return re.compile('^std::__[a-zA-Z0-9]+::' + typename + '<.*>$') + + # Starting with the type ORIG, search for the member type NAME. This # handles searching upward through superclasses. This is needed to # work around http://sourceware.org/bugzilla/show_bug.cgi?id=13615. @@ -84,34 +88,33 @@ def pair_to_tuple(val): - if val.type.name.startswith("std::__1::__compressed_pair"): + if make_type_re('__compressed_pair').match(val.type.name): t1 = val.type.template_argument(0) t2 = val.type.template_argument(1) base1 = val.type.fields()[0].type base2 = val.type.fields()[1].type - return ( - (val if base1.template_argument(2) - else val.cast(base1)["__value_"]).cast(t1), - (val if base2.template_argument(2) - else val.cast(base2)["__value_"]).cast(t2) - ) + return ((val if base1.template_argument(2) else + val.cast(base1)["__value_"]).cast(t1), + (val if base2.template_argument(2) else + val.cast(base2)["__value_"]).cast(t2)) else: return (val['first'], val['second']) + void_type = gdb.lookup_type('void') + def ptr_to_void_ptr(val): - if gdb.types.get_basic_type(val.type).code == gdb.TYPE_CODE_PTR: - return val.cast(void_type.pointer()) - else: - return val - + if gdb.types.get_basic_type(val.type).code == gdb.TYPE_CODE_PTR: + return val.cast(void_type.pointer()) + else: + return val -class StdStringPrinter: +class StringPrinter: "Print a std::basic_string of some kind" def __init__(self, typename, val): @@ -125,9 +128,9 @@ type = type.target() ss = pair_to_tuple(self.val['__r_'])[0]['__s'] - __short_mask = 0x1 + __short_mask = int(self.val['__short_mask']) if (ss['__size_'] & __short_mask) == 0: - len = (ss['__size_'] >> 1) + len = ss['__size_'] >> 1 if __short_mask == 1 else ss['__size_'] ptr = ss['__data_'] else: sl = pair_to_tuple(self.val['__r_'])[0]['__l'] @@ -158,7 +161,9 @@ else: state = 'count %d, weak %d' % (usecount, weakcount) - return '%s (%s) = %s => %s' % (self.typename, state, self.val['__ptr_'], self.val['__ptr_'].dereference()) + return '%s (%s) = %s => %s' % (self.typename, state, + self.val['__ptr_'], + self.val['__ptr_'].dereference()) class UniquePointerPrinter: @@ -171,11 +176,13 @@ def to_string(self): v = pair_to_tuple(self.val['__ptr_'])[0] if v == 0: - return '%s<%s> = %s <nullptr>' % (str(self.typename), str(v.type.target()), str(v)) - return '%s<%s> = %s => %s' % (str(self.typename), str(v.type.target()), str(v), v.dereference()) + return '%s<%s> = %s <nullptr>' % (str(self.typename), + str(v.type.target()), str(v)) + return '%s<%s> = %s => %s' % (str(self.typename), str(v.type.target()), + str(v), v.dereference()) -class StdPairPrinter: +class PairPrinter: "Print a std::pair" def __init__(self, typename, val): @@ -184,21 +191,20 @@ def children(self): vals = pair_to_tuple(self.val) - return [('first', vals[0]), - ('second', vals[1])] + return [('first', vals[0]), ('second', vals[1])] def to_string(self): return 'pair' + # def display_hint(self): # return 'array' -class StdTuplePrinter: +class TuplePrinter: "Print a std::tuple" class _iterator(Iterator): - def __init__(self, head): self.head = head['base_'] self.fields = self.head.type.fields() @@ -226,15 +232,15 @@ return 'empty %s' % (self.typename) return 'tuple' + # def display_hint(self): # return 'array' -class StdListPrinter: +class ListPrinter: "Print a std::list" class _iterator(Iterator): - def __init__(self, nodetype, head): self.nodetype = nodetype self.base = head['__next_'] @@ -268,11 +274,12 @@ return 'empty %s' % (self.typename) return '%s' % (self.typename) + # def display_hint(self): # return 'array' -class StdListIteratorPrinter: +class ListIteratorPrinter: "Print std::list::iterator" def __init__(self, typename, val): @@ -283,11 +290,10 @@ return self.val['__ptr_']['__value_'] -class StdForwardListPrinter: +class ForwardListPrinter: "Print a std::forward_list" class _iterator(Iterator): - def __init__(self, head): self.node = head self.count = 0 @@ -318,11 +324,10 @@ return '%s' % (self.typename) -class StdVectorPrinter: +class VectorPrinter: "Print a std::vector" class _iterator(Iterator): - def __init__(self, start, finish_or_size, bits_per_word, bitvec): self.bitvec = bitvec if bitvec: @@ -371,24 +376,23 @@ def children(self): if self.is_bool: - return self._iterator(self.val['__begin_'], - self.val['__size_'], - self.val['__bits_per_word'], - self.is_bool) + return self._iterator(self.val['__begin_'], self.val['__size_'], + self.val['__bits_per_word'], self.is_bool) else: - return self._iterator(self.val['__begin_'], - self.val['__end_'], - 0, + return self._iterator(self.val['__begin_'], self.val['__end_'], 0, self.is_bool) def to_string(self): if self.is_bool: length = self.val['__size_'] - capacity = pair_to_tuple(self.val['__cap_alloc_'])[0] * self.val['__bits_per_word'] + capacity = pair_to_tuple( + self.val['__cap_alloc_'])[0] * self.val['__bits_per_word'] if length == 0: - return 'empty %s<bool> (capacity=%d)' % (self.typename, int(capacity)) + return 'empty %s<bool> (capacity=%d)' % (self.typename, + int(capacity)) else: - return '%s<bool> (length=%d, capacity=%d)' % (self.typename, int(length), int(capacity)) + return '%s<bool> (length=%d, capacity=%d)' % ( + self.typename, int(length), int(capacity)) else: start = ptr_to_void_ptr(self.val['__begin_']) finish = ptr_to_void_ptr(self.val['__end_']) @@ -396,15 +400,17 @@ length = finish - start capacity = end - start if length == 0: - return 'empty %s (capacity=%d)' % (self.typename, int(capacity)) + return 'empty %s (capacity=%d)' % (self.typename, + int(capacity)) else: - return '%s (length=%d, capacity=%d)' % (self.typename, int(length), int(capacity)) + return '%s (length=%d, capacity=%d)' % ( + self.typename, int(length), int(capacity)) def display_hint(self): return 'array' -class StdVectorIteratorPrinter: +class VectorIteratorPrinter: "Print std::vector::iterator" def __init__(self, typename, val): @@ -414,7 +420,7 @@ return self.val['__i'].dereference() -class StdVectorBoolIteratorPrinter: +class VectorBoolIteratorPrinter: "Print std::vector<bool>::iterator" def __init__(self, typename, val): @@ -428,11 +434,10 @@ return 0 -class StdDequePrinter: +class DequePrinter: "Print a std::deque" class _iterator(Iterator): - def __init__(self, size, block_size, start, map_begin, map_end): self.block_size = block_size self.count = 0 @@ -445,7 +450,8 @@ self.end_p = 0 else: self.p = self.mp.dereference() + start % block_size - self.end_p = self.end_mp.dereference() + self.end_p % block_size + self.end_p = self.end_mp.dereference( + ) + self.end_p % block_size def __iter__(self): return self @@ -459,7 +465,8 @@ self.mp += 1 self.p = self.mp.dereference() - if (self.mp > self.end_mp) or ((self.p > self.end_p) and (self.mp == self.end_mp)): + if (self.mp > self.end_mp) or ((self.p > self.end_p) and + (self.mp == self.end_mp)): raise StopIteration return ('[%d]' % int(self.count - 1), old_p.dereference()) @@ -484,15 +491,15 @@ if block_size.is_optimized_out: # Warning, this is pretty flaky block_size = 4096 / size_of_value_type if size_of_value_type < 256 else 16 - return self._iterator(self.size, block_size, - self.val['__start_'], block_map['__begin_'], - block_map['__end_']) + return self._iterator(self.size, block_size, self.val['__start_'], + block_map['__begin_'], block_map['__end_']) + # def display_hint (self): # return 'array' -class StdDequeIteratorPrinter: +class DequeIteratorPrinter: "Print std::deque::iterator" def __init__(self, typename, val): @@ -502,7 +509,7 @@ return self.val['__ptr_'].dereference() -class StdStackOrQueuePrinter: +class StackOrQueuePrinter: "Print a std::stack or std::queue" def __init__(self, typename, val): @@ -521,7 +528,7 @@ return None -class StdBitsetPrinter: +class BitsetPrinter: "Print a std::bitset" def __init__(self, typename, val): @@ -553,12 +560,11 @@ return result -class StdSetPrinter: +class SetPrinter: "Print a std::set or std::multiset" # Turn an RbtreeIterator into a pretty-print iterator. class _iterator(Iterator): - def __init__(self, rbiter): self.rbiter = rbiter self.count = 0 @@ -591,12 +597,12 @@ def children(self): return self._iterator(self.rbiter) + # def display_hint (self): # return 'set' class RbtreeIterator: - def __init__(self, rbtree): self.node = rbtree['__begin_node_'] self.size = pair_to_tuple(rbtree['__pair3_'])[0] @@ -634,7 +640,7 @@ return result -class StdRbtreeIteratorPrinter: +class RbtreeIteratorPrinter: "Print std::set::iterator" def __init__(self, typename, val): @@ -644,12 +650,11 @@ return self.val['__ptr_']['__value_'] -class StdMapPrinter: +class MapPrinter: "Print a std::map or std::multimap" # Turn an RbtreeIterator into a pretty-print iterator. class _iterator(Iterator): - def __init__(self, rbiter): self.rbiter = rbiter self.count = 0 @@ -663,8 +668,8 @@ def __next__(self): item = self.rbiter.__next__() item = item.dereference()['__value_'] - result = ('[%d] %s' % (self.count, str( - item['__cc']['first'])), item['__cc']['second']) + result = ('[%d] %s' % (self.count, str(item['__cc']['first'])), + item['__cc']['second']) self.count += 1 return result @@ -683,11 +688,12 @@ def children(self): return self._iterator(self.rbiter) + # def display_hint (self): # return 'map' -class StdMapIteratorPrinter: +class MapIteratorPrinter: "Print std::map::iterator" def __init__(self, typename, val): @@ -700,7 +706,6 @@ class HashtableIterator: - def __init__(self, hashtable): self.node = pair_to_tuple(hashtable['__p1_'])[0]['__next_'] self.size = pair_to_tuple(hashtable['__p2_'])[0] @@ -714,8 +719,8 @@ def __next__(self): if self.node == 0: raise StopIteration - hash_node_type = gdb.lookup_type( - self.node.dereference().type.name + '::__node_pointer') + hash_node_type = gdb.lookup_type(self.node.dereference().type.name + + '::__node_pointer') node = self.node.cast(hash_node_type).dereference() self.node = node['__next_'] value = node['__value_'] @@ -727,7 +732,7 @@ return value -class StdHashtableIteratorPrinter: +class HashtableIteratorPrinter: "Print std::unordered_set::iterator" def __init__(self, typename, val): @@ -737,7 +742,7 @@ return self.val['__node_']['__value_'] -class StdUnorderedMapIteratorPrinter: +class UnorderedMapIteratorPrinter: "Print std::unordered_map::iterator" def __init__(self, typename, val): @@ -798,11 +803,12 @@ result = [] count = 0 for elt in self.hashtableiter: - result.append( - ('[%d] %s' % (count, str(elt['first'])), elt['second'])) + result.append(('[%d] %s' % (count, str(elt['__cc']['first'])), + elt['__cc']['second'])) count += 1 return result + # def display_hint (self): # return 'map' @@ -811,7 +817,6 @@ class RxPrinter(object): - def __init__(self, name, function): super(RxPrinter, self).__init__() self.name = name @@ -823,39 +828,23 @@ return None return self.function(self.name, value) + # A pretty-printer that conforms to the "PrettyPrinter" protocol from # gdb.printing. It can also be used directly as an old-style printer. class Printer(object): - def __init__(self, name): super(Printer, self).__init__() self.name = name self.subprinters = [] - self.lookup = {} + self.lookup = [] self.enabled = True - self.compiled_rx = re.compile('^([a-zA-Z0-9_:]+)<.*>$') def add(self, name, function): - # A small sanity check. - # FIXME - if not self.compiled_rx.match(name + '<>'): - raise ValueError( - 'libstdc++ programming error: "%s" does not match' % name) - printer = RxPrinter(name, function) + printer = RxPrinter('std::' + name, function) self.subprinters.append(printer) - self.lookup[name] = printer - - # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION. - def add_version(self, base, name, function): - self.add(base + name, function) - self.add(base + '__1::' + name, function) - - # Add a name using _GLIBCXX_BEGIN_NAMESPACE_CONTAINER. - def add_container(self, base, name, function): - self.add_version(base, name, function) - self.add_version(base + '__1::', name, function) + self.lookup.append((make_type_re(name), printer)) @staticmethod def get_basic_type(type): @@ -873,31 +862,24 @@ if not typename: return None - # All the types we match are template types, so we can use a - # dictionary. - match = self.compiled_rx.match(typename) - if not match: - return None - - basename = match.group(1) - if basename in self.lookup: - return self.lookup[basename].invoke(val) + for (regexp, printer) in self.lookup: + if regexp.match(typename): + return printer.invoke(val) # Cannot find a pretty printer. Return None. return None -libcxx_printer = None + +printer = None class FilteringTypePrinter(object): - def __init__(self, match, name): self.match = match self.name = name self.enabled = True class _recognizer(object): - def __init__(self, match, name): self.match = match self.name = name @@ -942,12 +924,9 @@ add_one_type_printer(obj, 'basic_ostream', pfx + 'ostream') add_one_type_printer(obj, 'basic_iostream', pfx + 'iostream') add_one_type_printer(obj, 'basic_stringbuf', pfx + 'stringbuf') - add_one_type_printer(obj, 'basic_istringstream', - pfx + 'istringstream') - add_one_type_printer(obj, 'basic_ostringstream', - pfx + 'ostringstream') - add_one_type_printer(obj, 'basic_stringstream', - pfx + 'stringstream') + add_one_type_printer(obj, 'basic_istringstream', pfx + 'istringstream') + add_one_type_printer(obj, 'basic_ostringstream', pfx + 'ostringstream') + add_one_type_printer(obj, 'basic_stringstream', pfx + 'stringstream') add_one_type_printer(obj, 'basic_filebuf', pfx + 'filebuf') add_one_type_printer(obj, 'basic_ifstream', pfx + 'ifstream') add_one_type_printer(obj, 'basic_ofstream', pfx + 'ofstream') @@ -970,8 +949,8 @@ add_one_type_printer(obj, 'basic_string', 'u16string') add_one_type_printer(obj, 'basic_string', 'u32string') - for dur in ('nanoseconds', 'microseconds', 'milliseconds', - 'seconds', 'minutes', 'hours'): + for dur in ('nanoseconds', 'microseconds', 'milliseconds', 'seconds', + 'minutes', 'hours'): add_one_type_printer(obj, 'duration', dur) add_one_type_printer(obj, 'linear_congruential_engine', 'minstd_rand0') @@ -989,128 +968,70 @@ "Register libc++ pretty-printers with objfile Obj." global _use_gdb_pp - global libcxx_printer + global printer if _use_gdb_pp: - gdb.printing.register_pretty_printer(obj, libcxx_printer) + gdb.printing.register_pretty_printer(obj, printer) else: if obj is None: obj = gdb - obj.pretty_printers.append(libcxx_printer) + obj.pretty_printers.append(printer) register_type_printers(obj) def build_libcxx_dictionary(): - global libcxx_printer + global printer - libcxx_printer = Printer("libc++-v1") + printer = Printer("libc++") - # For _GLIBCXX_BEGIN_NAMESPACE_VERSION. - vers = '(__1::)?' - # For _GLIBCXX_BEGIN_NAMESPACE_CONTAINER. - container = '(__cxx2011::' + vers + ')?' - - # libstdc++ objects requiring pretty-printing. - # In order from: - # http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01847.html - libcxx_printer.add_version('std::', 'basic_string', StdStringPrinter) - libcxx_printer.add_container('std::', 'bitset', StdBitsetPrinter) - libcxx_printer.add_container('std::', 'deque', StdDequePrinter) - libcxx_printer.add_container('std::', 'list', StdListPrinter) - libcxx_printer.add_container('std::', 'map', StdMapPrinter) - libcxx_printer.add_container('std::', 'multimap', StdMapPrinter) - libcxx_printer.add_container('std::', 'multiset', StdSetPrinter) - libcxx_printer.add_version('std::', 'priority_queue', - StdStackOrQueuePrinter) - libcxx_printer.add_version('std::', 'queue', StdStackOrQueuePrinter) - libcxx_printer.add_version('std::', 'tuple', StdTuplePrinter) - libcxx_printer.add_version('std::', 'pair', StdPairPrinter) - libcxx_printer.add_container('std::', 'set', StdSetPrinter) - libcxx_printer.add_version('std::', 'stack', StdStackOrQueuePrinter) - libcxx_printer.add_version('std::', 'unique_ptr', UniquePointerPrinter) - libcxx_printer.add_container('std::', 'vector', StdVectorPrinter) + # libc++ objects requiring pretty-printing. + printer.add('basic_string', StringPrinter) + printer.add('bitset', BitsetPrinter) + printer.add('deque', DequePrinter) + printer.add('list', ListPrinter) + printer.add('map', MapPrinter) + printer.add('multimap', MapPrinter) + printer.add('multiset', SetPrinter) + printer.add('priority_queue', StackOrQueuePrinter) + printer.add('queue', StackOrQueuePrinter) + printer.add('tuple', TuplePrinter) + printer.add('pair', PairPrinter) + printer.add('set', SetPrinter) + printer.add('stack', StackOrQueuePrinter) + printer.add('unique_ptr', UniquePointerPrinter) + printer.add('vector', VectorPrinter) # vector<bool> - # Printer registrations for classes compiled with -D_GLIBCXX_DEBUG. - libcxx_printer.add('std::__debug::bitset', StdBitsetPrinter) - libcxx_printer.add('std::__debug::deque', StdDequePrinter) - libcxx_printer.add('std::__debug::list', StdListPrinter) - libcxx_printer.add('std::__debug::map', StdMapPrinter) - libcxx_printer.add('std::__debug::multimap', StdMapPrinter) - libcxx_printer.add('std::__debug::multiset', StdSetPrinter) - libcxx_printer.add('std::__debug::priority_queue', StdStackOrQueuePrinter) - libcxx_printer.add('std::__debug::queue', StdStackOrQueuePrinter) - libcxx_printer.add('std::__debug::set', StdSetPrinter) - libcxx_printer.add('std::__debug::stack', StdStackOrQueuePrinter) - libcxx_printer.add('std::__debug::unique_ptr', UniquePointerPrinter) - libcxx_printer.add('std::__debug::vector', StdVectorPrinter) - # For array - the default GDB pretty-printer seems reasonable. - libcxx_printer.add_version('std::', 'shared_ptr', SharedPointerPrinter) - libcxx_printer.add_version('std::', 'weak_ptr', SharedPointerPrinter) - libcxx_printer.add_container('std::', 'unordered_map', UnorderedMapPrinter) - libcxx_printer.add_container('std::', 'unordered_set', UnorderedSetPrinter) - libcxx_printer.add_container('std::', 'unordered_multimap', - UnorderedMapPrinter) - libcxx_printer.add_container('std::', 'unordered_multiset', - UnorderedSetPrinter) - libcxx_printer.add_container( - 'std::', 'forward_list', StdForwardListPrinter) + printer.add('shared_ptr', SharedPointerPrinter) + printer.add('weak_ptr', SharedPointerPrinter) + printer.add('unordered_map', UnorderedMapPrinter) + printer.add('unordered_set', UnorderedSetPrinter) + printer.add('unordered_multimap', UnorderedMapPrinter) + printer.add('unordered_multiset', UnorderedSetPrinter) + printer.add('forward_list', ForwardListPrinter) - libcxx_printer.add_version('std::', 'shared_ptr', SharedPointerPrinter) - libcxx_printer.add_version('std::', 'weak_ptr', SharedPointerPrinter) - libcxx_printer.add_version('std::', 'unordered_map', UnorderedMapPrinter) - libcxx_printer.add_version('std::', 'unordered_set', UnorderedSetPrinter) - libcxx_printer.add_version('std::', 'unordered_multimap', - UnorderedMapPrinter) - libcxx_printer.add_version('std::', 'unordered_multiset', - UnorderedSetPrinter) + printer.add('shared_ptr', SharedPointerPrinter) + printer.add('weak_ptr', SharedPointerPrinter) + printer.add('unordered_map', UnorderedMapPrinter) + printer.add('unordered_set', UnorderedSetPrinter) + printer.add('unordered_multimap', UnorderedMapPrinter) + printer.add('unordered_multiset', UnorderedSetPrinter) - # These are the C++0x printer registrations for -D_GLIBCXX_DEBUG cases. - libcxx_printer.add('std::__debug::unordered_map', UnorderedMapPrinter) - libcxx_printer.add('std::__debug::unordered_set', UnorderedSetPrinter) - libcxx_printer.add('std::__debug::unordered_multimap', UnorderedMapPrinter) - libcxx_printer.add('std::__debug::unordered_multiset', UnorderedSetPrinter) - libcxx_printer.add('std::__debug::forward_list', StdForwardListPrinter) + printer.add('__list_iterator', ListIteratorPrinter) + printer.add('__list_const_iterator', ListIteratorPrinter) + printer.add('__tree_iterator', RbtreeIteratorPrinter) + printer.add('__tree_const_iterator', RbtreeIteratorPrinter) + printer.add('__hash_iterator', HashtableIteratorPrinter) + printer.add('__hash_const_iterator', HashtableIteratorPrinter) + printer.add('__hash_map_iterator', UnorderedMapIteratorPrinter) + printer.add('__hash_map_const_iterator', UnorderedMapIteratorPrinter) + printer.add('__map_iterator', MapIteratorPrinter) + printer.add('__map_const_iterator', MapIteratorPrinter) + printer.add('__deque_iterator', DequeIteratorPrinter) + printer.add('__wrap_iter', VectorIteratorPrinter) + printer.add('__bit_iterator', VectorBoolIteratorPrinter) - libcxx_printer.add_container('std::', '__list_iterator', - StdListIteratorPrinter) - libcxx_printer.add_container('std::', '__list_const_iterator', - StdListIteratorPrinter) - libcxx_printer.add_version('std::', '__tree_iterator', - StdRbtreeIteratorPrinter) - libcxx_printer.add_version('std::', '__tree_const_iterator', - StdRbtreeIteratorPrinter) - libcxx_printer.add_version('std::', '__hash_iterator', - StdHashtableIteratorPrinter) - libcxx_printer.add_version('std::', '__hash_const_iterator', - StdHashtableIteratorPrinter) - libcxx_printer.add_version('std::', '__hash_map_iterator', - StdUnorderedMapIteratorPrinter) - libcxx_printer.add_version('std::', '__hash_map_const_iterator', - StdUnorderedMapIteratorPrinter) - libcxx_printer.add_version('std::', '__map_iterator', - StdMapIteratorPrinter) - libcxx_printer.add_version('std::', '__map_const_iterator', - StdMapIteratorPrinter) - libcxx_printer.add_container('std::', '__deque_iterator', - StdDequeIteratorPrinter) - libcxx_printer.add_version('std::', '__wrap_iter', - StdVectorIteratorPrinter) - libcxx_printer.add_version('std::', '__bit_iterator', - StdVectorBoolIteratorPrinter) - - # Debug (compiled with -D_GLIBCXX_DEBUG) printer - # registrations. The Rb_tree debug iterator when unwrapped - # from the encapsulating __gnu_debug::_Safe_iterator does not - # have the __norm namespace. Just use the existing printer - # registration for that. - libcxx_printer.add('std::__norm::__list_iterator', - StdListIteratorPrinter) - libcxx_printer.add('std::__norm::__list_const_iterator', - StdListIteratorPrinter) - libcxx_printer.add('std::__norm::__deque_iterator', - StdDequeIteratorPrinter) build_libcxx_dictionary()
diff --git a/third_party/libcxx-pretty-printers/src/gdbinit b/third_party/libcxx-pretty-printers/src/gdbinit deleted file mode 100644 index c45e420..0000000 --- a/third_party/libcxx-pretty-printers/src/gdbinit +++ /dev/null
@@ -1,6 +0,0 @@ -python -import sys -sys.path.insert(0, '<path_to_libcxx-pp_src_dir>') -from libcxx.v1.printers import register_libcxx_printers -register_libcxx_printers (None) -end
diff --git a/third_party/libcxx-pretty-printers/src/libcxx/__init__.py b/third_party/libcxx-pretty-printers/src/libcxx/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/third_party/libcxx-pretty-printers/src/libcxx/__init__.py +++ /dev/null
@@ -1 +0,0 @@ -
diff --git a/third_party/libcxx-pretty-printers/src/libcxx/v1/__init__.py b/third_party/libcxx-pretty-printers/src/libcxx/v1/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/third_party/libcxx-pretty-printers/src/libcxx/v1/__init__.py +++ /dev/null
@@ -1 +0,0 @@ -
diff --git a/third_party/libwebm/OWNERS b/third_party/libwebm/OWNERS index ca0fd18a..43542744 100644 --- a/third_party/libwebm/OWNERS +++ b/third_party/libwebm/OWNERS
@@ -1,12 +1,9 @@ # The following OWNERS refer to libwebm Chromium integration. emircan@chromium.org +mcasas@chromium.org niklase@chromium.org # The following OWNER refer to libwebm content. tomfinegan@chromium.org -# Original (legacy) owner. -mcasas@chromium.org - -# TEAM: webrtc-dev@chromium.org # COMPONENT: Blink>MediaRecording
diff --git a/tools/gdb/gdbinit b/tools/gdb/gdbinit index f85c233e..99143aee 100644 --- a/tools/gdb/gdbinit +++ b/tools/gdb/gdbinit
@@ -35,11 +35,11 @@ if git.returncode: return libcxx_pretty_printers = os.path.join(str(src_dir).rstrip(), 'third_party', - 'libcxx-pretty-printers', 'src') + 'libcxx-pretty-printers') if not os.path.isdir(libcxx_pretty_printers): return sys.path.insert(1, libcxx_pretty_printers) - from libcxx.v1.printers import register_libcxx_printers + from printers import register_libcxx_printers register_libcxx_printers(None) libcxx_pretty_printers_loaded = True
diff --git a/tools/grit/grit/scons.py b/tools/grit/grit/scons.py deleted file mode 100644 index 71d45fc..0000000 --- a/tools/grit/grit/scons.py +++ /dev/null
@@ -1,254 +0,0 @@ -# Copyright (c) 2012 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. - -'''SCons integration for GRIT. -''' - -# NOTE: DO NOT IMPORT ANY GRIT STUFF HERE - we import lazily so that -# grit and its dependencies aren't imported until actually needed. - -import os -import types - -def _IsDebugEnabled(): - return 'GRIT_DEBUG' in os.environ and os.environ['GRIT_DEBUG'] == '1' - -def _SourceToFile(source): - '''Return the path to the source file, given the 'source' argument as provided - by SCons to the _Builder or _Emitter functions. - ''' - # Get the filename of the source. The 'source' parameter can be a string, - # a "node", or a list of strings or nodes. - if isinstance(source, types.ListType): - source = str(source[0]) - else: - source = str(source) - return source - - -def _ParseRcFlags(flags): - """Gets a mapping of defines. - - Args: - flags: env['RCFLAGS']; the input defines. - - Returns: - A tuple of (defines, res_file): - defines: A mapping of {name: val} - res_file: None, or the specified res file for static file dependencies. - """ - from grit import util - - defines = {} - res_file = None - # Get the CPP defines from the environment. - res_flag = '--res_file=' - for flag in flags: - if flag.startswith(res_flag): - res_file = flag[len(res_flag):] - continue - if flag.startswith('/D'): - flag = flag[2:] - name, val = util.ParseDefine(flag) - # Only apply to first instance of a given define - if name not in defines: - defines[name] = val - return (defines, res_file) - - -def _Builder(target, source, env): - print _SourceToFile(source) - - from grit import grit_runner - from grit.tool import build - options = grit_runner.Options() - # This sets options to default values - options.ReadOptions([]) - options.input = _SourceToFile(source) - - # TODO(joi) Check if we can get the 'verbose' option from the environment. - - builder = build.RcBuilder(defines=_ParseRcFlags(env['RCFLAGS'])[0]) - - # To ensure that our output files match what we promised SCons, we - # use the list of targets provided by SCons and update the file paths in - # our .grd input file with the targets. - builder.scons_targets = [str(t) for t in target] - builder.Run(options, []) - return None # success - - -def _GetOutputFiles(grd, base_dir): - """Processes outputs listed in the grd into rc_headers and rc_alls. - - Note that anything that's not an rc_header is classified as an rc_all. - - Args: - grd: An open GRD reader. - - Returns: - A tuple of (rc_headers, rc_alls, lang_folders): - rc_headers: Outputs marked as rc_header. - rc_alls: All other outputs. - lang_folders: The output language folders. - """ - rc_headers = [] - rc_alls = [] - lang_folders = {} - - # Explicit output files. - for output in grd.GetOutputFiles(): - path = os.path.join(base_dir, output.GetFilename()) - if (output.GetType() == 'rc_header'): - rc_headers.append(path) - else: - rc_alls.append(path) - if _IsDebugEnabled(): - print 'GRIT: Added target %s' % path - if output.attrs['lang'] != '': - lang_folders[output.attrs['lang']] = os.path.dirname(path) - - return (rc_headers, rc_alls, lang_folders) - - -def _ProcessNodes(grd, base_dir, lang_folders): - """Processes the GRD nodes to figure out file dependencies. - - Args: - grd: An open GRD reader. - base_dir: The base directory for filenames. - lang_folders: THe output language folders. - - Returns: - A tuple of (structure_outputs, translated_files, static_files): - structure_outputs: Structures marked as sconsdep. - translated_files: Files that are structures or skeletons, and get - translated by GRIT. - static_files: Files that are includes, and are used directly by res files. - """ - structure_outputs = [] - translated_files = [] - static_files = [] - - # Go through nodes, figuring out resources. Also output certain resources - # as build targets, based on the sconsdep flag. - for node in grd.ActiveDescendants(): - with node: - file = node.ToRealPath(node.GetInputPath()) - if node.name == 'structure': - translated_files.append(os.path.abspath(file)) - # TODO(joi) Should remove the "if sconsdep is true" thing as it is a - # hack - see grit/node/structure.py - if node.HasFileForLanguage() and node.attrs['sconsdep'] == 'true': - for lang in lang_folders: - path = node.FileForLanguage(lang, lang_folders[lang], - create_file=False, - return_if_not_generated=False) - if path: - structure_outputs.append(path) - if _IsDebugEnabled(): - print 'GRIT: Added target %s' % path - elif (node.name == 'skeleton' or (node.name == 'file' and node.parent and - node.parent.name == 'translations')): - translated_files.append(os.path.abspath(file)) - elif node.name == 'include': - # If it's added by file name and the file isn't easy to find, don't make - # it a dependency. This could add some build flakiness, but it doesn't - # work otherwise. - if node.attrs['filenameonly'] != 'true' or os.path.exists(file): - static_files.append(os.path.abspath(file)) - # If it's output from mk, look in the output directory. - elif node.attrs['mkoutput'] == 'true': - static_files.append(os.path.join(base_dir, os.path.basename(file))) - - return (structure_outputs, translated_files, static_files) - - -def _SetDependencies(env, base_dir, res_file, rc_alls, translated_files, - static_files): - """Sets dependencies in the environment. - - Args: - env: The SCons environment. - base_dir: The base directory for filenames. - res_file: The res_file specified in the RC flags. - rc_alls: All non-rc_header outputs. - translated_files: Files that are structures or skeletons, and get - translated by GRIT. - static_files: Files that are includes, and are used directly by res files. - """ - if res_file: - env.Depends(os.path.join(base_dir, res_file), static_files) - else: - # Make a best effort dependency setup when no res file is specified. - translated_files.extend(static_files) - - for rc_all in rc_alls: - env.Depends(rc_all, translated_files) - - -def _Emitter(target, source, env): - """Modifies the list of targets to include all outputs. - - Note that this also sets up the dependencies, even though it's an emitter - rather than a scanner. This is so that the resource header file doesn't show - as having dependencies. - - Args: - target: The list of targets to emit for. - source: The source or list of sources for the target. - env: The SCons environment. - - Returns: - A tuple of (targets, sources). - """ - from grit import grd_reader - from grit import util - - (defines, res_file) = _ParseRcFlags(env['RCFLAGS']) - - grd = grd_reader.Parse(_SourceToFile(source), debug=_IsDebugEnabled()) - # TODO(jperkins): This is a hack to get an output context set for the reader. - # This should really be smarter about the language. - grd.SetOutputLanguage('en') - grd.SetDefines(defines) - - base_dir = util.dirname(str(target[0])) - (rc_headers, rc_alls, lang_folders) = _GetOutputFiles(grd, base_dir) - (structure_outputs, translated_files, static_files) = _ProcessNodes(grd, - base_dir, lang_folders) - - rc_alls.extend(structure_outputs) - _SetDependencies(env, base_dir, res_file, rc_alls, translated_files, - static_files) - - targets = rc_headers - targets.extend(rc_alls) - - # Return target and source lists. - return (targets, source) - - -# Function name is mandated by newer versions of SCons. -def generate(env): - # Importing this module should be possible whenever this function is invoked - # since it should only be invoked by SCons. - import SCons.Builder - import SCons.Action - - # The varlist parameter tells SCons that GRIT needs to be invoked again - # if RCFLAGS has changed since last compilation. - build_action = SCons.Action.FunctionAction(_Builder, varlist=['RCFLAGS']) - emit_action = SCons.Action.FunctionAction(_Emitter, varlist=['RCFLAGS']) - - builder = SCons.Builder.Builder(action=build_action, emitter=emit_action, - src_suffix='.grd') - - # Add our builder and scanner to the environment. - env.Append(BUILDERS = {'GRIT': builder}) - - -# Function name is mandated by newer versions of SCons. -def exists(env): - return 1
diff --git a/tools/grit/grit/tool/build.py b/tools/grit/grit/tool/build.py index ecebf7c..46ea4ba 100644 --- a/tools/grit/grit/tool/build.py +++ b/tools/grit/grit/tool/build.py
@@ -2,8 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -'''The 'grit build' tool along with integration for this tool with the -SCons build system. +'''The 'grit build' tool. ''' import codecs @@ -218,12 +217,9 @@ print 'This tool takes no tool-specific arguments.' return 2 self.SetOptions(opts) - if self.scons_targets: - self.VerboseOut('Using SCons targets to identify files to output.\n') - else: - self.VerboseOut('Output directory: %s (absolute path: %s)\n' % - (self.output_directory, - os.path.abspath(self.output_directory))) + self.VerboseOut('Output directory: %s (absolute path: %s)\n' % + (self.output_directory, + os.path.abspath(self.output_directory))) if whitelist_filenames: self.whitelist_names = set() @@ -281,11 +277,6 @@ # has been called, otherwise None. self.res = None - # Set to a list of filenames for the output nodes that are relative - # to the current working directory. They are in the same order as the - # output nodes in the file. - self.scons_targets = None - # The set of names that are whitelisted to actually be included in the # output. self.whitelist_names = None @@ -351,20 +342,9 @@ return 'utf_16' def Process(self): - # Update filenames with those provided by SCons if we're being invoked - # from SCons. The list of SCons targets also includes all <structure> - # node outputs, but it starts with our output files, in the order they - # occur in the .grd - if self.scons_targets: - assert len(self.scons_targets) >= len(self.res.GetOutputFiles()) - outfiles = self.res.GetOutputFiles() - for ix in range(len(outfiles)): - outfiles[ix].output_filename = os.path.abspath( - self.scons_targets[ix]) - else: - for output in self.res.GetOutputFiles(): - output.output_filename = os.path.abspath(os.path.join( - self.output_directory, output.GetOutputFilename())) + for output in self.res.GetOutputFiles(): + output.output_filename = os.path.abspath(os.path.join( + self.output_directory, output.GetOutputFilename())) # If there are whitelisted names, tag the tree once up front, this way # while looping through the actual output, it is just an attribute check. @@ -490,7 +470,9 @@ and we run - grit -i blah.grd -o ../out/gen --depdir ../out --depfile ../out/gen/blah.rd.d + grit -i blah.grd -o ../out/gen \ + --depdir ../out \ + --depfile ../out/gen/blah.rd.d from the directory src/ we will generate a depfile ../out/gen/blah.grd.d that has the contents
diff --git a/tools/idl_parser/idl_lexer.py b/tools/idl_parser/idl_lexer.py index e39650175..b7e0674 100755 --- a/tools/idl_parser/idl_lexer.py +++ b/tools/idl_parser/idl_lexer.py
@@ -71,7 +71,6 @@ 'float' : 'FLOAT', 'FrozenArray' : 'FROZENARRAY', 'getter': 'GETTER', - 'implements' : 'IMPLEMENTS', 'includes' : 'INCLUDES', 'Infinity' : 'INFINITY', 'inherit' : 'INHERIT',
diff --git a/tools/idl_parser/idl_parser.py b/tools/idl_parser/idl_parser.py index e53489d..17f05c3 100755 --- a/tools/idl_parser/idl_parser.py +++ b/tools/idl_parser/idl_parser.py
@@ -259,7 +259,6 @@ | Dictionary | Enum | Typedef - | ImplementsStatement | IncludesStatement""" p[0] = p[1] @@ -497,11 +496,6 @@ """Typedef : TYPEDEF error ';'""" p[0] = self.BuildError(p, 'Typedef') - def p_ImplementsStatement(self, p): - """ImplementsStatement : identifier IMPLEMENTS identifier ';'""" - name = self.BuildAttribute('REFERENCE', p[3]) - p[0] = self.BuildNamed('Implements', p, 1, name) - def p_IncludesStatement(self, p): """IncludesStatement : identifier INCLUDES identifier ';'""" name = self.BuildAttribute('REFERENCE', p[3]) @@ -825,7 +819,6 @@ | DICTIONARY | ENUM | GETTER - | IMPLEMENTS | INCLUDES | INHERIT | LEGACYCALLER
diff --git a/tools/idl_parser/idl_parser_test.py b/tools/idl_parser/idl_parser_test.py index 4d27abe..d7c8a5d 100755 --- a/tools/idl_parser/idl_parser_test.py +++ b/tools/idl_parser/idl_parser_test.py
@@ -52,52 +52,52 @@ self._TestNode(node, filename) -class TestImplements(unittest.TestCase): +class TestIncludes(unittest.TestCase): def setUp(self): self.parser = IDLParser(IDLLexer(), mute_error=True) - def _ParseImplements(self, idl_text): + def _ParseIncludes(self, idl_text): filenode = self.parser.ParseText(filename='', data=idl_text) self.assertEqual(1, len(filenode.GetChildren())) return filenode.GetChildren()[0] - def testAImplementsB(self): - idl_text = 'A implements B;' - implements_node = self._ParseImplements(idl_text) - self.assertEqual('Implements(A)', str(implements_node)) - reference_node = implements_node.GetProperty('REFERENCE') + def testAIncludesB(self): + idl_text = 'A includes B;' + includes_node = self._ParseIncludes(idl_text) + self.assertEqual('Includes(A)', str(includes_node)) + reference_node = includes_node.GetProperty('REFERENCE') self.assertEqual('B', str(reference_node)) - def testBImplementsC(self): - idl_text = 'B implements C;' - implements_node = self._ParseImplements(idl_text) - self.assertEqual('Implements(B)', str(implements_node)) - reference_node = implements_node.GetProperty('REFERENCE') + def testBIncludesC(self): + idl_text = 'B includes C;' + includes_node = self._ParseIncludes(idl_text) + self.assertEqual('Includes(B)', str(includes_node)) + reference_node = includes_node.GetProperty('REFERENCE') self.assertEqual('C', str(reference_node)) def testUnexpectedSemicolon(self): - idl_text = 'A implements;' - node = self._ParseImplements(idl_text) + idl_text = 'A includes;' + node = self._ParseIncludes(idl_text) self.assertEqual('Error', node.GetClass()) error_message = node.GetName() - self.assertEqual('Unexpected ";" after keyword "implements".', + self.assertEqual('Unexpected ";" after keyword "includes".', error_message) - def testUnexpectedImplements(self): - idl_text = 'implements C;' - node = self._ParseImplements(idl_text) + def testUnexpectedIncludes(self): + idl_text = 'includes C;' + node = self._ParseIncludes(idl_text) self.assertEqual('Error', node.GetClass()) error_message = node.GetName() - self.assertEqual('Unexpected implements.', + self.assertEqual('Unexpected includes.', error_message) - def testUnexpectedImplementsAfterBracket(self): - idl_text = '[foo] implements B;' - node = self._ParseImplements(idl_text) + def testUnexpectedIncludesAfterBracket(self): + idl_text = '[foo] includes B;' + node = self._ParseIncludes(idl_text) self.assertEqual('Error', node.GetClass()) error_message = node.GetName() - self.assertEqual('Unexpected keyword "implements" after "]".', + self.assertEqual('Unexpected keyword "includes" after "]".', error_message)
diff --git a/tools/idl_parser/test_lexer/keywords.in b/tools/idl_parser/test_lexer/keywords.in index 612facfd..c175d28 100644 --- a/tools/idl_parser/test_lexer/keywords.in +++ b/tools/idl_parser/test_lexer/keywords.in
@@ -15,7 +15,6 @@ FALSE false FLOAT float GETTER getter -IMPLEMENTS implements INFINITY Infinity INHERIT inherit INTERFACE interface
diff --git a/tools/idl_parser/test_parser/interface_web.idl b/tools/idl_parser/test_parser/interface_web.idl index 58e744d..566e27a 100644 --- a/tools/idl_parser/test_parser/interface_web.idl +++ b/tools/idl_parser/test_parser/interface_web.idl
@@ -617,12 +617,6 @@ [ Exposed(Window, Worker) ] interface InterfaceExposedError { }; /** TREE - *Implements(Foo) - * REFERENCE: Bar - */ -Foo implements Bar; - -/** TREE *Includes(Foo) * REFERENCE: Bar */
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 496c60d..5d7a0e9 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -168,6 +168,8 @@ 'Dawn Linux x64 Builder': 'dawn_tests_release_trybot', 'Dawn Linux x64 DEPS Builder': 'dawn_tests_release_trybot', + 'Dawn Mac x64 Builder': 'dawn_tests_release_trybot', + 'Dawn Win10 x86 Builder': 'dawn_tests_release_trybot_x86', 'Dawn Win10 x64 Builder': 'dawn_tests_release_trybot', 'Dawn Win10 x86 DEPS Builder': 'dawn_tests_release_trybot_x86',
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 86d5826..3553b23 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -34177,6 +34177,7 @@ <int value="1298981651" label="disable-new-task-manager"/> <int value="1300282719" label="OfflinePagesBackgroundLoading:enabled"/> <int value="1300753556" label="ManualPasswordGenerationAndroid:disabled"/> + <int value="1301902557" label="AutofillCreditCardAuthentication:disabled"/> <int value="1302421166" label="NativeNotifications:disabled"/> <int value="1304636193" label="ArcEnableUnifiedAudioFocus:enabled"/> <int value="1307003774" label="AutofillEnableCompanyName:disabled"/> @@ -34293,6 +34294,7 @@ <int value="1479248574" label="disable-voice-input"/> <int value="1481562816" label="disable-password-link"/> <int value="1482039233" label="SearchSuggestionsOnLocalNtp:disabled"/> + <int value="1482839038" label="AutofillCreditCardAuthentication:enabled"/> <int value="1486171015" label="disable-fill-on-account-select"/> <int value="1487341558" label="MacViewsAutofillPopup:enabled"/> <int value="1488193175" label="ChromeOSAssistant:enabled"/>
diff --git a/tools/metrics/histograms/pretty_print.py b/tools/metrics/histograms/pretty_print.py index dd57976d..a72d2c5 100755 --- a/tools/metrics/histograms/pretty_print.py +++ b/tools/metrics/histograms/pretty_print.py
@@ -59,24 +59,33 @@ def fixObsoleteOrder(tree): """Put obsolete tags at the beginning of histogram tags.""" + obsoletes = [] + for child in tree: - obsoletes = [] if child.tag == 'obsolete': obsoletes.append(child) - for obsolete in obsoletes: - tree.remove(obsolete) - tree.insert(0, obsolete) - fixObsoleteOrder(child) + else: + fixObsoleteOrder(child) + + for obsolete in obsoletes: + tree.remove(obsolete) + + # Only keep the first obsolete tag. + if obsoletes: + tree.insert(0, obsoletes[0]) def DropNodesByTagName(tree, tag): """Drop all nodes with named tag from the XML tree.""" + removes = [] + for child in tree: - removes = [] if child.tag == tag: removes.append(child) - for child in removes: - tree.remove(child) - DropNodesByTagName(child, tag) + else: + DropNodesByTagName(child, tag) + + for child in removes: + tree.remove(child) def PrettyPrintHistograms(raw_xml): """Pretty-print the given histograms XML.
diff --git a/tools/metrics/histograms/pretty_print_test.py b/tools/metrics/histograms/pretty_print_test.py index e0c1280c..07f91e2 100755 --- a/tools/metrics/histograms/pretty_print_test.py +++ b/tools/metrics/histograms/pretty_print_test.py
@@ -27,6 +27,9 @@ </histogram> <histogram name="Foo.Bar" units="xxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyzzzz"> <summary>Foo</summary> + <obsolete>Obsolete 1</obsolete> + <obsolete>Obsolete 2</obsolete> + <enums>This shouldn't be here</enums> </histogram> </histograms> <enums>This shouldn't be here</enums> @@ -43,6 +46,9 @@ <histograms> <histogram name="Foo.Bar" units="xxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyzzzz"> + <obsolete> + Obsolete 1 + </obsolete> <summary>Foo</summary> </histogram>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 3bb08260..a2e4927 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -42,6 +42,44 @@ </metric> </event> +<event name="AbusiveExperienceHeuristic.JavaScriptDialog"> + <owner>yaoxia@chromium.org</owner> + <metric name="DismissalCause"> + <summary> + An enum that specifies the dismissal reason for JavaScript popup dialog + that can be triggered by window.alert(), window.confirm() or + window.prompt(). See JavaScriptDialogTabHelper::DismissalCause for the + enum elements. + </summary> + </metric> +</event> + +<event name="AbusiveExperienceHeuristic.TabUnder"> + <owner>csharrison@chromium.org</owner> + <metric name="DidTabUnder"> + <summary> + True if the page attempted a tab-under navigation. + </summary> + </metric> +</event> + +<event name="AbusiveExperienceHeuristic.WindowOpen"> + <owner>yaoxia@chromium.org</owner> + <summary> + Recorded whenever window.open() is called when AdTagging is enabled. + </summary> + <metric name="FromAdScript"> + <summary> + True if the page called window.open() with an ad script in the stack. + </summary> + </metric> + <metric name="FromAdSubframe"> + <summary> + True if the page called window.open() from an ad subframe. + </summary> + </metric> +</event> + <event name="AdPageLoad"> <owner>johnidel@chromium.org</owner> <owner>jkarlin@chromium.org</owner> @@ -87,44 +125,6 @@ </metric> </event> -<event name="AbusiveExperienceHeuristic.TabUnder"> - <owner>csharrison@chromium.org</owner> - <metric name="DidTabUnder"> - <summary> - True if the page attempted a tab-under navigation. - </summary> - </metric> -</event> - -<event name="AbusiveExperienceHeuristic.WindowOpen"> - <owner>yaoxia@chromium.org</owner> - <summary> - Recorded whenever window.open() is called when AdTagging is enabled. - </summary> - <metric name="FromAdScript"> - <summary> - True if the page called window.open() with an ad script in the stack. - </summary> - </metric> - <metric name="FromAdSubframe"> - <summary> - True if the page called window.open() from an ad subframe. - </summary> - </metric> -</event> - -<event name="AbusiveExperienceHeuristic.JavaScriptDialog"> - <owner>yaoxia@chromium.org</owner> - <metric name="DismissalCause"> - <summary> - An enum that specifies the dismissal reason for JavaScript popup dialog - that can be triggered by window.alert(), window.confirm() or - window.prompt(). See JavaScriptDialogTabHelper::DismissalCause for the - enum elements. - </summary> - </metric> -</event> - <event name="AmpPageLoad" singular="True"> <owner>sullivan@chromium.org</owner> <metric name="MainFrameAmpPageLoad"> @@ -185,93 +185,6 @@ </metric> </event> -<event name="Autofill.CardUploadDecision"> - <owner>sebsg@chromium.org</owner> - <metric name="UploadDecision"> - <summary> - Whether the upload was proposed to the user or the reasons why it was not. - The value is a bitmask of |CardUploadDecisionMetric|. - </summary> - </metric> -</event> - -<event name="AppListAppLaunch"> - <owner>pdyson@chromium.org</owner> - <summary> - Recorded when an app is launched from the launcher on ChromeOS. This can be - from the suggestion chip, or from the grid of apps. The UKM metrics are not - keyed by navigational urls. Instead, for Chrome apps the keys are based upon - the app id, for Play apps the keys are based upon a hash of the package name - and for PWAs the keys are the urls associated with the PWA. - </summary> - <metric name="AllClicksLast24Hours"> - <summary> - Total number of clicks launching logged apps in the last 24 hours. - Accurate to the nearest 15 minutes. Bucketing: values above 20 rounded - down to the nearest 10. Maximum value of 200. - </summary> - </metric> - <metric name="AllClicksLastHour"> - <summary> - Total number of clicks launching logged apps in the last hour. Accurate to - the nearest minute. Bucketing: values above 20 rounded down to the nearest - 10. Maximum value of 200. - </summary> - </metric> - <metric name="AppType"> - <summary> - The type of app. 1: CHROME, 2: PLAY, 3: PWA. - </summary> - </metric> - <metric name="ClickMethod"> - <summary> - Click method. 1: MOUSE, 2: TOUCH, 3: SYTLUS, 4: KEYBOARD. - </summary> - </metric> - <metric name="DayOfWeek"> - <summary> - An enum representing the day of the week that the data was logged in the - local time zone. Sunday = 0. - </summary> - </metric> - <metric name="DeviceMode"> - <summary> - The mode of the device. 1: CLOSED_LID (Lid is closed), 2: LAPTOP (Lid is - open, tablet mode off or unsupported) , 3: TABLET (Lid is open, tablet - mode on or no lid at all). - </summary> - </metric> - <metric name="DeviceType"> - <summary> - The type of the device. 1: TABLET, 2: LAPTOP. - </summary> - </metric> - <metric name="HourOfDay"> - <summary> - The hour of the day when the data is logged. Hours since midnight in the - local time zone. - </summary> - </metric> - <metric name="LaunchedFrom"> - <summary> - Where the app was launched from. 1: GRID, 2: SUGGESTED, 3: SHELF. - </summary> - </metric> - <metric name="PositionIndex"> - <summary> - The position of the app within the grid/suggested apps/shelf. 0 is the - first position. - </summary> - </metric> - <metric name="TotalHours"> - <summary> - Number of hours in the current session up to this event. Bucketing: - exponential buckets, increasing in size by 25%, rounded to the nearest - integer. i.e. 0, 1, 2, 3, 4, 5, 6, 7, 9, 12, 15, 18, 23, 28, 36, 44... - </summary> - </metric> -</event> - <event name="AppListAppClickData"> <owner>pdyson@chromium.org</owner> <summary> @@ -508,6 +421,93 @@ </metric> </event> +<event name="AppListAppLaunch"> + <owner>pdyson@chromium.org</owner> + <summary> + Recorded when an app is launched from the launcher on ChromeOS. This can be + from the suggestion chip, or from the grid of apps. The UKM metrics are not + keyed by navigational urls. Instead, for Chrome apps the keys are based upon + the app id, for Play apps the keys are based upon a hash of the package name + and for PWAs the keys are the urls associated with the PWA. + </summary> + <metric name="AllClicksLast24Hours"> + <summary> + Total number of clicks launching logged apps in the last 24 hours. + Accurate to the nearest 15 minutes. Bucketing: values above 20 rounded + down to the nearest 10. Maximum value of 200. + </summary> + </metric> + <metric name="AllClicksLastHour"> + <summary> + Total number of clicks launching logged apps in the last hour. Accurate to + the nearest minute. Bucketing: values above 20 rounded down to the nearest + 10. Maximum value of 200. + </summary> + </metric> + <metric name="AppType"> + <summary> + The type of app. 1: CHROME, 2: PLAY, 3: PWA. + </summary> + </metric> + <metric name="ClickMethod"> + <summary> + Click method. 1: MOUSE, 2: TOUCH, 3: SYTLUS, 4: KEYBOARD. + </summary> + </metric> + <metric name="DayOfWeek"> + <summary> + An enum representing the day of the week that the data was logged in the + local time zone. Sunday = 0. + </summary> + </metric> + <metric name="DeviceMode"> + <summary> + The mode of the device. 1: CLOSED_LID (Lid is closed), 2: LAPTOP (Lid is + open, tablet mode off or unsupported) , 3: TABLET (Lid is open, tablet + mode on or no lid at all). + </summary> + </metric> + <metric name="DeviceType"> + <summary> + The type of the device. 1: TABLET, 2: LAPTOP. + </summary> + </metric> + <metric name="HourOfDay"> + <summary> + The hour of the day when the data is logged. Hours since midnight in the + local time zone. + </summary> + </metric> + <metric name="LaunchedFrom"> + <summary> + Where the app was launched from. 1: GRID, 2: SUGGESTED, 3: SHELF. + </summary> + </metric> + <metric name="PositionIndex"> + <summary> + The position of the app within the grid/suggested apps/shelf. 0 is the + first position. + </summary> + </metric> + <metric name="TotalHours"> + <summary> + Number of hours in the current session up to this event. Bucketing: + exponential buckets, increasing in size by 25%, rounded to the nearest + integer. i.e. 0, 1, 2, 3, 4, 5, 6, 7, 9, 12, 15, 18, 23, 28, 36, 44... + </summary> + </metric> +</event> + +<event name="Autofill.CardUploadDecision"> + <owner>sebsg@chromium.org</owner> + <metric name="UploadDecision"> + <summary> + Whether the upload was proposed to the user or the reasons why it was not. + The value is a bitmask of |CardUploadDecisionMetric|. + </summary> + </metric> +</event> + <event name="Autofill.DeveloperEngagement"> <owner>jiahuiguo@google.com</owner> <summary> @@ -629,129 +629,6 @@ </metric> </event> -<event name="Autofill.HiddenRepresentationalFieldSkipDecision"> - <owner>parastoog@chromium.org</owner> - <summary> - Recorded while trying to fill or preview a hidden or a representational - field. - </summary> - <metric name="FieldOverallType"> - <summary> - Field's overall |ServerFieldType|. See |AutofillField.GetStorableType()|. - </summary> - </metric> - <metric name="FieldSignature"> - <summary> - The signature of the field. This is the hash identifier used to denote - this field for query and voting purposes. See - components/autofill/core/common/signatures_util.cc for more details. - </summary> - </metric> - <metric name="FieldTypeGroup"> - <summary> - Field's |FieldTypeGroup|. See |AutofillType.group()|. - </summary> - </metric> - <metric name="FormSignature"> - <summary> - The signature of the form. This is the hash identifier used to denote this - form for query and voting purposes. See - components/autofill/core/common/signatures_util.cc for more details. - </summary> - </metric> - <metric name="HeuristicType"> - <summary> - Field's |ServerFieldType| based on heuristics. See - |AutofillField.heuristic_type()|. - </summary> - </metric> - <metric name="HtmlFieldMode"> - <summary> - Whether the field's autocomplete hint specified 'billing' or 'shipping'. - See |AutofillField.html_mode()|. - </summary> - </metric> - <metric name="HtmlFieldType"> - <summary> - Field's autocomplete field type hint. See |AutofillField.html_type()|. - </summary> - </metric> - <metric name="IsSkipped"> - <summary> - True if the field was skipped while filling or previewing the form, - because it was hidden or representational, but not a 'select' one. - </summary> - </metric> - <metric name="ServerType"> - <summary> - Field's |ServerFieldType| returned by server. See - |AutofillField.server_type()|. - </summary> - </metric> -</event> - -<event name="Autofill.RepeatedServerTypePredictionRationalized"> - <owner>parastoog@chromium.org</owner> - <summary> - Recorded when a field type predicted by server is rationalized because of - repetition. - </summary> - <metric name="FieldNewOverallType"> - <summary> - Field's overall |ServerFieldType| after rationalization. See - |AutofillField.GetStorableType()|. - </summary> - </metric> - <metric name="FieldOldOverallType"> - <summary> - Field's overall |ServerFieldType| before rationalization. See - |AutofillField.GetStorableType()|. - </summary> - </metric> - <metric name="FieldSignature"> - <summary> - The signature of the field. This is the hash identifier used to denote - this field for query and voting purposes. See - components/autofill/core/common/signatures_util.cc for more details. - </summary> - </metric> - <metric name="FieldTypeGroup"> - <summary> - Field's |FieldTypeGroup|. See |AutofillType.group()|. - </summary> - </metric> - <metric name="FormSignature"> - <summary> - The signature of the form. This is the hash identifier used to denote this - form for query and voting purposes. See - components/autofill/core/common/signatures_util.cc for more details. - </summary> - </metric> - <metric name="HeuristicType"> - <summary> - Field's |ServerFieldType| based on heuristics. See - |AutofillField.heuristic_type()|. - </summary> - </metric> - <metric name="HtmlFieldMode"> - <summary> - Whether the field's autocomplete hint specified 'billing' or 'shipping'. - See |AutofillField.html_mode()|. - </summary> - </metric> - <metric name="HtmlFieldType"> - <summary> - Field's autocomplete field type hint. See |AutofillField.html_type()|. - </summary> - </metric> - <metric name="ServerType"> - <summary> - Field's |ServerFieldType| returned by server. See - |AutofillField.server_type()|. - </summary> - </metric> -</event> - <event name="Autofill.FormEvent"> <owner>dlkumar@google.com</owner> <summary> @@ -815,6 +692,67 @@ </metric> </event> +<event name="Autofill.HiddenRepresentationalFieldSkipDecision"> + <owner>parastoog@chromium.org</owner> + <summary> + Recorded while trying to fill or preview a hidden or a representational + field. + </summary> + <metric name="FieldOverallType"> + <summary> + Field's overall |ServerFieldType|. See |AutofillField.GetStorableType()|. + </summary> + </metric> + <metric name="FieldSignature"> + <summary> + The signature of the field. This is the hash identifier used to denote + this field for query and voting purposes. See + components/autofill/core/common/signatures_util.cc for more details. + </summary> + </metric> + <metric name="FieldTypeGroup"> + <summary> + Field's |FieldTypeGroup|. See |AutofillType.group()|. + </summary> + </metric> + <metric name="FormSignature"> + <summary> + The signature of the form. This is the hash identifier used to denote this + form for query and voting purposes. See + components/autofill/core/common/signatures_util.cc for more details. + </summary> + </metric> + <metric name="HeuristicType"> + <summary> + Field's |ServerFieldType| based on heuristics. See + |AutofillField.heuristic_type()|. + </summary> + </metric> + <metric name="HtmlFieldMode"> + <summary> + Whether the field's autocomplete hint specified 'billing' or 'shipping'. + See |AutofillField.html_mode()|. + </summary> + </metric> + <metric name="HtmlFieldType"> + <summary> + Field's autocomplete field type hint. See |AutofillField.html_type()|. + </summary> + </metric> + <metric name="IsSkipped"> + <summary> + True if the field was skipped while filling or previewing the form, + because it was hidden or representational, but not a 'select' one. + </summary> + </metric> + <metric name="ServerType"> + <summary> + Field's |ServerFieldType| returned by server. See + |AutofillField.server_type()|. + </summary> + </metric> +</event> + <event name="Autofill.InteractedWithForm"> <owner>jiahuiguo@google.com</owner> <summary> @@ -849,6 +787,68 @@ </metric> </event> +<event name="Autofill.RepeatedServerTypePredictionRationalized"> + <owner>parastoog@chromium.org</owner> + <summary> + Recorded when a field type predicted by server is rationalized because of + repetition. + </summary> + <metric name="FieldNewOverallType"> + <summary> + Field's overall |ServerFieldType| after rationalization. See + |AutofillField.GetStorableType()|. + </summary> + </metric> + <metric name="FieldOldOverallType"> + <summary> + Field's overall |ServerFieldType| before rationalization. See + |AutofillField.GetStorableType()|. + </summary> + </metric> + <metric name="FieldSignature"> + <summary> + The signature of the field. This is the hash identifier used to denote + this field for query and voting purposes. See + components/autofill/core/common/signatures_util.cc for more details. + </summary> + </metric> + <metric name="FieldTypeGroup"> + <summary> + Field's |FieldTypeGroup|. See |AutofillType.group()|. + </summary> + </metric> + <metric name="FormSignature"> + <summary> + The signature of the form. This is the hash identifier used to denote this + form for query and voting purposes. See + components/autofill/core/common/signatures_util.cc for more details. + </summary> + </metric> + <metric name="HeuristicType"> + <summary> + Field's |ServerFieldType| based on heuristics. See + |AutofillField.heuristic_type()|. + </summary> + </metric> + <metric name="HtmlFieldMode"> + <summary> + Whether the field's autocomplete hint specified 'billing' or 'shipping'. + See |AutofillField.html_mode()|. + </summary> + </metric> + <metric name="HtmlFieldType"> + <summary> + Field's autocomplete field type hint. See |AutofillField.html_type()|. + </summary> + </metric> + <metric name="ServerType"> + <summary> + Field's |ServerFieldType| returned by server. See + |AutofillField.server_type()|. + </summary> + </metric> +</event> + <event name="Autofill.SelectedMaskedServerCard"> <obsolete> Deprecated 2/2019 @@ -997,6 +997,70 @@ </metric> </event> +<event name="BackgroundFetch"> + <owner>nator@chromium.org</owner> + <owner>rayankans@chromium.org</owner> + <owner>peter@chromium.org</owner> + <summary> + A BackgroundFetch event is logged before a background fetch is started from + a document context. + </summary> + <metric name="DeniedDueToPermissions"> + <summary> + Boolean for whether the background fetch was denied due to permission. + This includes only the content setting permission. + </summary> + </metric> + <metric name="DownloadTotal"> + <summary> + The value of downloadTotal provided with the background fetch. This is the + number of bytes that the developer expects to be downloaded with the + background fetch. This number is exponentially bucketed for privacy + reasons, and uses the UKM GetExponentialBucketMin method with a value of + 2.0 for spacing. + </summary> + </metric> + <metric name="HasTitle"> + <summary> + Boolean for whether a title was provided with the background fetch. + </summary> + </metric> + <metric name="NumIcons"> + <summary> + Count of icons provided with the background fetch. + </summary> + </metric> + <metric name="NumRequestsInFetch"> + <summary> + Number of requests in the background fetch. This number is exponentially + bucketed for privacy reasons, and uses the UKM GetExponentialBucketMin + method with a value of 2.0 for spacing. + </summary> + </metric> + <metric name="RatioOfIdealToChosenIconSize"> + <summary> + Ratio of the ideal icon to the chosen icon size, times hundred. This will + be set to -1 if either ideal icon size is 0, or if none of the provided + icons are suitable. + </summary> + </metric> +</event> + +<event name="BackgroundFetchDeletingRegistration"> + <owner>nator@chromium.org</owner> + <owner>rayankans@chromium.org</owner> + <owner>peter@chromium.org</owner> + <summary> + A BackgroundFetchDeletingRegistration event is logged when a background + fetch job is being deleted. + </summary> + <metric name="UserInitiatedAbort"> + <summary> + Boolean for whether the background fetch job was cancelled from the UI. + </summary> + </metric> +</event> + <event name="Blink.UpdateTime"> <owner>schenney@chromium.org</owner> <summary> @@ -1801,6 +1865,18 @@ </metric> </event> +<event name="Compositor.Rendering"> + <owner>khushalsagar@chromium.org</owner> + <summary> + Metrics related to rendering in the compositor. + </summary> + <metric name="CheckerboardedImagesCount"> + <summary> + The number of images checker-imaged and re-rasterized on this page. + </summary> + </metric> +</event> + <event name="Compositor.UserInteraction"> <owner>khushalsagar@chromium.org</owner> <summary> @@ -1836,18 +1912,6 @@ </metric> </event> -<event name="Compositor.Rendering"> - <owner>khushalsagar@chromium.org</owner> - <summary> - Metrics related to rendering in the compositor. - </summary> - <metric name="CheckerboardedImagesCount"> - <summary> - The number of images checker-imaged and re-rasterized on this page. - </summary> - </metric> -</event> - <event name="ContextualSearch"> <owner>donnd@chromium.org</owner> <summary> @@ -2193,6 +2257,24 @@ </metric> </event> +<event name="Document.OutliveTimeAfterShutdown"> + <owner>hajimehoshi@chromium.org</owner> + <owner>keishi@chromium.org</owner> + <summary> + Recorded when a Document object survives certain number of garbage + collections after detached. It is expected that regular Document objects are + destroyed soon after detached, and if a document outlives longer, probably + this can be leaked. + </summary> + <metric name="GCCount"> + <summary> + Measures the numbers of garbarge collection after the document is + detached. This is recorded when the number reached certain numbers like 5 + or 10. + </summary> + </metric> +</event> + <event name="DocumentCreated"> <owner>beccahughes@chromium.org</owner> <summary> @@ -2218,62 +2300,6 @@ </metric> </event> -<event name="Document.OutliveTimeAfterShutdown"> - <owner>hajimehoshi@chromium.org</owner> - <owner>keishi@chromium.org</owner> - <summary> - Recorded when a Document object survives certain number of garbage - collections after detached. It is expected that regular Document objects are - destroyed soon after detached, and if a document outlives longer, probably - this can be leaked. - </summary> - <metric name="GCCount"> - <summary> - Measures the numbers of garbarge collection after the document is - detached. This is recorded when the number reached certain numbers like 5 - or 10. - </summary> - </metric> -</event> - -<event name="Download.Started"> - <owner>jming@chromium.org</owner> - <owner>xingliu@chromium.org</owner> - <summary> - Metrics taken when a download begins. It has one Download.Ended and none to - multiple Download.Interrupted/Download.Resumed events associated with it. - </summary> - <metric name="DownloadConnectionSecurity"> - <summary> - The state of the security of the final download URL and all the redirects - leading to it. Expressed as an enum defined in DownloadConnectionSecurity. - </summary> - </metric> - <metric name="DownloadId"> - <summary> - The id of the download that is used to associate separate events. - </summary> - </metric> - <metric name="DownloadSource"> - <summary> - The source of the download, expressed as an enum defined in DownloadEntry. - </summary> - </metric> - <metric name="FileType"> - <summary> - The type of file that is downloaded, expressed as an enum defined in - DownloadContentType. - </summary> - </metric> - <metric name="IsSameHostDownload"> - <summary> - A boolean denoting if the final download URL is the same host as the - initiating frame (i.e., whether the initiating site likely controls the - download itself). - </summary> - </metric> -</event> - <event name="Download.Completed"> <owner>jming@chromium.org</owner> <owner>xingliu@chromium.org</owner> @@ -2377,40 +2403,41 @@ </metric> </event> -<event name="Event.ScrollUpdate.Touch"> - <owner>nzolghadr@chromium.org</owner> +<event name="Download.Started"> + <owner>jming@chromium.org</owner> + <owner>xingliu@chromium.org</owner> <summary> - Metrics related to a scroll action caused by the generated ScrollUpdate - gesture event. + Metrics taken when a download begins. It has one Download.Ended and none to + multiple Download.Interrupted/Download.Resumed events associated with it. </summary> - <metric name="IsMainThread"> + <metric name="DownloadConnectionSecurity"> <summary> - Whether the event is handled on the main thread or not. + The state of the security of the final download URL and all the redirects + leading to it. Expressed as an enum defined in DownloadConnectionSecurity. </summary> </metric> - <metric name="TimeToHandled"> + <metric name="DownloadId"> <summary> - The time in microseconds between initial creation of a touch event and the - generated ScrollUpdate gesture event is handled on main/impl thread. If no - swap was induced by the ScrollUpdate gesture event, no recording is made. + The id of the download that is used to associate separate events. </summary> </metric> - <metric name="TimeToScrollUpdateSwapBegin"> + <metric name="DownloadSource"> <summary> - The time in microseconds between the initial creation of a touch event and - the start of the frame swap on the GPU service. If no swap was induced by - the event, no recording is made. The first GSU of every scrolling sequence - is excluded from this metric. + The source of the download, expressed as an enum defined in DownloadEntry. </summary> - <aggregation> - <history> - <index fields="profile.country"/> - <index fields="profile.country,profile.system_ram"/> - <statistics> - <quantiles type="std-percentiles"/> - </statistics> - </history> - </aggregation> + </metric> + <metric name="FileType"> + <summary> + The type of file that is downloaded, expressed as an enum defined in + DownloadContentType. + </summary> + </metric> + <metric name="IsSameHostDownload"> + <summary> + A boolean denoting if the final download URL is the same host as the + initiating frame (i.e., whether the initiating site likely controls the + download itself). + </summary> </metric> </event> @@ -2453,6 +2480,73 @@ </metric> </event> +<event name="Event.ScrollBegin.Wheel"> + <owner>nzolghadr@chromium.org</owner> + <summary> + Metrics related to first scroll action caused by the generated ScrollUpdate + gesture event. + </summary> + <metric name="IsMainThread"> + <summary> + Whether the event is handled on the main thread or not. + </summary> + </metric> + <metric name="TimeToHandled"> + <summary> + The time in microseconds between initial creation of a wheel event and the + first generated ScrollUpdate gesture event in a given scroll gesture event + sequence is handled on main/impl thread. If no swap was induced by the + ScrollBegin gesture event, no recording is made. + </summary> + </metric> + <metric name="TimeToScrollUpdateSwapBegin"> + <summary> + The time in microseconds between the initial creation of a wheel event and + the start of the frame swap on the GPU service caused by the generated + ScrollUpdate gesture event if that ScrollUpdate is the first such event in + a given scroll gesture event sequence. If no swap was induced by the + event, no recording is made. + </summary> + </metric> +</event> + +<event name="Event.ScrollUpdate.Touch"> + <owner>nzolghadr@chromium.org</owner> + <summary> + Metrics related to a scroll action caused by the generated ScrollUpdate + gesture event. + </summary> + <metric name="IsMainThread"> + <summary> + Whether the event is handled on the main thread or not. + </summary> + </metric> + <metric name="TimeToHandled"> + <summary> + The time in microseconds between initial creation of a touch event and the + generated ScrollUpdate gesture event is handled on main/impl thread. If no + swap was induced by the ScrollUpdate gesture event, no recording is made. + </summary> + </metric> + <metric name="TimeToScrollUpdateSwapBegin"> + <summary> + The time in microseconds between the initial creation of a touch event and + the start of the frame swap on the GPU service. If no swap was induced by + the event, no recording is made. The first GSU of every scrolling sequence + is excluded from this metric. + </summary> + <aggregation> + <history> + <index fields="profile.country"/> + <index fields="profile.country,profile.system_ram"/> + <statistics> + <quantiles type="std-percentiles"/> + </statistics> + </history> + </aggregation> + </metric> +</event> + <event name="Event.ScrollUpdate.Wheel"> <owner>nzolghadr@chromium.org</owner> <owner>tdresser@chromium.org</owner> @@ -2483,46 +2577,50 @@ </metric> </event> -<event name="Event.ScrollBegin.Wheel"> - <owner>nzolghadr@chromium.org</owner> +<event name="HistoryManipulationIntervention"> + <owner>shivanisha@chromium.org</owner> <summary> - Metrics related to first scroll action caused by the generated ScrollUpdate - gesture event. + Logged when an entry in the back-forward list is marked to be skipped on + subsequent back/forward button clicks as part of the history manipulation + intervention. This is logged when the entry is navigated away from. </summary> - <metric name="IsMainThread"> - <summary> - Whether the event is handled on the main thread or not. - </summary> - </metric> - <metric name="TimeToHandled"> - <summary> - The time in microseconds between initial creation of a wheel event and the - first generated ScrollUpdate gesture event in a given scroll gesture event - sequence is handled on main/impl thread. If no swap was induced by the - ScrollBegin gesture event, no recording is made. - </summary> - </metric> - <metric name="TimeToScrollUpdateSwapBegin"> - <summary> - The time in microseconds between the initial creation of a wheel event and - the start of the frame swap on the GPU service caused by the generated - ScrollUpdate gesture event if that ScrollUpdate is the first such event in - a given scroll gesture event sequence. If no swap was induced by the - event, no recording is made. - </summary> - </metric> </event> -<event name="PageForegroundSession"> - <owner>sullivan@chromium.org</owner> +<event name="HistoryNavigation" singular="True"> + <owner>altimin@chromium.org</owner> + <owner>arthursonzogni@chromium.org</owner> <summary> - Total time in foreground in milliseconds, recorded each time the page is - backgrounded. May be recorded multiple times for a single page visit. + Metrics recorded each time we commit a history navigation, which are needed + to estimate benefits of back-forward cache. </summary> - <metric name="ForegroundDuration"> + <metric name="LastCommittedSourceIdForTheSameDocument"> <summary> - Total time in foreground in milliseconds, recorded each time the page is - backgrounded. + For history navigations and reloads, the source id of the previous + navigation which loaded the page we're trying to navigate back to. + </summary> + </metric> + <metric name="NavigatedToTheMostRecentEntryForDocument"> + <summary> + Boolean for whether we navigated to the same navigation entry as the one + which was last visible. + + It can be false when subframes or same-document navigations are present. + For example, after navigating from http://foo to http://foo#bar and then + http://bar and then going back by 2 entries will mean we went to + http://foo while the last committed entry from this document was + http://foo#bar. + + It's expected to be rare, but might be problematic for back-forward cache. + </summary> + </metric> + <metric name="TimeSinceNavigatedAwayFromDocument"> + <summary> + Time in milliseconds from the moment the current navigation stopped being + active to the start of the current navigation. + + This is clamped to hours for values greater than 3 hours, to minutes for + values greater than 3 minutes, to seconds for values greater than 5 + seconds. </summary> </metric> </event> @@ -2555,6 +2653,41 @@ </metric> </event> +<event name="IOS.FindInPageSearchMatches"> + <owner>thegreenfrog@chromium.org</owner> + <owner>michaeldo@chromium.org</owner> + <summary> + Logged when the FindInPage returns a user search request result. + </summary> + <metric name="HasMatches"> + <summary> + True if there were matches. + </summary> + </metric> +</event> + +<event name="IOS.URLMismatchInLegacyAndSlimNavigationManager"> + <owner>eugenebut@chromium.org</owner> + <owner>danyao@chromium.org</owner> + <summary> + Logged when LegacyNavigationManager and KWKBasedNavigationManager have + different last committed URLs. This means that either old or new navigation + system has a URL spoofing bug. + </summary> + <metric name="HasMismatch"> + <summary> + True if there was a mismatch. + </summary> + <aggregation> + <history> + <statistics> + <enumeration/> + </statistics> + </history> + </aggregation> + </metric> +</event> + <event name="Layout.DisplayCutout.StateChanged"> <owner>beccahughes@chromium.org</owner> <owner>media-dev@chromium.org</owner> @@ -2792,318 +2925,6 @@ </metric> </event> -<event name="Media.EME.RequestMediaKeySystemAccess"> - <owner>xhwang@chromium.org</owner> - <owner>media-dev@chromium.org</owner> - <summary> - Event recorded when RequestMediaKeySystemAccess() is called as part of - Encrypted Media Extensions (EME) API. - </summary> - <metric name="KeySystem"> - <summary> - The key system passed in requestMediaKeySystemAccess() call. - </summary> - </metric> - <metric name="VideoCapabilities"> - <summary> - Whether there are any "videoCapabilities". - </summary> - </metric> - <metric name="VideoCapabilities.HasEmptyRobustness"> - <summary> - Whether there are any "videoCapabilities" with empty robustness. - </summary> - </metric> - <metric name="VideoCapabilities.HasHwSecureAllRobustness"> - <summary> - Whether there are any "videoCapabilities" with robustness being - "HW_SECURE_ALL". - </summary> - </metric> -</event> - -<event name="Media.Engagement.ShortPlaybackIgnored"> - <owner>beccahughes@chromium.org</owner> - <owner>media-dev@chromium.org</owner> - <summary> - The Media Engagement index stores the number of significant media playbacks - per origin and the number of audible players. From that we calculate a Media - Engagement Score. - - Media with a short playback length is ignored so we are logging any time the - player is ignored with the length in msec. This will allow us to identify - whether sites are being penalized or there is abuse and allow us to tweak - the length considered "short". - </summary> - <metric name="Length"/> -</event> - -<event name="Media.Engagement.SessionFinished"> - <owner>beccahughes@chromium.org</owner> - <owner>media-dev@chromium.org</owner> - <summary> - The Media Engagement index stores the number of significant media playbacks - per origin and the number of visits. From that we calculate a Media - Engagement Score. - - To tweak the scoring function we are logging the total number of significant - media playbacks, the total number of visits, the calculated engagement score - and the new number of significant media playbacks that occured this visit. - </summary> - <metric name="Engagement.IsHigh"> - <summary> - Whether the Media Engagement Service considers the score to be high (we - are using a two threshold approach so there is one threshold to be - considered high and another one to lose that status to reduce jitter). - </summary> - </metric> - <metric name="Engagement.IsHigh.Changed"> - <summary> - Whether the IsHigh bit changed during the current session. - </summary> - </metric> - <metric name="Engagement.IsHigh.Changes"> - <summary> - Counts of IsHigh changing (from 0 to 1 or 1 to 0). - </summary> - </metric> - <metric name="Engagement.IsPreloaded"> - <summary> - Whether the origin was preloaded (from the chrome://component) as a high - engagement origin. - </summary> - </metric> - <metric name="Engagement.Score"> - <summary> - The calculated Media Engagement score for the current origin. The score is - calculated by dividing the number of significant media playbacks by the - number of visits. If the number of visits is below 5 then the score will - be zero. This score is taken from MediaEngagementService. - </summary> - </metric> - <metric name="Playbacks.AudioContextTotal"> - <summary> - The total number of significant media playbacks on this origin that came - from WebAudio / AudioContext. - </summary> - </metric> - <metric name="Playbacks.Delta"> - <summary> - The number of significant media playbacks on this origin during this - session (a visit to an origin on the same tab). A playback is determined - significant if it meets certain criteria such as a video size of at least - 200x140px, is not muted, is playing, etc. - </summary> - </metric> - <metric name="Playbacks.MediaElementTotal"> - <summary> - The total number of significant media playbacks on this origin that came - from media elements. - </summary> - </metric> - <metric name="Playbacks.SecondsSinceLast"> - <summary> - The number of seconds between significant media playback on the last visit - and significant media playback on the current visit. If there was no - previous visit or significant media playback this visit it will be 0. - </summary> - </metric> - <metric name="Playbacks.Total"> - <summary> - The total number of significant media playbacks on this origin. - </summary> - </metric> - <metric name="Player.Audible.Delta"> - <summary> - The number of unique audio/video players on a page that was audible (made - sound) during a visit. - </summary> - </metric> - <metric name="Player.Audible.Total"> - <summary> - The delta from above but instead of a single visit, the total of all - deltas for all visits on this origin. - </summary> - </metric> - <metric name="Player.Significant.Delta"> - <summary> - The number of unique audio/video players on a page that was audible (made - sound) and considered significant (played for at least 7 seconds) during a - visit. - </summary> - </metric> - <metric name="Player.Significant.Total"> - <summary> - The delta from above but instead of a single visit, the total of all - deltas for all visits on this origin. - </summary> - </metric> - <metric name="Visits.Total"> - <summary> - The total number of visits to this origin. - </summary> - </metric> -</event> - -<event name="Media.SiteMuted" singular="True"> - <owner>steimel@chromium.org</owner> - <owner>media-dev@chromium.org</owner> - <summary> - Event recorded when a website tries to play audio but is muted by the sound - content setting. - </summary> - <metric name="MuteReason"> - <summary> - Enum value giving the reason the site was muted. Defined as - |SoundContentSettingObserver::MuteReason|. - </summary> - </metric> -</event> - -<event name="Media.WatchTime"> - <obsolete> - Deprecated 8/2017 in favor Media.BasicPlayback - </obsolete> - <owner>dalecurtis@chromium.org</owner> - <summary> - Watch time is defined as the amount of elapsed media time for audio+video - media aggregated per player instance. A minimum of 7 seconds of unmuted, - foreground media must be watched to start watch time monitoring. Watch time - is checked on a regular basis and reported upon one of the stop events - mentioned below or at player destruction if none occur prior. - - Any one of paused, hidden, or muted is sufficient to stop watch time metric - reports. Each of these has a hysteresis where if the state change is undone - within some time, the watch time will be counted as uninterrupted. - - Power events (on/off battery power) have a similar hysteresis, but unlike - the aforementioned properties, will not stop metric collection. - - Native controls events have a similar behavior than power events. - - Each seek event will result in a new watch time metric being started and the - old metric finalized as accurately as possible. - </summary> - <metric name="Audio.AC"/> - <metric name="Audio.All"/> - <metric name="Audio.Battery"/> - <metric name="Audio.EME"/> - <metric name="Audio.MSE"/> - <metric name="Audio.NativeControlsOff"/> - <metric name="Audio.NativeControlsOn"/> - <metric name="Audio.SRC"/> - <metric name="AudioVideo.AC"/> - <metric name="AudioVideo.All"/> - <metric name="AudioVideo.Background.AC"/> - <metric name="AudioVideo.Background.All"/> - <metric name="AudioVideo.Background.Battery"/> - <metric name="AudioVideo.Background.EME"/> - <metric name="AudioVideo.Background.MSE"/> - <metric name="AudioVideo.Background.SRC"/> - <metric name="AudioVideo.Battery"/> - <metric name="AudioVideo.DisplayFullscreen"/> - <metric name="AudioVideo.DisplayInline"/> - <metric name="AudioVideo.DisplayPictureInPicture"/> - <metric name="AudioVideo.EME"/> - <metric name="AudioVideo.MSE"/> - <metric name="AudioVideo.NativeControlsOff"/> - <metric name="AudioVideo.NativeControlsOn"/> - <metric name="AudioVideo.SRC"/> -</event> - -<event name="Media.WebAudio.AudioContext.AudibleTime"> - <owner>hongchan@chromium.org</owner> - <owner>rtoy@chromium.org</owner> - <owner>webaudio-dev@chromium.org</owner> - <summary> - Records the AudioContext audible time information. - </summary> - <metric name="AudibleTime"> - <summary> - Audible time in milliseconds for this event. - </summary> - </metric> - <metric name="IsMainFrame"> - <summary> - Indicates whether the event is fired from main frame. - </summary> - </metric> -</event> - -<event name="Media.WebMediaPlayerState"> - <owner>dalecurtis@chromium.org</owner> - <owner>media-dev@chromium.org</owner> - <summary> - Final state of WebMediaPlayerImpl instance. Records only immutable playback - properties. Contains a PlaybackID which links to Media.BasicPlayback events. - </summary> - <metric name="ContainerName"> - <summary> - media::container_names::MediaContainerName enum value. Only recorded for - !IsMSE src=URL playbacks, this is the container of the media being played - back; E.g., mp4, avi, mp3, etc. - </summary> - </metric> - <metric name="FinalPipelineStatus"> - <summary> - media::PipelineStatus enum value. Always 0 if the playback succeeded; all - other values indicate the playback ended in an error. - </summary> - </metric> - <metric name="IsEME"> - <summary> - Boolean value indicating if this event is for an EME playback. Note: EME - can be attached anytime during the lifecycle of a WebMediaPlayerImpl, but - once attached can't be removed. - </summary> - </metric> - <metric name="IsMSE"> - <summary> - Boolean value indicating if this event is for an MSE playback. If false it - means this was a SRC playback. - </summary> - </metric> - <metric name="IsTopFrame"> - <summary> - Flag indicating whether the report comes from the top frame or some inner - frame. For privacy, metrics from inner frames are recorded with the top - frame's origin, so this flag helps separate top frame vs. embedded - playbacks. - </summary> - </metric> - <metric name="PlayerID"> - <summary> - ID which corresponds to a given WebMediaPlayerImpl instance. May be linked - with Media.BasicPlayback events to understand a playback more deeply. - </summary> - </metric> - <metric name="TimeToFirstFrame"> - <summary> - Time in milliseconds from when WebMediaPlayerImpl starts loading until the - first video frame has been shown. - </summary> - </metric> - <metric name="TimeToMetadata"> - <summary> - Time in milliseconds from when WebMediaPlayerImpl starts loading until - metadata is known. - </summary> - </metric> - <metric name="TimeToPlayReady"> - <summary> - Time in milliseconds from when WebMediaPlayerImpl starts loading until it - has buffered enough to start playback. - </summary> - </metric> - <metric name="URLScheme"> - <summary> - media::mojom::MediaURLScheme enum value. Only recorded for !IsMSE src=URL - playbacks, this is the scheme of that URL; E.g., http, https, filesystem, - etc. - </summary> - </metric> -</event> - <event name="Media.BasicPlayback"> <owner>dalecurtis@chromium.org</owner> <owner>media-dev@chromium.org</owner> @@ -3289,6 +3110,174 @@ </metric> </event> +<event name="Media.EME.RequestMediaKeySystemAccess"> + <owner>xhwang@chromium.org</owner> + <owner>media-dev@chromium.org</owner> + <summary> + Event recorded when RequestMediaKeySystemAccess() is called as part of + Encrypted Media Extensions (EME) API. + </summary> + <metric name="KeySystem"> + <summary> + The key system passed in requestMediaKeySystemAccess() call. + </summary> + </metric> + <metric name="VideoCapabilities"> + <summary> + Whether there are any "videoCapabilities". + </summary> + </metric> + <metric name="VideoCapabilities.HasEmptyRobustness"> + <summary> + Whether there are any "videoCapabilities" with empty robustness. + </summary> + </metric> + <metric name="VideoCapabilities.HasHwSecureAllRobustness"> + <summary> + Whether there are any "videoCapabilities" with robustness being + "HW_SECURE_ALL". + </summary> + </metric> +</event> + +<event name="Media.Engagement.SessionFinished"> + <owner>beccahughes@chromium.org</owner> + <owner>media-dev@chromium.org</owner> + <summary> + The Media Engagement index stores the number of significant media playbacks + per origin and the number of visits. From that we calculate a Media + Engagement Score. + + To tweak the scoring function we are logging the total number of significant + media playbacks, the total number of visits, the calculated engagement score + and the new number of significant media playbacks that occured this visit. + </summary> + <metric name="Engagement.IsHigh"> + <summary> + Whether the Media Engagement Service considers the score to be high (we + are using a two threshold approach so there is one threshold to be + considered high and another one to lose that status to reduce jitter). + </summary> + </metric> + <metric name="Engagement.IsHigh.Changed"> + <summary> + Whether the IsHigh bit changed during the current session. + </summary> + </metric> + <metric name="Engagement.IsHigh.Changes"> + <summary> + Counts of IsHigh changing (from 0 to 1 or 1 to 0). + </summary> + </metric> + <metric name="Engagement.IsPreloaded"> + <summary> + Whether the origin was preloaded (from the chrome://component) as a high + engagement origin. + </summary> + </metric> + <metric name="Engagement.Score"> + <summary> + The calculated Media Engagement score for the current origin. The score is + calculated by dividing the number of significant media playbacks by the + number of visits. If the number of visits is below 5 then the score will + be zero. This score is taken from MediaEngagementService. + </summary> + </metric> + <metric name="Playbacks.AudioContextTotal"> + <summary> + The total number of significant media playbacks on this origin that came + from WebAudio / AudioContext. + </summary> + </metric> + <metric name="Playbacks.Delta"> + <summary> + The number of significant media playbacks on this origin during this + session (a visit to an origin on the same tab). A playback is determined + significant if it meets certain criteria such as a video size of at least + 200x140px, is not muted, is playing, etc. + </summary> + </metric> + <metric name="Playbacks.MediaElementTotal"> + <summary> + The total number of significant media playbacks on this origin that came + from media elements. + </summary> + </metric> + <metric name="Playbacks.SecondsSinceLast"> + <summary> + The number of seconds between significant media playback on the last visit + and significant media playback on the current visit. If there was no + previous visit or significant media playback this visit it will be 0. + </summary> + </metric> + <metric name="Playbacks.Total"> + <summary> + The total number of significant media playbacks on this origin. + </summary> + </metric> + <metric name="Player.Audible.Delta"> + <summary> + The number of unique audio/video players on a page that was audible (made + sound) during a visit. + </summary> + </metric> + <metric name="Player.Audible.Total"> + <summary> + The delta from above but instead of a single visit, the total of all + deltas for all visits on this origin. + </summary> + </metric> + <metric name="Player.Significant.Delta"> + <summary> + The number of unique audio/video players on a page that was audible (made + sound) and considered significant (played for at least 7 seconds) during a + visit. + </summary> + </metric> + <metric name="Player.Significant.Total"> + <summary> + The delta from above but instead of a single visit, the total of all + deltas for all visits on this origin. + </summary> + </metric> + <metric name="Visits.Total"> + <summary> + The total number of visits to this origin. + </summary> + </metric> +</event> + +<event name="Media.Engagement.ShortPlaybackIgnored"> + <owner>beccahughes@chromium.org</owner> + <owner>media-dev@chromium.org</owner> + <summary> + The Media Engagement index stores the number of significant media playbacks + per origin and the number of audible players. From that we calculate a Media + Engagement Score. + + Media with a short playback length is ignored so we are logging any time the + player is ignored with the length in msec. This will allow us to identify + whether sites are being penalized or there is abuse and allow us to tweak + the length considered "short". + </summary> + <metric name="Length"/> +</event> + +<event name="Media.SiteMuted" singular="True"> + <owner>steimel@chromium.org</owner> + <owner>media-dev@chromium.org</owner> + <summary> + Event recorded when a website tries to play audio but is muted by the sound + content setting. + </summary> + <metric name="MuteReason"> + <summary> + Enum value giving the reason the site was muted. Defined as + |SoundContentSettingObserver::MuteReason|. + </summary> + </metric> +</event> + <event name="Media.VideoDecodePerfRecord"> <owner>chcunningham@chromium.org</owner> <owner>media-dev@chromium.org</owner> @@ -3411,6 +3400,150 @@ </metric> </event> +<event name="Media.WatchTime"> + <obsolete> + Deprecated 8/2017 in favor Media.BasicPlayback + </obsolete> + <owner>dalecurtis@chromium.org</owner> + <summary> + Watch time is defined as the amount of elapsed media time for audio+video + media aggregated per player instance. A minimum of 7 seconds of unmuted, + foreground media must be watched to start watch time monitoring. Watch time + is checked on a regular basis and reported upon one of the stop events + mentioned below or at player destruction if none occur prior. + + Any one of paused, hidden, or muted is sufficient to stop watch time metric + reports. Each of these has a hysteresis where if the state change is undone + within some time, the watch time will be counted as uninterrupted. + + Power events (on/off battery power) have a similar hysteresis, but unlike + the aforementioned properties, will not stop metric collection. + + Native controls events have a similar behavior than power events. + + Each seek event will result in a new watch time metric being started and the + old metric finalized as accurately as possible. + </summary> + <metric name="Audio.AC"/> + <metric name="Audio.All"/> + <metric name="Audio.Battery"/> + <metric name="Audio.EME"/> + <metric name="Audio.MSE"/> + <metric name="Audio.NativeControlsOff"/> + <metric name="Audio.NativeControlsOn"/> + <metric name="Audio.SRC"/> + <metric name="AudioVideo.AC"/> + <metric name="AudioVideo.All"/> + <metric name="AudioVideo.Background.AC"/> + <metric name="AudioVideo.Background.All"/> + <metric name="AudioVideo.Background.Battery"/> + <metric name="AudioVideo.Background.EME"/> + <metric name="AudioVideo.Background.MSE"/> + <metric name="AudioVideo.Background.SRC"/> + <metric name="AudioVideo.Battery"/> + <metric name="AudioVideo.DisplayFullscreen"/> + <metric name="AudioVideo.DisplayInline"/> + <metric name="AudioVideo.DisplayPictureInPicture"/> + <metric name="AudioVideo.EME"/> + <metric name="AudioVideo.MSE"/> + <metric name="AudioVideo.NativeControlsOff"/> + <metric name="AudioVideo.NativeControlsOn"/> + <metric name="AudioVideo.SRC"/> +</event> + +<event name="Media.WebAudio.AudioContext.AudibleTime"> + <owner>hongchan@chromium.org</owner> + <owner>rtoy@chromium.org</owner> + <owner>webaudio-dev@chromium.org</owner> + <summary> + Records the AudioContext audible time information. + </summary> + <metric name="AudibleTime"> + <summary> + Audible time in milliseconds for this event. + </summary> + </metric> + <metric name="IsMainFrame"> + <summary> + Indicates whether the event is fired from main frame. + </summary> + </metric> +</event> + +<event name="Media.WebMediaPlayerState"> + <owner>dalecurtis@chromium.org</owner> + <owner>media-dev@chromium.org</owner> + <summary> + Final state of WebMediaPlayerImpl instance. Records only immutable playback + properties. Contains a PlaybackID which links to Media.BasicPlayback events. + </summary> + <metric name="ContainerName"> + <summary> + media::container_names::MediaContainerName enum value. Only recorded for + !IsMSE src=URL playbacks, this is the container of the media being played + back; E.g., mp4, avi, mp3, etc. + </summary> + </metric> + <metric name="FinalPipelineStatus"> + <summary> + media::PipelineStatus enum value. Always 0 if the playback succeeded; all + other values indicate the playback ended in an error. + </summary> + </metric> + <metric name="IsEME"> + <summary> + Boolean value indicating if this event is for an EME playback. Note: EME + can be attached anytime during the lifecycle of a WebMediaPlayerImpl, but + once attached can't be removed. + </summary> + </metric> + <metric name="IsMSE"> + <summary> + Boolean value indicating if this event is for an MSE playback. If false it + means this was a SRC playback. + </summary> + </metric> + <metric name="IsTopFrame"> + <summary> + Flag indicating whether the report comes from the top frame or some inner + frame. For privacy, metrics from inner frames are recorded with the top + frame's origin, so this flag helps separate top frame vs. embedded + playbacks. + </summary> + </metric> + <metric name="PlayerID"> + <summary> + ID which corresponds to a given WebMediaPlayerImpl instance. May be linked + with Media.BasicPlayback events to understand a playback more deeply. + </summary> + </metric> + <metric name="TimeToFirstFrame"> + <summary> + Time in milliseconds from when WebMediaPlayerImpl starts loading until the + first video frame has been shown. + </summary> + </metric> + <metric name="TimeToMetadata"> + <summary> + Time in milliseconds from when WebMediaPlayerImpl starts loading until + metadata is known. + </summary> + </metric> + <metric name="TimeToPlayReady"> + <summary> + Time in milliseconds from when WebMediaPlayerImpl starts loading until it + has buffered enough to start playback. + </summary> + </metric> + <metric name="URLScheme"> + <summary> + media::mojom::MediaURLScheme enum value. Only recorded for !IsMSE src=URL + playbacks, this is the scheme of that URL; E.g., http, https, filesystem, + etc. + </summary> + </metric> +</event> + <event name="Memory.Experimental"> <owner>erikchen@chromium.org</owner> <owner>ssid@chromium.org</owner> @@ -3972,6 +4105,25 @@ </metric> </event> +<event name="MixedContentAutoupgrade.ResourceRequest"> + <owner>carlosil@chromium.org</owner> + <summary> + Status and Network error or HTTP response code for a resource request that + was autoupgraded to HTTPS as part of the mixed content autoupgrade + experiment. + </summary> + <metric name="Code"> + <summary> + The HTTP response or network error code for an autoupgraded request. + </summary> + </metric> + <metric name="Status"> + <summary> + An enum with 0 representing started, 1 failed, and 2 response received. + </summary> + </metric> +</event> + <event name="Net.LegacyTLSVersion"> <owner>davidben@chromium.org</owner> <summary> @@ -3980,6 +4132,39 @@ </summary> </event> +<event name="NoStatePrefetch" singular="True"> + <owner>tbansal@chromium.org</owner> + <summary> + Metrics related to NoStatePrefetch that are recorded using the same UKM IDs + as PageLoad. + </summary> + <metric name="PrefetchedRecently.FinalStatus"> + <summary> + Final status of the nostate prefetch if one was recently attempted for + either the committed URL of this navigation or for any URL in the redirect + chain for the main frame resource for this navigation. page. Recorded as + enum PrerenderFinalStatus in //tools/metrics/histograms/enums.xml. + </summary> + </metric> + <metric name="PrefetchedRecently.Origin"> + <summary> + Triggering origin of the nostate prefetch if one was recently attempted + for either the committed URL of this navigation or for any URL in the + redirect chain for the main frame resource for this navigation. Recorded + as enum PrerenderOrigin in //tools/metrics/histograms/enums.xml. + </summary> + </metric> + <metric name="PrefetchedRecently.PrefetchAge"> + <summary> + Records the time (in milliseconds) from the start of the nostate prefetch + to the time of commit of this navigation. Metric is recorded down to the + nearest power of 2. Recorded only if a nostate prefetch was recently + attempted for either the committed URL of this navigation or for any URL + in the redirect chain for the main frame resource for this navigation. + </summary> + </metric> +</event> + <event name="Notification"> <owner>peter@chromium.org</owner> <summary> @@ -4079,109 +4264,6 @@ </metric> </event> -<event name="BackgroundFetch"> - <owner>nator@chromium.org</owner> - <owner>rayankans@chromium.org</owner> - <owner>peter@chromium.org</owner> - <summary> - A BackgroundFetch event is logged before a background fetch is started from - a document context. - </summary> - <metric name="DeniedDueToPermissions"> - <summary> - Boolean for whether the background fetch was denied due to permission. - This includes only the content setting permission. - </summary> - </metric> - <metric name="DownloadTotal"> - <summary> - The value of downloadTotal provided with the background fetch. This is the - number of bytes that the developer expects to be downloaded with the - background fetch. This number is exponentially bucketed for privacy - reasons, and uses the UKM GetExponentialBucketMin method with a value of - 2.0 for spacing. - </summary> - </metric> - <metric name="HasTitle"> - <summary> - Boolean for whether a title was provided with the background fetch. - </summary> - </metric> - <metric name="NumIcons"> - <summary> - Count of icons provided with the background fetch. - </summary> - </metric> - <metric name="NumRequestsInFetch"> - <summary> - Number of requests in the background fetch. This number is exponentially - bucketed for privacy reasons, and uses the UKM GetExponentialBucketMin - method with a value of 2.0 for spacing. - </summary> - </metric> - <metric name="RatioOfIdealToChosenIconSize"> - <summary> - Ratio of the ideal icon to the chosen icon size, times hundred. This will - be set to -1 if either ideal icon size is 0, or if none of the provided - icons are suitable. - </summary> - </metric> -</event> - -<event name="BackgroundFetchDeletingRegistration"> - <owner>nator@chromium.org</owner> - <owner>rayankans@chromium.org</owner> - <owner>peter@chromium.org</owner> - <summary> - A BackgroundFetchDeletingRegistration event is logged when a background - fetch job is being deleted. - </summary> - <metric name="UserInitiatedAbort"> - <summary> - Boolean for whether the background fetch job was cancelled from the UI. - </summary> - </metric> -</event> - -<event name="HistoryNavigation" singular="True"> - <owner>altimin@chromium.org</owner> - <owner>arthursonzogni@chromium.org</owner> - <summary> - Metrics recorded each time we commit a history navigation, which are needed - to estimate benefits of back-forward cache. - </summary> - <metric name="LastCommittedSourceIdForTheSameDocument"> - <summary> - For history navigations and reloads, the source id of the previous - navigation which loaded the page we're trying to navigate back to. - </summary> - </metric> - <metric name="NavigatedToTheMostRecentEntryForDocument"> - <summary> - Boolean for whether we navigated to the same navigation entry as the one - which was last visible. - - It can be false when subframes or same-document navigations are present. - For example, after navigating from http://foo to http://foo#bar and then - http://bar and then going back by 2 entries will mean we went to - http://foo while the last committed entry from this document was - http://foo#bar. - - It's expected to be rare, but might be problematic for back-forward cache. - </summary> - </metric> - <metric name="TimeSinceNavigatedAwayFromDocument"> - <summary> - Time in milliseconds from the moment the current navigation stopped being - active to the start of the current navigation. - - This is clamped to hours for values greater than 3 hours, to minutes for - values greater than 3 minutes, to seconds for values greater than 5 - seconds. - </summary> - </metric> -</event> - <event name="OfflinePages.SavePageRequested"> <obsolete> Deprecated 03/2019 @@ -4215,6 +4297,20 @@ </metric> </event> +<event name="PageForegroundSession"> + <owner>sullivan@chromium.org</owner> + <summary> + Total time in foreground in milliseconds, recorded each time the page is + backgrounded. May be recorded multiple times for a single page visit. + </summary> + <metric name="ForegroundDuration"> + <summary> + Total time in foreground in milliseconds, recorded each time the page is + backgrounded. + </summary> + </metric> +</event> + <event name="PageLoad" singular="True"> <owner>bmcquade@chromium.org</owner> <summary> @@ -4782,37 +4878,20 @@ </metric> </event> -<event name="NoStatePrefetch" singular="True"> - <owner>tbansal@chromium.org</owner> +<event name="PageLoad.FromGoogleSearch" singular="True"> + <owner>bmcquade@chromium.org</owner> + <owner>mushan@chromium.org</owner> <summary> - Metrics related to NoStatePrefetch that are recorded using the same UKM IDs - as PageLoad. + Recorded for page loads that were navigated to via Google Search. </summary> - <metric name="PrefetchedRecently.FinalStatus"> - <summary> - Final status of the nostate prefetch if one was recently attempted for - either the committed URL of this navigation or for any URL in the redirect - chain for the main frame resource for this navigation. page. Recorded as - enum PrerenderFinalStatus in //tools/metrics/histograms/enums.xml. - </summary> - </metric> - <metric name="PrefetchedRecently.Origin"> - <summary> - Triggering origin of the nostate prefetch if one was recently attempted - for either the committed URL of this navigation or for any URL in the - redirect chain for the main frame resource for this navigation. Recorded - as enum PrerenderOrigin in //tools/metrics/histograms/enums.xml. - </summary> - </metric> - <metric name="PrefetchedRecently.PrefetchAge"> - <summary> - Records the time (in milliseconds) from the start of the nostate prefetch - to the time of commit of this navigation. Metric is recorded down to the - nearest power of 2. Recorded only if a nostate prefetch was recently - attempted for either the committed URL of this navigation or for any URL - in the redirect chain for the main frame resource for this navigation. - </summary> - </metric> +</event> + +<event name="PageLoad.ServiceWorkerControlled" singular="True"> + <owner>bmcquade@chromium.org</owner> + <owner>falken@chromium.org</owner> + <summary> + Recorded for page loads controlled by a service worker. + </summary> </event> <event name="PageLoadCapping" singular="True"> @@ -4833,20 +4912,43 @@ </metric> </event> -<event name="PageLoad.FromGoogleSearch" singular="True"> - <owner>bmcquade@chromium.org</owner> - <owner>mushan@chromium.org</owner> +<event name="PageWithPassword"> + <owner>battre@chromium.org</owner> <summary> - Recorded for page loads that were navigated to via Google Search. + Metrics about websites that contain password forms and the user's + interactions with them. No events are created for pages that don't contain + password forms. </summary> -</event> - -<event name="PageLoad.ServiceWorkerControlled" singular="True"> - <owner>bmcquade@chromium.org</owner> - <owner>falken@chromium.org</owner> - <summary> - Recorded for page loads controlled by a service worker. - </summary> + <metric name="FormManagerAvailable"> + <summary> + Records whether Chrome was sufficiently aware of forms during various + stages of saving a credential on the site, or whether saving was aborted + due to absence of the corresponding form manager. Values correspond to the + enum PasswordManagerMetricsRecorder::FormManagerAvailable. + </summary> + </metric> + <metric name="PageLevelUserAction"> + <summary> + Records if the user interacts with the password manager in a way that + cannot (reliably) be attributed to a specific PasswordFormManager. Values + correspond to the enum + PasswordManagerMetricsRecorder::PageLevelUserAction. + </summary> + </metric> + <metric name="ProvisionalSaveFailure"> + <summary> + Records a provisional save failure in case the password manager cannot + offer to save a credential. Recorded values correspond to the enum + PasswordManagerMetricsRecorder::ProvisionalSaveFailure. + </summary> + </metric> + <metric name="UserModifiedPasswordField"> + <summary> + Records a 1 for every page on which a user has modified a password text + field - regardless of how many password fields a page contains or the user + modifies. + </summary> + </metric> </event> <event name="PasswordForm"> @@ -5237,45 +5339,6 @@ </metric> </event> -<event name="PageWithPassword"> - <owner>battre@chromium.org</owner> - <summary> - Metrics about websites that contain password forms and the user's - interactions with them. No events are created for pages that don't contain - password forms. - </summary> - <metric name="FormManagerAvailable"> - <summary> - Records whether Chrome was sufficiently aware of forms during various - stages of saving a credential on the site, or whether saving was aborted - due to absence of the corresponding form manager. Values correspond to the - enum PasswordManagerMetricsRecorder::FormManagerAvailable. - </summary> - </metric> - <metric name="PageLevelUserAction"> - <summary> - Records if the user interacts with the password manager in a way that - cannot (reliably) be attributed to a specific PasswordFormManager. Values - correspond to the enum - PasswordManagerMetricsRecorder::PageLevelUserAction. - </summary> - </metric> - <metric name="ProvisionalSaveFailure"> - <summary> - Records a provisional save failure in case the password manager cannot - offer to save a credential. Recorded values correspond to the enum - PasswordManagerMetricsRecorder::ProvisionalSaveFailure. - </summary> - </metric> - <metric name="UserModifiedPasswordField"> - <summary> - Records a 1 for every page on which a user has modified a password text - field - regardless of how many password fields a page contains or the user - modifies. - </summary> - </metric> -</event> - <event name="PaymentRequest.CheckoutEvents"> <owner>sebsg@chromium.org</owner> <metric name="CompletionStatus"> @@ -5293,6 +5356,14 @@ </metric> </event> +<event name="Pepper.Broker" singular="True"> + <owner>raymes@chromium.org</owner> + <summary> + Event recorded when a flash instance connects to the broker, resulting in a + channel being opened to the broker process. + </summary> +</event> + <event name="Permission"> <owner>timloh@chromium.org</owner> <summary> @@ -5343,6 +5414,40 @@ </summary> </event> +<event name="Popup.Closed"> + <owner>csharrison@chromium.org</owner> + <owner>jkarlin@chromium.org</owner> + <summary> + A popup window was closed. + </summary> + <metric name="EngagementTime"> + <summary> + The time (in ms, rounded down to the nearest power of 2) a popup + WebContents is visible / foregrounded, until it is closed. Keyed by the + popup opener's URL (not the URL of the popup). + </summary> + </metric> + <metric name="NumInteractions"> + <summary> + Integer value representing how many user interactions the popup had. This + is capped at 100. See IsUserInteractionInputType in web_contents_impl for + what an interaction is. Currently it is a mouse, scroll begin, touch + start, or raw key down event. + </summary> + </metric> + <metric name="Trusted"> + <summary> + Boolean value representing whether the popup was opened via some trusted + event (e.g. context menu, ctrl-click, etc). + </summary> + </metric> + <metric name="UserInitiatedClose"> + <summary> + Boolean value to represent whether the popup was closed by user gesture. + </summary> + </metric> +</event> + <event name="Previews" singular="True"> <owner>ryansturm@chromium.org</owner> <summary> @@ -5468,22 +5573,6 @@ </metric> </event> -<event name="ResponsivenessMeasurement"> - <owner>npm@chromium.org</owner> - <owner>tdresser@chromium.org</owner> - <summary> - Responsiveness metrics recorded once every 5 seconds. - </summary> - <metric name="ExpectedTaskQueueingDuration"> - <summary> - Duration in MS for expected task queueing duration. The metric reflects - the responsiveness of a tab. A lower value means the tab will respond to - inputs faster. This metric is equal to - RendererScheduler.ExpectedTaskQueueingDuration of the main frame process. - </summary> - </metric> -</event> - <event name="RendererSchedulerTask"> <owner>altimin@chromium.org</owner> <summary> @@ -5576,44 +5665,18 @@ </metric> </event> -<event name="Pepper.Broker" singular="True"> - <owner>raymes@chromium.org</owner> +<event name="ResponsivenessMeasurement"> + <owner>npm@chromium.org</owner> + <owner>tdresser@chromium.org</owner> <summary> - Event recorded when a flash instance connects to the broker, resulting in a - channel being opened to the broker process. + Responsiveness metrics recorded once every 5 seconds. </summary> -</event> - -<event name="Popup.Closed"> - <owner>csharrison@chromium.org</owner> - <owner>jkarlin@chromium.org</owner> - <summary> - A popup window was closed. - </summary> - <metric name="EngagementTime"> + <metric name="ExpectedTaskQueueingDuration"> <summary> - The time (in ms, rounded down to the nearest power of 2) a popup - WebContents is visible / foregrounded, until it is closed. Keyed by the - popup opener's URL (not the URL of the popup). - </summary> - </metric> - <metric name="NumInteractions"> - <summary> - Integer value representing how many user interactions the popup had. This - is capped at 100. See IsUserInteractionInputType in web_contents_impl for - what an interaction is. Currently it is a mouse, scroll begin, touch - start, or raw key down event. - </summary> - </metric> - <metric name="Trusted"> - <summary> - Boolean value representing whether the popup was opened via some trusted - event (e.g. context menu, ctrl-click, etc). - </summary> - </metric> - <metric name="UserInitiatedClose"> - <summary> - Boolean value to represent whether the popup was closed by user gesture. + Duration in MS for expected task queueing duration. The metric reflects + the responsiveness of a tab. A lower value means the tab will respond to + inputs faster. This metric is equal to + RendererScheduler.ExpectedTaskQueueingDuration of the main frame process. </summary> </metric> </event> @@ -5886,6 +5949,19 @@ </metric> </event> +<event name="SSL.MixedContentShown"> + <owner>carlosil@chromium.org</owner> + <summary> + Logged when mixed content is displayed on a site. + </summary> + <metric name="Type"> + <summary> + A value of the MixedContentType enum, detailing the type of mixed content + included on the site. + </summary> + </metric> +</event> + <event name="SubframeDownload"> <obsolete> Deprecated as of 03/2019. @@ -5958,23 +6034,6 @@ </metric> </event> -<event name="Translate"> - <owner>hamelphi@chromium.org</owner> - <summary> - Metrics related to a Translate event. These metrics are described in - TranslateEventProto. - </summary> - <metric name="AcceptCount"/> - <metric name="Country"/> - <metric name="DeclineCount"/> - <metric name="EventType"/> - <metric name="IgnoreCount"/> - <metric name="RankerResponse"/> - <metric name="RankerVersion"/> - <metric name="SourceLanguage" semantic_type="ST_DEMOGRAPHIC_INFO"/> - <metric name="TargetLanguage" semantic_type="ST_DEMOGRAPHIC_INFO"/> -</event> - <event name="TabManager.Background.FirstAlertFired"> <owner>chrisha@chromium.org</owner> <owner>lpy@chromium.org</owner> @@ -6168,6 +6227,120 @@ </metric> </event> +<event name="TabManager.Experimental.BackgroundTabOpening.TabSwitchLoadStopped" + singular="True"> + <owner>zhenw@chromium.org</owner> + <summary> + Collects data when a tab is switched to from another tab and then finishes + loading in the foreground during a background tab opening session (the + duration of time from when the browser starts to open background tabs until + the time the browser has finished loading those tabs or otherwise decided to + stop loading them). The event is only recorded when a tab is switched to + from another tab within the same tabstrip. As a result, the initial + foreground tab is not included in this event since it was not switched to + from another tab. The event is not recorded when the session overlaps with + session restore. + </summary> + <metric name="BackgroundTabLoadingCount"> + <summary> + Number of background tabs that are loading. + </summary> + </metric> + <metric name="BackgroundTabOpeningSessionId"> + <summary> + The ID of this background tab opening session. + </summary> + </metric> + <metric name="BackgroundTabPendingCount"> + <summary> + Number of background tabs that are pending. + </summary> + </metric> + <metric name="SequenceId"> + <summary> + The ID of this event's sequence in current background tab opening session. + </summary> + </metric> + <metric name="SystemTabCount"> + <summary> + Number of all tabs of the system, which includes all browser windows. + </summary> + </metric> + <metric name="TabSwitchLoadTime"> + <summary> + Tab switch load time in MS. It is defined as the time between when the + user switches to a backround tab, and the time when that tab finishes + loading in the foreground. If the user switches away before the tab + finishes loading, a metric will not be recorded unless the user switches + back, in which case the tab switch load time is measured from that point + in time. + </summary> + </metric> +</event> + +<event name="TabManager.Experimental.SessionRestore.ForegroundTab.PageLoad" + singular="True"> + <owner>zhenw@chromium.org</owner> + <summary> + Collects the tab counts for the foreground tab page load during session + restore. The event is not recorded when the session overlaps with background + tab opening. This event should be combined with PageLoad event for analysis. + </summary> + <metric name="SessionRestoreTabCount"> + <summary> + Number of tabs that are restored. + </summary> + </metric> + <metric name="SystemTabCount"> + <summary> + Number of all tabs of the system, which includes all browser windows. + </summary> + </metric> +</event> + +<event name="TabManager.Experimental.SessionRestore.TabSwitchLoadStopped" + singular="True"> + <owner>zhenw@chromium.org</owner> + <summary> + Collects data when a tab is switched to from another tab and then finishes + loading in the foreground during session restore The event is only recorded + when a tab is switched to from another tab within the same tabstrip. As a + result, the initial foreground tab is not included in this event since it + was not switched to from another tab. The event is not recorded when the + session overlaps with background tab opening. + </summary> + <metric name="SequenceId"> + <summary> + The ID of this event's sequence in current session restore session. + </summary> + </metric> + <metric name="SessionRestoreSessionId"> + <summary> + The ID of this session restore session. + </summary> + </metric> + <metric name="SessionRestoreTabCount"> + <summary> + Number of tabs that are restored. + </summary> + </metric> + <metric name="SystemTabCount"> + <summary> + Number of all tabs of the system, which includes all browser windows. + </summary> + </metric> + <metric name="TabSwitchLoadTime"> + <summary> + Tab switch load time in MS. It is defined as the time between when the + user switches to a background tab, and the time when that tab finishes + loading in the foreground. If the user switches away before the tab + finishes loading, a metric will not be recorded unless the user switches + back, in which case the tab switch load time is measured from that point + in time. + </summary> + </metric> +</event> + <event name="TabManager.LifecycleStateChange"> <owner>chrisha@chromium.org</owner> <owner>fdoray@chromium.org</owner> @@ -6373,158 +6546,6 @@ </metric> </event> -<event name="TabManager.WindowMetrics"> - <owner>michaelpg@chromium.org</owner> - <summary> - Collects information about a browser or app window to associate with the - TabManager.TabMetrics entries for tabs in that window. - </summary> - <metric name="IsActive"> - <summary> - Whether the window is the active (frontmost) window. - </summary> - </metric> - <metric name="ShowState"> - <summary> - Enumeration of the window show state, such as fullscreen or minimized. - Values are enumerated in metrics::WindowMetricsEvent::ShowState. - </summary> - </metric> - <metric name="TabCount"> - <summary> - Number of tabs in the tab strip. Rounded down to the nearest exponential - bucket (with a bucket spacing factor of 1.5). Will be 1 for windows with - only one top-level WebContents, such as app windows. - </summary> - </metric> - <metric name="Type"> - <summary> - Enumeration for the type of the window. Values are enumerated in - metrics::WindowMetricsEvent::Type. - </summary> - </metric> - <metric name="WindowId"> - <summary> - Session ID of the browser or app window this entry represents, unique for - the browsing session. - </summary> - </metric> -</event> - -<event name="TabManager.Experimental.BackgroundTabOpening.TabSwitchLoadStopped" - singular="True"> - <owner>zhenw@chromium.org</owner> - <summary> - Collects data when a tab is switched to from another tab and then finishes - loading in the foreground during a background tab opening session (the - duration of time from when the browser starts to open background tabs until - the time the browser has finished loading those tabs or otherwise decided to - stop loading them). The event is only recorded when a tab is switched to - from another tab within the same tabstrip. As a result, the initial - foreground tab is not included in this event since it was not switched to - from another tab. The event is not recorded when the session overlaps with - session restore. - </summary> - <metric name="BackgroundTabLoadingCount"> - <summary> - Number of background tabs that are loading. - </summary> - </metric> - <metric name="BackgroundTabOpeningSessionId"> - <summary> - The ID of this background tab opening session. - </summary> - </metric> - <metric name="BackgroundTabPendingCount"> - <summary> - Number of background tabs that are pending. - </summary> - </metric> - <metric name="SequenceId"> - <summary> - The ID of this event's sequence in current background tab opening session. - </summary> - </metric> - <metric name="SystemTabCount"> - <summary> - Number of all tabs of the system, which includes all browser windows. - </summary> - </metric> - <metric name="TabSwitchLoadTime"> - <summary> - Tab switch load time in MS. It is defined as the time between when the - user switches to a backround tab, and the time when that tab finishes - loading in the foreground. If the user switches away before the tab - finishes loading, a metric will not be recorded unless the user switches - back, in which case the tab switch load time is measured from that point - in time. - </summary> - </metric> -</event> - -<event name="TabManager.Experimental.SessionRestore.ForegroundTab.PageLoad" - singular="True"> - <owner>zhenw@chromium.org</owner> - <summary> - Collects the tab counts for the foreground tab page load during session - restore. The event is not recorded when the session overlaps with background - tab opening. This event should be combined with PageLoad event for analysis. - </summary> - <metric name="SessionRestoreTabCount"> - <summary> - Number of tabs that are restored. - </summary> - </metric> - <metric name="SystemTabCount"> - <summary> - Number of all tabs of the system, which includes all browser windows. - </summary> - </metric> -</event> - -<event name="TabManager.Experimental.SessionRestore.TabSwitchLoadStopped" - singular="True"> - <owner>zhenw@chromium.org</owner> - <summary> - Collects data when a tab is switched to from another tab and then finishes - loading in the foreground during session restore The event is only recorded - when a tab is switched to from another tab within the same tabstrip. As a - result, the initial foreground tab is not included in this event since it - was not switched to from another tab. The event is not recorded when the - session overlaps with background tab opening. - </summary> - <metric name="SequenceId"> - <summary> - The ID of this event's sequence in current session restore session. - </summary> - </metric> - <metric name="SessionRestoreSessionId"> - <summary> - The ID of this session restore session. - </summary> - </metric> - <metric name="SessionRestoreTabCount"> - <summary> - Number of tabs that are restored. - </summary> - </metric> - <metric name="SystemTabCount"> - <summary> - Number of all tabs of the system, which includes all browser windows. - </summary> - </metric> - <metric name="TabSwitchLoadTime"> - <summary> - Tab switch load time in MS. It is defined as the time between when the - user switches to a background tab, and the time when that tab finishes - loading in the foreground. If the user switches away before the tab - finishes loading, a metric will not be recorded unless the user switches - back, in which case the tab switch load time is measured from that point - in time. - </summary> - </metric> -</event> - <event name="TabManager.SessionRestore.ForegroundTab.ExpectedTaskQueueingDurationInfo"> <owner>zhenw@chromium.org</owner> @@ -6581,6 +6602,243 @@ </metric> </event> +<event name="TabManager.TabMetrics"> + <owner>michaelpg@chromium.org</owner> + <summary> + Collects tab information for a tab after navigations, activations and close + events. + </summary> + <metric name="ContentType"> + <summary> + Obsolete. Enumeration for the MIME type of the page. Values are enumerated + in metrics::TabMetricsEvent::ContentType. + </summary> + </metric> + <metric name="DefaultProtocolHandler"> + <summary> + Obsolete. Schemes that a page from this page's origin is the default + protocol handler for, meaning the user has chosen to accept (or the + handler was preinstalled by Chrome). The metric is repeated, occurring for + each such protocol handler, and uses values from + metrics::TabMetricsEvent::Scheme. + </summary> + </metric> + <metric name="HasBeforeUnloadHandler"> + <summary> + Boolean value indicating whether the page has a beforeunload JavaScript + event handler. + </summary> + </metric> + <metric name="HasFormEntry"> + <summary> + Boolean value indicating whether the page has any user-input text. + </summary> + </metric> + <metric name="IsExtensionProtected"> + <summary> + Obsolete. True if an extension has marked this tab as non-discardable via + the chrome.tabs.update() extension API. + </summary> + </metric> + <metric name="IsPinned"> + <summary> + Boolean value indicating whether the tab is pinned in the tabstrip. + </summary> + </metric> + <metric name="KeyEventCount"> + <summary> + Number of key events that were sent to the page. + </summary> + </metric> + <metric name="LabelId"> + <summary> + An int64 random number generated at logging time. The same number will + also be logged to the TabManager.Background.ForegroundedOrClosed event, so + that feature label can be paired. + </summary> + </metric> + <metric name="MouseEventCount"> + <summary> + Number of mouse events that were sent to the page. + </summary> + </metric> + <metric name="MRUIndex"> + <summary> + Index of the tab in most-recently-used order. A value of N means there are + N tabs more recently used than the one that is being foregrounded or + closed. + </summary> + </metric> + <metric name="NavigationEntryCount"> + <summary> + Number of navigation entries in the tab's NavigationController. + Corresponds to the size of the tab's back/forward list. + </summary> + </metric> + <metric name="NumReactivationBefore"> + <summary> + Number of reactivations that this tab had till now. + </summary> + </metric> + <metric name="PageTransitionCoreType"> + <summary> + Type of the page transition for this navigation. Uses the core values from + ui::PageTransition. + </summary> + </metric> + <metric name="PageTransitionFromAddressBar"> + <summary> + True if the page transition came from interacting with the address bar, + such as by typing a URL or performing a search. + </summary> + </metric> + <metric name="PageTransitionIsRedirect"> + <summary> + True if the page transition type is a redirect, in which case the + PageTransition type may not be accurate. + </summary> + </metric> + <metric name="QueryId"> + <summary> + An int64 random number generated at query time of + TabManager::GetSortedLifecycleUnitsFromTabRanker. Tabs with the same + QueryId will be later on combined in one full list for further analysis. + </summary> + </metric> + <metric name="SequenceId"> + <obsolete> + Deprecated 11/2018 in favor LabelId. + </obsolete> + <summary> + This metric is obsolete in 11/2018 in favor of LabelId for pairing with + Tabmanager.ForegroundedOrClosed event. The sequence of this event and + TabManager.ForegroundedOrClosed event in the current session. Incremented + by 1 each time one of the two events is logged to provide an ordering of + events. + </summary> + </metric> + <metric name="SiteEngagementScore"> + <summary> + Site engagement score in the range [0, 100], rounded down to a multiple of + 10 to limit granularity. + </summary> + </metric> + <metric name="TimeFromBackgrounded"> + <summary> + Duration in MS from when the tab is backgrounded to when it is brought to + foreground or closed. + </summary> + </metric> + <metric name="TotalTabCount"> + <summary> + Total number of tabs open across all non-incognito browser windows. Helps + contextualize the MRUIndex value. + </summary> + </metric> + <metric name="TouchEventCount"> + <summary> + Number of touch events that were sent to the page. + </summary> + </metric> + <metric name="WasRecentlyAudible"> + <summary> + Boolean value indicating whether the tab has played audio within the last + two seconds. + </summary> + </metric> + <metric name="WindowId"> + <obsolete> + Deprecated 11/2018 in favor of putting window features directly in this + event. + </obsolete> + <summary> + WindowId of the WindowMetrics entry corresponding to the browser window + containing this tab. This metrics is not populated from 11/2018 because we + don't need to join this event with other WindowMetrics any more. + </summary> + </metric> + <metric name="WindowIsActive"> + <summary> + Boolean value indicating whether the window is the active (frontmost) + window. + </summary> + </metric> + <metric name="WindowShowState"> + <summary> + Enumeration of the window show state, such as fullscreen or minimized. + Values are enumerated in metrics::WindowMetricsEvent::ShowState. + </summary> + </metric> + <metric name="WindowTabCount"> + <summary> + Number of tabs in the tab strip. Rounded down to the nearest exponential + bucket (with a bucket spacing factor of 1.5). Will be 1 for windows with + only one top-level WebContents, such as app windows. + </summary> + </metric> + <metric name="WindowType"> + <summary> + Enumeration for the type of the window. Values are enumerated in + metrics::WindowMetricsEvent::Type. + </summary> + </metric> +</event> + +<event name="TabManager.WindowMetrics"> + <owner>michaelpg@chromium.org</owner> + <summary> + Collects information about a browser or app window to associate with the + TabManager.TabMetrics entries for tabs in that window. + </summary> + <metric name="IsActive"> + <summary> + Whether the window is the active (frontmost) window. + </summary> + </metric> + <metric name="ShowState"> + <summary> + Enumeration of the window show state, such as fullscreen or minimized. + Values are enumerated in metrics::WindowMetricsEvent::ShowState. + </summary> + </metric> + <metric name="TabCount"> + <summary> + Number of tabs in the tab strip. Rounded down to the nearest exponential + bucket (with a bucket spacing factor of 1.5). Will be 1 for windows with + only one top-level WebContents, such as app windows. + </summary> + </metric> + <metric name="Type"> + <summary> + Enumeration for the type of the window. Values are enumerated in + metrics::WindowMetricsEvent::Type. + </summary> + </metric> + <metric name="WindowId"> + <summary> + Session ID of the browser or app window this entry represents, unique for + the browsing session. + </summary> + </metric> +</event> + +<event name="Translate"> + <owner>hamelphi@chromium.org</owner> + <summary> + Metrics related to a Translate event. These metrics are described in + TranslateEventProto. + </summary> + <metric name="AcceptCount"/> + <metric name="Country"/> + <metric name="DeclineCount"/> + <metric name="EventType"/> + <metric name="IgnoreCount"/> + <metric name="RankerResponse"/> + <metric name="RankerVersion"/> + <metric name="SourceLanguage" semantic_type="ST_DEMOGRAPHIC_INFO"/> + <metric name="TargetLanguage" semantic_type="ST_DEMOGRAPHIC_INFO"/> +</event> + <event name="TrustedWebActivity.Open" singular="True"> <owner>peconn@chromium.org</owner> <summary> @@ -6848,313 +7106,6 @@ </metric> </event> -<event name="TabManager.TabMetrics"> - <owner>michaelpg@chromium.org</owner> - <summary> - Collects tab information for a tab after navigations, activations and close - events. - </summary> - <metric name="ContentType"> - <summary> - Obsolete. Enumeration for the MIME type of the page. Values are enumerated - in metrics::TabMetricsEvent::ContentType. - </summary> - </metric> - <metric name="DefaultProtocolHandler"> - <summary> - Obsolete. Schemes that a page from this page's origin is the default - protocol handler for, meaning the user has chosen to accept (or the - handler was preinstalled by Chrome). The metric is repeated, occurring for - each such protocol handler, and uses values from - metrics::TabMetricsEvent::Scheme. - </summary> - </metric> - <metric name="HasBeforeUnloadHandler"> - <summary> - Boolean value indicating whether the page has a beforeunload JavaScript - event handler. - </summary> - </metric> - <metric name="HasFormEntry"> - <summary> - Boolean value indicating whether the page has any user-input text. - </summary> - </metric> - <metric name="IsExtensionProtected"> - <summary> - Obsolete. True if an extension has marked this tab as non-discardable via - the chrome.tabs.update() extension API. - </summary> - </metric> - <metric name="IsPinned"> - <summary> - Boolean value indicating whether the tab is pinned in the tabstrip. - </summary> - </metric> - <metric name="KeyEventCount"> - <summary> - Number of key events that were sent to the page. - </summary> - </metric> - <metric name="LabelId"> - <summary> - An int64 random number generated at logging time. The same number will - also be logged to the TabManager.Background.ForegroundedOrClosed event, so - that feature label can be paired. - </summary> - </metric> - <metric name="MouseEventCount"> - <summary> - Number of mouse events that were sent to the page. - </summary> - </metric> - <metric name="MRUIndex"> - <summary> - Index of the tab in most-recently-used order. A value of N means there are - N tabs more recently used than the one that is being foregrounded or - closed. - </summary> - </metric> - <metric name="NavigationEntryCount"> - <summary> - Number of navigation entries in the tab's NavigationController. - Corresponds to the size of the tab's back/forward list. - </summary> - </metric> - <metric name="NumReactivationBefore"> - <summary> - Number of reactivations that this tab had till now. - </summary> - </metric> - <metric name="PageTransitionCoreType"> - <summary> - Type of the page transition for this navigation. Uses the core values from - ui::PageTransition. - </summary> - </metric> - <metric name="PageTransitionFromAddressBar"> - <summary> - True if the page transition came from interacting with the address bar, - such as by typing a URL or performing a search. - </summary> - </metric> - <metric name="PageTransitionIsRedirect"> - <summary> - True if the page transition type is a redirect, in which case the - PageTransition type may not be accurate. - </summary> - </metric> - <metric name="QueryId"> - <summary> - An int64 random number generated at query time of - TabManager::GetSortedLifecycleUnitsFromTabRanker. Tabs with the same - QueryId will be later on combined in one full list for further analysis. - </summary> - </metric> - <metric name="SequenceId"> - <obsolete> - Deprecated 11/2018 in favor LabelId. - </obsolete> - <summary> - This metric is obsolete in 11/2018 in favor of LabelId for pairing with - Tabmanager.ForegroundedOrClosed event. The sequence of this event and - TabManager.ForegroundedOrClosed event in the current session. Incremented - by 1 each time one of the two events is logged to provide an ordering of - events. - </summary> - </metric> - <metric name="SiteEngagementScore"> - <summary> - Site engagement score in the range [0, 100], rounded down to a multiple of - 10 to limit granularity. - </summary> - </metric> - <metric name="TimeFromBackgrounded"> - <summary> - Duration in MS from when the tab is backgrounded to when it is brought to - foreground or closed. - </summary> - </metric> - <metric name="TotalTabCount"> - <summary> - Total number of tabs open across all non-incognito browser windows. Helps - contextualize the MRUIndex value. - </summary> - </metric> - <metric name="TouchEventCount"> - <summary> - Number of touch events that were sent to the page. - </summary> - </metric> - <metric name="WasRecentlyAudible"> - <summary> - Boolean value indicating whether the tab has played audio within the last - two seconds. - </summary> - </metric> - <metric name="WindowId"> - <obsolete> - Deprecated 11/2018 in favor of putting window features directly in this - event. - </obsolete> - <summary> - WindowId of the WindowMetrics entry corresponding to the browser window - containing this tab. This metrics is not populated from 11/2018 because we - don't need to join this event with other WindowMetrics any more. - </summary> - </metric> - <metric name="WindowIsActive"> - <summary> - Boolean value indicating whether the window is the active (frontmost) - window. - </summary> - </metric> - <metric name="WindowShowState"> - <summary> - Enumeration of the window show state, such as fullscreen or minimized. - Values are enumerated in metrics::WindowMetricsEvent::ShowState. - </summary> - </metric> - <metric name="WindowTabCount"> - <summary> - Number of tabs in the tab strip. Rounded down to the nearest exponential - bucket (with a bucket spacing factor of 1.5). Will be 1 for windows with - only one top-level WebContents, such as app windows. - </summary> - </metric> - <metric name="WindowType"> - <summary> - Enumeration for the type of the window. Values are enumerated in - metrics::WindowMetricsEvent::Type. - </summary> - </metric> -</event> - -<event name="XR.WebXR" singular="True"> - <owner>billorr@chromium.org</owner> - <metric name="DidGetGamepads"> - <obsolete> - Deprecated in M75. - </obsolete> - <summary> - Boolean value that indicates that the Gamepad API was used on a WebXR - site. - </summary> - </metric> - <metric name="DidGetXRInputSources"> - <summary> - Boolean value that indicates that the WebXR input API was used. - </summary> - </metric> - <metric name="DidRequestAvailableDevices"> - <summary> - Boolean value that indicates that the API to enumerate devices was called. - </summary> - </metric> - <metric name="DidRequestPose"> - <summary> - Boolean value that indicates that poses were requested. - </summary> - </metric> - <metric name="DidRequestPresentation"> - <summary> - Boolean value that indicates that presentation was requested. - </summary> - </metric> - <metric name="DidUseNavigatorXR"> - <summary> - Boolean value that indicates that the WebXR Device API was used. - </summary> - </metric> - <metric name="ReturnedDevice"> - <summary> - Boolean value that indicates that a device was returned by the API to - enumerate devices. - </summary> - </metric> - <metric name="ReturnedPresentationCapableDevice"> - <summary> - Boolean value that indicates that a device was returned by the API to - enumerate devices, and that the device supports presentation. - </summary> - </metric> -</event> - -<event name="XR.PageSession" singular="True"> - <owner>offenwanger@chromium.org</owner> - <summary> - Records properties of page use in XR, including VR browsing and WebXR - presentation. - </summary> - <metric name="Duration"> - <summary> - The approximate amount of time the user spends on a page in XR in seconds. - Times are reported accurately when low, for example, under a minute, and - get rounded to minutes and then hours as they get larger. This is done by - SessionTracker::GetRoundedDurationInSeconds. - </summary> - </metric> - <metric name="EnteredFullscreen"> - <summary> - A boolean that is set to 1 if the user requested fullscreen while in XR on - some element on the page. - </summary> - </metric> - <metric name="EnteredVROnPageReason"> - <summary> - An enum that indicates that the user entered VR on this page and what - triggered the entry into VR, where 1 means VR was entered through headset - activation, and 2 means that request presentation triggered the entry into - VR. - </summary> - </metric> - <metric name="TimeOnPage"> - <summary> - Deprecated. - </summary> - </metric> - <metric name="WasOmniboxNavigation"> - <summary> - A boolean that is set to 1 if this page was entered into the omnibox, - either manually or using autocomplete. - </summary> - </metric> - <metric name="WasVoiceSearchNavigation"> - <summary> - A boolean that is set to 1 if this page was specifically requested and - recognized by a voice search. - </summary> - </metric> -</event> - -<event name="XR.WebXR.PresentationSession"> - <owner>offenwanger@chromium.org</owner> - <summary> - Records data for a presentation session, where WebXR is running an exclusive - presentation to some device. - </summary> - <metric name="Duration"> - <summary> - The approximate amount of time the user spends in presentation in seconds. - Times are reported accurately when low, for example, under a minute, and - get rounded to minutes and then hours as they get larger. This is done by - SessionTracker::GetRoundedDurationInSeconds. - </summary> - </metric> - <metric name="StartAction"> - <summary> - A metric to track specifically how the user got into XR presentation. 0: - Other, catch all. 1: RequestFrom2DBrowsing, the page requested - presentation while Chrome was in 2D mode. 2: RequestFromVRBrowsing, the - page requested presentation while Chrome was in VR browsing mode. 3: - HeadsetActivation, the user activated the VR headset while in 2D browsing - on the page, which listens for headset activations to request - presentation. 4: DeepLinkedApp, The page was launched in Chrome from the - VR system home (e.g., Daydream Home) and requested presentation. - </summary> - </metric> -</event> - <event name="VirtualKeyboard.Open"> <owner>shend@chromium.org</owner> <summary> @@ -7211,80 +7162,129 @@ </metric> </event> -<event name="IOS.FindInPageSearchMatches"> - <owner>thegreenfrog@chromium.org</owner> - <owner>michaeldo@chromium.org</owner> +<event name="XR.PageSession" singular="True"> + <owner>offenwanger@chromium.org</owner> <summary> - Logged when the FindInPage returns a user search request result. + Records properties of page use in XR, including VR browsing and WebXR + presentation. </summary> - <metric name="HasMatches"> + <metric name="Duration"> <summary> - True if there were matches. + The approximate amount of time the user spends on a page in XR in seconds. + Times are reported accurately when low, for example, under a minute, and + get rounded to minutes and then hours as they get larger. This is done by + SessionTracker::GetRoundedDurationInSeconds. + </summary> + </metric> + <metric name="EnteredFullscreen"> + <summary> + A boolean that is set to 1 if the user requested fullscreen while in XR on + some element on the page. + </summary> + </metric> + <metric name="EnteredVROnPageReason"> + <summary> + An enum that indicates that the user entered VR on this page and what + triggered the entry into VR, where 1 means VR was entered through headset + activation, and 2 means that request presentation triggered the entry into + VR. + </summary> + </metric> + <metric name="TimeOnPage"> + <summary> + Deprecated. + </summary> + </metric> + <metric name="WasOmniboxNavigation"> + <summary> + A boolean that is set to 1 if this page was entered into the omnibox, + either manually or using autocomplete. + </summary> + </metric> + <metric name="WasVoiceSearchNavigation"> + <summary> + A boolean that is set to 1 if this page was specifically requested and + recognized by a voice search. </summary> </metric> </event> -<event name="IOS.URLMismatchInLegacyAndSlimNavigationManager"> - <owner>eugenebut@chromium.org</owner> - <owner>danyao@chromium.org</owner> - <summary> - Logged when LegacyNavigationManager and KWKBasedNavigationManager have - different last committed URLs. This means that either old or new navigation - system has a URL spoofing bug. - </summary> - <metric name="HasMismatch"> +<event name="XR.WebXR" singular="True"> + <owner>billorr@chromium.org</owner> + <metric name="DidGetGamepads"> + <obsolete> + Deprecated in M75. + </obsolete> <summary> - True if there was a mismatch. - </summary> - <aggregation> - <history> - <statistics> - <enumeration/> - </statistics> - </history> - </aggregation> - </metric> -</event> - -<event name="MixedContentAutoupgrade.ResourceRequest"> - <owner>carlosil@chromium.org</owner> - <summary> - Status and Network error or HTTP response code for a resource request that - was autoupgraded to HTTPS as part of the mixed content autoupgrade - experiment. - </summary> - <metric name="Code"> - <summary> - The HTTP response or network error code for an autoupgraded request. + Boolean value that indicates that the Gamepad API was used on a WebXR + site. </summary> </metric> - <metric name="Status"> + <metric name="DidGetXRInputSources"> <summary> - An enum with 0 representing started, 1 failed, and 2 response received. + Boolean value that indicates that the WebXR input API was used. + </summary> + </metric> + <metric name="DidRequestAvailableDevices"> + <summary> + Boolean value that indicates that the API to enumerate devices was called. + </summary> + </metric> + <metric name="DidRequestPose"> + <summary> + Boolean value that indicates that poses were requested. + </summary> + </metric> + <metric name="DidRequestPresentation"> + <summary> + Boolean value that indicates that presentation was requested. + </summary> + </metric> + <metric name="DidUseNavigatorXR"> + <summary> + Boolean value that indicates that the WebXR Device API was used. + </summary> + </metric> + <metric name="ReturnedDevice"> + <summary> + Boolean value that indicates that a device was returned by the API to + enumerate devices. + </summary> + </metric> + <metric name="ReturnedPresentationCapableDevice"> + <summary> + Boolean value that indicates that a device was returned by the API to + enumerate devices, and that the device supports presentation. </summary> </metric> </event> -<event name="SSL.MixedContentShown"> - <owner>carlosil@chromium.org</owner> +<event name="XR.WebXR.PresentationSession"> + <owner>offenwanger@chromium.org</owner> <summary> - Logged when mixed content is displayed on a site. + Records data for a presentation session, where WebXR is running an exclusive + presentation to some device. </summary> - <metric name="Type"> + <metric name="Duration"> <summary> - A value of the MixedContentType enum, detailing the type of mixed content - included on the site. + The approximate amount of time the user spends in presentation in seconds. + Times are reported accurately when low, for example, under a minute, and + get rounded to minutes and then hours as they get larger. This is done by + SessionTracker::GetRoundedDurationInSeconds. </summary> </metric> -</event> - -<event name="HistoryManipulationIntervention"> - <owner>shivanisha@chromium.org</owner> - <summary> - Logged when an entry in the back-forward list is marked to be skipped on - subsequent back/forward button clicks as part of the history manipulation - intervention. This is logged when the entry is navigated away from. - </summary> + <metric name="StartAction"> + <summary> + A metric to track specifically how the user got into XR presentation. 0: + Other, catch all. 1: RequestFrom2DBrowsing, the page requested + presentation while Chrome was in 2D mode. 2: RequestFromVRBrowsing, the + page requested presentation while Chrome was in VR browsing mode. 3: + HeadsetActivation, the user activated the VR headset while in 2D browsing + on the page, which listens for headset activations to request + presentation. 4: DeepLinkedApp, The page was launched in Chrome from the + VR system home (e.g., Daydream Home) and requested presentation. + </summary> + </metric> </event> </ukm-configuration>
diff --git a/tools/metrics/ukm/ukm_model.py b/tools/metrics/ukm/ukm_model.py index 841257d..f278acca 100644 --- a/tools/metrics/ukm/ukm_model.py +++ b/tools/metrics/ukm/ukm_model.py
@@ -91,6 +91,7 @@ _UKM_CONFIGURATION_TYPE = models.ObjectNodeType( 'ukm-configuration', + alphabetization=[('event', _LOWERCASE_NAME_FN)], extra_newlines=(2, 1, 1), indent=False, children=[
diff --git a/tools/metrics/ukm/ukm_model_test.py b/tools/metrics/ukm/ukm_model_test.py index d681a49b..d456e1c 100755 --- a/tools/metrics/ukm/ukm_model_test.py +++ b/tools/metrics/ukm/ukm_model_test.py
@@ -49,6 +49,29 @@ </ukm-configuration> """.strip() +CONFIG_EVENT_NAMES_SORTED = """ +<ukm-configuration> + +<event name="Event1"/> + +<event name="Event2"/> + +<event name="Event3"/> + +</ukm-configuration> +""".strip() + +CONFIG_EVENT_NAMES_UNSORTED = """ +<ukm-configuration> + +<event name="Event2"/> + +<event name="Event3"/> + +<event name="Event1"/> + +</ukm-configuration> +""".strip() class UkmXmlTest(unittest.TestCase): @@ -70,6 +93,9 @@ self.assertIn('Metric:1', str(context.exception)) self.assertIn('does not match regex', str(context.exception)) + def testSortByEventName(self): + result = ukm_model.UpdateXML(CONFIG_EVENT_NAMES_UNSORTED) + self.assertMultiLineEqual(CONFIG_EVENT_NAMES_SORTED, result.strip()) if __name__ == '__main__': unittest.main()
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index d9e5d022..23a93cc 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -175,10 +175,12 @@ crbug.com/756119 [ All ] oilpan_gc_times.sync_scroll.key_mobile_sites_smooth/digg [ Skip ] # Benchmark: rendering.desktop +crbug.com/950710 [ All ] rendering.desktop/* [ Skip ] crbug.com/755556 [ Mac ] rendering.desktop/mix_blend_mode_animation_difference [ Skip ] crbug.com/755556 [ Mac ] rendering.desktop/mix_blend_mode_animation_hue [ Skip ] # Benchmark: rendering.mobile +crbug.com/950710 [ All ] rendering.mobile/* [ Skip ] crbug.com/785485 [ Android_Webview ] rendering.mobile/kevs_3d [ Skip ] crbug.com/785286 [ Android_Webview ] rendering.mobile/smash_cat [ Skip ] crbug.com/785286 [ Android_Webview ] rendering.mobile/effect_games [ Skip ] @@ -234,6 +236,9 @@ # crbug.com/894744 [ Android ] startup.mobile/cct:coldish:bbc [ Skip ] crbug.com/948789 [ Nexus_5 ] startup.mobile/maps_pwa:with_http_cache [ Skip ] crbug.com/948789 [ Nexus_5X ] startup.mobile/maps_pwa:with_http_cache [ Skip ] +crbug.com/950754 [ Android_Go ] startup.mobile/cct:coldish:bbc [ Skip ] +crbug.com/950754 [ Android_Go ] startup.mobile/intent:coldish:bbc [ Skip ] +crbug.com/950754 [ Android_Go ] startup.mobile/intent:warm:bbc [ Skip ] # Benchmark: system_health.common_desktop crbug.com/773084 [ Mac ] system_health.common_desktop/browse:tools:maps [ Skip ] @@ -384,6 +389,7 @@ crbug.com/853212 [ Android_Webview ] v8.browsing_mobile/browse:news:cnn [ Skip ] crbug.com/877648 [ Android_Go ] v8.browsing_mobile/browse:news:toi [ Skip ] crbug.com/877648 [ Android_Go ] v8.browsing_mobile/browse:news:cnn [ Skip ] +crbug.com/950757 [ Android_Go ] v8.browsing_mobile/browse:news:cnn:2018 [ Skip ] crbug.com/901967 [ Nexus6_Webview ] v8.browsing_mobile/browse:news:toi [ Skip ] crbug.com/923116 [ Android ] v8.browsing_mobile/browse:shopping:avito [ Skip ] crbug.com/929839 [ Android_Go ] v8.browsing_mobile/browse:chrome:newtab [ Skip ]
diff --git a/ui/accessibility/BUILD.gn b/ui/accessibility/BUILD.gn index a8b692a..a252b60 100644 --- a/ui/accessibility/BUILD.gn +++ b/ui/accessibility/BUILD.gn
@@ -39,6 +39,8 @@ "ax_action_data.h", "ax_action_handler.cc", "ax_action_handler.h", + "ax_clipping_behavior.h", + "ax_coordinate_system.h", "ax_enum_util.cc", "ax_enum_util.h", "ax_event.cc", @@ -58,6 +60,7 @@ "ax_node_data.h", "ax_node_position.cc", "ax_node_position.h", + "ax_offscreen_result.h", "ax_position.h", "ax_range.h", "ax_relative_bounds.cc",
diff --git a/ui/accessibility/ax_clipping_behavior.h b/ui/accessibility/ax_clipping_behavior.h new file mode 100644 index 0000000..c4652276 --- /dev/null +++ b/ui/accessibility/ax_clipping_behavior.h
@@ -0,0 +1,19 @@ +// 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 UI_ACCESSIBILITY_AX_CLIPPING_BEHAVIOR_H_ +#define UI_ACCESSIBILITY_AX_CLIPPING_BEHAVIOR_H_ + +namespace ui { + +// The clipping behavior to perform on bounds. Clipping limits a node's bounding +// box to the visible sizes of it's ancestors - which may be hidden or scrolled +// out of view. For a longer discussion on clipping behavior see the link below. +// https://chromium.googlesource.com/chromium/src/+/lkgr/docs/accessibility/offscreen.md +// kUnclipped: Do not apply clipping to bound results +// kClipped: Apply clipping to bound results +enum class AXClippingBehavior { kUnclipped, kClipped }; +} // namespace ui + +#endif // UI_ACCESSIBILITY_AX_CLIPPING_BEHAVIOR_H_
diff --git a/ui/accessibility/ax_coordinate_system.h b/ui/accessibility/ax_coordinate_system.h new file mode 100644 index 0000000..3cf1f2f6 --- /dev/null +++ b/ui/accessibility/ax_coordinate_system.h
@@ -0,0 +1,28 @@ +// 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 UI_ACCESSIBILITY_AX_COORDINATE_SYSTEM_H_ +#define UI_ACCESSIBILITY_AX_COORDINATE_SYSTEM_H_ + +namespace ui { + +// The coordinate system of bounds or points. The origin for all coordinate +// systems is the upper left hand corner of the region. Frame coordinates +// correspond to the current frame and root frame coordinates are relative to +// the topmost accessibility tree of the same type. For web content, root frame +// coordinates are relative to the root frame of the web page. From within an +// accessibility tree whose root is an iframe, frame coordinates are relative to +// the region of the iframe. From an iframe leaf accessibility node, frame +// coordinates are relative to the containing accessibility tree. For native UI, +// frame coordinates are relative to the current window whereas root frame +// coordinates are relative to the top-level window. The frame coordinates are +// equivalent to the root frame coordinates when the current accessibility tree +// is the root accessibility tree. +// kScreen: Relative to the screen space on the user's device +// kRootFrame: Relative to the top-level accessibility tree of the same type +// kFrame: Relative to the current accessibility tree +enum class AXCoordinateSystem { kScreen, kRootFrame, kFrame }; +} // namespace ui + +#endif // UI_ACCESSIBILITY_AX_COORDINATE_SYSTEM_H_
diff --git a/ui/accessibility/ax_event_generator.cc b/ui/accessibility/ax_event_generator.cc index dc904ad..df4c444 100644 --- a/ui/accessibility/ax_event_generator.cc +++ b/ui/accessibility/ax_event_generator.cc
@@ -369,6 +369,9 @@ DCHECK_EQ(tree_, tree); switch (attr) { + case ax::mojom::IntListAttribute::kControlsIds: + AddEvent(node, Event::CONTROLS_CHANGED); + break; case ax::mojom::IntListAttribute::kDescribedbyIds: AddEvent(node, Event::DESCRIBED_BY_CHANGED); break;
diff --git a/ui/accessibility/ax_event_generator.h b/ui/accessibility/ax_event_generator.h index 640868c0..a70216a 100644 --- a/ui/accessibility/ax_event_generator.h +++ b/ui/accessibility/ax_event_generator.h
@@ -30,6 +30,7 @@ CHILDREN_CHANGED, CLASS_NAME_CHANGED, COLLAPSED, + CONTROLS_CHANGED, DESCRIBED_BY_CHANGED, DESCRIPTION_CHANGED, DOCUMENT_SELECTION_CHANGED,
diff --git a/ui/accessibility/ax_event_generator_unittest.cc b/ui/accessibility/ax_event_generator_unittest.cc index 5cdbdef..d4f8fa1 100644 --- a/ui/accessibility/ax_event_generator_unittest.cc +++ b/ui/accessibility/ax_event_generator_unittest.cc
@@ -41,6 +41,9 @@ case AXEventGenerator::Event::COLLAPSED: event_name = "COLLAPSED"; break; + case AXEventGenerator::Event::CONTROLS_CHANGED: + event_name = "CONTROLS_CHANGED"; + break; case AXEventGenerator::Event::DESCRIBED_BY_CHANGED: event_name = "DESCRIBED_BY_CHANGED"; break; @@ -764,11 +767,11 @@ ids); ASSERT_TRUE(tree.Unserialize(update)); EXPECT_EQ( + "CONTROLS_CHANGED on 6, " "LANGUAGE_CHANGED on 2, " "OTHER_ATTRIBUTE_CHANGED on 3, " "OTHER_ATTRIBUTE_CHANGED on 4, " "OTHER_ATTRIBUTE_CHANGED on 5, " - "OTHER_ATTRIBUTE_CHANGED on 6, " "RELATED_NODE_CHANGED on 6", DumpEvents(&event_generator)); } @@ -1199,4 +1202,26 @@ DumpEvents(&event_generator)); } +TEST(AXEventGeneratorTest, ControlsChanged) { + AXTreeUpdate initial_state; + initial_state.root_id = 1; + initial_state.nodes.resize(2); + initial_state.nodes[0].id = 1; + initial_state.nodes[0].child_ids.push_back(2); + initial_state.nodes[1].id = 2; + + AXTree tree(initial_state); + AXEventGenerator event_generator(&tree); + AXTreeUpdate update = initial_state; + + std::vector<int> ids = {2}; + update.nodes[0].AddIntListAttribute(ax::mojom::IntListAttribute::kControlsIds, + ids); + EXPECT_TRUE(tree.Unserialize(update)); + EXPECT_EQ( + "CONTROLS_CHANGED on 1, " + "RELATED_NODE_CHANGED on 1", + DumpEvents(&event_generator)); +} + } // namespace ui
diff --git a/ui/accessibility/ax_offscreen_result.h b/ui/accessibility/ax_offscreen_result.h new file mode 100644 index 0000000..245d5aba --- /dev/null +++ b/ui/accessibility/ax_offscreen_result.h
@@ -0,0 +1,20 @@ +// 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 UI_ACCESSIBILITY_AX_OFFSCREEN_RESULT_H_ +#define UI_ACCESSIBILITY_AX_OFFSCREEN_RESULT_H_ + +namespace ui { + +// The onscreen state of result bounds or points. Any object is offscreen if +// it is fully clipped or scrolled out of view by any of its ancestors so that +// it is not rendered on the screen. For a longer discussion on what offscreen +// means in the context of Chromium see the link below. +// https://chromium.googlesource.com/chromium/src/+/lkgr/docs/accessibility/offscreen.md +// kOnscreen: The resulting bound or point is onscreen +// kOffscreen: The resulting bound or point is offscreen +enum class AXOffscreenResult { kOnscreen, kOffscreen }; +} // namespace ui + +#endif // UI_ACCESSIBILITY_AX_OFFSCREEN_RESULT_H_
diff --git a/ui/accessibility/ax_range.h b/ui/accessibility/ax_range.h index f7af36b..1f2f6269 100644 --- a/ui/accessibility/ax_range.h +++ b/ui/accessibility/ax_range.h
@@ -192,8 +192,6 @@ current_line_end = range_end->Clone(); DCHECK(current_line_end->GetAnchor() == current_line_start->GetAnchor()); - int length_of_current_line = - current_line_end->text_offset() - current_line_start->text_offset(); if (current_line_start->GetAnchor()->data().role == ax::mojom::Role::kInlineTextBox) { @@ -207,13 +205,13 @@ AXPlatformNodeDelegate* current_anchor_delegate = manager->GetDelegate(current_tree_id, current_anchor->id()); - gfx::Rect current_rect = current_anchor_delegate->GetScreenBoundsForRange( - current_line_start->text_offset(), length_of_current_line, - /*clipped*/ true); + gfx::Rect current_rect = current_anchor_delegate->GetRangeBoundsRect( + current_line_start->text_offset(), current_line_end->text_offset(), + AXCoordinateSystem::kScreen, AXClippingBehavior::kClipped); // Only add rects that are within the current viewport. The 'clipped' - // parameter for GetScreenBoundsForRange will return an empty rect in - // that case. + // parameter for GetClippedScreenRangeBoundsRect will return an empty rect + // in that case. if (!current_rect.IsEmpty()) rectangles.emplace_back(current_rect);
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc index 80d0e46..ee24ec5 100644 --- a/ui/accessibility/ax_tree.cc +++ b/ui/accessibility/ax_tree.cc
@@ -450,6 +450,9 @@ } } + // Clear list_info_map_ + ordered_set_info_map_.clear(); + std::set<const AXNode*>& new_nodes = update_state.new_nodes; std::vector<AXTreeObserver::Change> changes; changes.reserve(update.nodes.size()); @@ -492,9 +495,6 @@ observer.OnAtomicUpdateFinished(this, root_->id() != old_root_id, changes); } - // Clear list_info_map_ - ordered_set_info_map_.clear(); - return true; } @@ -980,6 +980,7 @@ // examined, stop adding to this set. if (original_node_index < i) break; + // If a decrease in level has been detected before the original node // has been examined, then everything previously added to items actually // belongs to a different set. Clear items vector. @@ -1078,11 +1079,20 @@ // 1. Node role matches ordered set role. // 2. The node that calculations were called on is the ordered_set. if (node.SetRoleMatchesItemRole(ordered_set) || ordered_set == &node) { + auto ordered_set_info_result = + ordered_set_info_map_.find(ordered_set->id()); // If ordered_set is not in the cache, assign it a new set_size. - if (ordered_set_info_map_.find(ordered_set->id()) == - ordered_set_info_map_.end()) { + if (ordered_set_info_result == ordered_set_info_map_.end()) { ordered_set_info_map_[ordered_set->id()] = OrderedSetInfo(); ordered_set_info_map_[ordered_set->id()].set_size = set_size_value; + ordered_set_info_map_[ordered_set->id()].lowest_hierarchical_level = + hierarchical_level; + } else { + OrderedSetInfo ordered_set_info = ordered_set_info_result->second; + if (ordered_set_info.lowest_hierarchical_level > hierarchical_level) { + ordered_set_info.set_size = set_size_value; + ordered_set_info.lowest_hierarchical_level = hierarchical_level; + } } }
diff --git a/ui/accessibility/ax_tree.h b/ui/accessibility/ax_tree.h index 1e8542b..5cc2035 100644 --- a/ui/accessibility/ax_tree.h +++ b/ui/accessibility/ax_tree.h
@@ -240,6 +240,7 @@ struct OrderedSetInfo { int32_t pos_in_set; int32_t set_size; + int32_t lowest_hierarchical_level; OrderedSetInfo() : pos_in_set(0), set_size(0) {} ~OrderedSetInfo() {} };
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc index 82eec09..89fbad0 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -216,19 +216,21 @@ SetWeakGPtrToAtkObject(&g_active_top_level_frame, new_top_level_frame); } -AXPlatformNodeDelegate::TextRangeBoundsCoordinateSystem -AtkCoordTypeToTextRangeBoundsCoordinateSystem(AtkCoordType coordinate_type) { +AXCoordinateSystem AtkCoordTypeToAXCoordinateSystem( + AtkCoordType coordinate_type) { switch (coordinate_type) { case ATK_XY_SCREEN: - return AXPlatformNodeDelegate::Screen; + return AXCoordinateSystem::kScreen; case ATK_XY_WINDOW: - return AXPlatformNodeDelegate::Window; + return AXCoordinateSystem::kRootFrame; #ifdef ATK_230 case ATK_XY_PARENT: - return AXPlatformNodeDelegate::Parent; + // AXCoordinateSystem does not support parent coordinates. + NOTIMPLEMENTED(); + return AXCoordinateSystem::kFrame; #endif // ATK_230 default: - return AXPlatformNodeDelegate::Screen; + return AXCoordinateSystem::kScreen; } } @@ -1189,6 +1191,30 @@ } #endif +gfx::Rect GetUnclippedParentRangeBoundsRect( + AXPlatformNodeDelegate* ax_platform_node_delegate, + const int start_offset, + const int end_offset) { + const AXPlatformNode* parent_platform_node = + AXPlatformNode::FromNativeViewAccessible( + ax_platform_node_delegate->GetParent()); + if (parent_platform_node) { + const AXPlatformNodeDelegate* parent_ax_platform_node_delegate = + parent_platform_node->GetDelegate(); + if (parent_ax_platform_node_delegate) { + return ax_platform_node_delegate->GetRangeBoundsRect( + start_offset, end_offset, AXCoordinateSystem::kRootFrame, + AXClippingBehavior::kUnclipped) - + parent_ax_platform_node_delegate + ->GetBoundsRect(AXCoordinateSystem::kRootFrame, + AXClippingBehavior::kClipped) + .OffsetFromOrigin(); + } + } + + return gfx::Rect(); +} + void GetCharacterExtents(AtkText* atk_text, int offset, int* x, @@ -1200,10 +1226,21 @@ AXPlatformNodeAuraLinux* obj = AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(atk_text)); if (obj) { - rect = obj->GetDelegate()->GetTextRangeBoundsRect( - obj->UnicodeToUTF16OffsetInText(offset), - obj->UnicodeToUTF16OffsetInText(offset + 1), - AtkCoordTypeToTextRangeBoundsCoordinateSystem(coordinate_type)); + switch (coordinate_type) { +#ifdef ATK_230 + case ATK_XY_PARENT: + rect = GetUnclippedParentRangeBoundsRect(obj->GetDelegate(), offset, + offset + 1); + break; +#endif + default: + rect = obj->GetDelegate()->GetRangeBoundsRect( + obj->UnicodeToUTF16OffsetInText(offset), + obj->UnicodeToUTF16OffsetInText(offset + 1), + AtkCoordTypeToAXCoordinateSystem(coordinate_type), + AXClippingBehavior::kUnclipped); + break; + } } if (x) @@ -1228,10 +1265,21 @@ AXPlatformNodeAuraLinux* obj = AtkObjectToAXPlatformNodeAuraLinux(ATK_OBJECT(atk_text)); if (obj) { - rect = obj->GetDelegate()->GetTextRangeBoundsRect( - obj->UnicodeToUTF16OffsetInText(start_offset), - obj->UnicodeToUTF16OffsetInText(end_offset), - AtkCoordTypeToTextRangeBoundsCoordinateSystem(coordinate_type)); + switch (coordinate_type) { +#ifdef ATK_230 + case ATK_XY_PARENT: + rect = GetUnclippedParentRangeBoundsRect(obj->GetDelegate(), + start_offset, end_offset); + break; +#endif + default: + rect = obj->GetDelegate()->GetRangeBoundsRect( + obj->UnicodeToUTF16OffsetInText(start_offset), + obj->UnicodeToUTF16OffsetInText(end_offset), + AtkCoordTypeToAXCoordinateSystem(coordinate_type), + AXClippingBehavior::kUnclipped); + break; + } } out_rectangle->x = rect.x(); @@ -3339,7 +3387,8 @@ void AXPlatformNodeAuraLinux::SetExtentsRelativeToAtkCoordinateType( gint* x, gint* y, gint* width, gint* height, AtkCoordType coord_type) { - gfx::Rect extents = delegate_->GetUnclippedScreenBoundsRect(); + gfx::Rect extents = delegate_->GetBoundsRect(AXCoordinateSystem::kScreen, + AXClippingBehavior::kUnclipped); if (x) *x = extents.x();
diff --git a/ui/accessibility/platform/ax_platform_node_delegate.h b/ui/accessibility/platform/ax_platform_node_delegate.h index a30aabc..6126acfb 100644 --- a/ui/accessibility/platform/ax_platform_node_delegate.h +++ b/ui/accessibility/platform/ax_platform_node_delegate.h
@@ -9,9 +9,12 @@ #include <utility> #include <vector> +#include "ui/accessibility/ax_clipping_behavior.h" +#include "ui/accessibility/ax_coordinate_system.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_export.h" #include "ui/accessibility/ax_node_position.h" +#include "ui/accessibility/ax_offscreen_result.h" #include "ui/accessibility/ax_position.h" #include "ui/accessibility/ax_text_utils.h" #include "ui/accessibility/platform/ax_unique_id.h" @@ -78,34 +81,28 @@ // Get the child of a node given a 0-based index. virtual gfx::NativeViewAccessible ChildAtIndex(int index) = 0; - // Get the bounds of this node in screen coordinates, applying clipping - // to all bounding boxes so that the resulting rect is within the window. - virtual gfx::Rect GetClippedScreenBoundsRect() const = 0; + // Return the bounds of this node in the coordinate system indicated. If the + // clipping behavior is set to clipped, clipping is applied. If an offscreen + // result address is provided, it will be populated depending on whether the + // returned bounding box is onscreen or offscreen. + virtual gfx::Rect GetBoundsRect( + const AXCoordinateSystem coordinate_system, + const AXClippingBehavior clipping_behavior, + AXOffscreenResult* offscreen_result = nullptr) const = 0; - // Get the bounds of this node in screen coordinates without applying - // any clipping; it may be outside of the window or offscreen. - virtual gfx::Rect GetUnclippedScreenBoundsRect() const = 0; - - // Returns the bounds of the given range in screen coordinates. Only valid - // when the role is WebAXRoleStaticText. - virtual gfx::Rect GetScreenBoundsForRange(int start, - int len, - bool clipped = false) const = 0; - - // Get the bounds of the given text range in the given coordinate system. - // Screen gets these boundaries in screen coordinates, Window in coordinates - // relative to the parent window, and Parent relative to the parent node. The - // offsets refer to offsets within the text returned for this node when - // treated as a platform text node. - enum TextRangeBoundsCoordinateSystem { - Screen, - Window, - Parent, - }; - virtual gfx::Rect GetTextRangeBoundsRect( - int start_offset, - int end_offset, - TextRangeBoundsCoordinateSystem coordinate_system) const = 0; + // Return the bounds of the text range given by text offsets in the coordinate + // system indicated. When determining the text offset of a node, the text of + // this node is included while descendant text may be accounted for with a + // single special character. If the clipping behavior is set to clipped, + // clipping is applied. If an offscreen result address is provided, it will be + // populated depending on whether the returned bounding box is onscreen or + // offscreen. + virtual gfx::Rect GetRangeBoundsRect( + const int start_offset, + const int end_offset, + const AXCoordinateSystem coordinate_system, + const AXClippingBehavior clipping_behavior, + AXOffscreenResult* offscreen_result = nullptr) const = 0; // Do a *synchronous* hit test of the given location in global screen // coordinates, and the node within this node's subtree (inclusive) that's
diff --git a/ui/accessibility/platform/ax_platform_node_delegate_base.cc b/ui/accessibility/platform/ax_platform_node_delegate_base.cc index 6836394d..e5252bf 100644 --- a/ui/accessibility/platform/ax_platform_node_delegate_base.cc +++ b/ui/accessibility/platform/ax_platform_node_delegate_base.cc
@@ -51,27 +51,32 @@ return nullptr; } -gfx::Rect AXPlatformNodeDelegateBase::GetClippedScreenBoundsRect() const { +gfx::Rect AXPlatformNodeDelegateBase::GetBoundsRect( + const AXCoordinateSystem coordinate_system, + const AXClippingBehavior clipping_behavior, + AXOffscreenResult* offscreen_result) const { return gfx::Rect(); } -gfx::Rect AXPlatformNodeDelegateBase::GetUnclippedScreenBoundsRect() const { +gfx::Rect AXPlatformNodeDelegateBase::GetRangeBoundsRect( + const int start_offset, + const int end_offset, + const AXCoordinateSystem coordinate_system, + const AXClippingBehavior clipping_behavior, + AXOffscreenResult* offscreen_result) const { return gfx::Rect(); } -gfx::Rect AXPlatformNodeDelegateBase::GetScreenBoundsForRange( - int start, - int len, - bool clipped) const { - return gfx::Rect(); +gfx::Rect AXPlatformNodeDelegateBase::GetClippedScreenBoundsRect( + AXOffscreenResult* offscreen_result) const { + return GetBoundsRect(AXCoordinateSystem::kScreen, + AXClippingBehavior::kClipped, offscreen_result); } -gfx::Rect AXPlatformNodeDelegateBase::GetTextRangeBoundsRect( - int start_offset, - int end_offset, - AXPlatformNodeDelegate::TextRangeBoundsCoordinateSystem coordinate_system) - const { - return gfx::Rect(); +gfx::Rect AXPlatformNodeDelegateBase::GetUnclippedScreenBoundsRect( + AXOffscreenResult* offscreen_result) const { + return GetBoundsRect(AXCoordinateSystem::kScreen, + AXClippingBehavior::kUnclipped, offscreen_result); } gfx::NativeViewAccessible AXPlatformNodeDelegateBase::HitTestSync(int x,
diff --git a/ui/accessibility/platform/ax_platform_node_delegate_base.h b/ui/accessibility/platform/ax_platform_node_delegate_base.h index d38ba8cc..86ad39f1 100644 --- a/ui/accessibility/platform/ax_platform_node_delegate_base.h +++ b/ui/accessibility/platform/ax_platform_node_delegate_base.h
@@ -51,27 +51,22 @@ // Get the child of a node given a 0-based index. gfx::NativeViewAccessible ChildAtIndex(int index) override; - // Get the bounds of this node in screen coordinates, applying clipping - // to all bounding boxes so that the resulting rect is within the window. - gfx::Rect GetClippedScreenBoundsRect() const override; + gfx::Rect GetBoundsRect(const AXCoordinateSystem coordinate_system, + const AXClippingBehavior clipping_behavior, + AXOffscreenResult* offscreen_result) const override; - // Get the bounds of this node in screen coordinates without applying - // any clipping; it may be outside of the window or offscreen. - gfx::Rect GetUnclippedScreenBoundsRect() const override; + gfx::Rect GetRangeBoundsRect( + const int start_offset, + const int end_offset, + const AXCoordinateSystem coordinate_system, + const AXClippingBehavior clipping_behavior, + AXOffscreenResult* offscreen_result) const override; - // Get the bounds of this node with text offsets in screen coordinates, - // optionally applying clipping to all bounding boxes so that the resulting - // rect is within the window. Only valid when the role is - // ax::mojom::Role::kStaticText. - gfx::Rect GetScreenBoundsForRange(int start, - int len, - bool clipped = false) const override; - - gfx::Rect GetTextRangeBoundsRect( - int start_offset, - int end_offset, - AXPlatformNodeDelegate::TextRangeBoundsCoordinateSystem coordinate_system) - const override; + // Derivative utils for AXPlatformNodeDelegate::GetBoundsRect + gfx::Rect GetClippedScreenBoundsRect( + AXOffscreenResult* offscreen_result = nullptr) const; + gfx::Rect GetUnclippedScreenBoundsRect( + AXOffscreenResult* offscreen_result = nullptr) const; // Do a *synchronous* hit test of the given location in global screen // coordinates, and the node within this node's subtree (inclusive) that's
diff --git a/ui/accessibility/platform/ax_platform_node_mac.mm b/ui/accessibility/platform/ax_platform_node_mac.mm index c23d872..f7f0f3e 100644 --- a/ui/accessibility/platform/ax_platform_node_mac.mm +++ b/ui/accessibility/platform/ax_platform_node_mac.mm
@@ -374,8 +374,8 @@ - (NSRect)boundsInScreen { if (!node_ || !node_->GetDelegate()) return NSZeroRect; - return gfx::ScreenRectToNSRect( - node_->GetDelegate()->GetClippedScreenBoundsRect()); + return gfx::ScreenRectToNSRect(node_->GetDelegate()->GetBoundsRect( + ui::AXCoordinateSystem::kScreen, ui::AXClippingBehavior::kClipped)); } - (NSString*)getStringAttribute:(ax::mojom::StringAttribute)attribute {
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index 17e54a59..bbc7d8a 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -414,8 +414,10 @@ SAFEARRAY* AXPlatformNodeWin::CreateClickablePointArray() { SAFEARRAY* clickable_point_array = SafeArrayCreateVector(VT_R8, 0, 2); - gfx::Point center = - GetDelegate()->GetUnclippedScreenBoundsRect().CenterPoint(); + gfx::Point center = GetDelegate() + ->GetBoundsRect(AXCoordinateSystem::kScreen, + AXClippingBehavior::kUnclipped) + .CenterPoint(); double* double_array; SafeArrayAccessData(clickable_point_array, @@ -433,7 +435,8 @@ if (!GetDelegate() || !IsScrollable()) return {}; - const gfx::Rect bounds = GetDelegate()->GetClippedScreenBoundsRect(); + const gfx::Rect bounds = GetDelegate()->GetBoundsRect( + AXCoordinateSystem::kScreen, AXClippingBehavior::kClipped); const int large_horizontal_change = bounds.width(); const int large_vertical_change = bounds.height(); @@ -591,7 +594,10 @@ COM_OBJECT_VALIDATE_1_ARG(child); gfx::Point point(x_left, y_top); - if (!GetDelegate()->GetClippedScreenBoundsRect().Contains(point)) { + if (!GetDelegate() + ->GetBoundsRect(AXCoordinateSystem::kScreen, + AXClippingBehavior::kClipped) + .Contains(point)) { // Return S_FALSE and VT_EMPTY when outside the object's boundaries. child->vt = VT_EMPTY; return S_FALSE; @@ -652,7 +658,8 @@ COM_OBJECT_VALIDATE_VAR_ID_4_ARGS_AND_GET_TARGET(var_id, x_left, y_top, width, height, target); - gfx::Rect bounds = target->GetDelegate()->GetUnclippedScreenBoundsRect(); + gfx::Rect bounds = target->GetDelegate()->GetBoundsRect( + AXCoordinateSystem::kScreen, AXClippingBehavior::kUnclipped); *x_left = bounds.x(); *y_top = bounds.y(); *width = bounds.width(); @@ -1372,7 +1379,8 @@ if (GetParent()) { AXPlatformNodeBase* base = FromNativeViewAccessible(GetParent()); scroll_to += base->GetDelegate() - ->GetUnclippedScreenBoundsRect() + ->GetBoundsRect(AXCoordinateSystem::kScreen, + AXClippingBehavior::kUnclipped) .OffsetFromOrigin(); } } else if (coordinate_type != IA2_COORDTYPE_SCREEN_RELATIVE) { @@ -1791,7 +1799,8 @@ return S_OK; } - gfx::RectF clipped_bounds(GetDelegate()->GetClippedScreenBoundsRect()); + gfx::RectF clipped_bounds(GetDelegate()->GetBoundsRect( + AXCoordinateSystem::kScreen, AXClippingBehavior::kClipped)); float x_min = GetIntAttribute(ax::mojom::IntAttribute::kScrollXMin); float x_max = GetIntAttribute(ax::mojom::IntAttribute::kScrollXMax); float total_width = clipped_bounds.width() + x_max - x_min; @@ -1824,7 +1833,8 @@ return S_OK; } - gfx::RectF clipped_bounds(GetDelegate()->GetClippedScreenBoundsRect()); + gfx::RectF clipped_bounds(GetDelegate()->GetBoundsRect( + AXCoordinateSystem::kScreen, AXClippingBehavior::kClipped)); float y_min = GetIntAttribute(ax::mojom::IntAttribute::kScrollYMin); float y_max = GetIntAttribute(ax::mojom::IntAttribute::kScrollYMax); float total_height = clipped_bounds.height() + y_max - y_min; @@ -3474,7 +3484,8 @@ WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_BOUNDINGRECTANGLE); UIA_VALIDATE_CALL_1_ARG(bounding_rectangle); - gfx::Rect bounds = delegate_->GetUnclippedScreenBoundsRect(); + gfx::Rect bounds = delegate_->GetBoundsRect(AXCoordinateSystem::kScreen, + AXClippingBehavior::kUnclipped); bounding_rectangle->left = bounds.x(); bounding_rectangle->top = bounds.y(); bounding_rectangle->width = bounds.width(); @@ -3593,7 +3604,7 @@ break; case UIA_ControllerForPropertyId: - result->vt = VT_ARRAY; + result->vt = VT_ARRAY | VT_UNKNOWN; result->parray = CreateUIAElementsArrayForRelation( ax::mojom::IntListAttribute::kControlsIds); break;
diff --git a/ui/accessibility/platform/ax_platform_node_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_win_unittest.cc index 973fb75..aa37e488 100644 --- a/ui/accessibility/platform/ax_platform_node_win_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_win_unittest.cc
@@ -1796,7 +1796,7 @@ // TODO(dougt): Try adding one more relation. } -TEST_F(AXPlatformNodeWinTest, TestRelationTargetsOfType) { +TEST_F(AXPlatformNodeWinTest, DISABLED_TestRelationTargetsOfType) { AXNodeData root; root.id = 1; root.role = ax::mojom::Role::kRootWebArea; @@ -3357,6 +3357,44 @@ } } +TEST_F(AXPlatformNodeWinTest, TestUIAGetControllerForPropertyId) { + AXNodeData root; + root.id = 1; + root.role = ax::mojom::Role::kRootWebArea; + root.child_ids = {2, 3, 4}; + + AXNodeData tab; + tab.id = 2; + tab.role = ax::mojom::Role::kTab; + tab.SetName("tab"); + std::vector<int32_t> controller_ids = {3, 4}; + tab.AddIntListAttribute(ax::mojom::IntListAttribute::kControlsIds, + controller_ids); + + AXNodeData panel1; + panel1.id = 3; + panel1.role = ax::mojom::Role::kTabPanel; + panel1.SetName("panel1"); + + AXNodeData panel2; + panel2.id = 4; + panel2.role = ax::mojom::Role::kTabPanel; + panel2.SetName("panel2"); + + Init(root, tab, panel1, panel2); + TestAXNodeWrapper* root_wrapper = + TestAXNodeWrapper::GetOrCreate(tree_.get(), GetRootNode()); + root_wrapper->BuildAllWrappers(tree_.get(), GetRootNode()); + + ComPtr<IRawElementProviderSimple> tab_node = + QueryInterfaceFromNode<IRawElementProviderSimple>( + GetRootNode()->children()[0]); + + std::vector<std::wstring> expected_names = {L"panel1", L"panel2"}; + EXPECT_UIA_ELEMENT_ARRAY_BSTR_EQ(tab_node, UIA_ControllerForPropertyId, + UIA_NamePropertyId, expected_names); +} + TEST_F(AXPlatformNodeWinTest, TestUIAGetDescribedByPropertyId) { AXNodeData root; std::vector<int32_t> describedby_ids = {1, 2, 3};
diff --git a/ui/accessibility/platform/ax_system_caret_win.cc b/ui/accessibility/platform/ax_system_caret_win.cc index e8f28e71..d7f9511d 100644 --- a/ui/accessibility/platform/ax_system_caret_win.cc +++ b/ui/accessibility/platform/ax_system_caret_win.cc
@@ -109,13 +109,19 @@ return nullptr; } -gfx::Rect AXSystemCaretWin::GetClippedScreenBoundsRect() const { - // We could optionally add clipping here if ever needed. - return ToEnclosingRect(data_.relative_bounds.bounds); -} - -gfx::Rect AXSystemCaretWin::GetUnclippedScreenBoundsRect() const { - return ToEnclosingRect(data_.relative_bounds.bounds); +gfx::Rect AXSystemCaretWin::GetBoundsRect( + const AXCoordinateSystem coordinate_system, + const AXClippingBehavior clipping_behavior, + AXOffscreenResult* offscreen_result) const { + switch (coordinate_system) { + case AXCoordinateSystem::kScreen: + // We could optionally add clipping here if ever needed. + return ToEnclosingRect(data_.relative_bounds.bounds); + case AXCoordinateSystem::kRootFrame: + case AXCoordinateSystem::kFrame: + NOTIMPLEMENTED(); + return gfx::Rect(); + } } gfx::AcceleratedWidget
diff --git a/ui/accessibility/platform/ax_system_caret_win.h b/ui/accessibility/platform/ax_system_caret_win.h index a4d2392..a18ed98 100644 --- a/ui/accessibility/platform/ax_system_caret_win.h +++ b/ui/accessibility/platform/ax_system_caret_win.h
@@ -37,8 +37,9 @@ // |AXPlatformNodeDelegate| members. const AXNodeData& GetData() const override; gfx::NativeViewAccessible GetParent() override; - gfx::Rect GetClippedScreenBoundsRect() const override; - gfx::Rect GetUnclippedScreenBoundsRect() const override; + gfx::Rect GetBoundsRect(const AXCoordinateSystem coordinate_system, + const AXClippingBehavior clipping_behavior, + AXOffscreenResult* offscreen_result) const override; gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override; bool ShouldIgnoreHoveredStateForTesting() override; const ui::AXUniqueId& GetUniqueId() const override;
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.cc b/ui/accessibility/platform/test_ax_node_wrapper.cc index 4698d0d..cb27fcb 100644 --- a/ui/accessibility/platform/test_ax_node_wrapper.cc +++ b/ui/accessibility/platform/test_ax_node_wrapper.cc
@@ -126,27 +126,43 @@ nullptr; } -gfx::Rect TestAXNodeWrapper::GetClippedScreenBoundsRect() const { - // We could add clipping here if needed. - gfx::RectF bounds = GetData().relative_bounds.bounds; - bounds.Offset(g_offset); - return gfx::ToEnclosingRect(bounds); +gfx::Rect TestAXNodeWrapper::GetBoundsRect( + const AXCoordinateSystem coordinate_system, + const AXClippingBehavior clipping_behavior, + AXOffscreenResult* offscreen_result) const { + switch (coordinate_system) { + case AXCoordinateSystem::kScreen: { + // We could optionally add clipping here if ever needed. + gfx::RectF bounds = GetData().relative_bounds.bounds; + bounds.Offset(g_offset); + return gfx::ToEnclosingRect(bounds); + } + case AXCoordinateSystem::kRootFrame: + case AXCoordinateSystem::kFrame: + NOTIMPLEMENTED(); + return gfx::Rect(); + } } -gfx::Rect TestAXNodeWrapper::GetUnclippedScreenBoundsRect() const { - gfx::RectF bounds = GetData().relative_bounds.bounds; - bounds.Offset(g_offset); - return gfx::ToEnclosingRect(bounds); -} - -gfx::Rect TestAXNodeWrapper::GetScreenBoundsForRange(int start, - int len, - bool clipped) const { - // Ignoring start, len, and clipped, as there's no clean way to map these - // via unit tests. - gfx::RectF bounds = GetData().relative_bounds.bounds; - bounds.Offset(g_offset); - return gfx::ToEnclosingRect(bounds); +gfx::Rect TestAXNodeWrapper::GetRangeBoundsRect( + const int start_offset, + const int end_offset, + const AXCoordinateSystem coordinate_system, + const AXClippingBehavior clipping_behavior, + AXOffscreenResult* offscreen_result) const { + switch (coordinate_system) { + case AXCoordinateSystem::kScreen: { + // Ignoring start, len, and clipped, as there's no clean way to map these + // via unit tests. + gfx::RectF bounds = GetData().relative_bounds.bounds; + bounds.Offset(g_offset); + return gfx::ToEnclosingRect(bounds); + } + case AXCoordinateSystem::kRootFrame: + case AXCoordinateSystem::kFrame: + NOTIMPLEMENTED(); + return gfx::Rect(); + } } TestAXNodeWrapper* TestAXNodeWrapper::HitTestSyncInternal(int x, int y) {
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.h b/ui/accessibility/platform/test_ax_node_wrapper.h index 7c2ccfc..05509b1e 100644 --- a/ui/accessibility/platform/test_ax_node_wrapper.h +++ b/ui/accessibility/platform/test_ax_node_wrapper.h
@@ -55,11 +55,15 @@ gfx::NativeViewAccessible GetParent() override; int GetChildCount() override; gfx::NativeViewAccessible ChildAtIndex(int index) override; - gfx::Rect GetClippedScreenBoundsRect() const override; - gfx::Rect GetUnclippedScreenBoundsRect() const override; - gfx::Rect GetScreenBoundsForRange(int start, - int len, - bool clipped) const override; + gfx::Rect GetBoundsRect(const AXCoordinateSystem coordinate_system, + const AXClippingBehavior clipping_behavior, + AXOffscreenResult* offscreen_result) const override; + gfx::Rect GetRangeBoundsRect( + const int start_offset, + const int end_offset, + const AXCoordinateSystem coordinate_system, + const AXClippingBehavior clipping_behavior, + AXOffscreenResult* offscreen_result) const override; gfx::NativeViewAccessible HitTestSync(int x, int y) override; gfx::NativeViewAccessible GetFocus() override; AXPlatformNode* GetFromNodeID(int32_t id) override;
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn index 67cfa13..49f1ed3 100644 --- a/ui/base/BUILD.gn +++ b/ui/base/BUILD.gn
@@ -351,6 +351,8 @@ "accelerators/global_media_keys_listener_win.cc", "accelerators/global_media_keys_listener_win.h", "accelerators/media_keys_listener_win.cc", + "accelerators/system_media_controls_media_keys_listener.cc", + "accelerators/system_media_controls_media_keys_listener.h", ] } else if (use_mpris) { sources += [ @@ -445,6 +447,10 @@ } } + if (is_win) { + deps += [ "//ui/base/win/system_media_controls" ] + } + if (use_mpris) { deps += [ "//dbus", @@ -1001,10 +1007,13 @@ if (is_win) { sources += [ + "accelerators/system_media_controls_media_keys_listener_unittest.cc", "dragdrop/os_exchange_data_win_unittest.cc", "win/hwnd_subclass_unittest.cc", ] + deps += [ "//ui/base/win/system_media_controls:test_support" ] + ldflags = [ "/DELAYLOAD:d2d1.dll", "/DELAYLOAD:d3d10_1.dll",
diff --git a/ui/base/accelerators/media_keys_listener_win.cc b/ui/base/accelerators/media_keys_listener_win.cc index 5a24b96..c50ea0ca 100644 --- a/ui/base/accelerators/media_keys_listener_win.cc +++ b/ui/base/accelerators/media_keys_listener_win.cc
@@ -5,6 +5,7 @@ #include "ui/base/accelerators/media_keys_listener.h" #include "ui/base/accelerators/global_media_keys_listener_win.h" +#include "ui/base/accelerators/system_media_controls_media_keys_listener.h" namespace ui { @@ -14,10 +15,18 @@ DCHECK(delegate); if (scope == Scope::kGlobal) { - if (!GlobalMediaKeysListenerWin::has_instance()) + // We should never have more than one global media keys listener. + if (!SystemMediaControlsMediaKeysListener::has_instance() && + !GlobalMediaKeysListenerWin::has_instance()) { + auto listener = + std::make_unique<SystemMediaControlsMediaKeysListener>(delegate); + if (listener->Initialize()) + return listener; + + // If |Initialize()| fails, then we fall back to the + // GlobalMediaKeysListenerWin. return std::make_unique<GlobalMediaKeysListenerWin>(delegate); - // We shouldn't try to create more than one GlobalMediaKeysListenerWin - // instance. + } NOTREACHED(); } return nullptr;
diff --git a/ui/base/accelerators/system_media_controls_media_keys_listener.cc b/ui/base/accelerators/system_media_controls_media_keys_listener.cc new file mode 100644 index 0000000..a07e0eb --- /dev/null +++ b/ui/base/accelerators/system_media_controls_media_keys_listener.cc
@@ -0,0 +1,136 @@ +// 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 "ui/base/accelerators/system_media_controls_media_keys_listener.h" + +#include "ui/base/accelerators/accelerator.h" +#include "ui/base/win/system_media_controls/system_media_controls_service.h" + +namespace ui { + +// static +bool SystemMediaControlsMediaKeysListener::has_instance_ = false; + +SystemMediaControlsMediaKeysListener::SystemMediaControlsMediaKeysListener( + MediaKeysListener::Delegate* delegate) + : delegate_(delegate) { + DCHECK(delegate_); + DCHECK(!has_instance_); + has_instance_ = true; +} + +SystemMediaControlsMediaKeysListener::~SystemMediaControlsMediaKeysListener() { + DCHECK(has_instance_); + has_instance_ = false; +} + +bool SystemMediaControlsMediaKeysListener::Initialize() { + // |service_| can be set for tests. + if (!service_) + service_ = system_media_controls::SystemMediaControlsService::GetInstance(); + + // If we still don't have a service, then that means the + // SystemMediaControlsService failed to connect to the + // SystemMediaTransportControls. If that's the case, return false. + if (!service_) + return false; + + service_->AddObserver(this); + return true; +} + +bool SystemMediaControlsMediaKeysListener::StartWatchingMediaKey( + KeyboardCode key_code) { + DCHECK(IsMediaKeycode(key_code)); + + // If we're already listening for this key, do nothing. + if (key_codes_.contains(key_code)) + return true; + + key_codes_.insert(key_code); + + DCHECK(service_); + + switch (key_code) { + case VKEY_MEDIA_PLAY_PAUSE: + service_->SetIsPlayEnabled(true); + service_->SetIsPauseEnabled(true); + break; + case VKEY_MEDIA_NEXT_TRACK: + service_->SetIsNextEnabled(true); + break; + case VKEY_MEDIA_PREV_TRACK: + service_->SetIsPreviousEnabled(true); + break; + case VKEY_MEDIA_STOP: + service_->SetIsStopEnabled(true); + break; + default: + NOTREACHED(); + } + + return true; +} + +void SystemMediaControlsMediaKeysListener::StopWatchingMediaKey( + KeyboardCode key_code) { + DCHECK(IsMediaKeycode(key_code)); + + // If we're not currently listening for this key, do nothing. + if (!key_codes_.contains(key_code)) + return; + + key_codes_.erase(key_code); + + DCHECK(service_); + + switch (key_code) { + case VKEY_MEDIA_PLAY_PAUSE: + service_->SetIsPlayEnabled(false); + service_->SetIsPauseEnabled(false); + break; + case VKEY_MEDIA_NEXT_TRACK: + service_->SetIsNextEnabled(false); + break; + case VKEY_MEDIA_PREV_TRACK: + service_->SetIsPreviousEnabled(false); + break; + case VKEY_MEDIA_STOP: + service_->SetIsStopEnabled(false); + break; + default: + NOTREACHED(); + } +} + +void SystemMediaControlsMediaKeysListener::OnNext() { + MaybeSendKeyCode(VKEY_MEDIA_NEXT_TRACK); +} + +void SystemMediaControlsMediaKeysListener::OnPrevious() { + MaybeSendKeyCode(VKEY_MEDIA_PREV_TRACK); +} + +void SystemMediaControlsMediaKeysListener::OnPause() { + MaybeSendKeyCode(VKEY_MEDIA_PLAY_PAUSE); +} + +void SystemMediaControlsMediaKeysListener::OnStop() { + MaybeSendKeyCode(VKEY_MEDIA_STOP); +} + +void SystemMediaControlsMediaKeysListener::OnPlay() { + MaybeSendKeyCode(VKEY_MEDIA_PLAY_PAUSE); +} + +void SystemMediaControlsMediaKeysListener::MaybeSendKeyCode( + KeyboardCode key_code) { + if (!key_codes_.contains(key_code)) + return; + + Accelerator accelerator(key_code, /*modifiers=*/0); + delegate_->OnMediaKeysAccelerator(accelerator); +} + +} // namespace ui
diff --git a/ui/base/accelerators/system_media_controls_media_keys_listener.h b/ui/base/accelerators/system_media_controls_media_keys_listener.h new file mode 100644 index 0000000..c900d841 --- /dev/null +++ b/ui/base/accelerators/system_media_controls_media_keys_listener.h
@@ -0,0 +1,69 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_BASE_ACCELERATORS_SYSTEM_MEDIA_CONTROLS_MEDIA_KEYS_LISTENER_H_ +#define UI_BASE_ACCELERATORS_SYSTEM_MEDIA_CONTROLS_MEDIA_KEYS_LISTENER_H_ + +#include "base/containers/flat_set.h" +#include "ui/base/accelerators/media_keys_listener.h" +#include "ui/base/ui_base_export.h" +#include "ui/base/win/system_media_controls/system_media_controls_service_observer.h" +#include "ui/events/keycodes/keyboard_codes.h" + +namespace system_media_controls { +class SystemMediaControlsService; +} // namespace system_media_controls + +namespace ui { + +// Implementation of MediaKeysListener that uses the System Media Transport +// Controls API to listen for media key presses. It only allows for a single +// instance to be created in order to prevent conflicts from multiple listeners. +class UI_BASE_EXPORT SystemMediaControlsMediaKeysListener + : public MediaKeysListener, + public system_media_controls::SystemMediaControlsServiceObserver { + public: + explicit SystemMediaControlsMediaKeysListener( + MediaKeysListener::Delegate* delegate); + ~SystemMediaControlsMediaKeysListener() override; + + static bool has_instance() { return has_instance_; } + + bool Initialize(); + + // MediaKeysListener implementation. + bool StartWatchingMediaKey(KeyboardCode key_code) override; + void StopWatchingMediaKey(KeyboardCode key_code) override; + + // system_media_controls::SystemMediaControlsServiceObserver implementation. + void OnNext() override; + void OnPrevious() override; + void OnPause() override; + void OnStop() override; + void OnPlay() override; + + void SetSystemMediaControlsServiceForTesting( + system_media_controls::SystemMediaControlsService* service) { + service_ = service; + } + + private: + static bool has_instance_; + + // Sends the key code to the delegate if the delegate has asked for it. + void MaybeSendKeyCode(KeyboardCode key_code); + + MediaKeysListener::Delegate* delegate_; + + // Set of keys codes that we're currently listening for. + base::flat_set<KeyboardCode> key_codes_; + + system_media_controls::SystemMediaControlsService* service_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(SystemMediaControlsMediaKeysListener); +}; + +} // namespace ui + +#endif // UI_BASE_ACCELERATORS_SYSTEM_MEDIA_CONTROLS_MEDIA_KEYS_LISTENER_H_
diff --git a/ui/base/accelerators/system_media_controls_media_keys_listener_unittest.cc b/ui/base/accelerators/system_media_controls_media_keys_listener_unittest.cc new file mode 100644 index 0000000..b07c9a59 --- /dev/null +++ b/ui/base/accelerators/system_media_controls_media_keys_listener_unittest.cc
@@ -0,0 +1,135 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/base/accelerators/system_media_controls_media_keys_listener.h" + +#include <memory> + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/accelerators/accelerator.h" +#include "ui/base/win/system_media_controls/mock_system_media_controls_service.h" + +using testing::_; +using testing::Expectation; +using testing::WithArg; + +namespace ui { + +namespace { + +class MockMediaKeysListenerDelegate : public MediaKeysListener::Delegate { + public: + MockMediaKeysListenerDelegate() = default; + ~MockMediaKeysListenerDelegate() override = default; + + // MediaKeysListener::Delegate implementation. + MOCK_METHOD1(OnMediaKeysAccelerator, void(const Accelerator& accelerator)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockMediaKeysListenerDelegate); +}; + +} // anonymous namespace + +class SystemMediaControlsMediaKeysListenerTest : public testing::Test { + public: + SystemMediaControlsMediaKeysListenerTest() { + listener_ = + std::make_unique<SystemMediaControlsMediaKeysListener>(&delegate_); + listener_->SetSystemMediaControlsServiceForTesting( + &mock_system_media_controls_service_); + } + + ~SystemMediaControlsMediaKeysListenerTest() override = default; + + protected: + system_media_controls::testing::MockSystemMediaControlsService& + mock_system_media_controls_service() { + return mock_system_media_controls_service_; + } + MockMediaKeysListenerDelegate& delegate() { return delegate_; } + SystemMediaControlsMediaKeysListener* listener() { return listener_.get(); } + + private: + system_media_controls::testing::MockSystemMediaControlsService + mock_system_media_controls_service_; + MockMediaKeysListenerDelegate delegate_; + std::unique_ptr<SystemMediaControlsMediaKeysListener> listener_; + + DISALLOW_COPY_AND_ASSIGN(SystemMediaControlsMediaKeysListenerTest); +}; + +TEST_F(SystemMediaControlsMediaKeysListenerTest, + ListensToSystemMediaControlsService) { + EXPECT_CALL(mock_system_media_controls_service(), AddObserver(listener())); + listener()->Initialize(); +} + +TEST_F(SystemMediaControlsMediaKeysListenerTest, SimplePlayPauseTest) { + // Should be set to true when we start listening for the key. + EXPECT_CALL(mock_system_media_controls_service(), SetIsPlayEnabled(true)); + EXPECT_CALL(mock_system_media_controls_service(), SetIsPauseEnabled(true)); + + EXPECT_CALL(delegate(), OnMediaKeysAccelerator(_)) + .WillOnce(WithArg<0>([](const Accelerator& accelerator) { + EXPECT_EQ(ui::VKEY_MEDIA_PLAY_PAUSE, accelerator.key_code()); + })); + + ASSERT_TRUE(listener()->Initialize()); + listener()->StartWatchingMediaKey(ui::VKEY_MEDIA_PLAY_PAUSE); + + // Simulate media key press. + listener()->OnPlay(); +} + +TEST_F(SystemMediaControlsMediaKeysListenerTest, KeyCanBeReRegistered) { + Expectation enable_next = + EXPECT_CALL(mock_system_media_controls_service(), SetIsNextEnabled(true)); + Expectation disable_next = + EXPECT_CALL(mock_system_media_controls_service(), SetIsNextEnabled(false)) + .After(enable_next); + Expectation reenable_next = + EXPECT_CALL(mock_system_media_controls_service(), SetIsNextEnabled(true)) + .After(disable_next); + EXPECT_CALL(delegate(), OnMediaKeysAccelerator(_)) + .After(reenable_next) + .WillOnce(WithArg<0>([](const Accelerator& accelerator) { + EXPECT_EQ(ui::VKEY_MEDIA_NEXT_TRACK, accelerator.key_code()); + })); + + ASSERT_TRUE(listener()->Initialize()); + + // Start listening to register the key. + listener()->StartWatchingMediaKey(ui::VKEY_MEDIA_NEXT_TRACK); + + // Stop listening to unregister the key. + listener()->StopWatchingMediaKey(ui::VKEY_MEDIA_NEXT_TRACK); + + // Start listening to re-register the key. + listener()->StartWatchingMediaKey(ui::VKEY_MEDIA_NEXT_TRACK); + + // Simulate media key press. + listener()->OnNext(); +} + +TEST_F(SystemMediaControlsMediaKeysListenerTest, ListenForMultipleKeys) { + // Should be set to true when we start listening for the key. + EXPECT_CALL(mock_system_media_controls_service(), SetIsPlayEnabled(true)); + EXPECT_CALL(mock_system_media_controls_service(), SetIsPauseEnabled(true)); + EXPECT_CALL(mock_system_media_controls_service(), SetIsPreviousEnabled(true)); + + // Should receive the key presses. + EXPECT_CALL(delegate(), OnMediaKeysAccelerator(_)).Times(2); + + ASSERT_TRUE(listener()->Initialize()); + listener()->StartWatchingMediaKey(ui::VKEY_MEDIA_PLAY_PAUSE); + listener()->StartWatchingMediaKey(ui::VKEY_MEDIA_PREV_TRACK); + + // Simulate media key press. + listener()->OnPlay(); + listener()->OnPrevious(); +} + +} // namespace ui
diff --git a/ui/base/ime/fuchsia/input_method_fuchsia.h b/ui/base/ime/fuchsia/input_method_fuchsia.h index 4707189c..2863e7d 100644 --- a/ui/base/ime/fuchsia/input_method_fuchsia.h +++ b/ui/base/ime/fuchsia/input_method_fuchsia.h
@@ -21,7 +21,7 @@ namespace ui { // Handles input from physical keyboards and the IME service. -class COMPONENT_EXPORT(UI_BASE_IME) InputMethodFuchsia +class COMPONENT_EXPORT(UI_BASE_IME_FUCHSIA) InputMethodFuchsia : public InputMethodBase, public InputEventDispatcherDelegate, public fuchsia::ui::input::InputMethodEditorClient {
diff --git a/ui/base/win/system_media_controls/BUILD.gn b/ui/base/win/system_media_controls/BUILD.gn new file mode 100644 index 0000000..41ca483 --- /dev/null +++ b/ui/base/win/system_media_controls/BUILD.gn
@@ -0,0 +1,36 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +component("system_media_controls") { + sources = [ + "system_media_controls_service.cc", + "system_media_controls_service.h", + "system_media_controls_service_impl.cc", + "system_media_controls_service_impl.h", + "system_media_controls_service_observer.cc", + "system_media_controls_service_observer.h", + ] + + defines = [ "IS_SYSTEM_MEDIA_CONTROLS_IMPL" ] + + deps = [ + "//base", + "//ui/gfx", + ] +} + +static_library("test_support") { + testonly = true + + sources = [ + "mock_system_media_controls_service.cc", + "mock_system_media_controls_service.h", + ] + + deps = [ + ":system_media_controls", + "//base", + "//testing/gmock", + ] +}
diff --git a/ui/base/win/system_media_controls/OWNERS b/ui/base/win/system_media_controls/OWNERS new file mode 100644 index 0000000..4152d74 --- /dev/null +++ b/ui/base/win/system_media_controls/OWNERS
@@ -0,0 +1 @@ +steimel@chromium.org \ No newline at end of file
diff --git a/ui/base/win/system_media_controls/mock_system_media_controls_service.cc b/ui/base/win/system_media_controls/mock_system_media_controls_service.cc new file mode 100644 index 0000000..3f3e4bb --- /dev/null +++ b/ui/base/win/system_media_controls/mock_system_media_controls_service.cc
@@ -0,0 +1,17 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/base/win/system_media_controls/mock_system_media_controls_service.h" + +namespace system_media_controls { + +namespace testing { + +MockSystemMediaControlsService::MockSystemMediaControlsService() = default; + +MockSystemMediaControlsService::~MockSystemMediaControlsService() = default; + +} // namespace testing + +} // namespace system_media_controls
diff --git a/ui/base/win/system_media_controls/mock_system_media_controls_service.h b/ui/base/win/system_media_controls/mock_system_media_controls_service.h new file mode 100644 index 0000000..4f5c913 --- /dev/null +++ b/ui/base/win/system_media_controls/mock_system_media_controls_service.h
@@ -0,0 +1,44 @@ +// 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 UI_BASE_WIN_SYSTEM_MEDIA_CONTROLS_MOCK_SYSTEM_MEDIA_CONTROLS_SERVICE_H_ +#define UI_BASE_WIN_SYSTEM_MEDIA_CONTROLS_MOCK_SYSTEM_MEDIA_CONTROLS_SERVICE_H_ + +#include "base/macros.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "ui/base/win/system_media_controls/system_media_controls_service.h" + +namespace system_media_controls { + +class SystemMediaControlsServiceObserver; + +namespace testing { + +// Mock implementation of SystemMediaControlsService for testing. +class MockSystemMediaControlsService : public SystemMediaControlsService { + public: + MockSystemMediaControlsService(); + ~MockSystemMediaControlsService() override; + + // SystemMediaControlsService implementation. + MOCK_METHOD1(AddObserver, void(SystemMediaControlsServiceObserver* observer)); + MOCK_METHOD1(RemoveObserver, + void(SystemMediaControlsServiceObserver* observer)); + MOCK_METHOD1(SetIsNextEnabled, void(bool value)); + MOCK_METHOD1(SetIsPreviousEnabled, void(bool value)); + MOCK_METHOD1(SetIsPlayEnabled, void(bool value)); + MOCK_METHOD1(SetIsPauseEnabled, void(bool value)); + MOCK_METHOD1(SetIsStopEnabled, void(bool value)); + MOCK_METHOD1(SetPlaybackStatus, + void(ABI::Windows::Media::MediaPlaybackStatus status)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockSystemMediaControlsService); +}; + +} // namespace testing + +} // namespace system_media_controls + +#endif // UI_BASE_WIN_SYSTEM_MEDIA_CONTROLS_MOCK_SYSTEM_MEDIA_CONTROLS_SERVICE_H_
diff --git a/ui/base/win/system_media_controls/system_media_controls_service.cc b/ui/base/win/system_media_controls/system_media_controls_service.cc new file mode 100644 index 0000000..58d5a86 --- /dev/null +++ b/ui/base/win/system_media_controls/system_media_controls_service.cc
@@ -0,0 +1,22 @@ +// 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 "ui/base/win/system_media_controls/system_media_controls_service.h" + +#include "ui/base/win/system_media_controls/system_media_controls_service_impl.h" + +namespace system_media_controls { + +// static +SystemMediaControlsService* SystemMediaControlsService::GetInstance() { + internal::SystemMediaControlsServiceImpl* impl = + internal::SystemMediaControlsServiceImpl::GetInstance(); + if (impl->Initialize()) + return impl; + return nullptr; +} + +SystemMediaControlsService::~SystemMediaControlsService() = default; + +} // namespace system_media_controls
diff --git a/ui/base/win/system_media_controls/system_media_controls_service.h b/ui/base/win/system_media_controls/system_media_controls_service.h new file mode 100644 index 0000000..fe66681 --- /dev/null +++ b/ui/base/win/system_media_controls/system_media_controls_service.h
@@ -0,0 +1,50 @@ +// 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 UI_BASE_WIN_SYSTEM_MEDIA_CONTROLS_SYSTEM_MEDIA_CONTROLS_SERVICE_H_ +#define UI_BASE_WIN_SYSTEM_MEDIA_CONTROLS_SYSTEM_MEDIA_CONTROLS_SERVICE_H_ + +#include <windows.media.control.h> + +#include "base/component_export.h" + +namespace system_media_controls { + +class SystemMediaControlsServiceObserver; + +// The SystemMediaControlsService connects with Windows's System Media Transport +// Controls, receives media key events, and propagates those events to listening +// SystemMediaControlsServiceObservers. The SystemMediaControlsService tells the +// System Media Transport Controls which actions are currently available. The +// SystemMediaControlsService is also used to keep the System Media Transport +// Controls informed of the current media playback state and metadata. +class COMPONENT_EXPORT(SYSTEM_MEDIA_CONTROLS) SystemMediaControlsService { + public: + // Returns the singleton instance, creating if necessary. If the + // SystemMediaControlsService fails to connect to the + // SystemMediaTransportControls, this returns null. + static SystemMediaControlsService* GetInstance(); + + virtual void AddObserver(SystemMediaControlsServiceObserver* observer) = 0; + virtual void RemoveObserver(SystemMediaControlsServiceObserver* observer) = 0; + + // TODO(steimel): Add other controls. + // Enable or disable specific controls. + virtual void SetIsNextEnabled(bool value) = 0; + virtual void SetIsPreviousEnabled(bool value) = 0; + virtual void SetIsPlayEnabled(bool value) = 0; + virtual void SetIsPauseEnabled(bool value) = 0; + virtual void SetIsStopEnabled(bool value) = 0; + + // Setters for metadata. + virtual void SetPlaybackStatus( + ABI::Windows::Media::MediaPlaybackStatus status) = 0; + + protected: + virtual ~SystemMediaControlsService(); +}; + +} // namespace system_media_controls + +#endif // UI_BASE_WIN_SYSTEM_MEDIA_CONTROLS_SYSTEM_MEDIA_CONTROLS_SERVICE_H_
diff --git a/ui/base/win/system_media_controls/system_media_controls_service_impl.cc b/ui/base/win/system_media_controls/system_media_controls_service_impl.cc new file mode 100644 index 0000000..9d7a1a44 --- /dev/null +++ b/ui/base/win/system_media_controls/system_media_controls_service_impl.cc
@@ -0,0 +1,210 @@ +// 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 "ui/base/win/system_media_controls/system_media_controls_service_impl.h" + +#include <systemmediatransportcontrolsinterop.h> +#include <windows.media.control.h> +#include <wrl/client.h> +#include <wrl/event.h> + +#include "base/strings/string_piece.h" +#include "base/win/core_winrt_util.h" +#include "base/win/scoped_hstring.h" +#include "ui/base/win/system_media_controls/system_media_controls_service_observer.h" +#include "ui/gfx/win/singleton_hwnd.h" + +namespace system_media_controls { + +namespace internal { + +using ABI::Windows::Media::ISystemMediaTransportControls; +using ABI::Windows::Media::ISystemMediaTransportControlsButtonPressedEventArgs; +using ABI::Windows::Media::SystemMediaTransportControls; +using ABI::Windows::Media::SystemMediaTransportControlsButton; +using ABI::Windows::Media::SystemMediaTransportControlsButtonPressedEventArgs; + +// static +SystemMediaControlsServiceImpl* SystemMediaControlsServiceImpl::GetInstance() { + // We use a base::Singleton here instead of a base::NoDestruct so that we can + // clean up external listeners against the Windows platform at exit. + return base::Singleton<SystemMediaControlsServiceImpl>::get(); +} + +SystemMediaControlsServiceImpl::SystemMediaControlsServiceImpl() = default; + +SystemMediaControlsServiceImpl::~SystemMediaControlsServiceImpl() { + if (has_valid_registration_token_) { + DCHECK(system_media_controls_); + system_media_controls_->remove_ButtonPressed(registration_token_); + system_media_controls_->put_IsEnabled(false); + } +} + +bool SystemMediaControlsServiceImpl::Initialize() { + if (attempted_to_initialize_) + return initialized_; + + attempted_to_initialize_ = true; + + if (!base::win::ResolveCoreWinRTDelayload() || + !base::win::ScopedHString::ResolveCoreWinRTStringDelayload()) { + return false; + } + + Microsoft::WRL::ComPtr<ISystemMediaTransportControlsInterop> interop; + HRESULT hr = base::win::GetActivationFactory< + ISystemMediaTransportControlsInterop, + RuntimeClass_Windows_Media_SystemMediaTransportControls>(&interop); + if (FAILED(hr)) + return false; + + hr = interop->GetForWindow(gfx::SingletonHwnd::GetInstance()->hwnd(), + IID_PPV_ARGS(&system_media_controls_)); + if (FAILED(hr)) + return false; + + auto handler = + Microsoft::WRL::Callback<ABI::Windows::Foundation::ITypedEventHandler< + SystemMediaTransportControls*, + SystemMediaTransportControlsButtonPressedEventArgs*>>( + &SystemMediaControlsServiceImpl::ButtonPressed); + hr = system_media_controls_->add_ButtonPressed(handler.Get(), + ®istration_token_); + if (FAILED(hr)) + return false; + + has_valid_registration_token_ = true; + + hr = system_media_controls_->put_IsEnabled(true); + if (FAILED(hr)) + return false; + + initialized_ = true; + return true; +} + +void SystemMediaControlsServiceImpl::AddObserver( + SystemMediaControlsServiceObserver* observer) { + observers_.AddObserver(observer); +} + +void SystemMediaControlsServiceImpl::RemoveObserver( + SystemMediaControlsServiceObserver* observer) { + observers_.RemoveObserver(observer); +} + +void SystemMediaControlsServiceImpl::SetIsNextEnabled(bool value) { + DCHECK(initialized_); + HRESULT hr = system_media_controls_->put_IsNextEnabled(value); + DCHECK(SUCCEEDED(hr)); +} + +void SystemMediaControlsServiceImpl::SetIsPreviousEnabled(bool value) { + DCHECK(initialized_); + HRESULT hr = system_media_controls_->put_IsPreviousEnabled(value); + DCHECK(SUCCEEDED(hr)); +} + +void SystemMediaControlsServiceImpl::SetIsPlayEnabled(bool value) { + DCHECK(initialized_); + HRESULT hr = system_media_controls_->put_IsPlayEnabled(value); + DCHECK(SUCCEEDED(hr)); +} + +void SystemMediaControlsServiceImpl::SetIsPauseEnabled(bool value) { + DCHECK(initialized_); + HRESULT hr = system_media_controls_->put_IsPauseEnabled(value); + DCHECK(SUCCEEDED(hr)); +} + +void SystemMediaControlsServiceImpl::SetIsStopEnabled(bool value) { + DCHECK(initialized_); + HRESULT hr = system_media_controls_->put_IsStopEnabled(value); + DCHECK(SUCCEEDED(hr)); +} + +void SystemMediaControlsServiceImpl::SetPlaybackStatus( + ABI::Windows::Media::MediaPlaybackStatus status) { + DCHECK(initialized_); + HRESULT hr = system_media_controls_->put_PlaybackStatus(status); + DCHECK(SUCCEEDED(hr)); +} + +void SystemMediaControlsServiceImpl::OnPlay() { + for (SystemMediaControlsServiceObserver& obs : observers_) + obs.OnPlay(); +} + +void SystemMediaControlsServiceImpl::OnPause() { + for (SystemMediaControlsServiceObserver& obs : observers_) + obs.OnPause(); +} + +void SystemMediaControlsServiceImpl::OnNext() { + for (SystemMediaControlsServiceObserver& obs : observers_) + obs.OnNext(); +} + +void SystemMediaControlsServiceImpl::OnPrevious() { + for (SystemMediaControlsServiceObserver& obs : observers_) + obs.OnPrevious(); +} + +void SystemMediaControlsServiceImpl::OnStop() { + for (SystemMediaControlsServiceObserver& obs : observers_) + obs.OnStop(); +} + +// static +HRESULT SystemMediaControlsServiceImpl::ButtonPressed( + ISystemMediaTransportControls* sender, + ISystemMediaTransportControlsButtonPressedEventArgs* args) { + SystemMediaTransportControlsButton button; + HRESULT hr = args->get_Button(&button); + if (FAILED(hr)) + return hr; + + SystemMediaControlsServiceImpl* impl = GetInstance(); + + switch (button) { + case SystemMediaTransportControlsButton:: + SystemMediaTransportControlsButton_Play: + impl->OnPlay(); + break; + case SystemMediaTransportControlsButton:: + SystemMediaTransportControlsButton_Pause: + impl->OnPause(); + break; + case SystemMediaTransportControlsButton:: + SystemMediaTransportControlsButton_Next: + impl->OnNext(); + break; + case SystemMediaTransportControlsButton:: + SystemMediaTransportControlsButton_Previous: + impl->OnPrevious(); + break; + case SystemMediaTransportControlsButton:: + SystemMediaTransportControlsButton_Stop: + impl->OnStop(); + break; + case SystemMediaTransportControlsButton:: + SystemMediaTransportControlsButton_Record: + case SystemMediaTransportControlsButton:: + SystemMediaTransportControlsButton_FastForward: + case SystemMediaTransportControlsButton:: + SystemMediaTransportControlsButton_Rewind: + case SystemMediaTransportControlsButton:: + SystemMediaTransportControlsButton_ChannelUp: + case SystemMediaTransportControlsButton:: + SystemMediaTransportControlsButton_ChannelDown: + break; + } + + return S_OK; +} + +} // namespace internal + +} // namespace system_media_controls
diff --git a/ui/base/win/system_media_controls/system_media_controls_service_impl.h b/ui/base/win/system_media_controls/system_media_controls_service_impl.h new file mode 100644 index 0000000..fb10cde --- /dev/null +++ b/ui/base/win/system_media_controls/system_media_controls_service_impl.h
@@ -0,0 +1,86 @@ +// 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 UI_BASE_WIN_SYSTEM_MEDIA_CONTROLS_SYSTEM_MEDIA_CONTROLS_SERVICE_IMPL_H_ +#define UI_BASE_WIN_SYSTEM_MEDIA_CONTROLS_SYSTEM_MEDIA_CONTROLS_SERVICE_IMPL_H_ + +#include <windows.foundation.h> +#include <windows.media.control.h> +#include <wrl/client.h> + +#include "base/component_export.h" +#include "base/memory/singleton.h" +#include "base/observer_list.h" +#include "ui/base/win/system_media_controls/system_media_controls_service.h" + +namespace system_media_controls { + +class SystemMediaControlsServiceObserver; + +namespace internal { + +// Implementation of SystemMediaControlsService that actually connects to the +// Windows's System Media Transport Controls. +class COMPONENT_EXPORT(SYSTEM_MEDIA_CONTROLS) SystemMediaControlsServiceImpl + : public SystemMediaControlsService { + public: + SystemMediaControlsServiceImpl(); + ~SystemMediaControlsServiceImpl() override; + + static SystemMediaControlsServiceImpl* GetInstance(); + + // Connects to the SystemMediaTransportControls. Returns true if connection + // is successful. If already connected, does nothing and returns true. + bool Initialize(); + + // SystemMediaControlsService implementation. + void AddObserver(SystemMediaControlsServiceObserver* observer) override; + void RemoveObserver(SystemMediaControlsServiceObserver* observer) override; + void SetIsNextEnabled(bool value) override; + void SetIsPreviousEnabled(bool value) override; + void SetIsPlayEnabled(bool value) override; + void SetIsPauseEnabled(bool value) override; + void SetIsStopEnabled(bool value) override; + void SetPlaybackStatus( + ABI::Windows::Media::MediaPlaybackStatus status) override; + + private: + friend struct base::DefaultSingletonTraits<SystemMediaControlsServiceImpl>; + + static HRESULT ButtonPressed( + ABI::Windows::Media::ISystemMediaTransportControls* sender, + ABI::Windows::Media::ISystemMediaTransportControlsButtonPressedEventArgs* + args); + + // Called by ButtonPressed when the particular key is pressed. + void OnPlay(); + void OnPause(); + void OnNext(); + void OnPrevious(); + void OnStop(); + + Microsoft::WRL::ComPtr<ABI::Windows::Media::ISystemMediaTransportControls> + system_media_controls_; + EventRegistrationToken registration_token_; + + // True if we've already tried to connect to the SystemMediaTransportControls. + bool attempted_to_initialize_ = false; + + // True if we've successfully registered a button handler on the + // SystemMediaTransportControls. + bool has_valid_registration_token_ = false; + + // True if we've successfully connected to the SystemMediaTransportControls. + bool initialized_ = false; + + base::ObserverList<SystemMediaControlsServiceObserver> observers_; + + DISALLOW_COPY_AND_ASSIGN(SystemMediaControlsServiceImpl); +}; + +} // namespace internal + +} // namespace system_media_controls + +#endif // UI_BASE_WIN_SYSTEM_MEDIA_CONTROLS_SYSTEM_MEDIA_CONTROLS_SERVICE_IMPL_H_
diff --git a/ui/base/win/system_media_controls/system_media_controls_service_observer.cc b/ui/base/win/system_media_controls/system_media_controls_service_observer.cc new file mode 100644 index 0000000..cad848d --- /dev/null +++ b/ui/base/win/system_media_controls/system_media_controls_service_observer.cc
@@ -0,0 +1,12 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/base/win/system_media_controls/system_media_controls_service_observer.h" + +namespace system_media_controls { + +SystemMediaControlsServiceObserver::~SystemMediaControlsServiceObserver() = + default; + +} // namespace system_media_controls
diff --git a/ui/base/win/system_media_controls/system_media_controls_service_observer.h b/ui/base/win/system_media_controls/system_media_controls_service_observer.h new file mode 100644 index 0000000..0f82420a --- /dev/null +++ b/ui/base/win/system_media_controls/system_media_controls_service_observer.h
@@ -0,0 +1,29 @@ +// 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 UI_BASE_WIN_SYSTEM_MEDIA_CONTROLS_SYSTEM_MEDIA_CONTROLS_SERVICE_OBSERVER_H_ +#define UI_BASE_WIN_SYSTEM_MEDIA_CONTROLS_SYSTEM_MEDIA_CONTROLS_SERVICE_OBSERVER_H_ + +#include "base/component_export.h" +#include "base/observer_list_types.h" + +namespace system_media_controls { + +// Interface to observe events on the SystemMediaControlsService. +class COMPONENT_EXPORT(SYSTEM_MEDIA_CONTROLS) SystemMediaControlsServiceObserver + : public base::CheckedObserver { + public: + virtual void OnNext() = 0; + virtual void OnPrevious() = 0; + virtual void OnPause() = 0; + virtual void OnStop() = 0; + virtual void OnPlay() = 0; + + protected: + ~SystemMediaControlsServiceObserver() override; +}; + +} // namespace system_media_controls + +#endif // UI_BASE_WIN_SYSTEM_MEDIA_CONTROLS_SYSTEM_MEDIA_CONTROLS_SERVICE_OBSERVER_H_
diff --git a/ui/display/manager/display_configurator.cc b/ui/display/manager/display_configurator.cc index bf5b24b..cae3071 100644 --- a/ui/display/manager/display_configurator.cc +++ b/ui/display/manager/display_configurator.cc
@@ -916,25 +916,23 @@ std::move(apply_protection_callbacks_.front()); apply_protection_callbacks_.pop(); - if (!success) { - std::move(callback).Run(false); - return; - } + if (success) { + if (protection_mask == CONTENT_PROTECTION_METHOD_NONE) { + auto it = content_protection_requests_.find(client_id); + if (it != content_protection_requests_.end()) { + ContentProtections& protections = it->second; + protections.erase(display_id); - if (protection_mask == CONTENT_PROTECTION_METHOD_NONE) { - auto it = content_protection_requests_.find(client_id); - if (it != content_protection_requests_.end()) { - ContentProtections& protections = it->second; - protections.erase(display_id); - - if (protections.empty()) - content_protection_requests_.erase(client_id); + if (protections.empty()) + content_protection_requests_.erase(client_id); + } + } else { + content_protection_requests_[client_id][display_id] = protection_mask; } - } else { - content_protection_requests_[client_id][display_id] = protection_mask; } - std::move(callback).Run(true); + std::move(callback).Run(success); + if (!content_protection_tasks_.empty()) content_protection_tasks_.front().Run(); }
diff --git a/ui/display/manager/display_configurator_unittest.cc b/ui/display/manager/display_configurator_unittest.cc index 3fb738a..dd6dbc9 100644 --- a/ui/display/manager/display_configurator_unittest.cc +++ b/ui/display/manager/display_configurator_unittest.cc
@@ -993,6 +993,84 @@ log_->GetActionsAndClear()); } +TEST_F(DisplayConfiguratorTest, ContentProtectionAsync) { + Init(false); + configurator_.ForceInitialConfigure(); + EXPECT_NE(kNoActions, log_->GetActionsAndClear()); + + auto id = configurator_.RegisterContentProtectionClient(); + EXPECT_TRUE(id); + + UpdateOutputs(2, true); + EXPECT_NE(kNoActions, log_->GetActionsAndClear()); + + native_display_delegate_->set_run_async(true); + + // Asynchronous tasks should be pending. + constexpr int kTaskCount = 3; + for (int i = 0; i < kTaskCount; ++i) { + configurator_.ApplyContentProtection( + id, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP, + base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + configurator_.QueryContentProtection( + id, outputs_[1]->display_id(), + base::BindOnce(&DisplayConfiguratorTest::QueryContentProtectionCallback, + base::Unretained(this))); + } + + EXPECT_EQ(0, apply_content_protection_call_count_); + EXPECT_EQ(0, query_content_protection_call_count_); + + native_display_delegate_->set_hdcp_state(HDCP_STATE_ENABLED); + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(kTaskCount, apply_content_protection_call_count_); + EXPECT_TRUE(apply_content_protection_success_); + + EXPECT_EQ(kTaskCount, query_content_protection_call_count_); + EXPECT_TRUE(query_content_protection_success_); + EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), + query_content_protection_connection_mask_); + EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_HDCP), + query_content_protection_protection_mask_); + + EXPECT_EQ(GetSetHDCPStateAction(*outputs_[1], HDCP_STATE_DESIRED), + log_->GetActionsAndClear()); + + // Pending task should run even if previous task fails. + native_display_delegate_->set_set_hdcp_state_expectation(false); + + configurator_.ApplyContentProtection( + id, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_NONE, + base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback, + base::Unretained(this))); + + configurator_.QueryContentProtection( + id, outputs_[1]->display_id(), + base::BindOnce(&DisplayConfiguratorTest::QueryContentProtectionCallback, + base::Unretained(this))); + + EXPECT_EQ(kTaskCount, apply_content_protection_call_count_); + EXPECT_EQ(kTaskCount, query_content_protection_call_count_); + + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(kTaskCount + 1, apply_content_protection_call_count_); + EXPECT_FALSE(apply_content_protection_success_); + + EXPECT_EQ(kTaskCount + 1, query_content_protection_call_count_); + EXPECT_TRUE(query_content_protection_success_); + EXPECT_EQ(static_cast<uint32_t>(DISPLAY_CONNECTION_TYPE_HDMI), + query_content_protection_connection_mask_); + EXPECT_EQ(static_cast<uint32_t>(CONTENT_PROTECTION_METHOD_HDCP), + query_content_protection_protection_mask_); + + EXPECT_EQ(GetSetHDCPStateAction(*outputs_[1], HDCP_STATE_UNDESIRED), + log_->GetActionsAndClear()); +} + TEST_F(DisplayConfiguratorTest, DoNotConfigureWithSuspendedDisplays) { InitWithSingleOutput();
diff --git a/ui/display/manager/test/test_native_display_delegate.cc b/ui/display/manager/test/test_native_display_delegate.cc index a90af3fa..ec2490f 100644 --- a/ui/display/manager/test/test_native_display_delegate.cc +++ b/ui/display/manager/test/test_native_display_delegate.cc
@@ -83,14 +83,26 @@ void TestNativeDisplayDelegate::GetHDCPState(const DisplaySnapshot& output, GetHDCPStateCallback callback) { - std::move(callback).Run(get_hdcp_expectation_, hdcp_state_); + if (run_async_) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), get_hdcp_expectation_, + hdcp_state_)); + } else { + std::move(callback).Run(get_hdcp_expectation_, hdcp_state_); + } } void TestNativeDisplayDelegate::SetHDCPState(const DisplaySnapshot& output, HDCPState state, SetHDCPStateCallback callback) { log_->AppendAction(GetSetHDCPStateAction(output, state)); - std::move(callback).Run(set_hdcp_expectation_); + + if (run_async_) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), set_hdcp_expectation_)); + } else { + std::move(callback).Run(set_hdcp_expectation_); + } } bool TestNativeDisplayDelegate::SetColorMatrix(
diff --git a/ui/file_manager/file_manager/background/js/mock_drive_sync_handler.js b/ui/file_manager/file_manager/background/js/mock_drive_sync_handler.js index 763ecab4..917123c 100644 --- a/ui/file_manager/file_manager/background/js/mock_drive_sync_handler.js +++ b/ui/file_manager/file_manager/background/js/mock_drive_sync_handler.js
@@ -6,36 +6,55 @@ /** * Mock of DriveSyncHandler. - * - * @constructor - * @struct * @implements {DriveSyncHandler} - * @extends {cr.EventTarget} */ -function MockDriveSyncHandler() { - /** - * @type {boolean} Drive sync suppressed state. - * @private - */ - this.syncSuppressed_ = false; +class MockDriveSyncHandler extends cr.EventTarget { + constructor() { + super(); + + /** + * @type {boolean} Drive sync suppressed state. + * @private + */ + this.syncSuppressed_ = false; + + /** + * @type {boolean} Drive sync disabled on mobile notification state. + * @private + */ + this.showingDisabledMobileSyncNotification_ = false; + } /** - * @type {boolean} Drive sync disabled on mobile notification state. - * @private + * Returns the completed event name. + * @return {string} */ - this.showingDisabledMobileSyncNotification_ = false; -} + getCompletedEventName() { + return MockDriveSyncHandler.DRIVE_SYNC_COMPLETED_EVENT; + } -MockDriveSyncHandler.prototype = /** @struct */ { - __proto__: cr.EventTarget.prototype, + /** + * Returns whether the Drive sync is currently suppressed or not. + * @return {boolean} + */ + isSyncSuppressed() { + return this.syncSuppressed_; + } + + /** + * Shows a notification that Drive sync is disabled on cellular networks. + */ + showDisabledMobileSyncNotification() { + this.showingDisabledMobileSyncNotification_ = true; + } /** * @return {boolean} Whether the handler is syncing items or not. */ get syncing() { return false; - }, -}; + } +} /** * Completed event name. @@ -44,26 +63,3 @@ * @const */ MockDriveSyncHandler.DRIVE_SYNC_COMPLETED_EVENT = 'completed'; - -/** - * Returns the completed event name. - * @return {string} - */ -MockDriveSyncHandler.prototype.getCompletedEventName = () => { - return MockDriveSyncHandler.DRIVE_SYNC_COMPLETED_EVENT; -}; - -/** - * Returns whether the Drive sync is currently suppressed or not. - * @return {boolean} - */ -MockDriveSyncHandler.prototype.isSyncSuppressed = function() { - return this.syncSuppressed_; -}; - -/** - * Shows a notification that Drive sync is disabled on cellular networks. - */ -MockDriveSyncHandler.prototype.showDisabledMobileSyncNotification = function() { - this.showingDisabledMobileSyncNotification_ = true; -};
diff --git a/ui/file_manager/file_manager/background/js/mock_file_operation_manager.js b/ui/file_manager/file_manager/background/js/mock_file_operation_manager.js index caf9c088..7f2d263 100644 --- a/ui/file_manager/file_manager/background/js/mock_file_operation_manager.js +++ b/ui/file_manager/file_manager/background/js/mock_file_operation_manager.js
@@ -6,100 +6,93 @@ /** * Mock implementation of {FileOperationManager} for tests. - * @constructor - * @struct * @implements {FileOperationManager} - * @extends {cr.EventTarget} */ -function MockFileOperationManager() { - /** - * Event to be dispatched when requestTaskCancel is called. Note: the - * unittest writes this value before calling requestTaskCancel(). - * @type {Event} - */ - this.cancelEvent = null; +class MockFileOperationManager extends cr.EventTarget { + constructor() { + super(); - /** @type {!Array<string>} */ - this.generatedTaskIds = []; + /** + * Event to be dispatched when requestTaskCancel is called. Note: the + * unittest writes this value before calling requestTaskCancel(). + * @type {Event} + */ + this.cancelEvent = null; - /** @type {Function} */ - this.pasteResolver = null; -} + /** @type {!Array<string>} */ + this.generatedTaskIds = []; -MockFileOperationManager.prototype = /** @struct */ { - __proto__: cr.EventTarget.prototype, -}; - -/** - * Dispatches a cancel event that has been specified by the unittest. - */ -MockFileOperationManager.prototype.requestTaskCancel = function() { - assert(this.cancelEvent); - this.dispatchEvent(this.cancelEvent); -}; - -/** - * Kick off pasting. - * - * @param {Array<Entry>} sourceEntries Entries of the source files. - * @param {DirectoryEntry} targetEntry The destination entry of the target - * directory. - * @param {boolean} isMove True if the operation is "move", otherwise (i.e. - * if the operation is "copy") false. - * @param {string=} opt_taskId If the corresponding item has already created - * at another places, we need to specify the ID of the item. If the - * item is not created, FileOperationManager generates new ID. - */ -MockFileOperationManager.prototype.paste = function( - sourceEntries, targetEntry, isMove, opt_taskId) { - if (this.pasteResolver) { - this.pasteResolver.call(this, { - sourceEntries: sourceEntries, - targetEntry: targetEntry, - isMove: isMove, - opt_taskId: opt_taskId - }); - // Reset the resolver for the next paste call. + /** @type {Function} */ this.pasteResolver = null; } -}; -/** - * @return {Promise<Object>} A promise that is resolved the next time #paste is - * called. The Object contains the arguments that #paste was called with. - */ -MockFileOperationManager.prototype.whenPasteCalled = function() { - if (this.pasteResolver) { - throw new Error('Only one paste call can be waited on at a time.'); + /** + * Dispatches a cancel event that has been specified by the unittest. + */ + requestTaskCancel() { + assert(this.cancelEvent); + this.dispatchEvent(this.cancelEvent); } - return new Promise((resolve, reject) => { - this.pasteResolver = resolve; - }); -}; + /** + * Kick off pasting. + * + * @param {Array<Entry>} sourceEntries Entries of the source files. + * @param {DirectoryEntry} targetEntry The destination entry of the target + * directory. + * @param {boolean} isMove True if the operation is "move", otherwise (i.e. + * if the operation is "copy") false. + * @param {string=} opt_taskId If the corresponding item has already created + * at another places, we need to specify the ID of the item. If the + * item is not created, FileOperationManager generates new ID. + */ + paste(sourceEntries, targetEntry, isMove, opt_taskId) { + if (this.pasteResolver) { + this.pasteResolver.call(this, { + sourceEntries: sourceEntries, + targetEntry: targetEntry, + isMove: isMove, + opt_taskId: opt_taskId + }); + // Reset the resolver for the next paste call. + this.pasteResolver = null; + } + } -/** - * Generates a unique task Id. - * @return {string} - */ -MockFileOperationManager.prototype.generateTaskId = function() { - const newTaskId = 'task' + this.generatedTaskIds.length; - this.generatedTaskIds.push(newTaskId); - return newTaskId; -}; + /** + * @return {Promise<Object>} A promise that is resolved the next time #paste + * is called. The Object contains the arguments that #paste was called with. + */ + whenPasteCalled() { + if (this.pasteResolver) { + throw new Error('Only one paste call can be waited on at a time.'); + } -/** - * @return {boolean} Whether or not the given task ID belongs to a task - * generated by this manager. - */ -MockFileOperationManager.prototype.isKnownTaskId = function(id) { - return this.generatedTaskIds.indexOf(id) !== -1; -}; + return new Promise((resolve, reject) => { + this.pasteResolver = resolve; + }); + } -MockFileOperationManager.prototype.hasQueuedTasks = () => {}; + /** + * Generates a unique task Id. + * @return {string} + */ + generateTaskId() { + const newTaskId = 'task' + this.generatedTaskIds.length; + this.generatedTaskIds.push(newTaskId); + return newTaskId; + } -MockFileOperationManager.prototype.filterSameDirectoryEntry = () => {}; + /** + * @return {boolean} Whether or not the given task ID belongs to a task + * generated by this manager. + */ + isKnownTaskId(id) { + return this.generatedTaskIds.indexOf(id) !== -1; + } -MockFileOperationManager.prototype.deleteEntries = () => {}; - -MockFileOperationManager.prototype.zipSelection = () => {}; + hasQueuedTasks() {} + filterSameDirectoryEntry() {} + deleteEntries() {} + zipSelection() {} +}
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn index 4209133..6e998bd0 100644 --- a/ui/file_manager/file_manager/foreground/js/BUILD.gn +++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -682,9 +682,6 @@ } js_library("spinner_controller") { - deps = [ - "//ui/webui/resources/js/cr:event_target", - ] } js_unittest("spinner_controller_unittest") {
diff --git a/ui/file_manager/file_manager/foreground/js/spinner_controller.js b/ui/file_manager/file_manager/foreground/js/spinner_controller.js index e5ec81f6..4d92c44 100644 --- a/ui/file_manager/file_manager/foreground/js/spinner_controller.js +++ b/ui/file_manager/file_manager/foreground/js/spinner_controller.js
@@ -6,96 +6,95 @@ * Controller for spinners. Spinner requests can be stacked. Eg. if show() * is called 3 times, the hide callback has to be called 3 times to make the * spinner invisible. - * - * @param {!Element} element - * @constructor - * @extends {cr.EventTarget} */ -function SpinnerController(element) { - /** - * The container element of the file list. - * @type {!Element} - * @const - * @private - */ - this.element_ = element; +class SpinnerController { + /** @param {!Element} element */ + constructor(element) { + /** + * The container element of the file list. + * @type {!Element} + * @const + * @private + */ + this.element_ = element; + + /** + * @type {number} + * @private + */ + this.activeSpinners_ = 0; + + /** + * @type {!Object<number, boolean>} + * @private + */ + this.pendingSpinnerTimerIds_ = {}; + + /** + * @type {number} + * @private + */ + this.blinkDuration_ = 1000; // In milliseconds. + } /** - * @type {number} - * @private + * Blinks the spinner for a short period of time. Hides automatically. */ - this.activeSpinners_ = 0; + blink() { + const hideCallback = this.show(); + setTimeout(hideCallback, this.blinkDuration_); + } /** - * @type {!Object<number, boolean>} - * @private + * Shows the spinner immediately until the returned callback is called. + * @return {function()} Hide callback. */ - this.pendingSpinnerTimerIds_ = {}; + show() { + return this.showWithDelay(0, () => {}); + } /** - * @type {number} + * Shows the spinner until hide is called. The returned callback must be + * called when the spinner is not necessary anymore. + * @param {number} delay Delay in milliseconds. + * @param {function()} callback Show callback. + * @return {function()} Hide callback. + */ + showWithDelay(delay, callback) { + const timerId = setTimeout(() => { + this.activeSpinners_++; + if (this.activeSpinners_ === 1) { + this.element_.hidden = false; + } + delete this.pendingSpinnerTimerIds_[timerId]; + callback(); + }, delay); + + this.pendingSpinnerTimerIds_[timerId] = true; + return this.maybeHide_.bind(this, timerId); + } + + /** + * @param {number} duration Duration in milliseconds. + */ + setBlinkDurationForTesting(duration) { + this.blinkDuration_ = duration; + } + + /** + * @param {number} timerId * @private */ - this.blinkDuration_ = 1000; // In milliseconds. -} - -/** - * Blinks the spinner for a short period of time. Hides automatically. - */ -SpinnerController.prototype.blink = function() { - const hideCallback = this.show(); - setTimeout(hideCallback, this.blinkDuration_); -}; - -/** - * Shows the spinner immediately until the returned callback is called. - * @return {function()} Hide callback. - */ -SpinnerController.prototype.show = function() { - return this.showWithDelay(0, () => {}); -}; - -/** - * Shows the spinner until hide is called. The returned callback must be called - * when the spinner is not necessary anymore. - * @param {number} delay Delay in milliseconds. - * @param {function()} callback Show callback. - * @return {function()} Hide callback. - */ -SpinnerController.prototype.showWithDelay = function(delay, callback) { - const timerId = setTimeout(() => { - this.activeSpinners_++; - if (this.activeSpinners_ === 1) { - this.element_.hidden = false; + maybeHide_(timerId) { + if (timerId in this.pendingSpinnerTimerIds_) { + clearTimeout(timerId); + delete this.pendingSpinnerTimerIds_[timerId]; + return; } - delete this.pendingSpinnerTimerIds_[timerId]; - callback(); - }, delay); - this.pendingSpinnerTimerIds_[timerId] = true; - return this.maybeHide_.bind(this, timerId); -}; - -/** - * @param {number} duration Duration in milliseconds. - */ -SpinnerController.prototype.setBlinkDurationForTesting = function(duration) { - this.blinkDuration_ = duration; -}; - -/** - * @param {number} timerId - * @private - */ -SpinnerController.prototype.maybeHide_ = function(timerId) { - if (timerId in this.pendingSpinnerTimerIds_) { - clearTimeout(timerId); - delete this.pendingSpinnerTimerIds_[timerId]; - return; + this.activeSpinners_--; + if (this.activeSpinners_ === 0) { + this.element_.hidden = true; + } } - - this.activeSpinners_--; - if (this.activeSpinners_ === 0) { - this.element_.hidden = true; - } -}; +}
diff --git a/ui/file_manager/image_loader/piex/tests.js b/ui/file_manager/image_loader/piex/tests.js index a072483..18ed115a 100644 --- a/ui/file_manager/image_loader/piex/tests.js +++ b/ui/file_manager/image_loader/piex/tests.js
@@ -72,18 +72,18 @@ }; const images = [ - "images/SONY_A500_01.ARW", - "images/EOS_XS_REBEL.CR2", - "images/RAW_CANON_1DM2.CR2", - "images/L100_4220.DNG", - "images/RAW_LEICA_M8.DNG", - "images/FUJI_E550_RAW.RAF", - "images/NIKON_UB20_O35.NEF", - "images/NIKON_GDN0447.NEF", - "images/OLYMPUS_SC877.ORF", - "images/NIKON_CPIX78.NRW", - "images/PANASONIC_DMC.RW2", - "images/UNKNOWN_FORMAT.JPG", + 'images/SONY_A500_01.ARW', + 'images/EOS_XS_REBEL.CR2', + 'images/RAW_CANON_1DM2.CR2', + 'images/L100_4220.DNG', + 'images/RAW_LEICA_M8.DNG', + 'images/FUJI_E550_RAW.RAF', + 'images/NIKON_UB20_O35.NEF', + 'images/NIKON_GDN0447.NEF', + 'images/OLYMPUS_SC877.ORF', + 'images/NIKON_CPIX78.NRW', + 'images/PANASONIC_DMC.RW2', + 'images/UNKNOWN_FORMAT.JPG', ]; await page.evaluate(() => {
diff --git a/ui/native_theme/common_theme.cc b/ui/native_theme/common_theme.cc index 8d7e0fa..d0f6ba7 100644 --- a/ui/native_theme/common_theme.cc +++ b/ui/native_theme/common_theme.cc
@@ -61,6 +61,8 @@ case NativeTheme::kColorId_DialogBackground: return color_utils::AlphaBlend(SK_ColorWHITE, gfx::kGoogleGrey900, 0.04f); + case NativeTheme::kColorId_BubbleFooterBackground: + return SkColorSetRGB(0x32, 0x36, 0x39); case NativeTheme::kColorId_ProminentButtonColor: return gfx::kGoogleBlue300; case NativeTheme::kColorId_TextOnProminentButtonColor: @@ -159,6 +161,8 @@ case NativeTheme::kColorId_DialogBackground: case NativeTheme::kColorId_BubbleBackground: return SK_ColorWHITE; + case NativeTheme::kColorId_BubbleFooterBackground: + return gfx::kGoogleGrey050; // Buttons case NativeTheme::kColorId_ButtonEnabledColor:
diff --git a/ui/native_theme/native_theme.h b/ui/native_theme/native_theme.h index ebbb9cc7..cf93b2c 100644 --- a/ui/native_theme/native_theme.h +++ b/ui/native_theme/native_theme.h
@@ -296,6 +296,7 @@ // Dialogs kColorId_DialogBackground, kColorId_BubbleBackground, + kColorId_BubbleFooterBackground, // FocusableBorder kColorId_FocusedBorderColor, kColorId_UnfocusedBorderColor,
diff --git a/ui/native_theme/native_theme_dark_aura.cc b/ui/native_theme/native_theme_dark_aura.cc index 17b216ec..ba8aeac 100644 --- a/ui/native_theme/native_theme_dark_aura.cc +++ b/ui/native_theme/native_theme_dark_aura.cc
@@ -22,6 +22,7 @@ case kColorId_WindowBackground: case kColorId_DialogBackground: case kColorId_BubbleBackground: + case kColorId_BubbleFooterBackground: return SK_ColorBLACK; // Button
diff --git a/ui/views/accessibility/ax_virtual_view.cc b/ui/views/accessibility/ax_virtual_view.cc index c10ca2be..ec7296e 100644 --- a/ui/views/accessibility/ax_virtual_view.cc +++ b/ui/views/accessibility/ax_virtual_view.cc
@@ -266,15 +266,20 @@ return nullptr; } -gfx::Rect AXVirtualView::GetClippedScreenBoundsRect() const { - // We could optionally add clipping here if ever needed. - // TODO(nektar): Implement bounds that are relative to the parent. - return gfx::ToEnclosingRect(custom_data_.relative_bounds.bounds); -} - -gfx::Rect AXVirtualView::GetUnclippedScreenBoundsRect() const { - // TODO(nektar): Implement bounds that are relative to the parent. - return gfx::ToEnclosingRect(custom_data_.relative_bounds.bounds); +gfx::Rect AXVirtualView::GetBoundsRect( + const ui::AXCoordinateSystem coordinate_system, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result) const { + switch (coordinate_system) { + case ui::AXCoordinateSystem::kScreen: + // We could optionally add clipping here if ever needed. + // TODO(nektar): Implement bounds that are relative to the parent. + return gfx::ToEnclosingRect(custom_data_.relative_bounds.bounds); + case ui::AXCoordinateSystem::kRootFrame: + case ui::AXCoordinateSystem::kFrame: + NOTIMPLEMENTED(); + return gfx::Rect(); + } } gfx::NativeViewAccessible AXVirtualView::HitTestSync(int x, int y) {
diff --git a/ui/views/accessibility/ax_virtual_view.h b/ui/views/accessibility/ax_virtual_view.h index 66fd2f79..e807edc9 100644 --- a/ui/views/accessibility/ax_virtual_view.h +++ b/ui/views/accessibility/ax_virtual_view.h
@@ -128,8 +128,10 @@ gfx::NativeViewAccessible ChildAtIndex(int index) override; gfx::NativeViewAccessible GetNSWindow() override; gfx::NativeViewAccessible GetParent() override; - gfx::Rect GetClippedScreenBoundsRect() const override; - gfx::Rect GetUnclippedScreenBoundsRect() const override; + gfx::Rect GetBoundsRect( + const ui::AXCoordinateSystem coordinate_system, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result) const override; gfx::NativeViewAccessible HitTestSync(int x, int y) override; gfx::NativeViewAccessible GetFocus() override; ui::AXPlatformNode* GetFromNodeID(int32_t id) override;
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate.cc b/ui/views/accessibility/view_ax_platform_node_delegate.cc index 2c4392a..b6ac0c5 100644 --- a/ui/views/accessibility/view_ax_platform_node_delegate.cc +++ b/ui/views/accessibility/view_ax_platform_node_delegate.cc
@@ -296,13 +296,19 @@ return nullptr; } -gfx::Rect ViewAXPlatformNodeDelegate::GetClippedScreenBoundsRect() const { - // We could optionally add clipping here if ever needed. - return view()->GetBoundsInScreen(); -} - -gfx::Rect ViewAXPlatformNodeDelegate::GetUnclippedScreenBoundsRect() const { - return view()->GetBoundsInScreen(); +gfx::Rect ViewAXPlatformNodeDelegate::GetBoundsRect( + const ui::AXCoordinateSystem coordinate_system, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result) const { + switch (coordinate_system) { + case ui::AXCoordinateSystem::kScreen: + // We could optionally add clipping here if ever needed. + return view()->GetBoundsInScreen(); + case ui::AXCoordinateSystem::kRootFrame: + case ui::AXCoordinateSystem::kFrame: + NOTIMPLEMENTED(); + return gfx::Rect(); + } } gfx::NativeViewAccessible ViewAXPlatformNodeDelegate::HitTestSync(int x,
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate.h b/ui/views/accessibility/view_ax_platform_node_delegate.h index 2021a2a..455052d 100644 --- a/ui/views/accessibility/view_ax_platform_node_delegate.h +++ b/ui/views/accessibility/view_ax_platform_node_delegate.h
@@ -51,8 +51,10 @@ gfx::NativeViewAccessible ChildAtIndex(int index) override; gfx::NativeViewAccessible GetNSWindow() override; gfx::NativeViewAccessible GetParent() override; - gfx::Rect GetClippedScreenBoundsRect() const override; - gfx::Rect GetUnclippedScreenBoundsRect() const override; + gfx::Rect GetBoundsRect( + const ui::AXCoordinateSystem coordinate_system, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result) const override; gfx::NativeViewAccessible HitTestSync(int x, int y) override; gfx::NativeViewAccessible GetFocus() override; ui::AXPlatformNode* GetFromNodeID(int32_t id) override;
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate_win.cc b/ui/views/accessibility/view_ax_platform_node_delegate_win.cc index a1e7b940..457a4fc 100644 --- a/ui/views/accessibility/view_ax_platform_node_delegate_win.cc +++ b/ui/views/accessibility/view_ax_platform_node_delegate_win.cc
@@ -110,14 +110,19 @@ return HWNDForView(view()); } -gfx::Rect ViewAXPlatformNodeDelegateWin::GetClippedScreenBoundsRect() const { - // We could optionally add clipping here if ever needed. - return GetUnclippedScreenBoundsRect(); +gfx::Rect ViewAXPlatformNodeDelegateWin::GetBoundsRect( + const ui::AXCoordinateSystem coordinate_system, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result) const { + switch (coordinate_system) { + case ui::AXCoordinateSystem::kScreen: + // We could optionally add clipping here if ever needed. + return display::win::ScreenWin::DIPToScreenRect( + HWNDForView(view()), view()->GetBoundsInScreen()); + case ui::AXCoordinateSystem::kRootFrame: + case ui::AXCoordinateSystem::kFrame: + NOTIMPLEMENTED(); + return gfx::Rect(); + } } - -gfx::Rect ViewAXPlatformNodeDelegateWin::GetUnclippedScreenBoundsRect() const { - gfx::Rect bounds = view()->GetBoundsInScreen(); - return display::win::ScreenWin::DIPToScreenRect(HWNDForView(view()), bounds); -} - } // namespace views
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate_win.h b/ui/views/accessibility/view_ax_platform_node_delegate_win.h index 2715eae7..30fc304 100644 --- a/ui/views/accessibility/view_ax_platform_node_delegate_win.h +++ b/ui/views/accessibility/view_ax_platform_node_delegate_win.h
@@ -20,8 +20,10 @@ // |ViewAXPlatformNodeDelegate| overrides: gfx::NativeViewAccessible GetParent() override; gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override; - gfx::Rect GetClippedScreenBoundsRect() const override; - gfx::Rect GetUnclippedScreenBoundsRect() const override; + gfx::Rect GetBoundsRect( + const ui::AXCoordinateSystem coordinate_system, + const ui::AXClippingBehavior clipping_behavior, + ui::AXOffscreenResult* offscreen_result) const override; private: DISALLOW_COPY_AND_ASSIGN(ViewAXPlatformNodeDelegateWin);
diff --git a/ui/views/bubble/footnote_container_view.cc b/ui/views/bubble/footnote_container_view.cc index 6929a19..4fb844f 100644 --- a/ui/views/bubble/footnote_container_view.cc +++ b/ui/views/bubble/footnote_container_view.cc
@@ -65,9 +65,8 @@ FootnoteContainerView::~FootnoteContainerView() = default; void FootnoteContainerView::SetCornerRadius(float corner_radius) { - SkColor background_color = GetNativeTheme()->SystemDarkModeEnabled() - ? SkColorSetRGB(0x32, 0x36, 0x39) - : gfx::kGoogleGrey050; + SkColor background_color = GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_BubbleFooterBackground); SetBackground(std::make_unique<HalfRoundedRectBackground>(background_color, corner_radius)); }
diff --git a/ui/views/controls/button/button.cc b/ui/views/controls/button/button.cc index 3adb1a5..1b5ba78 100644 --- a/ui/views/controls/button/button.cc +++ b/ui/views/controls/button/button.cc
@@ -484,6 +484,9 @@ return button()->GetDragOperations(press_pt); } bool InDrag() override { return button()->InDrag(); } + + private: + DISALLOW_COPY_AND_ASSIGN(DefaultButtonControllerDelegate); }; //////////////////////////////////////////////////////////////////////////////// @@ -501,7 +504,7 @@ hover_animation_.SetSlideDuration(kHoverFadeDurationMs); SetInstallFocusRingOnFocus(PlatformStyle::kPreferFocusRings); button_controller_ = std::make_unique<ButtonController>( - this, std::make_unique<DefaultButtonControllerDelegate>(this)); + this, CreateButtonControllerDelegate()); } Button::KeyClickAction Button::GetKeyClickActionForEvent( @@ -553,8 +556,9 @@ return button_controller_->IsTriggerableEvent(event); } -void Button::SetButtonController(std::unique_ptr<ButtonController> handler) { - button_controller_ = std::move(handler); +void Button::SetButtonController( + std::unique_ptr<ButtonController> button_controller) { + button_controller_ = std::move(button_controller); } bool Button::ShouldUpdateInkDropOnClickCanceled() const {
diff --git a/ui/views/controls/button/button.h b/ui/views/controls/button/button.h index d1103fb6..7211006c 100644 --- a/ui/views/controls/button/button.h +++ b/ui/views/controls/button/button.h
@@ -281,7 +281,7 @@ FocusRing* focus_ring() { return focus_ring_.get(); } - void SetButtonController(std::unique_ptr<ButtonController> handler); + void SetButtonController(std::unique_ptr<ButtonController> button_controller); // The button's listener. Notified when clicked. ButtonListener* listener_;
diff --git a/ui/views/controls/button/button_controller.cc b/ui/views/controls/button/button_controller.cc index 4afbc100..17d0a12 100644 --- a/ui/views/controls/button/button_controller.cc +++ b/ui/views/controls/button/button_controller.cc
@@ -17,10 +17,6 @@ ButtonController::~ButtonController() = default; -MenuButtonController* ButtonController::AsMenuButtonController() { - return nullptr; -} - bool ButtonController::OnMousePressed(const ui::MouseEvent& event) { if (button_->state() == Button::STATE_DISABLED) return true;
diff --git a/ui/views/controls/button/button_controller.h b/ui/views/controls/button/button_controller.h index 0688f45b..242b6fe4 100644 --- a/ui/views/controls/button/button_controller.h +++ b/ui/views/controls/button/button_controller.h
@@ -11,8 +11,6 @@ namespace views { -class MenuButtonController; - // Handles logic not related to the visual aspects of a Button such as event // handling and state changes. class VIEWS_EXPORT ButtonController { @@ -21,12 +19,6 @@ std::unique_ptr<ButtonControllerDelegate> delegate); virtual ~ButtonController(); - // Convenience method for downcasting; the ButtonController implementation - // returns null. - // TODO(cyan): Remove this method and have MenuButton store a data member of - // concrete type MenuButtonController*. - virtual MenuButtonController* AsMenuButtonController(); - // Methods that parallel View::On<Event> handlers: virtual bool OnMousePressed(const ui::MouseEvent& event); virtual void OnMouseReleased(const ui::MouseEvent& event);
diff --git a/ui/views/controls/button/button_controller_delegate.h b/ui/views/controls/button/button_controller_delegate.h index dab98c3..8c32a47 100644 --- a/ui/views/controls/button/button_controller_delegate.h +++ b/ui/views/controls/button/button_controller_delegate.h
@@ -28,7 +28,7 @@ // Parallels method views::InkDropEventHandler::GetInkDrop: virtual InkDrop* GetInkDrop() = 0; - // Parallels method views::View: + // Parallels methods in views::View: virtual int GetDragOperations(const gfx::Point& press_pt) = 0; virtual bool InDrag() = 0; @@ -37,6 +37,8 @@ private: Button* button_; + + DISALLOW_COPY_AND_ASSIGN(ButtonControllerDelegate); }; } // namespace views
diff --git a/ui/views/controls/button/menu_button.cc b/ui/views/controls/button/menu_button.cc index 927f64d..2b2a7b8 100644 --- a/ui/views/controls/button/menu_button.cc +++ b/ui/views/controls/button/menu_button.cc
@@ -19,15 +19,14 @@ int button_context) : LabelButton(nullptr, text, button_context) { SetHorizontalAlignment(gfx::ALIGN_LEFT); - SetButtonController(std::make_unique<MenuButtonController>( - this, menu_button_listener, CreateButtonControllerDelegate())); + std::unique_ptr<MenuButtonController> menu_button_controller = + std::make_unique<MenuButtonController>(this, menu_button_listener, + CreateButtonControllerDelegate()); + menu_button_controller_ = menu_button_controller.get(); + SetButtonController(std::move(menu_button_controller)); } MenuButton::~MenuButton() = default; -MenuButtonController* MenuButton::button_controller() const { - return Button::button_controller()->AsMenuButtonController(); -} - bool MenuButton::Activate(const ui::Event* event) { return button_controller()->Activate(event); }
diff --git a/ui/views/controls/button/menu_button.h b/ui/views/controls/button/menu_button.h index d225527f..fcc74fa 100644 --- a/ui/views/controls/button/menu_button.h +++ b/ui/views/controls/button/menu_button.h
@@ -35,7 +35,9 @@ int button_context = style::CONTEXT_BUTTON); ~MenuButton() override; - MenuButtonController* button_controller() const; + MenuButtonController* button_controller() const { + return menu_button_controller_; + } bool Activate(const ui::Event* event); @@ -53,6 +55,8 @@ void NotifyClick(const ui::Event& event) final; private: + MenuButtonController* menu_button_controller_; + DISALLOW_COPY_AND_ASSIGN(MenuButton); };
diff --git a/ui/views/controls/button/menu_button_controller.cc b/ui/views/controls/button/menu_button_controller.cc index 0699575..fdda1a16 100644 --- a/ui/views/controls/button/menu_button_controller.cc +++ b/ui/views/controls/button/menu_button_controller.cc
@@ -70,10 +70,6 @@ MenuButtonController::~MenuButtonController() = default; -MenuButtonController* MenuButtonController::AsMenuButtonController() { - return this; -} - bool MenuButtonController::OnMousePressed(const ui::MouseEvent& event) { if (button()->request_focus_on_press()) button()->RequestFocus();
diff --git a/ui/views/controls/button/menu_button_controller.h b/ui/views/controls/button/menu_button_controller.h index 7932afb..9afcbb8 100644 --- a/ui/views/controls/button/menu_button_controller.h +++ b/ui/views/controls/button/menu_button_controller.h
@@ -46,7 +46,6 @@ ~MenuButtonController() override; // view::ButtonController - MenuButtonController* AsMenuButtonController() override; bool OnMousePressed(const ui::MouseEvent& event) override; void OnMouseReleased(const ui::MouseEvent& event) override; void OnMouseMoved(const ui::MouseEvent& event) override;
diff --git a/ui/views/controls/menu/menu_item_view.cc b/ui/views/controls/menu/menu_item_view.cc index 5ca281f..21379b8d 100644 --- a/ui/views/controls/menu/menu_item_view.cc +++ b/ui/views/controls/menu/menu_item_view.cc
@@ -19,6 +19,8 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/menu_model.h" #include "ui/base/ui_base_features.h" +#include "ui/events/base_event_utils.h" +#include "ui/events/keycodes/dom/dom_code.h" #include "ui/gfx/animation/animation.h" #include "ui/gfx/canvas.h" #include "ui/gfx/color_utils.h" @@ -216,7 +218,16 @@ bool MenuItemView::HandleAccessibleAction(const ui::AXActionData& action_data) { if (action_data.action != ax::mojom::Action::kDoDefault) return View::HandleAccessibleAction(action_data); - GetMenuController()->Accept(this, ui::EF_NONE); + + // kDoDefault in View would simulate a mouse click in the center of this + // MenuItemView. However, mouse events for menus are dispatched via + // Widget::SetCapture() to the MenuController rather than to MenuItemView, so + // there is no effect. VKEY_RETURN provides a better UX anyway, since it will + // move focus to a submenu. + ui::KeyEvent event(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::DomCode::ENTER, + ui::EF_NONE, ui::DomKey::ENTER, ui::EventTimeForNow()); + GetMenuController()->SetSelection(this, MenuController::SELECTION_DEFAULT); + GetMenuController()->OnWillDispatchKeyEvent(&event); return true; }
diff --git a/ui/views/controls/scrollbar/scroll_bar.cc b/ui/views/controls/scrollbar/scroll_bar.cc index 0b66dc8e..2679f2ad 100644 --- a/ui/views/controls/scrollbar/scroll_bar.cc +++ b/ui/views/controls/scrollbar/scroll_bar.cc
@@ -405,7 +405,7 @@ thumb_position = thumb_position - (thumb_size / 2); float result = (thumb_position * (contents_size_ - viewport_size_)) / (track_size - thumb_size); - return gfx::ToFlooredInt(result); + return gfx::ToRoundedInt(result); } void ScrollBar::SetContentsScrollOffset(int contents_scroll_offset) {
diff --git a/ui/views/controls/slider.cc b/ui/views/controls/slider.cc index 5c82cb6..ebb9cb4 100644 --- a/ui/views/controls/slider.cc +++ b/ui/views/controls/slider.cc
@@ -26,14 +26,6 @@ namespace { constexpr int kSlideValueChangeDurationMs = 150; - -// The image chunks. -enum BorderElements { - LEFT, - CENTER_LEFT, - CENTER_RIGHT, - RIGHT, -}; } // namespace namespace views {
diff --git a/ui/views/controls/textfield/textfield_model.cc b/ui/views/controls/textfield/textfield_model.cc index e50e979..4c3328e4 100644 --- a/ui/views/controls/textfield/textfield_model.cc +++ b/ui/views/controls/textfield/textfield_model.cc
@@ -27,10 +27,10 @@ // Commit() marks an edit as an independent operation that shouldn't be merged. class Edit { public: - enum Type { - INSERT_EDIT, - DELETE_EDIT, - REPLACE_EDIT, + enum class Type { + kInsert, + kDelete, + kReplace, }; virtual ~Edit() = default; @@ -55,7 +55,7 @@ // user deletes characters then hits return. In this case, the // delete should be treated as separate edit that can be undone // and should not be merged with the replace edit. - if (type_ != DELETE_EDIT && edit->force_merge()) { + if (type_ != Type::kDelete && edit->force_merge()) { MergeReplace(edit); return true; } @@ -109,7 +109,7 @@ // Merge the replace edit into the current edit. This handles the special case // where an omnibox autocomplete string is set after a new character is typed. void MergeReplace(const Edit* edit) { - CHECK_EQ(REPLACE_EDIT, edit->type_); + CHECK_EQ(Type::kReplace, edit->type_); CHECK_EQ(0U, edit->old_text_start_); CHECK_EQ(0U, edit->new_text_start_); base::string16 old_text = edit->old_text_; @@ -151,7 +151,7 @@ class InsertEdit : public Edit { public: InsertEdit(bool mergeable, const base::string16& new_text, size_t at) - : Edit(INSERT_EDIT, + : Edit(Type::kInsert, mergeable ? MergeType::kMergeable : MergeType::kDoNotMerge, base::string16(), at, @@ -163,7 +163,8 @@ // Edit implementation. bool DoMerge(const Edit* edit) override { - if (edit->type() != INSERT_EDIT || new_text_end() != edit->new_text_start_) + if (edit->type() != Type::kInsert || + new_text_end() != edit->new_text_start_) return false; // If continuous edit, merge it. // TODO(oshima): gtk splits edits between whitespace. Find out what @@ -184,7 +185,7 @@ size_t new_cursor_pos, const base::string16& new_text, size_t new_text_start) - : Edit(REPLACE_EDIT, + : Edit(Type::kReplace, merge_type, old_text, old_text_start, @@ -196,7 +197,7 @@ // Edit implementation. bool DoMerge(const Edit* edit) override { - if (edit->type() == DELETE_EDIT || + if (edit->type() == Type::kDelete || new_text_end() != edit->old_text_start_ || edit->old_text_start_ != edit->new_text_start_) return false; @@ -214,7 +215,7 @@ size_t text_start, bool backward, gfx::Range old_selection) - : Edit(DELETE_EDIT, + : Edit(Type::kDelete, mergeable ? MergeType::kMergeable : MergeType::kDoNotMerge, text, text_start, @@ -226,7 +227,7 @@ // Edit implementation. bool DoMerge(const Edit* edit) override { - if (edit->type() != DELETE_EDIT) + if (edit->type() != Type::kDelete) return false; if (delete_backward_) { @@ -299,11 +300,6 @@ } // namespace -using internal::Edit; -using internal::DeleteEdit; -using internal::InsertEdit; -using internal::ReplaceEdit; - ///////////////////////////////////////////////////////////////// // TextfieldModel: public @@ -679,7 +675,7 @@ composition_range_.start(), composition_range_.length()); // TODO(oshima): current behavior on ChromeOS is a bit weird and not // sure exactly how this should work. Find out and fix if necessary. - AddOrMergeEditHistory(std::make_unique<InsertEdit>( + AddOrMergeEditHistory(std::make_unique<internal::InsertEdit>( false, composition, composition_range_.start())); render_text_->SetCursorPosition(composition_range_.end()); ClearComposition(); @@ -770,8 +766,8 @@ const base::string16 old_text = text().substr(old_text_start, range.length()); bool backward = range.is_reversed(); gfx::Range curr_selection = render_text_->selection(); - auto edit = std::make_unique<DeleteEdit>(mergeable, old_text, old_text_start, - backward, curr_selection); + auto edit = std::make_unique<internal::DeleteEdit>( + mergeable, old_text, old_text_start, backward, curr_selection); edit->Redo(this); AddOrMergeEditHistory(std::move(edit)); } @@ -792,7 +788,7 @@ size_t new_text_start) { size_t old_text_start = replacement_range.GetMin(); bool backward = replacement_range.is_reversed(); - auto edit = std::make_unique<ReplaceEdit>( + auto edit = std::make_unique<internal::ReplaceEdit>( merge_type, GetTextFromRange(replacement_range), old_text_start, render_text_->selection(), backward, new_cursor_pos, new_text, new_text_start); @@ -802,13 +798,14 @@ void TextfieldModel::ExecuteAndRecordInsert(const base::string16& new_text, bool mergeable) { - auto edit = - std::make_unique<InsertEdit>(mergeable, new_text, GetCursorPosition()); + auto edit = std::make_unique<internal::InsertEdit>(mergeable, new_text, + GetCursorPosition()); edit->Redo(this); AddOrMergeEditHistory(std::move(edit)); } -void TextfieldModel::AddOrMergeEditHistory(std::unique_ptr<Edit> edit) { +void TextfieldModel::AddOrMergeEditHistory( + std::unique_ptr<internal::Edit> edit) { ClearRedoHistory(); if (current_edit_ != edit_history_.end() &&
diff --git a/ui/webui/resources/cr_components/chromeos/BUILD.gn b/ui/webui/resources/cr_components/chromeos/BUILD.gn index 3c7e363..895487a 100644 --- a/ui/webui/resources/cr_components/chromeos/BUILD.gn +++ b/ui/webui/resources/cr_components/chromeos/BUILD.gn
@@ -9,6 +9,7 @@ group("closure_compile") { deps = [ ":chromeos_resources", + "cellular_setup:closure_compile", "multidevice_setup:closure_compile", "network:closure_compile", "quick_unlock:closure_compile",
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/BUILD.gn b/ui/webui/resources/cr_components/chromeos/cellular_setup/BUILD.gn new file mode 100644 index 0000000..98f14a7 --- /dev/null +++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/BUILD.gn
@@ -0,0 +1,19 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") + +assert(is_chromeos, "MultiDevice UI is Chrome OS only.") + +js_type_check("closure_compile") { + deps = [ + ":cellular_setup", + ] +} + +js_library("cellular_setup") { + deps = [ + "//ui/webui/resources/js:i18n_behavior", + ] +}
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/OWNERS b/ui/webui/resources/cr_components/chromeos/cellular_setup/OWNERS new file mode 100644 index 0000000..75e2f312 --- /dev/null +++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/OWNERS
@@ -0,0 +1,2 @@ +azeemarshad@chromium.org +khorimoto@chromium.org
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup.html b/ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup.html new file mode 100644 index 0000000..11c88bf3 --- /dev/null +++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup.html
@@ -0,0 +1,12 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> + +<dom-module id="cellular-setup"> + <template> + <!-- TODO(azeemarshad): Replace button with actual content.--> + <button>[[i18n('cancel')]]</button> + </template> + <script src="cellular_setup.js"> + </script> +</dom-module>
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup.js b/ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup.js new file mode 100644 index 0000000..b4e2344 --- /dev/null +++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup.js
@@ -0,0 +1,10 @@ +// 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. + +// TODO(azeemarshad): Implement cellular setup UI. +Polymer({ + is: 'cellular-setup', + + behaviors: [I18nBehavior], +});
diff --git a/ui/webui/resources/cr_components/cr_components_resources.grdp b/ui/webui/resources/cr_components/cr_components_resources.grdp index 8c5d906e..6248ce7 100644 --- a/ui/webui/resources/cr_components/cr_components_resources.grdp +++ b/ui/webui/resources/cr_components/cr_components_resources.grdp
@@ -259,6 +259,16 @@ type="chrome_html" compress="gzip" /> + <!-- Shared between cellular setup flow and OOBE. --> + <structure name="IDR_WEBUI_CHROMEOS_CELLULAR_SETUP_CELLULAR_SETUP_BROWSER_HTML" + file="cr_components/chromeos/cellular_setup/cellular_setup.html" + type="chrome_html" + compress="gzip" /> + <structure name="IDR_WEBUI_CHROMEOS_CELLULAR_SETUP_CELLULAR_SETUP_BROWSER_JS" + file="cr_components/chromeos/cellular_setup/cellular_setup.js" + type="chrome_html" + compress="gzip" /> + <!-- Shared between MultiDevice setup flow and OOBE. --> <structure name="IDR_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_BROWSER_PROXY_HTML" file="cr_components/chromeos/multidevice_setup/multidevice_setup_browser_proxy.html"