diff --git a/AUTHORS b/AUTHORS index 6714e69..bf850cc 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -366,6 +366,7 @@ Ilia Demianenko <ilia.demianenko@gmail.com> Ilia K <ki.stfu@gmail.com> Ilya Konstantinov <ilya.konstantinov@gmail.com> +Imam Mohammad Bokhary <imam.bokhary@samsung.com> Imranur Rahman <i.rahman@samsung.com> Imranur Rahman <ir.shimul@gmail.com> Ion Rosca <rosca@adobe.com>
diff --git a/DEPS b/DEPS index a7dc181..08794874 100644 --- a/DEPS +++ b/DEPS
@@ -167,11 +167,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'f7e9d17791e406285df83449b95cd498d1a9cd1f', + 'skia_revision': '3787f51c65c33eda4a5f81e16b5e7e2d01f93943', # 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': '377dc2acc20702d6b96dc7a9e32a8b7164448670', + 'v8_revision': 'd033cf119f93f2fe742ea7970d3394a060cffb3c', # 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. @@ -179,11 +179,11 @@ # 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': '7f506bde16f165f923e9fd7e80c4f8b6314618fd', + 'angle_revision': 'a0159c03485b0ac91784d12d544927d83453d186', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '6b4b8141e11d7e1a397aa04f39c0c7eb20428104', + 'swiftshader_revision': 'faa2a365b5c0e90a5e1156c01a3acb4246632316', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -286,7 +286,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spv_tools_revision': '510ca9d616f5682a225b894a64b2af8fa5997d48', + 'spv_tools_revision': '10951a7c9a13ec663bc1dfdaec268840be865e9a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -302,11 +302,11 @@ # 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': '64f4dd71278a76e1cffb4578e6441a09fd231283', + 'dawn_revision': '86ac0b93c9afc7682c9e31f573dd387dc601dfbf', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'quiche_revision': 'e3f2f7bd0dddec518b59fed97a3a6d48cbbd1f59', + 'quiche_revision': 'f0fe2069005c907660534fc7d3ee9694c79799d6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -862,7 +862,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '3004764570f3c3bc0669ffaf194ab828d6a0153d', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'a2aeb375f63ca0734f3eb63d9256b50221c1d920', 'condition': 'checkout_linux', }, @@ -1269,7 +1269,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '5d1b15f34c87999b97d5b1d768e14b59b75934d4', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '7505235b577c4f720c439ae33f409d0563e13360', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1459,7 +1459,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '7c4e67ff117d6c640e6dd17989afe2fb7da7eecb', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '1903a35e00e89555180b8442c42d3bdbd91565ee', + Var('webrtc_git') + '/src.git' + '@' + 'ba2ba59c4ba1009ad04e56bb3804c882bc63441b', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1521,7 +1521,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@e1fd70911515747eeeb1e32f37ccf2f16a0b4a0a', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@b2ed47b33935fb53bf38bf1af020f9dfbf7666be', 'condition': 'checkout_src_internal', },
diff --git a/ash/wm/overview/overview_window_drag_controller.cc b/ash/wm/overview/overview_window_drag_controller.cc index dbdbc2f..1ebd144 100644 --- a/ash/wm/overview/overview_window_drag_controller.cc +++ b/ash/wm/overview/overview_window_drag_controller.cc
@@ -560,24 +560,9 @@ if (!ShouldUpdateDragIndicatorsOrSnap(location_in_screen)) return; - IndicatorState indicator_state; - if (CanSnapInSplitview(item_->GetWindow())) { - snap_position_ = GetSnapPosition(location_in_screen); - switch (snap_position_) { - case SplitViewController::NONE: - indicator_state = IndicatorState::kDragArea; - break; - case SplitViewController::LEFT: - indicator_state = IndicatorState::kPreviewAreaLeft; - break; - case SplitViewController::RIGHT: - indicator_state = IndicatorState::kPreviewAreaRight; - break; - } - } else { - snap_position_ = SplitViewController::NONE; - indicator_state = IndicatorState::kCannotSnap; - } + snap_position_ = GetSnapPosition(location_in_screen); + IndicatorState indicator_state = + GetIndicatorState(item_->GetWindow(), snap_position_); item_->overview_grid()->RearrangeDuringDrag(item_->GetWindow(), indicator_state); overview_session_->SetSplitViewDragIndicatorsIndicatorState( @@ -676,38 +661,9 @@ return default_snap_position; } - if (is_landscape) { - // The window can be snapped if it reaches close enough to the screen - // edge of the screen (on primary axis). The edge insets are a fixed ratio - // of the screen plus some padding. This matches the drag indicators ui. - const int screen_edge_inset_for_drag = - area.width() * kHighlightScreenPrimaryAxisRatio + - kHighlightScreenEdgePaddingDp; - area.Inset(screen_edge_inset_for_drag, 0); - if (location_in_screen.x() <= area.x()) { - return is_primary ? SplitViewController::LEFT - : SplitViewController::RIGHT; - } - if (location_in_screen.x() >= area.right() - 1) { - return is_primary ? SplitViewController::RIGHT - : SplitViewController::LEFT; - } - return SplitViewController::NONE; - } else { - const int screen_edge_inset_for_drag = - area.height() * kHighlightScreenPrimaryAxisRatio + - kHighlightScreenEdgePaddingDp; - area.Inset(0, screen_edge_inset_for_drag); - if (location_in_screen.y() <= area.y()) { - return is_primary ? SplitViewController::LEFT - : SplitViewController::RIGHT; - } - if (location_in_screen.y() >= area.bottom() - 1) { - return is_primary ? SplitViewController::RIGHT - : SplitViewController::LEFT; - } - return SplitViewController::NONE; - } + return ::ash::GetSnapPosition( + item_->GetWindow(), + gfx::Point(location_in_screen.x(), location_in_screen.y()), area); } void OverviewWindowDragController::SnapWindow(
diff --git a/ash/wm/splitview/split_view_utils.cc b/ash/wm/splitview/split_view_utils.cc index 6faaeb75..f8341fe 100644 --- a/ash/wm/splitview/split_view_utils.cc +++ b/ash/wm/splitview/split_view_utils.cc
@@ -355,4 +355,64 @@ : SplitViewController::RIGHT); } +SplitViewController::SnapPosition GetSnapPosition( + aura::Window* window, + const gfx::Point& location_in_screen, + const gfx::Rect& work_area) { + if (!ShouldAllowSplitView() || !CanSnapInSplitview(window)) + return SplitViewController::NONE; + + const bool is_landscape = IsCurrentScreenOrientationLandscape(); + const bool is_primary = IsCurrentScreenOrientationPrimary(); + + // Check to see if the current event location |location_in_screen|is within + // the drag indicators bounds. + gfx::Rect area(work_area); + if (is_landscape) { + const int screen_edge_inset_for_drag = + area.width() * kHighlightScreenPrimaryAxisRatio + + kHighlightScreenEdgePaddingDp; + area.Inset(screen_edge_inset_for_drag, 0); + if (location_in_screen.x() <= area.x()) { + return is_primary ? SplitViewController::LEFT + : SplitViewController::RIGHT; + } + if (location_in_screen.x() >= area.right() - 1) { + return is_primary ? SplitViewController::RIGHT + : SplitViewController::LEFT; + } + return SplitViewController::NONE; + } + + const int screen_edge_inset_for_drag = + area.height() * kHighlightScreenPrimaryAxisRatio + + kHighlightScreenEdgePaddingDp; + area.Inset(0, screen_edge_inset_for_drag); + if (location_in_screen.y() <= area.y()) + return is_primary ? SplitViewController::LEFT : SplitViewController::RIGHT; + if (location_in_screen.y() >= area.bottom() - 1) + return is_primary ? SplitViewController::RIGHT : SplitViewController::LEFT; + return SplitViewController::NONE; +} + +IndicatorState GetIndicatorState( + aura::Window* window, + SplitViewController::SnapPosition snap_position) { + if (!ShouldAllowSplitView()) + return IndicatorState::kNone; + + switch (snap_position) { + case SplitViewController::LEFT: + return IndicatorState::kPreviewAreaLeft; + case SplitViewController::RIGHT: + return IndicatorState::kPreviewAreaRight; + case SplitViewController::NONE: + return CanSnapInSplitview(window) ? IndicatorState::kDragArea + : IndicatorState::kCannotSnap; + } + + NOTREACHED(); + return IndicatorState::kNone; +} + } // namespace ash
diff --git a/ash/wm/splitview/split_view_utils.h b/ash/wm/splitview/split_view_utils.h index 0cd0552..f0cc61c9 100644 --- a/ash/wm/splitview/split_view_utils.h +++ b/ash/wm/splitview/split_view_utils.h
@@ -8,6 +8,7 @@ #include "ash/ash_export.h" #include "ash/display/screen_orientation_controller.h" #include "ash/wm/splitview/split_view_controller.h" +#include "ash/wm/splitview/split_view_drag_indicators.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/transform.h" @@ -105,6 +106,19 @@ ASH_EXPORT bool IsPhysicalLeftOrTop(SplitViewController::SnapPosition position); +// Returns the desired snap position based on |location_in_screen|. The window +// needs to be dragged into the drag indicator area on the edge of the screen +// to be able to get snapped. +ASH_EXPORT SplitViewController::SnapPosition GetSnapPosition( + aura::Window* window, + const gfx::Point& location_in_screen, + const gfx::Rect& work_area); + +// Returns the desried indicator state based on the desired |snap_position|. +ASH_EXPORT IndicatorState +GetIndicatorState(aura::Window* window, + SplitViewController::SnapPosition snap_position); + } // namespace ash #endif // ASH_WM_SPLITVIEW_SPLIT_VIEW_UTILS_H_
diff --git a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc index 3cb1c429..6c28bc0 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_drag_delegate.cc
@@ -316,31 +316,24 @@ IndicatorState TabletModeWindowDragDelegate::GetIndicatorState( const gfx::Point& location_in_screen) const { - // Do not show the drag indicators if split view is disabled globally. - if (!ShouldAllowSplitView()) - return IndicatorState::kNone; - // Do not show the drag indicators if the window hasn't been considered as // moved. if (!is_window_considered_moved_) return IndicatorState::kNone; - SplitViewController::SnapPosition snap_position = - GetSnapPosition(location_in_screen); - if (snap_position != SplitViewController::NONE) { - return snap_position == SplitViewController::LEFT - ? IndicatorState::kPreviewAreaLeft - : IndicatorState::kPreviewAreaRight; + IndicatorState indicator_state = ::ash::GetIndicatorState( + dragged_window_, GetSnapPosition(location_in_screen)); + + // In portrait screen orientation no top drag indicator since we're dragging + // from top. + if (!IsCurrentScreenOrientationLandscape()) { + if (indicator_state == IndicatorState::kDragArea) + indicator_state = IndicatorState::kDragAreaRight; + else if (indicator_state == IndicatorState::kCannotSnap) + indicator_state = IndicatorState::kCannotSnapRight; } - const bool can_snap = CanSnapInSplitview(dragged_window_); - - // No top drag indicator if in portrait screen orientation. - if (IsCurrentScreenOrientationLandscape()) - return can_snap ? IndicatorState::kDragArea : IndicatorState::kCannotSnap; - - return can_snap ? IndicatorState::kDragAreaRight - : IndicatorState::kCannotSnapRight; + return indicator_state; } bool TabletModeWindowDragDelegate::ShouldOpenOverviewWhenDragStarts() { @@ -362,39 +355,24 @@ if (!(is_window_considered_moved_ && CanSnapInSplitview(dragged_window_))) return SplitViewController::NONE; - const bool is_landscape = IsCurrentScreenOrientationLandscape(); - const bool is_primary = IsCurrentScreenOrientationPrimary(); - gfx::Rect work_area_bounds = display::Screen::GetScreen() - ->GetDisplayNearestWindow(dragged_window_) - .work_area(); - // Check to see if the current event location |location_in_screen|is within - // the drag indicators bounds. - if (is_landscape) { - const int screen_edge_inset = - work_area_bounds.width() * kHighlightScreenPrimaryAxisRatio + - kHighlightScreenEdgePaddingDp; - work_area_bounds.Inset(screen_edge_inset, 0); - if (location_in_screen.x() < work_area_bounds.x()) { - return is_primary ? SplitViewController::LEFT - : SplitViewController::RIGHT; - } - if (location_in_screen.x() >= work_area_bounds.right()) { - return is_primary ? SplitViewController::RIGHT - : SplitViewController::LEFT; - } - return SplitViewController::NONE; - } + SplitViewController::SnapPosition snap_position = + ::ash::GetSnapPosition(dragged_window_, location_in_screen, + display::Screen::GetScreen() + ->GetDisplayNearestWindow(dragged_window_) + .work_area()); + // For portrait mode, since the drag always starts from the top of the // screen, we only allow the window to be dragged to snap to the bottom of // the screen. - const int screen_edge_inset = - work_area_bounds.height() * kHighlightScreenPrimaryAxisRatio + - kHighlightScreenEdgePaddingDp; - work_area_bounds.Inset(0, screen_edge_inset); - if (location_in_screen.y() >= work_area_bounds.bottom()) - return is_primary ? SplitViewController::RIGHT : SplitViewController::LEFT; + const bool is_landscape = IsCurrentScreenOrientationLandscape(); + const bool is_primary = IsCurrentScreenOrientationPrimary(); + if (!is_landscape && + ((is_primary && snap_position == SplitViewController::LEFT) || + (!is_primary && snap_position == SplitViewController::RIGHT))) { + snap_position = SplitViewController::NONE; + } - return SplitViewController::NONE; + return snap_position; } void TabletModeWindowDragDelegate::UpdateDraggedWindowTransform(
diff --git a/base/allocator/debugallocation_shim.cc b/base/allocator/debugallocation_shim.cc index 479cfca..24addf9 100644 --- a/base/allocator/debugallocation_shim.cc +++ b/base/allocator/debugallocation_shim.cc
@@ -7,9 +7,10 @@ // AFDO can mess with them. Better not to use AFDO there. This is a // temporary hack. We will add a mechanism in the build system to // avoid using -fauto-profile for tcmalloc files. -#if !defined(__clang__) && (defined(OS_CHROMEOS) || __GNUC__ > 5) +#if !defined(__clang__) && \ + (defined(OS_CHROMEOS) || (__GNUC__ > 5 && __GNUC__ < 7)) // Note that this option only seems to be available in the chromeos GCC 4.9 -// toolchain, and stock GCC 5 and up. +// toolchain, and stock GCC 5 upto 7. #pragma GCC optimize ("no-auto-profile") #endif
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 1dac8be..305a667 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -147,6 +147,8 @@ "layers/video_layer_impl.h", "layers/viewport.cc", "layers/viewport.h", + "metrics/begin_main_frame_metrics.cc", + "metrics/begin_main_frame_metrics.h", "metrics/compositor_frame_reporter.cc", "metrics/compositor_frame_reporter.h", "metrics/compositor_frame_reporting_controller.cc",
diff --git a/cc/metrics/begin_main_frame_metrics.cc b/cc/metrics/begin_main_frame_metrics.cc new file mode 100644 index 0000000..d4e83ead --- /dev/null +++ b/cc/metrics/begin_main_frame_metrics.cc
@@ -0,0 +1,11 @@ +// 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 "cc/metrics/begin_main_frame_metrics.h" + +namespace cc { + +BeginMainFrameMetrics::BeginMainFrameMetrics() = default; + +} // namespace cc
diff --git a/cc/metrics/begin_main_frame_metrics.h b/cc/metrics/begin_main_frame_metrics.h new file mode 100644 index 0000000..2927360 --- /dev/null +++ b/cc/metrics/begin_main_frame_metrics.h
@@ -0,0 +1,35 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_METRICS_BEGIN_MAIN_FRAME_METRICS_H_ +#define CC_METRICS_BEGIN_MAIN_FRAME_METRICS_H_ + +#include "base/time/time.h" +#include "cc/cc_export.h" + +namespace cc { + +// Latency timing data for Main Frame lifecycle updates triggered by cc. +// The data is captured in LocalFrameViewUKMAggregator and passed back through +// the proxy when a main frame ends. LayerTreeHost updates the update_layers_ +// value in LayerTreeHost::UpdateLayers. +// TODO(schenney): Include work done in LayerTreeHost::AnimateLayers? +struct CC_EXPORT BeginMainFrameMetrics { + base::TimeDelta handle_input_events; + base::TimeDelta animate; + base::TimeDelta style_update; + base::TimeDelta layout_update; + base::TimeDelta prepaint; + base::TimeDelta composite; + base::TimeDelta paint; + base::TimeDelta scrolling_coordinator; + base::TimeDelta composite_commit; + base::TimeDelta update_layers; + + BeginMainFrameMetrics(); +}; + +} // namespace cc + +#endif // CC_METRICS_BEGIN_MAIN_FRAME_METRICS_H_
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index ebc3206d..c5fb67f 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc
@@ -26,6 +26,7 @@ #include "cc/input/input_handler.h" #include "cc/layers/layer.h" #include "cc/layers/layer_impl.h" +#include "cc/metrics/begin_main_frame_metrics.h" #include "cc/metrics/compositor_timing_history.h" #include "cc/test/animation_test_common.h" #include "cc/test/fake_compositor_frame_reporting_controller.h" @@ -401,6 +402,9 @@ void RecordStartOfFrameMetrics() override {} void RecordEndOfFrameMetrics(base::TimeTicks) override {} + std::unique_ptr<BeginMainFrameMetrics> GetBeginMainFrameMetrics() override { + return nullptr; + } void UpdateLayerTreeHost() override { test_hooks_->UpdateLayerTreeHost(); }
diff --git a/cc/test/stub_layer_tree_host_client.cc b/cc/test/stub_layer_tree_host_client.cc index 650faaf..f7bd15e 100644 --- a/cc/test/stub_layer_tree_host_client.cc +++ b/cc/test/stub_layer_tree_host_client.cc
@@ -4,8 +4,15 @@ #include "cc/test/stub_layer_tree_host_client.h" +#include "cc/metrics/begin_main_frame_metrics.h" + namespace cc { StubLayerTreeHostClient::~StubLayerTreeHostClient() = default; +std::unique_ptr<BeginMainFrameMetrics> +StubLayerTreeHostClient::GetBeginMainFrameMetrics() { + return nullptr; +} + } // namespace cc
diff --git a/cc/test/stub_layer_tree_host_client.h b/cc/test/stub_layer_tree_host_client.h index 3eabe45..1445f542 100644 --- a/cc/test/stub_layer_tree_host_client.h +++ b/cc/test/stub_layer_tree_host_client.h
@@ -22,9 +22,9 @@ void BeginMainFrame(const viz::BeginFrameArgs& args) override {} void OnDeferMainFrameUpdatesChanged(bool) override {} void OnDeferCommitsChanged(bool) override {} - void RecordStartOfFrameMetrics() override {} void RecordEndOfFrameMetrics(base::TimeTicks) override {} + std::unique_ptr<BeginMainFrameMetrics> GetBeginMainFrameMetrics() override; void BeginMainFrameNotExpectedSoon() override {} void BeginMainFrameNotExpectedUntil(base::TimeTicks time) override {} void UpdateLayerTreeHost() override {}
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 47e6061..4020cb88 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -291,8 +291,12 @@ return debug_state_; } -void LayerTreeHost::RequestMainFrameUpdate() { +void LayerTreeHost::RequestMainFrameUpdate(bool report_cc_metrics) { client_->UpdateLayerTreeHost(); + if (report_cc_metrics) + begin_main_frame_metrics_ = client_->GetBeginMainFrameMetrics(); + else + begin_main_frame_metrics_.reset(); } // This function commits the LayerTreeHost to an impl tree. When modifying @@ -678,7 +682,7 @@ DCHECK(IsSingleThreaded()); // This function is only valid when not using the scheduler. DCHECK(!settings_.single_thread_proxy_scheduler); - RequestMainFrameUpdate(); + RequestMainFrameUpdate(false); UpdateLayers(); } @@ -704,8 +708,11 @@ client_->DidUpdateLayers(); micro_benchmark_controller_.DidUpdateLayers(); + base::TimeDelta elapsed_delta = timer.Elapsed(); + if (begin_main_frame_metrics_) + begin_main_frame_metrics_->update_layers = elapsed_delta; if (const char* client_name = GetClientNameForMetrics()) { - auto elapsed = timer.Elapsed().InMicroseconds(); + auto elapsed = elapsed_delta.InMicroseconds(); std::string histogram_name = base::StringPrintf("Compositing.%s.LayersUpdateTime", client_name);
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index af65ef80..95936f7 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h
@@ -33,6 +33,7 @@ #include "cc/input/scrollbar.h" #include "cc/layers/layer_collections.h" #include "cc/layers/layer_list_iterator.h" +#include "cc/metrics/begin_main_frame_metrics.h" #include "cc/paint/node_id.h" #include "cc/trees/compositor_mode.h" #include "cc/trees/layer_tree_frame_sink.h" @@ -567,7 +568,7 @@ void BeginMainFrameNotExpectedSoon(); void BeginMainFrameNotExpectedUntil(base::TimeTicks time); void AnimateLayers(base::TimeTicks monotonic_frame_begin_time); - void RequestMainFrameUpdate(); + void RequestMainFrameUpdate(bool report_cc_metrics); void FinishCommitOnImplThread(LayerTreeHostImpl* host_impl); void WillCommit(); void CommitComplete(); @@ -876,6 +877,12 @@ // added here. std::vector<PresentationTimeCallback> pending_presentation_time_callbacks_; + // Latency information for work done in ProxyMain::BeginMainFrame. The + // unique_ptr is allocated in RequestMainFrameUpdate, and passed to Blink's + // LocalFrameView that fills in the fields. This object adds the timing for + // UpdateLayers. CC reads the data during commit, and clears the unique_ptr. + std::unique_ptr<BeginMainFrameMetrics> begin_main_frame_metrics_; + // Used to vend weak pointers to LayerTreeHost to ScopedDeferMainFrameUpdate // objects. base::WeakPtrFactory<LayerTreeHost> defer_main_frame_update_weak_ptr_factory_{
diff --git a/cc/trees/layer_tree_host_client.h b/cc/trees/layer_tree_host_client.h index 7f424be..40ade06 100644 --- a/cc/trees/layer_tree_host_client.h +++ b/cc/trees/layer_tree_host_client.h
@@ -22,6 +22,7 @@ } namespace cc { +struct BeginMainFrameMetrics; struct ElementId; struct ApplyViewportChangesArgs { @@ -149,6 +150,13 @@ // the time from the start of BeginMainFrame to the Commit, or early out. virtual void RecordStartOfFrameMetrics() = 0; virtual void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) = 0; + // Return metrics information for the stages of BeginMainFrame. This is + // ultimately implemented by Blink's LocalFrameUKMAggregator. It must be a + // distinct call from the FrameMetrics above because the BeginMainFrameMetrics + // for compositor latency must be gathered before the layer tree is + // committed to the compositor, which is before the call to + // RecordEndOfFrameMetrics. + virtual std::unique_ptr<BeginMainFrameMetrics> GetBeginMainFrameMetrics() = 0; protected: virtual ~LayerTreeHostClient() {}
diff --git a/cc/trees/proxy_main.cc b/cc/trees/proxy_main.cc index 1205949b..2aaa7e2 100644 --- a/cc/trees/proxy_main.cc +++ b/cc/trees/proxy_main.cc
@@ -217,6 +217,13 @@ } layer_tree_host_->WillBeginMainFrame(); + + // This call winds through to the LocalFrameView to mark the beginning + // of a main frame for metrics purposes. Some metrics are only gathered + // between calls to RecordStartOfFrameMetrics and RecordEndOfFrameMetrics. + // This is not wrapped into layer_tree_host_->WillBeginMainFrame because + // it should only be called from the multi-threaded proxy (we do not want + // metrics gathering in tests). layer_tree_host_->RecordStartOfFrameMetrics(); // See LayerTreeHostClient::BeginMainFrame for more documentation on @@ -236,7 +243,7 @@ // See LayerTreeHostClient::MainFrameUpdate for more documentation on // what this does. - layer_tree_host_->RequestMainFrameUpdate(); + layer_tree_host_->RequestMainFrameUpdate(true /* report_cc_metrics */); // At this point the main frame may have deferred main frame updates to // avoid committing right now, or we may be deferring commits but not
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc index 39a7888d..13279a0 100644 --- a/cc/trees/single_thread_proxy.cc +++ b/cc/trees/single_thread_proxy.cc
@@ -859,7 +859,7 @@ layer_tree_host_->WillBeginMainFrame(); layer_tree_host_->BeginMainFrame(begin_frame_args); layer_tree_host_->AnimateLayers(begin_frame_args.frame_time); - layer_tree_host_->RequestMainFrameUpdate(); + layer_tree_host_->RequestMainFrameUpdate(false /* record_cc_metrics */); } void SingleThreadProxy::DoPainting() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java index 7de0777..6839d423 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java
@@ -40,8 +40,8 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper; -import org.chromium.chrome.browser.util.AccessibilityUtil; import org.chromium.chrome.browser.widget.ViewHighlighter; +import org.chromium.ui.widget.Toast; import java.util.ArrayList; import java.util.List; @@ -412,7 +412,7 @@ ? resources.getString(R.string.menu_refresh) : resources.getString(R.string.menu_stop_refresh); } - return AccessibilityUtil.showAccessibilityToast(context, view, description); + return Toast.showAnchoredToast(context, view, description); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java index c8adedc..dc409ee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusView.java
@@ -32,8 +32,8 @@ import org.chromium.chrome.browser.omnibox.SearchEngineLogoUtils; import org.chromium.chrome.browser.toolbar.ToolbarCommonPropertiesModel; import org.chromium.chrome.browser.ui.widget.CompositeTouchDelegate; -import org.chromium.chrome.browser.util.AccessibilityUtil; import org.chromium.ui.UiUtils; +import org.chromium.ui.widget.Toast; /** * StatusView is a location bar's view displaying status (icons and/or text). @@ -252,7 +252,7 @@ public boolean onLongClick(View view) { if (mAccessibilityToast == 0) return false; Context context = getContext(); - return AccessibilityUtil.showAccessibilityToast( + return Toast.showAnchoredToast( context, view, context.getResources().getString(mAccessibilityToast)); } };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java index 450b8caa..bf356dd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/ChromeGcmListenerService.java
@@ -14,7 +14,6 @@ import com.google.android.gms.gcm.GcmListenerService; import com.google.ipc.invalidation.ticl.android2.channel.AndroidGcmController; -import org.chromium.base.ApplicationStatus; import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.ThreadUtils; @@ -129,7 +128,7 @@ * the next time Chrome is launched into foreground. */ private static boolean maybePersistLazyMessage(GCMMessage message) { - if (ApplicationStatus.hasVisibleActivities()) { + if (isNativeLoaded()) { return false; } @@ -236,4 +235,9 @@ System.exit(-1); } } + + private static boolean isNativeLoaded() { + return ChromeBrowserInitializer.getInstance(ContextUtils.getApplicationContext()) + .hasNativeInitializationCompleted(); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java index f9e68e8..4d31065 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java
@@ -26,9 +26,9 @@ /** * JNI wrapper for the native ProfileSyncService. * - * This class purely makes calls to native and contains absolutely no business logic. It is only + * This class mostly makes calls to native and contains a minimum of business logic. It is only * usable from the UI thread as the native ProfileSyncService requires its access to be on the - * UI thread. See chrome/browser/sync/profile_sync_service.h for more details. + * UI thread. See components/sync/driver/profile_sync_service.h for more details. */ public class ProfileSyncService { @@ -40,34 +40,6 @@ public void syncStateChanged(); } - /** - * Callback for getAllNodes. - */ - public static class GetAllNodesCallback { - private String mNodesString; - - // Invoked when getAllNodes completes. - public void onResult(String nodesString) { - mNodesString = nodesString; - } - - // Returns the result of GetAllNodes as a JSONArray. - @VisibleForTesting - public JSONArray getNodesAsJsonArray() throws JSONException { - return new JSONArray(mNodesString); - } - } - - /** - * Provider for the Android master sync flag. - */ - interface MasterSyncEnabledProvider { - // Returns whether master sync is enabled. - public boolean isMasterSyncEnabled(); - } - - private static final String TAG = "ProfileSyncService"; - private static final int[] ALL_SELECTABLE_TYPES = new int[] { ModelType.AUTOFILL, ModelType.BOOKMARKS, @@ -90,11 +62,6 @@ */ private long mNativeProfileSyncServiceAndroid; - /** - * An object that knows whether Android's master sync setting is enabled. - */ - private MasterSyncEnabledProvider mMasterSyncEnabledProvider; - private int mSetupInProgressCounter; /** @@ -148,7 +115,7 @@ ThreadUtils.assertOnUiThread(); // This may cause us to create ProfileSyncService even if sync has not - // been set up, but ProfileSyncService::Startup() won't be called until + // been set up, but ProfileSyncService won't actually start until // credentials are available. mNativeProfileSyncServiceAndroid = ProfileSyncServiceJni.get().init(ProfileSyncService.this); @@ -160,105 +127,9 @@ } /** - * Sets the the machine tag used by session sync. - */ - public void setSessionsId(String sessionTag) { - ThreadUtils.assertOnUiThread(); - ProfileSyncServiceJni.get().setSyncSessionsId( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this, sessionTag); - } - - /** - * Returns the actual passphrase type being used for encryption. The sync engine must be - * running (isEngineInitialized() returns true) before calling this function. - * <p/> - * This method should only be used if you want to know the raw value. For checking whether - * we should ask the user for a passphrase, use isPassphraseRequiredForDecryption(). - */ - public @Passphrase.Type int getPassphraseType() { - assert isEngineInitialized(); - int passphraseType = ProfileSyncServiceJni.get().getPassphraseType( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - if (passphraseType < 0 || passphraseType >= Passphrase.Type.NUM_ENTRIES) { - throw new IllegalArgumentException(); - } - return passphraseType; - } - - /** - * Returns true if the current explicit passphrase time is defined. - */ - public boolean hasExplicitPassphraseTime() { - assert isEngineInitialized(); - return ProfileSyncServiceJni.get().hasExplicitPassphraseTime( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - - /** - * Returns the current explicit passphrase time in milliseconds since epoch. - */ - public long getExplicitPassphraseTime() { - assert isEngineInitialized(); - return ProfileSyncServiceJni.get().getExplicitPassphraseTime( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - - public String getSyncEnterGooglePassphraseBodyWithDateText() { - assert isEngineInitialized(); - return ProfileSyncServiceJni.get().getSyncEnterGooglePassphraseBodyWithDateText( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - - public String getSyncEnterCustomPassphraseBodyWithDateText() { - assert isEngineInitialized(); - return ProfileSyncServiceJni.get().getSyncEnterCustomPassphraseBodyWithDateText( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - - public String getCurrentSignedInAccountText() { - assert isEngineInitialized(); - return ProfileSyncServiceJni.get().getCurrentSignedInAccountText( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - - public String getSyncEnterCustomPassphraseBodyText() { - return ProfileSyncServiceJni.get().getSyncEnterCustomPassphraseBodyText( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - - public int getNumberOfSyncedDevices() { - return ProfileSyncServiceJni.get().getNumberOfSyncedDevices( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - - /** - * Checks if sync is currently set to use a custom passphrase. The sync engine must be running - * (isEngineInitialized() returns true) before calling this function. + * Checks if the sync engine is initialized. * - * @return true if sync is using a custom passphrase. - */ - public boolean isUsingSecondaryPassphrase() { - assert isEngineInitialized(); - return ProfileSyncServiceJni.get().isUsingSecondaryPassphrase( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - - /** - * Checks if we need a passphrase to decrypt a currently-enabled data type. This returns false - * if a passphrase is needed for a type that is not currently enabled. - * - * @return true if we need a passphrase. - */ - public boolean isPassphraseRequiredForDecryption() { - assert isEngineInitialized(); - return ProfileSyncServiceJni.get().isPassphraseRequiredForDecryption( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - - /** - * Checks if the sync engine is running. - * - * @return true if sync is initialized/running. + * @return true if the sync engine is initialized. */ public boolean isEngineInitialized() { return ProfileSyncServiceJni.get().isEngineInitialized( @@ -266,51 +137,28 @@ } /** - * Checks if encrypting all the data types is allowed. + * Checks whether Sync-the-feature can (attempt to) start. This means that there is a primary + * account and no disable reasons. Note that the Sync machinery may start up in transport-only + * mode even if this is false. * - * @return true if encrypting all data types is allowed, false if only passwords are allowed to - * be encrypted. + * @return true if Sync can start, false otherwise. */ - public boolean isEncryptEverythingAllowed() { - assert isEngineInitialized(); - return ProfileSyncServiceJni.get().isEncryptEverythingAllowed( + public boolean canSyncFeatureStart() { + return ProfileSyncServiceJni.get().canSyncFeatureStart( mNativeProfileSyncServiceAndroid, ProfileSyncService.this); } /** - * Checks if the user has chosen to encrypt all data types. Note that some data types (e.g. - * DEVICE_INFO) are never encrypted. + * Checks whether Sync-the-feature is currently active. Note that Sync-the-transport may be + * active even if this is false. * - * @return true if all data types are encrypted, false if only passwords are encrypted. + * @return true if Sync is active, false otherwise. */ - public boolean isEncryptEverythingEnabled() { - assert isEngineInitialized(); - return ProfileSyncServiceJni.get().isEncryptEverythingEnabled( + public boolean isSyncActive() { + return ProfileSyncServiceJni.get().isSyncActive( mNativeProfileSyncServiceAndroid, ProfileSyncService.this); } - /** - * Turns on encryption of all data types. This only takes effect after sync configuration is - * completed and setChosenDataTypes() is invoked. - */ - public void enableEncryptEverything() { - assert isEngineInitialized(); - ProfileSyncServiceJni.get().enableEncryptEverything( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - - public void setEncryptionPassphrase(String passphrase) { - assert isEngineInitialized(); - ProfileSyncServiceJni.get().setEncryptionPassphrase( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this, passphrase); - } - - public boolean setDecryptionPassphrase(String passphrase) { - assert isEngineInitialized(); - return ProfileSyncServiceJni.get().setDecryptionPassphrase( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this, passphrase); - } - public @GoogleServiceAuthError.State int getAuthError() { int authErrorCode = ProfileSyncServiceJni.get().getAuthError( mNativeProfileSyncServiceAndroid, ProfileSyncService.this); @@ -320,12 +168,42 @@ return authErrorCode; } + /** + * Checks whether Sync is disabled by enterprise policy (through prefs) or account policy + * received from the sync server. + * + * @return true if Sync is disabled, false otherwise. + */ + public boolean isSyncDisabledByEnterprisePolicy() { + return ProfileSyncServiceJni.get().isSyncDisabledByEnterprisePolicy( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + + public boolean hasUnrecoverableError() { + return ProfileSyncServiceJni.get().hasUnrecoverableError( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + public boolean requiresClientUpgrade() { return ProfileSyncServiceJni.get().requiresClientUpgrade( mNativeProfileSyncServiceAndroid, ProfileSyncService.this); } /** + * Gets the set of data types that are "preferred" in sync. Those are the + * chosen ones (see getChosenDataTypes), plus any that are implied by them. + * + * This is unaffected by whether sync is on. + * + * @return Set of preferred data types. + */ + public Set<Integer> getPreferredDataTypes() { + int[] modelTypeArray = ProfileSyncServiceJni.get().getPreferredDataTypes( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + return modelTypeArrayToSet(modelTypeArray); + } + + /** * Gets the set of data types that are currently syncing. * * This is affected by whether sync is on. @@ -352,37 +230,6 @@ return modelTypeArrayToSet(modelTypeArray); } - /** - * Gets the set of data types that are "preferred" in sync. Those are the - * "chosen" ones (see above), plus any that are implied by them. - * - * This is unaffected by whether sync is on. - * - * @return Set of preferred types. - */ - public Set<Integer> getPreferredDataTypes() { - int[] modelTypeArray = ProfileSyncServiceJni.get().getPreferredDataTypes( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - return modelTypeArrayToSet(modelTypeArray); - } - - private static Set<Integer> modelTypeArrayToSet(int[] modelTypeArray) { - Set<Integer> modelTypeSet = new HashSet<Integer>(); - for (int i = 0; i < modelTypeArray.length; i++) { - modelTypeSet.add(modelTypeArray[i]); - } - return modelTypeSet; - } - - private static int[] modelTypeSetToArray(Set<Integer> modelTypeSet) { - int[] modelTypeArray = new int[modelTypeSet.size()]; - int i = 0; - for (int modelType : modelTypeSet) { - modelTypeArray[i++] = modelType; - } - return modelTypeArray; - } - public boolean hasKeepEverythingSynced() { return ProfileSyncServiceJni.get().hasKeepEverythingSynced( mNativeProfileSyncServiceAndroid, ProfileSyncService.this); @@ -402,11 +249,6 @@ syncEverything ? ALL_SELECTABLE_TYPES : modelTypeSetToArray(enabledTypes)); } - public void triggerRefresh() { - ProfileSyncServiceJni.get().triggerRefresh( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - public void setFirstSetupComplete(int syncFirstSetupCompleteSource) { ProfileSyncServiceJni.get().setFirstSetupComplete(mNativeProfileSyncServiceAndroid, ProfileSyncService.this, syncFirstSetupCompleteSource); @@ -417,6 +259,16 @@ mNativeProfileSyncServiceAndroid, ProfileSyncService.this); } + public void requestStart() { + ProfileSyncServiceJni.get().requestStart( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + + public void requestStop() { + ProfileSyncServiceJni.get().requestStop( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + /** * Checks whether syncing is requested by the user, i.e. the user has at least started a Sync * setup flow, and has not disabled syncing in settings. Note that even if this is true, other @@ -430,40 +282,6 @@ } /** - * Checks whether Sync-the-feature can (attempt to) start. This means that there is a primary - * account and no disable reasons. Note that the Sync machinery may start up in transport-only - * mode even if this is false. - * - * @return true if Sync can start, false otherwise. - */ - public boolean canSyncFeatureStart() { - return ProfileSyncServiceJni.get().canSyncFeatureStart( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - - /** - * Checks whether Sync-the-feature is currently active. Note that Sync-the-transport may be - * active even if this is false. - * - * @return true if Sync is active, false otherwise. - */ - public boolean isSyncActive() { - return ProfileSyncServiceJni.get().isSyncActive( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - - /** - * Checks whether Sync is disabled by enterprise policy (through prefs) or account policy - * received from the sync server. - * - * @return true if Sync is disabled, false otherwise. - */ - public boolean isSyncDisabledByEnterprisePolicy() { - return ProfileSyncServiceJni.get().isSyncDisabledByEnterprisePolicy( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - - /** * Instances of this class keep sync paused until {@link #close} is called. Use * {@link ProfileSyncService#getSetupInProgressHandle} to create. Please note that * {@link #close} should be called on every instance of this class. @@ -523,45 +341,25 @@ mListeners.remove(listener); } - public boolean hasUnrecoverableError() { - return ProfileSyncServiceJni.get().hasUnrecoverableError( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - /** * Called when the state of the native sync engine has changed, so various * UI elements can update themselves. */ @CalledByNative + @VisibleForTesting public void syncStateChanged() { for (SyncStateChangedListener listener : mListeners) { listener.syncStateChanged(); } } - /** - * Starts the sync engine. - */ - public void requestStart() { - ProfileSyncServiceJni.get().requestStart( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - - /** - * Stops the sync engine. - */ - public void requestStop() { - ProfileSyncServiceJni.get().requestStop( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this); - } - public void setSyncAllowedByPlatform(boolean allowed) { ProfileSyncServiceJni.get().setSyncAllowedByPlatform( mNativeProfileSyncServiceAndroid, ProfileSyncService.this, allowed); } /** - * Flushes the sync directory. + * Flushes the sync directory to disk. */ public void flushDirectory() { ProfileSyncServiceJni.get().flushDirectory( @@ -569,29 +367,131 @@ } /** - * Returns the time when the last sync cycle was completed. - * - * @return The difference measured in microseconds, between last sync cycle completion time - * and 1 January 1970 00:00:00 UTC. + * Returns the actual passphrase type being used for encryption. The sync engine must be + * running (isEngineInitialized() returns true) before calling this function. + * <p/> + * This method should only be used if you want to know the raw value. For checking whether + * we should ask the user for a passphrase, use isPassphraseRequiredForDecryption(). */ - @VisibleForTesting - public long getLastSyncedTimeForTest() { - return ProfileSyncServiceJni.get().getLastSyncedTimeForTest( + public @Passphrase.Type int getPassphraseType() { + assert isEngineInitialized(); + int passphraseType = ProfileSyncServiceJni.get().getPassphraseType( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + if (passphraseType < 0 || passphraseType >= Passphrase.Type.NUM_ENTRIES) { + throw new IllegalArgumentException(); + } + return passphraseType; + } + + /** + * Returns true if the current explicit passphrase time is defined. + */ + public boolean hasExplicitPassphraseTime() { + assert isEngineInitialized(); + return ProfileSyncServiceJni.get().hasExplicitPassphraseTime( mNativeProfileSyncServiceAndroid, ProfileSyncService.this); } /** - * Overrides the Sync engine's NetworkResources. This is used to set up the Sync FakeServer for - * testing. - * - * @param networkResources the pointer to the NetworkResources created by the native code. It - * is assumed that the Java caller has ownership of this pointer; - * ownership is transferred as part of this call. + * Returns the current explicit passphrase time in milliseconds since epoch. */ - @VisibleForTesting - public void overrideNetworkResourcesForTest(long networkResources) { - ProfileSyncServiceJni.get().overrideNetworkResourcesForTest( - mNativeProfileSyncServiceAndroid, ProfileSyncService.this, networkResources); + public long getExplicitPassphraseTime() { + assert isEngineInitialized(); + return ProfileSyncServiceJni.get().getExplicitPassphraseTime( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + + public String getSyncEnterGooglePassphraseBodyWithDateText() { + assert isEngineInitialized(); + return ProfileSyncServiceJni.get().getSyncEnterGooglePassphraseBodyWithDateText( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + + public String getSyncEnterCustomPassphraseBodyWithDateText() { + assert isEngineInitialized(); + return ProfileSyncServiceJni.get().getSyncEnterCustomPassphraseBodyWithDateText( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + + public String getCurrentSignedInAccountText() { + assert isEngineInitialized(); + return ProfileSyncServiceJni.get().getCurrentSignedInAccountText( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + + public String getSyncEnterCustomPassphraseBodyText() { + return ProfileSyncServiceJni.get().getSyncEnterCustomPassphraseBodyText( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + + /** + * Checks if sync is currently set to use a custom passphrase. The sync engine must be running + * (isEngineInitialized() returns true) before calling this function. + * + * @return true if sync is using a custom passphrase. + */ + public boolean isUsingSecondaryPassphrase() { + assert isEngineInitialized(); + return ProfileSyncServiceJni.get().isUsingSecondaryPassphrase( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + + /** + * Checks if we need a passphrase to decrypt a currently-enabled data type. This returns false + * if a passphrase is needed for a type that is not currently enabled. + * + * @return true if we need a passphrase. + */ + public boolean isPassphraseRequiredForDecryption() { + assert isEngineInitialized(); + return ProfileSyncServiceJni.get().isPassphraseRequiredForDecryption( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + + /** + * Checks if encrypting all the data types is allowed. + * + * @return true if encrypting all data types is allowed, false if only passwords are allowed to + * be encrypted. + */ + public boolean isEncryptEverythingAllowed() { + assert isEngineInitialized(); + return ProfileSyncServiceJni.get().isEncryptEverythingAllowed( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + + /** + * Checks if the user has chosen to encrypt all data types. Note that some data types (e.g. + * DEVICE_INFO) are never encrypted. + * + * @return true if all data types are encrypted, false if only passwords are encrypted. + */ + public boolean isEncryptEverythingEnabled() { + assert isEngineInitialized(); + return ProfileSyncServiceJni.get().isEncryptEverythingEnabled( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + + /** + * Turns on encryption of all data types. This only takes effect after sync configuration is + * completed and setChosenDataTypes() is invoked. + */ + public void enableEncryptEverything() { + assert isEngineInitialized(); + ProfileSyncServiceJni.get().enableEncryptEverything( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + + public void setEncryptionPassphrase(String passphrase) { + assert isEngineInitialized(); + ProfileSyncServiceJni.get().setEncryptionPassphrase( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this, passphrase); + } + + public boolean setDecryptionPassphrase(String passphrase) { + assert isEngineInitialized(); + return ProfileSyncServiceJni.get().setDecryptionPassphrase( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this, passphrase); } /** @@ -621,27 +521,72 @@ } /** - * Set the MasterSyncEnabledProvider for ProfileSyncService. - * - * This method is intentionally package-scope and should only be called once. + * Sets the the machine tag used by session sync. */ - void setMasterSyncEnabledProvider(MasterSyncEnabledProvider masterSyncEnabledProvider) { + public void setSessionsId(String sessionTag) { ThreadUtils.assertOnUiThread(); - assert mMasterSyncEnabledProvider == null; - mMasterSyncEnabledProvider = masterSyncEnabledProvider; + ProfileSyncServiceJni.get().setSyncSessionsId( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this, sessionTag); } /** - * Returns whether Android's master sync setting is enabled. + * Gets the number of devices known to sync. + * + * @return number of syncing devices */ - @CalledByNative - public boolean isMasterSyncEnabled() { - ThreadUtils.assertOnUiThread(); - // TODO(maxbogue): ensure that this method is never called before - // setMasterSyncEnabledProvider() and change the line below to an assert. - // See http://crbug.com/570569 - if (mMasterSyncEnabledProvider == null) return true; - return mMasterSyncEnabledProvider.isMasterSyncEnabled(); + public int getNumberOfSyncedDevices() { + return ProfileSyncServiceJni.get().getNumberOfSyncedDevices( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + + /** + * Returns the time when the last sync cycle was completed. + * + * @return The difference measured in microseconds, between last sync cycle completion time + * and 1 January 1970 00:00:00 UTC. + */ + @VisibleForTesting + public long getLastSyncedTimeForTest() { + return ProfileSyncServiceJni.get().getLastSyncedTimeForTest( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + + /** + * Overrides the Sync engine's NetworkResources. This is used to set up the Sync FakeServer for + * testing. + * + * @param networkResources the pointer to the NetworkResources created by the native code. It + * is assumed that the Java caller has ownership of this pointer; + * ownership is transferred as part of this call. + */ + @VisibleForTesting + public void overrideNetworkResourcesForTest(long networkResources) { + ProfileSyncServiceJni.get().overrideNetworkResourcesForTest( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this, networkResources); + } + + @VisibleForTesting + public void triggerRefresh() { + ProfileSyncServiceJni.get().triggerRefresh( + mNativeProfileSyncServiceAndroid, ProfileSyncService.this); + } + + /** + * Callback for getAllNodes. + */ + public static class GetAllNodesCallback { + private String mNodesString; + + // Invoked when getAllNodes completes. + public void onResult(String nodesString) { + mNodesString = nodesString; + } + + // Returns the result of GetAllNodes as a JSONArray. + @VisibleForTesting + public JSONArray getNodesAsJsonArray() throws JSONException { + return new JSONArray(mNodesString); + } } /** @@ -662,6 +607,23 @@ mNativeProfileSyncServiceAndroid, ProfileSyncService.this, callback); } + private static Set<Integer> modelTypeArrayToSet(int[] modelTypeArray) { + Set<Integer> modelTypeSet = new HashSet<Integer>(); + for (int i = 0; i < modelTypeArray.length; i++) { + modelTypeSet.add(modelTypeArray[i]); + } + return modelTypeSet; + } + + private static int[] modelTypeSetToArray(Set<Integer> modelTypeSet) { + int[] modelTypeArray = new int[modelTypeSet.size()]; + int i = 0; + for (int modelType : modelTypeSet) { + modelTypeArray[i++] = modelType; + } + return modelTypeArray; + } + @NativeMethods interface Natives { long init(ProfileSyncService caller);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java index 417d4e8..7bab384f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncController.java
@@ -74,13 +74,6 @@ AndroidSyncSettings.get().registerObserver(this); mProfileSyncService = ProfileSyncService.get(); mProfileSyncService.addSyncStateChangedListener(this); - mProfileSyncService.setMasterSyncEnabledProvider( - new ProfileSyncService.MasterSyncEnabledProvider() { - @Override - public boolean isMasterSyncEnabled() { - return AndroidSyncSettings.get().isMasterSyncEnabled(); - } - }); setSessionsId();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/NewTabButton.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/NewTabButton.java index 74208d5..98d401531 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/NewTabButton.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/NewTabButton.java
@@ -18,10 +18,10 @@ import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.device.DeviceClassManager; import org.chromium.chrome.browser.toolbar.IncognitoStateProvider.IncognitoStateObserver; -import org.chromium.chrome.browser.util.AccessibilityUtil; import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.ui.base.DeviceFormFactor; import org.chromium.ui.widget.ChromeImageButton; +import org.chromium.ui.widget.Toast; /** * Button for creating new tabs. @@ -55,7 +55,7 @@ CharSequence description = getResources().getString(mIsIncognito ? org.chromium.chrome.R.string.button_new_incognito_tab : org.chromium.chrome.R.string.button_new_tab); - return AccessibilityUtil.showAccessibilityToast(getContext(), v, description); + return Toast.showAnchoredToast(getContext(), v, description); } public void setIncognitoStateProvider(IncognitoStateProvider incognitoStateProvider) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java index 9becd72b..99272c8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/TabSwitcherButtonCoordinator.java
@@ -15,9 +15,9 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver; import org.chromium.chrome.browser.toolbar.TabCountProvider.TabCountObserver; -import org.chromium.chrome.browser.util.AccessibilityUtil; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; +import org.chromium.ui.widget.Toast; /** * The controller for the tab switcher button. This class handles all interactions that the tab @@ -53,7 +53,7 @@ CharSequence description = root.getResources().getString(R.string.open_tabs); mTabSwitcherButtonModel.set(TabSwitcherButtonProperties.ON_LONG_CLICK_LISTENER, - v -> AccessibilityUtil.showAccessibilityToast(root.getContext(), v, description)); + v -> Toast.showAnchoredToast(root.getContext(), v, description)); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java index ea755221..eabdc4c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java
@@ -60,7 +60,6 @@ import org.chromium.chrome.browser.toolbar.ToolbarDataProvider; import org.chromium.chrome.browser.toolbar.ToolbarTabController; import org.chromium.chrome.browser.ui.widget.TintedDrawable; -import org.chromium.chrome.browser.util.AccessibilityUtil; import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.components.url_formatter.UrlFormatter; import org.chromium.content_public.browser.UiThreadTaskTraits; @@ -72,6 +71,7 @@ import org.chromium.ui.interpolators.BakedBezierInterpolator; import org.chromium.ui.text.SpanApplier; import org.chromium.ui.text.SpanApplier.SpanInfo; +import org.chromium.ui.widget.Toast; import java.util.List; import java.util.regex.Pattern; @@ -520,8 +520,7 @@ @Override public boolean onLongClick(View v) { if (v == mCloseButton || v.getParent() == mCustomActionButtons) { - return AccessibilityUtil.showAccessibilityToast( - getContext(), v, v.getContentDescription()); + return Toast.showAnchoredToast(getContext(), v, v.getContentDescription()); } if (v == mTitleUrlContainer) { Tab tab = getCurrentTab();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButton.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButton.java index a1b9456..5173d896 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButton.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButton.java
@@ -13,8 +13,8 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.toolbar.TabCountProvider; import org.chromium.chrome.browser.toolbar.TabSwitcherDrawable; -import org.chromium.chrome.browser.util.AccessibilityUtil; import org.chromium.ui.widget.ChromeImageButton; +import org.chromium.ui.widget.Toast; /** * A button displaying the number of open tabs. Clicking the button toggles the tab switcher view. @@ -114,7 +114,7 @@ } else { CharSequence description = getResources().getString(org.chromium.chrome.R.string.open_tabs); - return AccessibilityUtil.showAccessibilityToast(getContext(), v, description); + return Toast.showAnchoredToast(getContext(), v, description); } } } \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java index 2577f6eb..e8b3f1c7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java
@@ -43,6 +43,7 @@ import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.ui.UiUtils; import org.chromium.ui.base.DeviceFormFactor; +import org.chromium.ui.widget.Toast; import java.util.ArrayList; import java.util.Collection; @@ -344,7 +345,7 @@ } else if (v == mSaveOfflineButton) { description = resources.getString(R.string.menu_download); } - return AccessibilityUtil.showAccessibilityToast(context, v, description); + return Toast.showAnchoredToast(context, v, description); } private void updateSwitcherButtonVisibility(boolean enabled) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java index 3c8d25f1..b457e3ee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/util/AccessibilityUtil.java
@@ -5,12 +5,9 @@ package org.chromium.chrome.browser.util; import android.accessibilityservice.AccessibilityServiceInfo; -import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.os.Build; -import android.view.Gravity; -import android.view.View; import android.view.accessibility.AccessibilityManager; import org.chromium.base.ActivityState; @@ -18,7 +15,6 @@ import org.chromium.base.ApplicationStatus.ActivityStateListener; import org.chromium.base.ContextUtils; import org.chromium.base.TraceEvent; -import org.chromium.ui.widget.Toast; import java.util.List; @@ -110,37 +106,4 @@ } return false; } - - /** - * Shows the content description toast for items on the toolbar. - * @param context The context to use for the toast. - * @param view The view to anchor the toast. - * @param description The string shown in the toast. - * @return Whether a toast has been shown successfully. - */ - @SuppressLint("RtlHardcoded") - public static boolean showAccessibilityToast( - Context context, View view, CharSequence description) { - if (description == null) return false; - - final int screenWidth = context.getResources().getDisplayMetrics().widthPixels; - final int screenHeight = context.getResources().getDisplayMetrics().heightPixels; - final int[] screenPos = new int[2]; - view.getLocationOnScreen(screenPos); - final int width = view.getWidth(); - final int height = view.getHeight(); - - final int horizontalGravity = - (screenPos[0] < screenWidth / 2) ? Gravity.LEFT : Gravity.RIGHT; - final int xOffset = (screenPos[0] < screenWidth / 2) - ? screenPos[0] + width / 2 - : screenWidth - screenPos[0] - width / 2; - final int yOffset = (screenPos[1] < screenHeight / 2) ? screenPos[1] + height / 2 - : screenPos[1] - height * 3 / 2; - - Toast toast = Toast.makeText(context, description, Toast.LENGTH_SHORT); - toast.setGravity(Gravity.TOP | horizontalGravity, xOffset, yOffset); - toast.show(); - return true; - } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/LocationBarLayoutTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/LocationBarLayoutTest.java index 1ac51a9..273b052 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/LocationBarLayoutTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/LocationBarLayoutTest.java
@@ -21,6 +21,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Restriction; import org.chromium.chrome.R; @@ -241,6 +242,7 @@ @Test @SmallTest + @DisabledTest @EnableFeatures(ChromeFeatureList.OMNIBOX_SEARCH_ENGINE_LOGO) @Feature({"OmniboxSearchEngineLogo"}) public void testOmniboxSearchEngineLogo_goneWhenIncognito() throws Exception {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/bottom/BottomToolbarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/bottom/BottomToolbarTest.java index a7c7275b..f9d28715 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/bottom/BottomToolbarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/bottom/BottomToolbarTest.java
@@ -16,6 +16,7 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.Restriction; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeSwitches; @@ -24,6 +25,7 @@ import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; import org.chromium.content_public.browser.test.util.TestThreadUtils; +import org.chromium.ui.test.util.UiRestriction; import java.util.concurrent.ExecutionException; @@ -32,6 +34,7 @@ */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) public class BottomToolbarTest { @Rule public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index 9bd2af42..4ea42dc 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -457,6 +457,7 @@ "//chromeos/services/multidevice_setup/public/cpp:manifest", "//chromeos/services/multidevice_setup/public/mojom", "//chromeos/services/network_config/public/mojom", + "//components/chromeos_camera/common:camera_app_helper", "//media/capture/video/chromeos/mojom:cros_camera", ] }
diff --git a/chrome/app/DEPS b/chrome/app/DEPS index fe64288..0b0bcd1 100644 --- a/chrome/app/DEPS +++ b/chrome/app/DEPS
@@ -52,6 +52,7 @@ "+chromeos/services/multidevice_setup", "+chromeos/services/network_config", "+components/autofill/content/common", + "+components/chromeos_camera/common", "+components/contextual_search/content/common", "+components/data_reduction_proxy/core/common", "+components/dom_distiller/content/common",
diff --git a/chrome/app/chrome_content_browser_overlay_manifest.cc b/chrome/app/chrome_content_browser_overlay_manifest.cc index d65f3207..49bbeb4 100644 --- a/chrome/app/chrome_content_browser_overlay_manifest.cc +++ b/chrome/app/chrome_content_browser_overlay_manifest.cc
@@ -56,6 +56,7 @@ #include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" #include "chromeos/services/network_config/public/mojom/constants.mojom.h" // nogncheck #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" // nogncheck +#include "components/chromeos_camera/common/camera_app_helper.mojom.h" #include "media/capture/video/chromeos/mojom/camera_app.mojom.h" #endif @@ -158,12 +159,12 @@ chrome::mojom::OfflinePageAutoFetcher, chrome::mojom::PrerenderCanceler, #if defined(OS_CHROMEOS) + chromeos_camera::mojom::CameraAppHelper, chromeos::crostini_installer::mojom::PageHandlerFactory, chromeos::ime::mojom::InputEngineManager, chromeos::machine_learning::mojom::PageHandler, chromeos::media_perception::mojom::MediaPerception, cros::mojom::CameraAppDeviceProvider, - cros::mojom::CameraAppHelper, #endif contextual_search::mojom::ContextualSearchJsApiService, dom_distiller::mojom::DistillabilityService,
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index 7b0aac0e..e754648 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -474,48 +474,6 @@ Google API keys are missing. Some functionality of Chromium will be disabled. </message> - <!-- About Chrome page --> - <if expr="not chromeos"> - <message name="IDS_UPGRADE_SUCCESSFUL_RELAUNCH" desc="Status label: Successfully updated Chromium"> - Nearly up to date! Relaunch Chromium to finish updating. - </message> - </if> - <if expr="chromeos"> - <message name="IDS_UPGRADE_SUCCESSFUL_RELAUNCH" desc="Status label: Successfully updated Chromium OS"> - Nearly up to date! Restart your device to finish updating. - </message> - </if> - <if expr="chromeos"> - <message name="IDS_UPGRADE_SUCCESSFUL_CHANNEL_SWITCH" desc="Status label: Channel was successfully switched on Chromium OS"> - Channel changed. Restart your device to apply changes. - </message> - </if> - <if expr="not chromeos"> - <message name="IDS_UPGRADE_UP_TO_DATE" desc="Status label: Already up to date (Chromium)"> - Chromium is up to date. - </message> - </if> - <if expr="chromeos"> - <message name="IDS_UPGRADE_UP_TO_DATE" desc="Status label: Already up to date (Chromium OS)"> - Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> is up to date. - </message> - </if> - <if expr="not chromeos"> - <message name="IDS_UPGRADE_UPDATING" desc="Status label: Updating Chromium"> - Updating Chromium... - </message> - </if> - <if expr="chromeos"> - <message name="IDS_UPGRADE_UPDATING" desc="Status label: Updating Chromium OS"> - Updating your device... - </message> - </if> - <if expr="chromeos"> - <message name="IDS_UPGRADE_UPDATING_CHANNEL_SWITCH" desc="Status label: Updating Chromium OS to a specified channel"> - Updating your device to <ph name="CHANNEL_NAME">$1<ex>stable</ex></ph> channel... - </message> - </if> - <!-- Extension/App install prompt --> <if expr="enable_extensions"> <!-- Extension installed bubble -->
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index e86e35e..be9f4d0 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -486,48 +486,6 @@ Google API keys are missing. Some functionality of Google Chrome will be disabled. </message> - <!-- About Chrome page --> - <if expr="not chromeos"> - <message name="IDS_UPGRADE_SUCCESSFUL_RELAUNCH" desc="Status label: Successfully updated Google Chrome"> - Nearly up to date! Relaunch Google Chrome to finish updating. - </message> - </if> - <if expr="chromeos"> - <message name="IDS_UPGRADE_SUCCESSFUL_RELAUNCH" desc="Status label: Successfully updated Chrome OS"> - Nearly up to date! Restart your device to finish updating. - </message> - </if> - <if expr="chromeos"> - <message name="IDS_UPGRADE_SUCCESSFUL_CHANNEL_SWITCH" desc="Status label: Channel was successfully switched on Chrome OS"> - Channel changed. Restart your device to apply changes. - </message> - </if> - <if expr="not chromeos"> - <message name="IDS_UPGRADE_UP_TO_DATE" desc="Status label: Already up to date (Google Chrome)"> - Google Chrome is up to date. - </message> - </if> - <if expr="chromeos"> - <message name="IDS_UPGRADE_UP_TO_DATE" desc="Status label: Already up to date (Chrome OS)"> - Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> is up to date. - </message> - </if> - <if expr="not chromeos"> - <message name="IDS_UPGRADE_UPDATING" desc="Status label: Updating Google Chrome"> - Updating Google Chrome... - </message> - </if> - <if expr="chromeos"> - <message name="IDS_UPGRADE_UPDATING" desc="Status label: Updating Chrome OS"> - Updating your device... - </message> - </if> - <if expr="chromeos"> - <message name="IDS_UPGRADE_UPDATING_CHANNEL_SWITCH" desc="Status label: Updating Chrome OS to a specified channel"> - Updating your device to <ph name="CHANNEL_NAME">$1<ex>stable</ex></ph> channel... - </message> - </if> - <!-- Extension/App install prompt --> <if expr="enable_extensions"> <!-- Extension installed bubble -->
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index f73c85fa..e476f15 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -3604,6 +3604,9 @@ <message name="IDS_SETTINGS_SITE_SETTINGS_CLEAR_THIRD_PARTY_COOKIES" desc="Label for the confirmation dialog button to delete all cookies and site data for third-party contexts."> Clear third-party cookies </message> + <message name="IDS_SETTINGS_SITE_SETTINGS_THIRD_PARTY_COOKIES_EXCEPTION_LABEL" desc="Label for site exceptions that affect third party cookies."> + Including third-party cookies + </message> <message name="IDS_SETTINGS_SITE_SETTINGS_COOKIE_REMOVE_DIALOG_TITLE" desc="Title of the dialog that warns about deleting all site data."> Clear site data </message>
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index e3433cd..e3620a1 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -259,23 +259,8 @@ AllowShowingSoftKeyboard(true); SetSpinPoodle(false); - // make sure user sees the error message. + // Make sure the user sees the error message. ExpandBottomSheet(); - { - const ClientSettings& settings = ui_delegate_->GetClientSettings(); - if (settings.enable_graceful_shutdown) { - // Keep showing the current UI for a while, without getting updates - // from the controller, then shut down the UI portion. - // - // A controller might still get attached while the timer is running, - // canceling the destruction. - destroy_timer_ = std::make_unique<base::OneShotTimer>(); - destroy_timer_->Start( - FROM_HERE, settings.graceful_shutdown_delay, - base::BindOnce(&UiControllerAndroid::DestroySelf, - weak_ptr_factory_.GetWeakPtr())); - } - } Detach(); return;
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.h b/chrome/browser/android/autofill_assistant/ui_controller_android.h index 25c5904..c730089 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.h +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.h
@@ -66,7 +66,7 @@ Client* client, UiDelegate* ui_delegate); - // Detaches the UI from the its delegate. This guarantees the delegate is not + // Detaches the UI from its delegate. This guarantees the delegate is not // called anymore after the call. void Detach();
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index 3b3acf7..008ec7fd 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -389,7 +389,7 @@ "DarkenWebsitesCheckboxInThemesSetting", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kDirectActions{"DirectActions", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kDrawVerticallyEdgeToEdge{ "DrawVerticallyEdgeToEdge", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/thin_webview/internal/java/src/org/chromium/chrome/browser/thinwebview/internal/CompositorViewImpl.java b/chrome/browser/android/thin_webview/internal/java/src/org/chromium/chrome/browser/thinwebview/internal/CompositorViewImpl.java index 1ff2296a..1433d3e 100644 --- a/chrome/browser/android/thin_webview/internal/java/src/org/chromium/chrome/browser/thinwebview/internal/CompositorViewImpl.java +++ b/chrome/browser/android/thin_webview/internal/java/src/org/chromium/chrome/browser/thinwebview/internal/CompositorViewImpl.java
@@ -146,7 +146,7 @@ } private static boolean useSurfaceView() { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N; + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; } @NativeMethods
diff --git a/chrome/browser/android/thumbnail/thumbnail_cache.cc b/chrome/browser/android/thumbnail/thumbnail_cache.cc index 0b41db09..683e93a 100644 --- a/chrome/browser/android/thumbnail/thumbnail_cache.cc +++ b/chrome/browser/android/thumbnail/thumbnail_cache.cc
@@ -11,7 +11,6 @@ #include "base/android/application_status_listener.h" #include "base/android/path_utils.h" #include "base/big_endian.h" -#include "base/command_line.h" #include "base/files/file.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -22,7 +21,6 @@ #include "build/build_config.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" -#include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/config/gpu_finch_features.h" #include "skia/ext/image_operations.h" #include "third_party/android_opengl/etc1/etc1.h" @@ -199,14 +197,6 @@ MakeSpaceForNewItemIfNecessary(tab_id); cache_.Put(tab_id, std::move(thumbnail)); - // Vulkan does not yet support compressed texture uploads. Disable compression - // and approximation when in experimental Vulkan mode. - // TODO(ericrk): Remove this restriction. https://crbug.com/906794 - if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseVulkan) || - base::FeatureList::IsEnabled(features::kVulkan)) { - return; - } - if (use_approximation_thumbnail_) { std::pair<SkBitmap, float> approximation = CreateApproximation(bitmap, thumbnail_scale);
diff --git a/chrome/browser/autofill/captured_sites_test_utils.cc b/chrome/browser/autofill/captured_sites_test_utils.cc index 55208cd..967069cd 100644 --- a/chrome/browser/autofill/captured_sites_test_utils.cc +++ b/chrome/browser/autofill/captured_sites_test_utils.cc
@@ -1157,7 +1157,7 @@ return false; VLOG(1) << "Typing '" << value << "' inside `" << xpath << "`."; - + PageActivityObserver page_activity_observer(frame); for (size_t index = 0; index < value->size(); index++) { ui::DomKey key = ui::DomKey::FromCharacter(value->at(index)); ui::KeyboardCode key_code = ui::NonPrintableDomKeyToKeyboardCode(key); @@ -1165,7 +1165,7 @@ SimulateKeyPress(content::WebContents::FromRenderFrameHost(frame), key, code, key_code, false, false, false, false); } - + page_activity_observer.WaitTillPageIsIdle(); return true; }
diff --git a/chrome/browser/autofill/manual_filling_controller_impl.cc b/chrome/browser/autofill/manual_filling_controller_impl.cc index 7f20822..1f64d03 100644 --- a/chrome/browser/autofill/manual_filling_controller_impl.cc +++ b/chrome/browser/autofill/manual_filling_controller_impl.cc
@@ -14,7 +14,6 @@ #include "chrome/browser/password_manager/chrome_password_manager_client.h" #include "chrome/browser/password_manager/password_accessory_controller.h" #include "chrome/browser/password_manager/password_accessory_metrics_util.h" -#include "chrome/browser/password_manager/touch_to_fill_controller.h" #include "chrome/browser/profiles/profile.h" #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_util.h" @@ -76,14 +75,12 @@ base::WeakPtr<PasswordAccessoryController> pwd_controller, base::WeakPtr<AddressAccessoryController> address_controller, base::WeakPtr<CreditCardAccessoryController> cc_controller, - base::WeakPtr<TouchToFillController> touch_to_fill_controller, std::unique_ptr<ManualFillingViewInterface> view) { DCHECK(web_contents) << "Need valid WebContents to attach controller to!"; DCHECK(!FromWebContents(web_contents)) << "Controller already attached!"; DCHECK(pwd_controller); DCHECK(address_controller); DCHECK(cc_controller); - DCHECK(touch_to_fill_controller); DCHECK(view); web_contents->SetUserData( @@ -92,7 +89,7 @@ base::WrapUnique(new ManualFillingControllerImpl( web_contents, favicon_service, std::move(pwd_controller), std::move(address_controller), std::move(cc_controller), - std::move(touch_to_fill_controller), std::move(view)))); + std::move(view)))); FromWebContents(web_contents)->Initialize(); } @@ -235,11 +232,6 @@ CreditCardAccessoryController::GetOrCreate(web_contents)->AsWeakPtr(); DCHECK(cc_controller_); } - - touch_to_fill_controller_ = - ChromePasswordManagerClient::FromWebContents(web_contents_) - ->GetOrCreateTouchToFillController() - ->AsWeakPtr(); } ManualFillingControllerImpl::ManualFillingControllerImpl( @@ -248,14 +240,12 @@ base::WeakPtr<PasswordAccessoryController> pwd_controller, base::WeakPtr<AddressAccessoryController> address_controller, base::WeakPtr<CreditCardAccessoryController> cc_controller, - base::WeakPtr<TouchToFillController> touch_to_fill_controller, std::unique_ptr<ManualFillingViewInterface> view) : web_contents_(web_contents), favicon_service_(favicon_service), pwd_controller_for_testing_(std::move(pwd_controller)), address_controller_(std::move(address_controller)), cc_controller_(std::move(cc_controller)), - touch_to_fill_controller_(std::move(touch_to_fill_controller)), view_(std::move(view)) {} bool ManualFillingControllerImpl::ShouldShowAccessory() const { @@ -325,7 +315,6 @@ case AccessoryTabType::CREDIT_CARDS: return cc_controller_.get(); case AccessoryTabType::TOUCH_TO_FILL: - return touch_to_fill_controller_.get(); case AccessoryTabType::ALL: case AccessoryTabType::COUNT: break; // Intentional failure.
diff --git a/chrome/browser/autofill/manual_filling_controller_impl.h b/chrome/browser/autofill/manual_filling_controller_impl.h index bbd3a15..031090df4 100644 --- a/chrome/browser/autofill/manual_filling_controller_impl.h +++ b/chrome/browser/autofill/manual_filling_controller_impl.h
@@ -29,7 +29,6 @@ class AccessoryController; class PasswordAccessoryController; -class TouchToFillController; // Use ManualFillingController::GetOrCreate to obtain instances of this class. class ManualFillingControllerImpl @@ -68,7 +67,6 @@ base::WeakPtr<PasswordAccessoryController> pwd_controller, base::WeakPtr<autofill::AddressAccessoryController> address_controller, base::WeakPtr<autofill::CreditCardAccessoryController> cc_controller, - base::WeakPtr<TouchToFillController> touch_to_fill_controller, std::unique_ptr<ManualFillingViewInterface> test_view); #if defined(UNIT_TEST) @@ -98,7 +96,6 @@ base::WeakPtr<PasswordAccessoryController> pwd_controller, base::WeakPtr<autofill::AddressAccessoryController> address_controller, base::WeakPtr<autofill::CreditCardAccessoryController> cc_controller, - base::WeakPtr<TouchToFillController> touch_to_fill_controller, std::unique_ptr<ManualFillingViewInterface> view); // Returns true if the keyboard accessory needs to be shown. @@ -144,7 +141,6 @@ base::WeakPtr<PasswordAccessoryController> pwd_controller_for_testing_; base::WeakPtr<autofill::AddressAccessoryController> address_controller_; base::WeakPtr<autofill::CreditCardAccessoryController> cc_controller_; - base::WeakPtr<TouchToFillController> touch_to_fill_controller_; // Hold the native instance of the view. Must be last declared and initialized // member so the view can be created in the constructor with a fully set up
diff --git a/chrome/browser/autofill/manual_filling_controller_impl_unittest.cc b/chrome/browser/autofill/manual_filling_controller_impl_unittest.cc index 9dee48f..031cd56 100644 --- a/chrome/browser/autofill/manual_filling_controller_impl_unittest.cc +++ b/chrome/browser/autofill/manual_filling_controller_impl_unittest.cc
@@ -70,7 +70,6 @@ ManualFillingControllerImpl::CreateForWebContentsForTesting( web_contents(), favicon_service(), mock_pwd_controller_.AsWeakPtr(), mock_address_controller_.AsWeakPtr(), mock_cc_controller_.AsWeakPtr(), - touch_to_fill_controller_.AsWeakPtr(), std::make_unique<NiceMock<MockManualFillingView>>()); } @@ -112,7 +111,6 @@ NiceMock<MockPasswordAccessoryController> mock_pwd_controller_; NiceMock<MockAddressAccessoryController> mock_address_controller_; NiceMock<MockCreditCardAccessoryController> mock_cc_controller_; - TouchToFillController touch_to_fill_controller_{web_contents_}; std::unique_ptr<StrictMock<favicon::MockFaviconService>> mock_favicon_service_ =
diff --git a/chrome/browser/banners/app_banner_manager.cc b/chrome/browser/banners/app_banner_manager.cc index 735fb1b..76067de 100644 --- a/chrome/browser/banners/app_banner_manager.cc +++ b/chrome/browser/banners/app_banner_manager.cc
@@ -23,6 +23,7 @@ #include "chrome/common/chrome_switches.h" #include "components/rappor/public/rappor_utils.h" #include "components/rappor/rappor_service_impl.h" +#include "content/public/browser/back_forward_cache.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" @@ -554,6 +555,21 @@ handle->IsSameDocument()) { return; } + + // If the page gets stored in the back-forward cache we will not trigger the + // pipeline again when navigating back (DidFinishLoad will not trigger). So + // only allow the page to enter the cache if we know for sure that no + // installation is needed. + // Note: this check must happen before calling Terminate as it might set the + // installable_web_app_check_result_ to kNo. + if (installable_web_app_check_result_ != InstallableWebAppCheckResult::kNo) { + web_contents() + ->GetController() + .GetBackForwardCache() + .DisableForRenderFrameHost(handle->GetPreviousRenderFrameHostId(), + "banners::AppBannerManager"); + } + if (state_ != State::COMPLETE && state_ != State::INACTIVE) Terminate(); ResetCurrentPageData();
diff --git a/chrome/browser/chromeos/account_manager/account_manager_policy_controller_browsertest.cc b/chrome/browser/chromeos/account_manager/account_manager_policy_controller_browsertest.cc index 0cd175d..4da29a5 100644 --- a/chrome/browser/chromeos/account_manager/account_manager_policy_controller_browsertest.cc +++ b/chrome/browser/chromeos/account_manager/account_manager_policy_controller_browsertest.cc
@@ -32,10 +32,6 @@ AccountManagerPolicyControllerTest() = default; ~AccountManagerPolicyControllerTest() override = default; - void SetUpCommandLine(base::CommandLine* command_line) override { - scoped_feature_list_.InitAndEnableFeature(features::kAccountManager); - } - void SetUpOnMainThread() override { // Prep private fields. ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); @@ -111,7 +107,6 @@ } private: - base::test::ScopedFeatureList scoped_feature_list_; base::ScopedTempDir temp_dir_; // Non-owning pointer. AccountManager* account_manager_ = nullptr;
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index 17a97c0..34d4abd6 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -674,6 +674,12 @@ TestCase("saveFileDialogDefaultFilter").WithBrowser(), TestCase("openFileDialogFileListShowContextMenu").WithBrowser())); +// Flaky on Chrome OS Debug. TODO(crbug.com/1008909). +WRAPPED_INSTANTIATE_TEST_SUITE_P( + DISABLED_CopyBetweenWindows, /* copy_between_windows.js */ + FilesAppBrowserTest, + ::testing::Values(TestCase("copyBetweenWindowsDriveToUsb"))); + WRAPPED_INSTANTIATE_TEST_SUITE_P( CopyBetweenWindows, /* copy_between_windows.js */ FilesAppBrowserTest, @@ -681,7 +687,7 @@ TestCase("copyBetweenWindowsLocalToUsb"), TestCase("copyBetweenWindowsUsbToDrive"), TestCase("copyBetweenWindowsDriveToLocal"), - TestCase("copyBetweenWindowsDriveToUsb"), +// TestCase("copyBetweenWindowsDriveToUsb"), TestCase("copyBetweenWindowsUsbToLocal"))); WRAPPED_INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc index 25947b8b..e5f0324d 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc +++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
@@ -654,7 +654,6 @@ void LoginDisplayHostWebUI::OnStartArcKiosk() { finalize_animation_type_ = ANIMATION_FADE_OUT; if (!login_window_) { - LoadURL(GURL(kAppLaunchSplashURL)); LoadURL(GURL(kArcKioskSplashURL)); }
diff --git a/chrome/browser/chromeos/login/webview_login_browsertest.cc b/chrome/browser/chromeos/login/webview_login_browsertest.cc index 8df3f4d5..b131575 100644 --- a/chrome/browser/chromeos/login/webview_login_browsertest.cc +++ b/chrome/browser/chromeos/login/webview_login_browsertest.cc
@@ -99,11 +99,11 @@ base::RunLoop run_loop; cookie_manager->SetCanonicalCookie( - net::CanonicalCookie(kTestCookieName, kTestCookieValue, kTestCookieHost, - "/", base::Time(), base::Time(), base::Time(), false, - false, net::CookieSameSite::NO_RESTRICTION, - net::COOKIE_PRIORITY_MEDIUM), - "http", net::CookieOptions(), + net::CanonicalCookie( + kTestCookieName, kTestCookieValue, kTestCookieHost, "/", base::Time(), + base::Time(), base::Time(), true /* secure */, false /* httponly*/, + net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_MEDIUM), + "https", net::CookieOptions(), base::Bind(&InjectCookieDoneCallback, run_loop.QuitClosure())); run_loop.Run(); }
diff --git a/chrome/browser/chromeos/policy/cloud_external_data_manager_base.cc b/chrome/browser/chromeos/policy/cloud_external_data_manager_base.cc index 6bd3d81..28ae56a 100644 --- a/chrome/browser/chromeos/policy/cloud_external_data_manager_base.cc +++ b/chrome/browser/chromeos/policy/cloud_external_data_manager_base.cc
@@ -436,21 +436,17 @@ void CloudExternalDataManagerBase::Connect( scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(!external_policy_data_fetcher_backend_); - external_policy_data_fetcher_backend_ = - std::make_unique<ExternalPolicyDataFetcherBackend>( - std::move(url_loader_factory)); backend_task_runner_->PostTask( FROM_HERE, base::BindOnce(&Backend::Connect, base::Unretained(backend_.get()), - external_policy_data_fetcher_backend_->CreateFrontend( - backend_task_runner_))); + std::make_unique<ExternalPolicyDataFetcher>( + std::move(url_loader_factory), backend_task_runner_))); } void CloudExternalDataManagerBase::Disconnect() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - external_policy_data_fetcher_backend_.reset(); + backend_task_runner_->PostTask( FROM_HERE, base::BindOnce(&Backend::Disconnect, base::Unretained(backend_.get())));
diff --git a/chrome/browser/chromeos/policy/cloud_external_data_manager_base.h b/chrome/browser/chromeos/policy/cloud_external_data_manager_base.h index 82606619..31849475 100644 --- a/chrome/browser/chromeos/policy/cloud_external_data_manager_base.h +++ b/chrome/browser/chromeos/policy/cloud_external_data_manager_base.h
@@ -21,7 +21,6 @@ namespace policy { class CloudExternalDataStore; -class ExternalPolicyDataFetcherBackend; // Downloads, verifies, caches and retrieves external data referenced by // policies. @@ -72,14 +71,6 @@ scoped_refptr<base::SequencedTaskRunner> backend_task_runner_; private: - // The |external_policy_data_fetcher_backend_| handles network I/O for the - // |backend_| because URLRequestContextGetter and URLFetchers cannot be - // referenced from background threads. It is instantiated on the thread |this| - // runs on but after that, must only be accessed and eventually destroyed via - // the |io_task_runner_|. - std::unique_ptr<ExternalPolicyDataFetcherBackend> - external_policy_data_fetcher_backend_; - // The |backend_| handles all data download scheduling, verification, caching // and retrieval. It is instantiated on the thread |this| runs on but after // that, must only be accessed and eventually destroyed via the
diff --git a/chrome/browser/chromeos/policy/device_policy_cloud_external_data_manager_browsertest.cc b/chrome/browser/chromeos/policy/device_policy_cloud_external_data_manager_browsertest.cc index bbc3ed1..1bb5d08 100644 --- a/chrome/browser/chromeos/policy/device_policy_cloud_external_data_manager_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_policy_cloud_external_data_manager_browsertest.cc
@@ -186,9 +186,8 @@ EXPECT_EQ(0, ComputeExternalDataCacheDirectorySize()); } -// Disabled. See https://crbug.com/1008275. IN_PROC_BROWSER_TEST_F(DevicePolicyCloudExternalDataManagerTest, - DISABLED_CleanUpResourceCache) { + CleanUpResourceCache) { EXPECT_EQ(0, ComputeExternalDataCacheDirectorySize()); std::string external_data = ReadExternalDataFile(kExternalDataPath); @@ -207,6 +206,10 @@ ComputeExternalDataCacheDirectorySize()); ClearDeviceNativePrintersExternalData(); + // We have to wait until + // CloudExternalDataManagerBase::Backend::OnMetadataUpdated(), which is + // responsible for removing outdated external policy files, is completed. + content::RunAllTasksUntilIdle(); // Check that policy data was cleared. EXPECT_EQ(0, ComputeExternalDataCacheDirectorySize()); }
diff --git a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc index 187ac341..433d4333 100644 --- a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc +++ b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
@@ -961,6 +961,31 @@ nullptr); } } + if (container.has_login_screen_caret_highlight_enabled()) { + PolicyLevel level; + if (GetPolicyLevel( + container.has_login_screen_caret_highlight_enabled_options(), + container.login_screen_caret_highlight_enabled_options(), + &level)) { + policies->Set(key::kDeviceLoginScreenCaretHighlightEnabled, level, + POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, + std::make_unique<base::Value>( + container.login_screen_caret_highlight_enabled()), + nullptr); + } + } + if (container.has_login_screen_mono_audio_enabled()) { + PolicyLevel level; + if (GetPolicyLevel( + container.has_login_screen_mono_audio_enabled_options(), + container.login_screen_mono_audio_enabled_options(), &level)) { + policies->Set(key::kDeviceLoginScreenMonoAudioEnabled, level, + POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD, + std::make_unique<base::Value>( + container.login_screen_mono_audio_enabled()), + nullptr); + } + } } }
diff --git a/chrome/browser/chromeos/policy/login_profile_policy_provider.cc b/chrome/browser/chromeos/policy/login_profile_policy_provider.cc index e0547de8b..1928551 100644 --- a/chrome/browser/chromeos/policy/login_profile_policy_provider.cc +++ b/chrome/browser/chromeos/policy/login_profile_policy_provider.cc
@@ -48,6 +48,8 @@ {key::kDeviceLoginScreenSelectToSpeakEnabled, key::kSelectToSpeakEnabled}, {key::kDeviceLoginScreenCursorHighlightEnabled, key::kCursorHighlightEnabled}, + {key::kDeviceLoginScreenCaretHighlightEnabled, key::kCaretHighlightEnabled}, + {key::kDeviceLoginScreenMonoAudioEnabled, key::kMonoAudioEnabled}, }; const DevicePolicyToUserPolicyMapEntry kRecommendedDevicePoliciesMap[] = {
diff --git a/chrome/browser/chromeos/policy/login_screen_accessibility_policy_browsertest.cc b/chrome/browser/chromeos/policy/login_screen_accessibility_policy_browsertest.cc index b8549ba..0d3e9c9 100644 --- a/chrome/browser/chromeos/policy/login_screen_accessibility_policy_browsertest.cc +++ b/chrome/browser/chromeos/policy/login_screen_accessibility_policy_browsertest.cc
@@ -647,4 +647,108 @@ accessibility_manager->SetCursorHighlightEnabled(false); EXPECT_FALSE(accessibility_manager->IsCursorHighlightEnabled()); } + +IN_PROC_BROWSER_TEST_F(LoginScreenAccessibilityPolicyBrowsertest, + DeviceLoginScreenCaretHighlightEnabled) { + // Verifies that the state of the caret highlight accessibility feature on + // the login screen can be controlled through device policy. + chromeos::AccessibilityManager* accessibility_manager = + chromeos::AccessibilityManager::Get(); + ASSERT_TRUE(accessibility_manager); + EXPECT_FALSE(accessibility_manager->IsCaretHighlightEnabled()); + + // Manually enable the caret highlight. + accessibility_manager->SetCaretHighlightEnabled(true); + EXPECT_TRUE(accessibility_manager->IsCaretHighlightEnabled()); + + // Disable the caret highlight through device policy and wait for the change + // to take effect. + em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); + proto.mutable_accessibility_settings() + ->set_login_screen_caret_highlight_enabled(false); + RefreshDevicePolicyAndWaitForPrefChange( + ash::prefs::kAccessibilityCaretHighlightEnabled); + + // Verify that the pref which controls the caret highlight in the login + // profile is managed by the policy. + EXPECT_TRUE(IsPrefManaged(ash::prefs::kAccessibilityCaretHighlightEnabled)); + EXPECT_EQ(base::Value(false), + GetPrefValue(ash::prefs::kAccessibilityCaretHighlightEnabled)); + + // Verify that the caret highlight cannot be enabled manually anymore. + accessibility_manager->SetCaretHighlightEnabled(true); + EXPECT_FALSE(accessibility_manager->IsCaretHighlightEnabled()); + + // Enable the caret highlight through device policy as a recommended value and + // wait for the change to take effect. + proto.mutable_accessibility_settings() + ->set_login_screen_caret_highlight_enabled(true); + proto.mutable_accessibility_settings() + ->mutable_login_screen_caret_highlight_enabled_options() + ->set_mode(em::PolicyOptions::RECOMMENDED); + RefreshDevicePolicyAndWaitForPrefChange( + ash::prefs::kAccessibilityCaretHighlightEnabled); + + // Verify that the pref which controls the caret highlight in the login + // profile is being applied as recommended by the policy. + EXPECT_FALSE(IsPrefManaged(ash::prefs::kAccessibilityCaretHighlightEnabled)); + EXPECT_EQ(base::Value(true), + GetPrefValue(ash::prefs::kAccessibilityCaretHighlightEnabled)); + + // Verify that the caret highlight can be enabled manually again. + accessibility_manager->SetCaretHighlightEnabled(false); + EXPECT_FALSE(accessibility_manager->IsCaretHighlightEnabled()); +} + +IN_PROC_BROWSER_TEST_F(LoginScreenAccessibilityPolicyBrowsertest, + DeviceLoginScreenMonoAudioEnabled) { + // Verifies that the state of the mono audio accessibility feature on + // the login screen can be controlled through device policy. + chromeos::AccessibilityManager* accessibility_manager = + chromeos::AccessibilityManager::Get(); + ASSERT_TRUE(accessibility_manager); + EXPECT_FALSE(accessibility_manager->IsMonoAudioEnabled()); + + // Manually enable the mono audio. + accessibility_manager->EnableMonoAudio(true); + EXPECT_TRUE(accessibility_manager->IsMonoAudioEnabled()); + + // Disable the mono audio through device policy and wait for the change + // to take effect. + em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); + proto.mutable_accessibility_settings()->set_login_screen_mono_audio_enabled( + false); + RefreshDevicePolicyAndWaitForPrefChange( + ash::prefs::kAccessibilityMonoAudioEnabled); + + // Verify that the pref which controls the mono audio in the login + // profile is managed by the policy. + EXPECT_TRUE(IsPrefManaged(ash::prefs::kAccessibilityMonoAudioEnabled)); + EXPECT_EQ(base::Value(false), + GetPrefValue(ash::prefs::kAccessibilityMonoAudioEnabled)); + + // Verify that the mono audio cannot be enabled manually anymore. + accessibility_manager->EnableMonoAudio(true); + EXPECT_FALSE(accessibility_manager->IsMonoAudioEnabled()); + + // Enable the mono audio through device policy as a recommended value and wait + // for the change to take effect. + proto.mutable_accessibility_settings()->set_login_screen_mono_audio_enabled( + true); + proto.mutable_accessibility_settings() + ->mutable_login_screen_mono_audio_enabled_options() + ->set_mode(em::PolicyOptions::RECOMMENDED); + RefreshDevicePolicyAndWaitForPrefChange( + ash::prefs::kAccessibilityMonoAudioEnabled); + + // Verify that the pref which controls the mono audio in the login + // profile is being applied as recommended by the policy. + EXPECT_FALSE(IsPrefManaged(ash::prefs::kAccessibilityMonoAudioEnabled)); + EXPECT_EQ(base::Value(true), + GetPrefValue(ash::prefs::kAccessibilityMonoAudioEnabled)); + + // Verify that the mono audio can be enabled manually again. + accessibility_manager->EnableMonoAudio(false); + EXPECT_FALSE(accessibility_manager->IsMonoAudioEnabled()); +} } // namespace policy
diff --git a/chrome/browser/extensions/api/sessions/sessions_apitest.cc b/chrome/browser/extensions/api/sessions/sessions_apitest.cc index f8fc80c5..4a84d88 100644 --- a/chrome/browser/extensions/api/sessions/sessions_apitest.cc +++ b/chrome/browser/extensions/api/sessions/sessions_apitest.cc
@@ -27,7 +27,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/testing_browser_process.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/engine/data_type_activation_response.h" #include "components/sync/model/data_type_activation_request.h" #include "components/sync/model/model_type_controller_delegate.h" @@ -144,8 +144,9 @@ return testing::AssertionSuccess(); } -std::string TagHashFromSpecifics(const sync_pb::SessionSpecifics& specifics) { - return syncer::GenerateSyncableHash( +syncer::ClientTagHash TagHashFromSpecifics( + const sync_pb::SessionSpecifics& specifics) { + return syncer::ClientTagHash::FromUnhashed( syncer::SESSIONS, sync_sessions::SessionStore::GetClientTag(specifics)); } @@ -236,7 +237,8 @@ auto header_entity_data = std::make_unique<syncer::EntityData>(); header_entity_data->client_tag_hash = TagHashFromSpecifics(header_entity.session()); - header_entity_data->id = "FakeId:" + header_entity_data->client_tag_hash; + header_entity_data->id = + "FakeId:" + header_entity_data->client_tag_hash.value(); header_entity_data->specifics = header_entity; header_entity_data->creation_time = time_now - base::TimeDelta::FromSeconds(index);
diff --git a/chrome/browser/extensions/chrome_extensions_interface_registration.cc b/chrome/browser/extensions/chrome_extensions_interface_registration.cc index b334d2e0..17c4d53 100644 --- a/chrome/browser/extensions/chrome_extensions_interface_registration.cc +++ b/chrome/browser/extensions/chrome_extensions_interface_registration.cc
@@ -83,7 +83,8 @@ uint32_t intent_id, arc::mojom::CameraIntentAction action, const std::vector<uint8_t>& data, - cros::mojom::CameraAppHelper::HandleCameraResultCallback callback) { + chromeos_camera::mojom::CameraAppHelper::HandleCameraResultCallback + callback) { auto* intent_helper = arc::ArcIntentHelperBridge::GetForBrowserContext(context); intent_helper->HandleCameraResult(intent_id, action, data, @@ -118,8 +119,9 @@ } // Connects to CameraAppHelper that could handle camera intents. -void ConnectToCameraAppHelper(cros::mojom::CameraAppHelperRequest request, - content::RenderFrameHost* source) { +void ConnectToCameraAppHelper( + chromeos_camera::mojom::CameraAppHelperRequest request, + content::RenderFrameHost* source) { auto handle_result_callback = base::BindRepeating( &HandleCameraResult, source->GetProcess()->GetBrowserContext()); auto camera_app_helper =
diff --git a/chrome/browser/media/webrtc/webrtc_video_quality_browsertest.cc b/chrome/browser/media/webrtc/webrtc_video_quality_browsertest.cc index 466f51b..e09ff30 100644 --- a/chrome/browser/media/webrtc/webrtc_video_quality_browsertest.cc +++ b/chrome/browser/media/webrtc/webrtc_video_quality_browsertest.cc
@@ -327,8 +327,16 @@ TestVideoQuality("VP8", false /* prefer_hw_video_codec */); } +// Flaky on windows. +// TODO(crbug.com/1008766): re-enable when flakiness is investigated, diagnosed +// and resolved. +#if defined(OS_WIN) +#define MAYBE_MANUAL_TestVideoQualityVp9 DISABLED_MANUAL_TestVideoQualityVp9 +#else +#define MAYBE_MANUAL_TestVideoQualityVp9 MANUAL_TestVideoQualityVp9 +#endif IN_PROC_BROWSER_TEST_P(WebRtcVideoQualityBrowserTest, - MANUAL_TestVideoQualityVp9) { + MAYBE_MANUAL_TestVideoQualityVp9) { base::ScopedAllowBlockingForTesting allow_blocking; TestVideoQuality("VP9", true /* prefer_hw_video_codec */); }
diff --git a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer.cc index 7791e23d..30152a2 100644 --- a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer.cc
@@ -109,6 +109,10 @@ } // TODO(csharrison): Optimize the domain lookup. + // Note: If either |url| or |first_party_url| is empty, SameDomainOrHost will + // return false, and function execution will continue because it is considered + // 3rd party. Since |first_party_url| is actually the |site_for_cookies|, this + // will happen e.g. for a 3rd party iframe on document.cookie access. if (!url.is_valid() || net::registry_controlled_domains::SameDomainOrHost( url, first_party_url, @@ -120,8 +124,17 @@ net::registry_controlled_domains::GetDomainAndRegistry( url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); - if (registrable_domain.empty()) - return; + // |registrable_domain| can be empty e.g. if |url| is on an IP address, or the + // domain is itself a TLD, or it's a file URL (in which case it has no host), + // etc. See comment for GetDomainAndRegistry() in + // //net/base/registry_controlled_domains/registry_controlled_domains.h. + if (registrable_domain.empty()) { + if (url.has_host()) { + registrable_domain = url.host(); + } else { + return; + } + } auto it = third_party_cookie_access_types_.find(registrable_domain);
diff --git a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer.h b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer.h index 3e4e9bdd..08453cc 100644 --- a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer.h
@@ -66,8 +66,8 @@ // third party document.cookie access happens when the context's registrable // domain differs from the main frame's. A third party resource request // happens when the URL request's registrable domain differs from the main - // frame's. URLs which have no registrable domain are not considered third - // party. + // frame's. For URLs which have no registrable domain, the hostname is used + // instead. std::map<std::string, CookieAccessTypes> third_party_cookie_access_types_; // A map of third parties that have accessed storage other than cookies. A
diff --git a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_browsertest.cc index afc7615..b7ed0e5 100644 --- a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_browsertest.cc +++ b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_browsertest.cc
@@ -6,8 +6,10 @@ #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/network_session_configurator/common/network_switches.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,12 +27,20 @@ class ThirdPartyMetricsObserverBrowserTest : public InProcessBrowserTest { protected: - ThirdPartyMetricsObserverBrowserTest() = default; + ThirdPartyMetricsObserverBrowserTest() + : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} ~ThirdPartyMetricsObserverBrowserTest() override = default; void SetUpOnMainThread() override { host_resolver()->AddRule("*", "127.0.0.1"); - ASSERT_TRUE(embedded_test_server()->Start()); + https_server()->AddDefaultHandlers(GetChromeTestDataDir()); + ASSERT_TRUE(https_server()->Start()); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + // HTTPS server only serves a valid cert for 127.0.0.1 or localhost, so this + // is needed to load pages from other hosts (b.com, c.com) without an error. + command_line->AppendSwitch(switches::kIgnoreCertificateErrors); } void NavigateToUntrackedUrl() { @@ -38,19 +48,29 @@ } void NavigateToPageWithFrame(const std::string& host) { - GURL main_url(embedded_test_server()->GetURL(host, "/iframe.html")); + GURL main_url(https_server()->GetURL(host, "/iframe.html")); ui_test_utils::NavigateToURL(browser(), main_url); } void NavigateFrameTo(const std::string& host, const std::string& path) { - GURL page = embedded_test_server()->GetURL(host, path); - EXPECT_TRUE(NavigateIframeToURL(web_contents(), "test", page)); + GURL page = https_server()->GetURL(host, path); + NavigateFrameToUrl(page); + } + + void NavigateFrameToUrl(const GURL& url) { + EXPECT_TRUE(NavigateIframeToURL(web_contents(), "test", url)); } content::WebContents* web_contents() { return browser()->tab_strip_model()->GetActiveWebContents(); } + net::EmbeddedTestServer* https_server() { return &https_server_; } + + // This is needed because third party cookies must be marked SameSite=None and + // Secure, so they must be accessed over HTTPS. + net::EmbeddedTestServer https_server_; + DISALLOW_COPY_AND_ASSIGN(ThirdPartyMetricsObserverBrowserTest); }; @@ -80,8 +100,29 @@ ThirdPartyCookiesReadAndWrite) { base::HistogramTester histogram_tester; NavigateToPageWithFrame("a.com"); // Same origin cookie read. - NavigateFrameTo("b.com", "/set-cookie?thirdparty"); // 3p cookie write - NavigateFrameTo("b.com", "/"); // 3p cookie read + // 3p cookie write + NavigateFrameTo("b.com", "/set-cookie?thirdparty=1;SameSite=None;Secure"); + // 3p cookie read + NavigateFrameTo("b.com", "/"); + NavigateToUntrackedUrl(); + + histogram_tester.ExpectUniqueSample(kReadCookieHistogram, 1, 1); + histogram_tester.ExpectUniqueSample(kWriteCookieHistogram, 1, 1); +} + +IN_PROC_BROWSER_TEST_F(ThirdPartyMetricsObserverBrowserTest, + ThirdPartyCookiesIPAddress) { + base::HistogramTester histogram_tester; + NavigateToPageWithFrame("a.com"); // Same origin cookie read. + GURL url = + https_server()->GetURL("/set-cookie?thirdparty=1;SameSite=None;Secure"); + // Hostname is an IP address. + ASSERT_EQ( + "", + net::registry_controlled_domains::GetDomainAndRegistry( + url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)); + NavigateFrameToUrl(url); // 3p cookie write + NavigateFrameTo(url.host(), "/"); // 3p cookie read NavigateToUntrackedUrl(); histogram_tester.ExpectUniqueSample(kReadCookieHistogram, 1, 1); @@ -92,10 +133,14 @@ MultipleThirdPartyCookiesReadAndWrite) { base::HistogramTester histogram_tester; NavigateToPageWithFrame("a.com"); // Same origin cookie read. - NavigateFrameTo("b.com", "/set-cookie?thirdparty"); // 3p cookie write - NavigateFrameTo("b.com", "/"); // 3p cookie read - NavigateFrameTo("c.com", "/set-cookie?thirdparty"); // 3p cookie write - NavigateFrameTo("c.com", "/"); // 3p cookie read + // 3p cookie write + NavigateFrameTo("b.com", "/set-cookie?thirdparty=1;SameSite=None;Secure"); + // 3p cookie read + NavigateFrameTo("b.com", "/"); + // 3p cookie write + NavigateFrameTo("c.com", "/set-cookie?thirdparty=1;SameSite=None;Secure"); + // 3p cookie read + NavigateFrameTo("c.com", "/"); NavigateToUntrackedUrl(); histogram_tester.ExpectUniqueSample(kReadCookieHistogram, 2, 1); @@ -130,7 +175,8 @@ ChildFrameAt(web_contents()->GetMainFrame(), 0); // Write a third-party cookie. - EXPECT_TRUE(content::ExecJs(frame, "document.cookie = 'foo=bar';")); + EXPECT_TRUE(content::ExecJs( + frame, "document.cookie = 'foo=bar;SameSite=None;Secure';")); // Read a third-party cookie. EXPECT_TRUE(content::ExecJs(frame, "let x = document.cookie;")); @@ -166,7 +212,8 @@ ChildFrameAt(web_contents()->GetMainFrame(), 0); // Write a third-party cookie. - EXPECT_TRUE(content::ExecJs(frame, "document.cookie = 'foo=bar';")); + EXPECT_TRUE(content::ExecJs( + frame, "document.cookie = 'foo=bar;SameSite=None;Secure';")); NavigateToUntrackedUrl(); histogram_tester.ExpectUniqueSample(kReadCookieHistogram, 0, 1);
diff --git a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_unittest.cc index 3075dce..418d49d 100644 --- a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_unittest.cc
@@ -54,16 +54,31 @@ } TEST_F(ThirdPartyMetricsObserverTest, - NoRegistrableDomainCookiesRead_NoneRecorded) { + NoRegistrableDomainNoHostCookiesRead_NoneRecorded) { NavigateAndCommit(GURL("https://top.com")); - SimulateCookiesRead(GURL("data:,Hello%2C%20World!"), GURL("https://top.com"), - net::CookieList(), false /* blocked_by_policy */); + GURL url = GURL("data:,Hello%2C%20World!"); + ASSERT_FALSE(url.has_host()); + SimulateCookiesRead(url, GURL("https://top.com"), net::CookieList(), + false /* blocked_by_policy */); NavigateToUntrackedUrl(); histogram_tester().ExpectUniqueSample(kReadCookieHistogram, 0, 1); } +TEST_F(ThirdPartyMetricsObserverTest, + NoRegistrableDomainWithHostCookiesRead_OneRecorded) { + NavigateAndCommit(GURL("https://top.com")); + + GURL url = GURL("https://127.0.0.1/cookies"); + ASSERT_TRUE(url.has_host()); + SimulateCookiesRead(url, GURL("https://top.com"), net::CookieList(), + false /* blocked_by_policy */); + NavigateToUntrackedUrl(); + + histogram_tester().ExpectUniqueSample(kReadCookieHistogram, 1, 1); +} + TEST_F(ThirdPartyMetricsObserverTest, OnlyFirstPartyCookiesRead_NotRecorded) { NavigateAndCommit(GURL("https://top.com")); @@ -138,16 +153,30 @@ } TEST_F(ThirdPartyMetricsObserverTest, - NoRegistrableDomainCookiesChanged_NoneRecorded) { + NoRegistrableDomainNoHostCookiesChanged_NoneRecorded) { NavigateAndCommit(GURL("https://top.com")); - SimulateCookieChange(GURL("data:,Hello%2C%20World!"), GURL("https://top.com"), - net::CanonicalCookie(), false /* blocked_by_policy */); + GURL url = GURL("data:,Hello%2C%20World!"); + ASSERT_FALSE(url.has_host()); + SimulateCookieChange(url, GURL("https://top.com"), net::CanonicalCookie(), + false /* blocked_by_policy */); NavigateToUntrackedUrl(); histogram_tester().ExpectUniqueSample(kWriteCookieHistogram, 0, 1); } TEST_F(ThirdPartyMetricsObserverTest, + NoRegistrableDomainWithHostCookiesChanged_OneRecorded) { + NavigateAndCommit(GURL("https://top.com")); + + GURL url = GURL("https://127.0.0.1/cookies"); + ASSERT_TRUE(url.has_host()); + SimulateCookieChange(url, GURL("https://top.com"), net::CanonicalCookie(), + false /* blocked_by_policy */); + NavigateToUntrackedUrl(); + histogram_tester().ExpectUniqueSample(kWriteCookieHistogram, 1, 1); +} + +TEST_F(ThirdPartyMetricsObserverTest, OnlyFirstPartyCookiesChanged_NotRecorded) { NavigateAndCommit(GURL("https://top.com"));
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc index ae21c2c..fce5072 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -781,7 +781,6 @@ ManualFillingControllerImpl::CreateForWebContentsForTesting( web_contents, favicon_service_.get(), mock_pwd_controller_.AsWeakPtr(), mock_address_controller_.AsWeakPtr(), mock_cc_controller_.AsWeakPtr(), - GetClient()->GetOrCreateTouchToFillController()->AsWeakPtr(), std::make_unique<NiceMock<MockManualFillingView>>()); }
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc index d7acbd7..56dae9d 100644 --- a/chrome/browser/password_manager/password_manager_browsertest.cc +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -329,9 +329,6 @@ } IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest, LoginFailed) { - // Log in, see a form on the landing page. That form is not related to the - // login form (=has a different action), so we should offer saving the - // password. NavigateToFile("/password/password_form.html"); NavigationObserver observer(WebContents());
diff --git a/chrome/browser/password_manager/touch_to_fill_controller.cc b/chrome/browser/password_manager/touch_to_fill_controller.cc index cf656f5d..19f8f88 100644 --- a/chrome/browser/password_manager/touch_to_fill_controller.cc +++ b/chrome/browser/password_manager/touch_to_fill_controller.cc
@@ -4,117 +4,51 @@ #include "chrome/browser/password_manager/touch_to_fill_controller.h" -#include <string> #include <utility> -#include "base/feature_list.h" #include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/browser/autofill/manual_filling_controller.h" -#include "chrome/browser/ui/autofill/autofill_popup_controller.h" -#include "components/autofill/core/browser/ui/popup_item_ids.h" -#include "components/autofill/core/browser/ui/suggestion.h" -#include "components/autofill/core/common/autofill_util.h" +#include "chrome/browser/touch_to_fill/touch_to_fill_view.h" #include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h" #include "components/password_manager/core/browser/origin_credential_store.h" #include "components/password_manager/core/browser/password_manager_driver.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h" +#include "components/url_formatter/elide_url.h" +#include "content/public/browser/web_contents.h" -using content::WebContents; +using password_manager::CredentialPair; +using password_manager::PasswordManagerDriver; -TouchToFillController::TouchToFillController(WebContents* web_contents) - : web_contents_(web_contents) { - DCHECK(web_contents); +namespace { + +void OnCredentialSelected(base::WeakPtr<PasswordManagerDriver> driver, + const CredentialPair& credential) { + if (!driver) + return; + + password_manager::metrics_util::LogFilledCredentialIsFromAndroidApp( + password_manager::IsValidAndroidFacetURI(credential.origin_url.spec())); + driver->FillSuggestion(credential.username, credential.password); } -TouchToFillController::TouchToFillController( - base::WeakPtr<ManualFillingController> mf_controller, - util::PassKey<TouchToFillControllerTest>) - : mf_controller_(std::move(mf_controller)) { - DCHECK(mf_controller_); -} +} // namespace + +TouchToFillController::TouchToFillController(content::WebContents* web_contents) + : web_contents_(web_contents) {} TouchToFillController::~TouchToFillController() = default; -void TouchToFillController::Show( - base::span<const password_manager::CredentialPair> credentials, - base::WeakPtr<password_manager::PasswordManagerDriver> driver) { - credentials_.assign(credentials.begin(), credentials.end()); - driver_ = std::move(driver); +void TouchToFillController::Show(base::span<const CredentialPair> credentials, + base::WeakPtr<PasswordManagerDriver> driver) { + if (!view_) + view_ = TouchToFillViewFactory::Create(this); - autofill::AccessorySheetData::Builder builder( - autofill::AccessoryTabType::TOUCH_TO_FILL, - // TODO(crbug.com/957532): Update title once mocks are finalized. - base::ASCIIToUTF16("Touch to Fill")); - - for (size_t i = 0; i < credentials_.size(); ++i) { - const auto& credential = credentials_[i]; - if (credential.is_public_suffix_match) - builder.AddUserInfo(credential.origin_url.spec()); - else - builder.AddUserInfo(); - - std::string field_id = base::NumberToString(i); - builder.AppendField(credential.username, credential.username, field_id, - /*is_obfuscated=*/false, - /*is_selectable=*/true); - builder.AppendField(credential.password, credential.password, - std::move(field_id), - /*is_obfuscated=*/true, - /*is_selectable=*/false); - } - - GetManualFillingController()->RefreshSuggestions(std::move(builder).Build()); -} - -void TouchToFillController::OnFillingTriggered( - const autofill::UserInfo::Field& selection) { - if (!driver_) { - LOG(DFATAL) << "|driver_| is not set or has been invalidated."; - return; - } - - size_t index = 0; - if (!base::StringToSizeT(selection.id(), &index)) { - LOG(DFATAL) << "Failed to convert selection.id(): " << selection.id(); - return; - } - - if (index >= credentials_.size()) { - LOG(DFATAL) << "Received invalid suggestion index: " << index; - return; - } - - const auto& credential = credentials_[index]; - password_manager::metrics_util::LogFilledCredentialIsFromAndroidApp( - password_manager::IsValidAndroidFacetURI(credential.origin_url.spec())); - // Invalidate |driver_| and |credentials_| to ignore future invocations of - // OnFillingTriggered for the same credentials. - std::exchange(driver_, nullptr) - ->FillSuggestion(credential.username, credential.password); - credentials_.clear(); - - mf_controller_->UpdateSourceAvailability( - ManualFillingController::FillingSource::TOUCH_TO_FILL, - /*has_suggestions=*/false); -} - -void TouchToFillController::OnOptionSelected( - autofill::AccessoryAction selected_action) { - // Not applicable for TouchToFillController. All user interactions should - // result in OnFillingTriggered(). - NOTREACHED(); + view_->Show(url_formatter::FormatUrlForSecurityDisplay( + driver->GetLastCommittedURL(), + url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC), + credentials, + base::BindOnce(OnCredentialSelected, std::move(driver))); } gfx::NativeView TouchToFillController::GetNativeView() { return web_contents_->GetNativeView(); } - -ManualFillingController* TouchToFillController::GetManualFillingController() { - if (!mf_controller_) - mf_controller_ = ManualFillingController::GetOrCreate(web_contents_); - DCHECK(mf_controller_); - return mf_controller_.get(); -}
diff --git a/chrome/browser/password_manager/touch_to_fill_controller.h b/chrome/browser/password_manager/touch_to_fill_controller.h index 36389a09..fdc3556 100644 --- a/chrome/browser/password_manager/touch_to_fill_controller.h +++ b/chrome/browser/password_manager/touch_to_fill_controller.h
@@ -6,69 +6,54 @@ #define CHROME_BROWSER_PASSWORD_MANAGER_TOUCH_TO_FILL_CONTROLLER_H_ #include <memory> +#include <utility> #include <vector> #include "base/containers/span.h" #include "base/memory/weak_ptr.h" -#include "base/util/type_safety/pass_key.h" -#include "chrome/browser/autofill/accessory_controller.h" +#include "chrome/browser/touch_to_fill/touch_to_fill_view.h" +#include "chrome/browser/touch_to_fill/touch_to_fill_view_factory.h" #include "ui/gfx/native_widget_types.h" namespace content { class WebContents; -} +} // namespace content namespace password_manager { class PasswordManagerDriver; struct CredentialPair; } // namespace password_manager -class ManualFillingController; -class TouchToFillControllerTest; - -class TouchToFillController - : public base::SupportsWeakPtr<TouchToFillController>, - public AccessoryController { +class TouchToFillController { public: explicit TouchToFillController(content::WebContents* web_contents); - // Explicitly set the ManualFillingController in unit tests. - explicit TouchToFillController( - base::WeakPtr<ManualFillingController> mf_controller, - util::PassKey<TouchToFillControllerTest>); - ~TouchToFillController() override; + TouchToFillController(const TouchToFillController&) = delete; + TouchToFillController& operator=(const TouchToFillController&) = delete; + ~TouchToFillController(); // Instructs the controller to show the provided |credentials| to the user. // Invokes FillSuggestion() on |driver| once the user made a selection. void Show(base::span<const password_manager::CredentialPair> credentials, base::WeakPtr<password_manager::PasswordManagerDriver> driver); - // AccessoryController: - void OnFillingTriggered(const autofill::UserInfo::Field& selection) override; - void OnOptionSelected(autofill::AccessoryAction selected_action) override; - // The web page view containing the focused field. gfx::NativeView GetNativeView(); - private: - // Lazy-initializes and returns the ManualFillingController for the current - // |web_contents_|. The lazy initialization is required to break a circular - // dependency between the constructors of the TouchToFillController and - // ManualFillingController. - ManualFillingController* GetManualFillingController(); +#if defined(UNIT_TEST) + void set_view(std::unique_ptr<TouchToFillView> view) { + view_ = std::move(view); + } +#endif - // The tab for which this class is scoped. + private: + // Weak pointer to the current WebContents. This is safe because the lifetime + // of this class is tied to ChromePasswordManagerClient, which implements + // WebContentsUserData. content::WebContents* web_contents_ = nullptr; - // The manual filling controller object to forward client requests to. - // TODO(crbug.com/957532): Make TouchToFillController independent of the - // ManualFillingController. - base::WeakPtr<ManualFillingController> mf_controller_; - - // Credentials passed from the latest invocation of Show(). - std::vector<password_manager::CredentialPair> credentials_; - - // Driver passed from the latest invocation of Show(). - base::WeakPtr<password_manager::PasswordManagerDriver> driver_; + // View used to communicate with the Android frontend. Lazily instantiated so + // that it can be injected by tests. + std::unique_ptr<TouchToFillView> view_; }; #endif // CHROME_BROWSER_PASSWORD_MANAGER_TOUCH_TO_FILL_CONTROLLER_H_
diff --git a/chrome/browser/password_manager/touch_to_fill_controller_unittest.cc b/chrome/browser/password_manager/touch_to_fill_controller_unittest.cc index 234107b..888e71f 100644 --- a/chrome/browser/password_manager/touch_to_fill_controller_unittest.cc +++ b/chrome/browser/password_manager/touch_to_fill_controller_unittest.cc
@@ -4,163 +4,118 @@ #include "chrome/browser/password_manager/touch_to_fill_controller.h" +#include <memory> +#include <tuple> + #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" -#include "chrome/browser/autofill/mock_manual_filling_controller.h" -#include "components/autofill/core/common/autofill_features.h" #include "components/password_manager/core/browser/origin_credential_store.h" #include "components/password_manager/core/browser/stub_password_manager_driver.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +namespace { + using password_manager::CredentialPair; +using ::testing::_; +using ::testing::ElementsAreArray; +using ::testing::Eq; +using ::testing::ReturnRefOfCopy; +using ::testing::WithArg; + +// Re-implementation of ::testing::SaveArg that works with move-only types. +template <size_t K, typename T> +auto SaveArg(T* ptr) { + return [ptr](auto&&... args) { + *ptr = std::get<K>( + std::forward_as_tuple(std::forward<decltype(args)>(args)...)); + }; +} + +constexpr char kExampleCom[] = "https://example.com/"; struct MockPasswordManagerDriver : password_manager::StubPasswordManagerDriver { MOCK_METHOD2(FillSuggestion, void(const base::string16&, const base::string16&)); + MOCK_CONST_METHOD0(GetLastCommittedURL, const GURL&()); }; +struct MockTouchToFillView : TouchToFillView { + MOCK_METHOD3(Show, + void(base::StringPiece16, + base::span<const password_manager::CredentialPair>, + ShowCallback)); + MOCK_METHOD0(OnDismiss, void()); +}; + +} // namespace + class TouchToFillControllerTest : public testing::Test { protected: - MockManualFillingController& manual_filling_controller() { - return mock_manual_filling_controller_; + TouchToFillControllerTest() { + auto mock_view = std::make_unique<MockTouchToFillView>(); + mock_view_ = mock_view.get(); + touch_to_fill_controller_.set_view(std::move(mock_view)); + + ON_CALL(driver_, GetLastCommittedURL()) + .WillByDefault(ReturnRefOfCopy(GURL(kExampleCom))); } MockPasswordManagerDriver& driver() { return driver_; } + MockTouchToFillView& view() { return *mock_view_; } + TouchToFillController& touch_to_fill_controller() { return touch_to_fill_controller_; } private: - testing::StrictMock<MockManualFillingController> - mock_manual_filling_controller_; + MockTouchToFillView* mock_view_ = nullptr; MockPasswordManagerDriver driver_; - TouchToFillController touch_to_fill_controller_{ - mock_manual_filling_controller_.AsWeakPtr(), - util::PassKey<TouchToFillControllerTest>()}; + TouchToFillController touch_to_fill_controller_{nullptr}; }; -TEST_F(TouchToFillControllerTest, Show_Empty) { - EXPECT_CALL(manual_filling_controller(), - RefreshSuggestions(autofill::AccessorySheetData::Builder( - autofill::AccessoryTabType::TOUCH_TO_FILL, - base::ASCIIToUTF16("Touch to Fill")) - .Build())); - touch_to_fill_controller().Show({}, driver().AsWeakPtr()); -} - TEST_F(TouchToFillControllerTest, Show_And_Fill) { - CredentialPair alice( - base::ASCIIToUTF16("alice"), base::ASCIIToUTF16("p4ssw0rd"), - GURL("https://example.com"), /*is_public_suffix_match=*/false); + CredentialPair credentials[] = { + {base::ASCIIToUTF16("alice"), base::ASCIIToUTF16("p4ssw0rd"), + GURL(kExampleCom), /*is_public_suffix_match=*/false}}; - EXPECT_CALL( - manual_filling_controller(), - RefreshSuggestions( - autofill::AccessorySheetData::Builder( - autofill::AccessoryTabType::TOUCH_TO_FILL, - base::ASCIIToUTF16("Touch to Fill")) - .AddUserInfo() - .AppendField(base::ASCIIToUTF16("alice"), - base::ASCIIToUTF16("alice"), "0", - /*is_obfuscated=*/false, /*is_selectable=*/true) - .AppendField(base::ASCIIToUTF16("p4ssw0rd"), - base::ASCIIToUTF16("p4ssw0rd"), "0", - /*is_obfuscated=*/true, /*is_selectable=*/false) - .Build())); - touch_to_fill_controller().Show(std::vector<CredentialPair>{alice}, - driver().AsWeakPtr()); - - // Test that OnFillingTriggered() with the right id results in the appropriate - // call to FillSuggestion() and UpdateSourceAvailability(). - EXPECT_CALL(driver(), FillSuggestion(base::ASCIIToUTF16("alice"), - base::ASCIIToUTF16("p4ssw0rd"))); - EXPECT_CALL(manual_filling_controller(), - UpdateSourceAvailability( - ManualFillingController::FillingSource::TOUCH_TO_FILL, - /*has_suggestions=*/false)); + TouchToFillView::ShowCallback callback; + EXPECT_CALL(view(), Show(Eq(base::ASCIIToUTF16("example.com")), + ElementsAreArray(credentials), _)) + .WillOnce(SaveArg<2>(&callback)); + touch_to_fill_controller().Show(credentials, driver().AsWeakPtr()); // Test that we correctly log the absence of an Android credential. base::HistogramTester tester; - touch_to_fill_controller().OnFillingTriggered(autofill::UserInfo::Field( - base::ASCIIToUTF16("alice"), base::ASCIIToUTF16("alice"), "0", - /*is_obfuscated=*/false, /*is_selectable=*/true)); + EXPECT_CALL(driver(), FillSuggestion(base::ASCIIToUTF16("alice"), + base::ASCIIToUTF16("p4ssw0rd"))); + std::move(callback).Run(credentials[0]); tester.ExpectUniqueSample("PasswordManager.FilledCredentialWasFromAndroidApp", false, 1); } -TEST_F(TouchToFillControllerTest, Show_PSL_Credential) { - // Test that showing a PSL credentials results in the origin being passed to - // the manual filling controller. - CredentialPair alice( - base::ASCIIToUTF16("alice"), base::ASCIIToUTF16("p4ssw0rd"), - GURL("https://sub.example.com/"), /*is_public_suffix_match=*/true); - - EXPECT_CALL( - manual_filling_controller(), - RefreshSuggestions( - autofill::AccessorySheetData::Builder( - autofill::AccessoryTabType::TOUCH_TO_FILL, - base::ASCIIToUTF16("Touch to Fill")) - .AddUserInfo("https://sub.example.com/") - .AppendField(base::ASCIIToUTF16("alice"), - base::ASCIIToUTF16("alice"), "0", - /*is_obfuscated=*/false, /*is_selectable=*/true) - .AppendField(base::ASCIIToUTF16("p4ssw0rd"), - base::ASCIIToUTF16("p4ssw0rd"), "0", - /*is_obfuscated=*/true, /*is_selectable=*/false) - .Build())); - touch_to_fill_controller().Show(std::vector<CredentialPair>{alice}, - driver().AsWeakPtr()); -} - TEST_F(TouchToFillControllerTest, Show_And_Fill_Android_Credential) { // Test multiple credentials with one of them being an Android credential. - CredentialPair alice( - base::ASCIIToUTF16("alice"), base::ASCIIToUTF16("p4ssw0rd"), - GURL("https://example.com"), /*is_public_suffix_match=*/false); + CredentialPair credentials[] = { + {base::ASCIIToUTF16("alice"), base::ASCIIToUTF16("p4ssw0rd"), + GURL(kExampleCom), + /*is_public_suffix_match=*/false}, + {base::ASCIIToUTF16("bob"), base::ASCIIToUTF16("s3cr3t"), + GURL("android://hash@com.example.my"), + /*is_public_suffix_match=*/false}}; - CredentialPair bob(base::ASCIIToUTF16("bob"), base::ASCIIToUTF16("s3cr3t"), - GURL("android://hash@com.example.my"), - /*is_public_suffix_match=*/false); - - EXPECT_CALL( - manual_filling_controller(), - RefreshSuggestions( - autofill::AccessorySheetData::Builder( - autofill::AccessoryTabType::TOUCH_TO_FILL, - base::ASCIIToUTF16("Touch to Fill")) - .AddUserInfo() - .AppendField(base::ASCIIToUTF16("alice"), - base::ASCIIToUTF16("alice"), "0", - /*is_obfuscated=*/false, /*is_selectable=*/true) - .AppendField(base::ASCIIToUTF16("p4ssw0rd"), - base::ASCIIToUTF16("p4ssw0rd"), "0", - /*is_obfuscated=*/true, /*is_selectable=*/false) - .AddUserInfo() - .AppendField(base::ASCIIToUTF16("bob"), base::ASCIIToUTF16("bob"), - "1", /*is_obfuscated=*/false, /*is_selectable=*/true) - .AppendField(base::ASCIIToUTF16("s3cr3t"), - base::ASCIIToUTF16("s3cr3t"), "1", - /*is_obfuscated=*/true, /*is_selectable=*/false) - .Build())); - touch_to_fill_controller().Show(std::vector<CredentialPair>{alice, bob}, - driver().AsWeakPtr()); - - EXPECT_CALL(driver(), FillSuggestion(base::ASCIIToUTF16("bob"), - base::ASCIIToUTF16("s3cr3t"))); - EXPECT_CALL(manual_filling_controller(), - UpdateSourceAvailability( - ManualFillingController::FillingSource::TOUCH_TO_FILL, - /*has_suggestions=*/false)); + TouchToFillView::ShowCallback callback; + EXPECT_CALL(view(), Show(Eq(base::ASCIIToUTF16("example.com")), + ElementsAreArray(credentials), _)) + .WillOnce(SaveArg<2>(&callback)); + touch_to_fill_controller().Show(credentials, driver().AsWeakPtr()); // Test that we correctly log the presence of an Android credential. base::HistogramTester tester; - touch_to_fill_controller().OnFillingTriggered(autofill::UserInfo::Field( - base::ASCIIToUTF16("bob"), base::ASCIIToUTF16("bob"), "1", - /*is_obfuscated=*/false, /*is_selectable=*/true)); + EXPECT_CALL(driver(), FillSuggestion(base::ASCIIToUTF16("bob"), + base::ASCIIToUTF16("s3cr3t"))); + std::move(callback).Run(credentials[1]); tester.ExpectUniqueSample("PasswordManager.FilledCredentialWasFromAndroidApp", true, 1); }
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index b13601d1..2af1911 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -671,6 +671,12 @@ { key::kDeviceLoginScreenCursorHighlightEnabled, nullptr, base::Value::Type::BOOLEAN }, + { key::kDeviceLoginScreenCaretHighlightEnabled, + nullptr, + base::Value::Type::BOOLEAN }, + { key::kDeviceLoginScreenMonoAudioEnabled, + nullptr, + base::Value::Type::BOOLEAN }, { key::kRebootAfterUpdate, prefs::kRebootAfterUpdate, base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index 910a401..9a1e792 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -2311,10 +2311,7 @@ break; case IDC_CONTENT_CONTEXT_RELOADFRAME: - // We always obey the cache here. - // TODO(evanm): Perhaps we could allow shift-clicking the menu item to do - // a cache-ignoring reload of the frame. - source_web_contents_->ReloadFocusedFrame(false); + source_web_contents_->ReloadFocusedFrame(); break; case IDC_CONTENT_CONTEXT_VIEWFRAMESOURCE:
diff --git a/chrome/browser/resources/chromeos/camera/.eslintrc.js b/chrome/browser/resources/chromeos/camera/.eslintrc.js index 875b7ac6..bb791539 100644 --- a/chrome/browser/resources/chromeos/camera/.eslintrc.js +++ b/chrome/browser/resources/chromeos/camera/.eslintrc.js
@@ -150,6 +150,7 @@ // Adds BigInt64Array here since current version of eslint does not treat // BigInt64Array as a defined type. 'BigInt64Array': 'readable', + 'chromeosCamera': 'readable', 'cros': 'readable', 'ImageCapture': 'readable', 'webkitRequestFileSystem': 'readable',
diff --git a/chrome/browser/resources/chromeos/camera/BUILD.gn b/chrome/browser/resources/chromeos/camera/BUILD.gn index 814152f..0aa961c3 100644 --- a/chrome/browser/resources/chromeos/camera/BUILD.gn +++ b/chrome/browser/resources/chromeos/camera/BUILD.gn
@@ -234,6 +234,7 @@ copy("chrome_camera_app_mojo_generated") { sources = [ "$root_gen_dir/components/arc/mojom/camera_intent.mojom-lite.js", + "$root_gen_dir/components/chromeos_camera/common/camera_app_helper.mojom-lite.js", "$root_gen_dir/media/capture/mojom/image_capture.mojom-lite.js", "$root_gen_dir/media/capture/video/chromeos/mojom/camera_app.mojom-lite.js", "$root_gen_dir/media/capture/video/chromeos/mojom/camera_common.mojom-lite.js", @@ -246,6 +247,7 @@ deps = [ "//components/arc/mojom:camera_intent_js", + "//components/chromeos_camera/common:camera_app_helper_js", "//media/capture/mojom:image_capture_js", "//media/capture/video/chromeos/mojom:cros_camera_js", "//mojo/public/js:bindings_lite",
diff --git a/chrome/browser/resources/chromeos/camera/src/js/mojo/BUILD.gn b/chrome/browser/resources/chromeos/camera/src/js/mojo/BUILD.gn index cbfdda4c..ba8aca3 100644 --- a/chrome/browser/resources/chromeos/camera/src/js/mojo/BUILD.gn +++ b/chrome/browser/resources/chromeos/camera/src/js/mojo/BUILD.gn
@@ -15,7 +15,7 @@ js_library("chrome_helper") { deps = [ "//components/arc/mojom:camera_intent_js_library_for_compile", - "//media/capture/video/chromeos/mojom:cros_camera_js_library_for_compile", + "//components/chromeos_camera/common:camera_app_helper_js_library_for_compile", ] externs_list = [ "$externs_path/pending.js" ] }
diff --git a/chrome/browser/resources/chromeos/camera/src/js/mojo/chrome_helper.js b/chrome/browser/resources/chromeos/camera/src/js/mojo/chrome_helper.js index 6c431182..9e70d267 100644 --- a/chrome/browser/resources/chromeos/camera/src/js/mojo/chrome_helper.js +++ b/chrome/browser/resources/chromeos/camera/src/js/mojo/chrome_helper.js
@@ -24,9 +24,9 @@ constructor() { /** * An interface remote that is used to communicate with Chrome. - * @type {cros.mojom.CameraAppHelperRemote} + * @type {chromeosCamera.mojom.CameraAppHelperRemote} */ - this.remote_ = cros.mojom.CameraAppHelper.getRemote(); + this.remote_ = chromeosCamera.mojom.CameraAppHelper.getRemote(); } /**
diff --git a/chrome/browser/resources/chromeos/camera/src/js/util.js b/chrome/browser/resources/chromeos/camera/src/js/util.js index 2ebdcab..3ae841901 100644 --- a/chrome/browser/resources/chromeos/camera/src/js/util.js +++ b/chrome/browser/resources/chromeos/camera/src/js/util.js
@@ -857,7 +857,8 @@ // App-window's isFullscreen, isMaximized state and window's outer-size may // not be updated immediately during resizing. Use if app-window's outerBounds // width matches screen width here as workarounds. - return chrome.app.window.current().outerBounds.width >= screen.width; + return chrome.app.window.current().outerBounds.width >= screen.width || + chrome.app.window.current().outerBounds.height >= screen.height; }; /**
diff --git a/chrome/browser/resources/chromeos/camera/src/views/main.html b/chrome/browser/resources/chromeos/camera/src/views/main.html index 2805f65..5d3f398 100644 --- a/chrome/browser/resources/chromeos/camera/src/views/main.html +++ b/chrome/browser/resources/chromeos/camera/src/views/main.html
@@ -37,6 +37,7 @@ <script src="../js/mojo/range.mojom-lite.js"></script> <script src="../js/mojo/camera_intent.mojom-lite.js"></script> <script src="../js/mojo/camera_app.mojom-lite.js"></script> + <script src="../js/mojo/camera_app_helper.mojom-lite.js"></script> <script src="../js/mojo/chrome_helper.js"></script> <script src="../js/mojo/device_operator.js"></script> <script src="../js/mojo/image_capture.js"></script>
diff --git a/chrome/browser/resources/chromeos/login/md_screen_container.css b/chrome/browser/resources/chromeos/login/md_screen_container.css index 3cbba1a68..1d559ae 100644 --- a/chrome/browser/resources/chromeos/login/md_screen_container.css +++ b/chrome/browser/resources/chromeos/login/md_screen_container.css
@@ -123,6 +123,15 @@ width: 100%; } +#oobe.account-picker { + max-height: unset; + max-width: unset; + padding-bottom: unset; + padding-inline-end: unset; + padding-inline-start: unset; + padding-top: unset; +} + #outer-container.fullscreen, #outer-container.fullscreen #oobe, #inner-container,
diff --git a/chrome/browser/resources/settings/site_settings/constants.js b/chrome/browser/resources/settings/site_settings/constants.js index a7cf78b..f65608a 100644 --- a/chrome/browser/resources/settings/site_settings/constants.js +++ b/chrome/browser/resources/settings/site_settings/constants.js
@@ -121,3 +121,10 @@ MOST_VISITED: 'most-visited', STORAGE: 'data-stored', }; + +/** + * String representation of the wildcard used for universal + * match for SiteExceptions. + * @type {string} + */ +settings.SITE_EXCEPTION_WILDCARD = '*';
diff --git a/chrome/browser/resources/settings/site_settings/site_list_entry.html b/chrome/browser/resources/settings/site_settings/site_list_entry.html index f296bf5..da64458 100644 --- a/chrome/browser/resources/settings/site_settings/site_list_entry.html +++ b/chrome/browser/resources/settings/site_settings/site_list_entry.html
@@ -36,16 +36,17 @@ <site-favicon url="[[model.origin]]"></site-favicon> <div class="middle no-min-width"> <div class="text-elide"> - <span class="url-directionality">[[model.displayName]]</span> + <span class="url-directionality">[[computeDisplayName_(model)]] + </span> </div> <!-- This div must not contain extra whitespace. --> <div class="secondary text-elide" - id="siteDescription">[[siteDescription_]]</div> + id="siteDescription">[[computeSiteDescription_(model)]]</div> </div> <template is="dom-if" if="[[allowNavigateToSiteDetail_]]"> <cr-icon-button class="subpage-arrow" - aria-label$="[[model.displayName]]" + aria-label$="[[computeDisplayName_(model)]]" aria-describedby="siteDescription" focus-row-control focus-type="site-details"></cr-icon-button> <div class="separator"></div>
diff --git a/chrome/browser/resources/settings/site_settings/site_list_entry.js b/chrome/browser/resources/settings/site_settings/site_list_entry.js index fda7071a..b296f31 100644 --- a/chrome/browser/resources/settings/site_settings/site_list_entry.js +++ b/chrome/browser/resources/settings/site_settings/site_list_entry.js
@@ -55,12 +55,6 @@ }, /** @private */ - siteDescription_: { - type: String, - computed: 'computeSiteDescription_(model)', - }, - - /** @private */ showPolicyPrefIndicator_: { type: Boolean, computed: 'computeShowPolicyPrefIndicator_(model)', @@ -126,34 +120,59 @@ }, /** + * Returns the appropriate display name to show for the exception. + * This can, for example, be the website that is affected itself, + * or the website whose third parties are also affected. + * @return {string} + */ + computeDisplayName_: function() { + if (this.model.embeddingOrigin && + this.model.category === settings.ContentSettingsTypes.COOKIES && + this.model.origin.trim() == settings.SITE_EXCEPTION_WILDCARD) { + return this.model.embeddingOrigin; + } + return this.model.displayName; + }, + + /** * Returns the appropriate site description to display. This can, for example, * be blank, an 'embedded on <site>' or 'Current incognito session' (or a * mix of the last two). - * @return {string} The site description. + * @return {string} */ computeSiteDescription_: function() { - let displayName = ''; + let description = ''; + if (this.model.embeddingOrigin) { - displayName = loadTimeData.getStringF( - 'embeddedOnHost', this.sanitizePort(this.model.embeddingOrigin)); + if (this.model.category === settings.ContentSettingsTypes.COOKIES && + this.model.origin.trim() == settings.SITE_EXCEPTION_WILDCARD) { + description = + loadTimeData.getString( + 'siteSettingsCookiesThirdPartyExceptionLabel'); + } else { + description = loadTimeData.getStringF( + 'embeddedOnHost', this.sanitizePort(this.model.embeddingOrigin)); + } } else if (this.category == settings.ContentSettingsTypes.GEOLOCATION) { - displayName = loadTimeData.getString('embeddedOnAnyHost'); + description = loadTimeData.getString('embeddedOnAnyHost'); } // <if expr="chromeos"> if (this.model.category === settings.ContentSettingsTypes.NOTIFICATIONS && this.model.showAndroidSmsNote) { - displayName = loadTimeData.getString('androidSmsNote'); + description = loadTimeData.getString('androidSmsNote'); } // </if> if (this.model.incognito) { - if (displayName.length > 0) { - return loadTimeData.getStringF('embeddedIncognitoSite', displayName); + if (description.length > 0) { + description = + loadTimeData.getStringF('embeddedIncognitoSite', description); + } else { + description = loadTimeData.getString('incognitoSite'); } - return loadTimeData.getString('incognitoSite'); } - return displayName; + return description; }, /**
diff --git a/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc b/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc index 532dc2f0..5b27f911c 100644 --- a/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc +++ b/chrome/browser/signin/chromeos_mirror_account_consistency_browsertest.cc
@@ -143,37 +143,15 @@ "consistency_enabled_by_default=false"); } -class ChromeOsMirrorAccountConsistencyTestWithAccountManagerEnabled - : public ChromeOsMirrorAccountConsistencyTest { - public: - ChromeOsMirrorAccountConsistencyTestWithAccountManagerEnabled() = default; - ~ChromeOsMirrorAccountConsistencyTestWithAccountManagerEnabled() override = - default; - - void SetUp() override { - scoped_feature_list_.InitAndEnableFeature( - chromeos::features::kAccountManager); - ChromeOsMirrorAccountConsistencyTest::SetUp(); - } - - private: - base::test::ScopedFeatureList scoped_feature_list_; - - DISALLOW_COPY_AND_ASSIGN( - ChromeOsMirrorAccountConsistencyTestWithAccountManagerEnabled); -}; - -IN_PROC_BROWSER_TEST_F( - ChromeOsMirrorAccountConsistencyTestWithAccountManagerEnabled, - PRE_TestMirrorRequestChromeOsNotChildAccount) { +IN_PROC_BROWSER_TEST_F(ChromeOsMirrorAccountConsistencyTest, + PRE_TestMirrorRequestChromeOsNotChildAccount) { RegisterUser(account_id_); chromeos::StartupUtils::MarkOobeCompleted(); } -// Mirror is not enabled for non-child accounts. -IN_PROC_BROWSER_TEST_F( - ChromeOsMirrorAccountConsistencyTestWithAccountManagerEnabled, - TestMirrorRequestChromeOsNotChildAccount) { +// Mirror is enabled for non-child accounts. +IN_PROC_BROWSER_TEST_F(ChromeOsMirrorAccountConsistencyTest, + TestMirrorRequestChromeOsNotChildAccount) { // Not a child user. LoginUser(account_id_);
diff --git a/chrome/browser/sync/device_info_sync_service_factory.cc b/chrome/browser/sync/device_info_sync_service_factory.cc index 6fcf71c..6de949e 100644 --- a/chrome/browser/sync/device_info_sync_service_factory.cc +++ b/chrome/browser/sync/device_info_sync_service_factory.cc
@@ -23,9 +23,43 @@ #include "components/sync/base/sync_prefs.h" #include "components/sync/model/model_type_store_service.h" #include "components/sync_device_info/device_info_prefs.h" +#include "components/sync_device_info/device_info_sync_client.h" #include "components/sync_device_info/device_info_sync_service_impl.h" #include "components/sync_device_info/local_device_info_provider_impl.h" +namespace { + +class DeviceInfoSyncClient : public syncer::DeviceInfoSyncClient { + public: + explicit DeviceInfoSyncClient(Profile* profile) : profile_(profile) {} + ~DeviceInfoSyncClient() override = default; + + // syncer::DeviceInfoSyncClient: + std::string GetSigninScopedDeviceId() const override { +// Since the local sync backend is currently only supported on Windows don't +// even check the pref on other os-es. +#if defined(OS_WIN) + syncer::SyncPrefs prefs(profile_->GetPrefs()); + if (prefs.IsLocalSyncEnabled()) { + return "local_device"; + } +#endif // defined(OS_WIN) + + return GetSigninScopedDeviceIdForProfile(profile_); + } + + // syncer::DeviceInfoSyncClient: + bool GetSendTabToSelfReceivingEnabled() const override { + return send_tab_to_self::IsReceivingEnabledByUserOnThisDevice( + profile_->GetPrefs()); + } + + private: + Profile* const profile_; +}; + +} // namespace + // static syncer::DeviceInfoSyncService* DeviceInfoSyncServiceFactory::GetForProfile( Profile* profile) { @@ -72,41 +106,17 @@ content::BrowserContext* context) const { Profile* profile = Profile::FromBrowserContext(context); - syncer::LocalDeviceInfoProviderImpl::SigninScopedDeviceIdCallback - signin_scoped_device_id_callback; - syncer::LocalDeviceInfoProviderImpl::SendTabToSelfReceivingEnabledCallback - send_tab_to_self_receiving_enabled_callback; - bool local_sync_backend_enabled = false; - -// Since the local sync backend is currently only supported on Windows don't -// even check the pref on other os-es. -#if defined(OS_WIN) - syncer::SyncPrefs prefs(profile->GetPrefs()); - local_sync_backend_enabled = prefs.IsLocalSyncEnabled(); -#endif // defined(OS_WIN) - - if (local_sync_backend_enabled) { - signin_scoped_device_id_callback = - base::BindRepeating([]() { return std::string("local_device"); }); - } else { - signin_scoped_device_id_callback = - base::BindRepeating(&GetSigninScopedDeviceIdForProfile, profile); - } - - send_tab_to_self_receiving_enabled_callback = base::BindRepeating( - &send_tab_to_self::IsReceivingEnabledByUserOnThisDevice, - profile->GetPrefs()); - + auto device_info_sync_client = + std::make_unique<DeviceInfoSyncClient>(profile); auto local_device_info_provider = std::make_unique<syncer::LocalDeviceInfoProviderImpl>( chrome::GetChannel(), chrome::GetVersionString(), - signin_scoped_device_id_callback, - send_tab_to_self_receiving_enabled_callback); - + device_info_sync_client.get()); auto device_prefs = std::make_unique<syncer::DeviceInfoPrefs>(profile->GetPrefs()); return new syncer::DeviceInfoSyncServiceImpl( ModelTypeStoreServiceFactory::GetForProfile(profile)->GetStoreFactory(), - std::move(local_device_info_provider), std::move(device_prefs)); + std::move(local_device_info_provider), std::move(device_prefs), + std::move(device_info_sync_client)); }
diff --git a/chrome/browser/sync/glue/synced_tab_delegate_android.cc b/chrome/browser/sync/glue/synced_tab_delegate_android.cc index aab6d56b..acb90ef 100644 --- a/chrome/browser/sync/glue/synced_tab_delegate_android.cc +++ b/chrome/browser/sync/glue/synced_tab_delegate_android.cc
@@ -33,7 +33,7 @@ } // namespace SyncedTabDelegateAndroid::SyncedTabDelegateAndroid(TabAndroid* tab_android) - : tab_android_(tab_android), source_tab_id_(SessionID::InvalidValue()) {} + : tab_android_(tab_android) {} SyncedTabDelegateAndroid::~SyncedTabDelegateAndroid() {} @@ -45,10 +45,6 @@ return SessionIdFromAndroidId(tab_android_->GetAndroidId()); } -SessionID SyncedTabDelegateAndroid::GetSourceTabID() const { - return source_tab_id_; -} - bool SyncedTabDelegateAndroid::IsPlaceholderTab() const { return web_contents() == nullptr; } @@ -57,8 +53,6 @@ content::WebContents* web_contents, int source_tab_android_id) { TabContentsSyncedTabDelegate::SetWebContents(web_contents); - - source_tab_id_ = SessionIdFromAndroidId(source_tab_android_id); } void SyncedTabDelegateAndroid::ResetWebContents() {
diff --git a/chrome/browser/sync/glue/synced_tab_delegate_android.h b/chrome/browser/sync/glue/synced_tab_delegate_android.h index c4608ab..2a87b97 100644 --- a/chrome/browser/sync/glue/synced_tab_delegate_android.h +++ b/chrome/browser/sync/glue/synced_tab_delegate_android.h
@@ -32,7 +32,6 @@ // SyncedTabDelegate: SessionID GetWindowId() const override; SessionID GetSessionId() const override; - SessionID GetSourceTabID() const override; bool IsPlaceholderTab() const override; // Set the web contents for this tab and handles source tab ID initialization. @@ -43,7 +42,6 @@ private: TabAndroid* tab_android_; - SessionID source_tab_id_; DISALLOW_COPY_AND_ASSIGN(SyncedTabDelegateAndroid); };
diff --git a/chrome/browser/sync/profile_sync_service_android.cc b/chrome/browser/sync/profile_sync_service_android.cc index 6ea3241d6..30863e6e8 100644 --- a/chrome/browser/sync/profile_sync_service_android.cc +++ b/chrome/browser/sync/profile_sync_service_android.cc
@@ -120,13 +120,6 @@ env, weak_java_profile_sync_service_.get(env)); } -bool ProfileSyncServiceAndroid::IsSyncAllowedByAndroid() const { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - JNIEnv* env = AttachCurrentThread(); - return Java_ProfileSyncService_isMasterSyncEnabled( - env, weak_java_profile_sync_service_.get(env)); -} - // Pure ProfileSyncService calls. jboolean ProfileSyncServiceAndroid::IsSyncRequested(
diff --git a/chrome/browser/sync/profile_sync_service_android.h b/chrome/browser/sync/profile_sync_service_android.h index b322c88..e5cbed0 100644 --- a/chrome/browser/sync/profile_sync_service_android.h +++ b/chrome/browser/sync/profile_sync_service_android.h
@@ -184,9 +184,6 @@ const base::android::JavaParamRef<jobject>& obj); private: - // Returns whether sync is allowed by Android. - bool IsSyncAllowedByAndroid() const; - // A reference to the Chrome profile object. Profile* profile_;
diff --git a/chrome/browser/sync/profile_sync_service_factory_unittest.cc b/chrome/browser/sync/profile_sync_service_factory_unittest.cc index 5678ae8..409272c 100644 --- a/chrome/browser/sync/profile_sync_service_factory_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_factory_unittest.cc
@@ -45,7 +45,7 @@ // Returns the collection of default datatypes. std::vector<syncer::ModelType> DefaultDatatypes() { - static_assert(46 == syncer::ModelType::NUM_ENTRIES, + static_assert(39 == syncer::ModelType::NUM_ENTRIES, "When adding a new type, you probably want to add it here as " "well (assuming it is already enabled).");
diff --git a/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.cc b/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.cc index 1a166c3..e352d2d 100644 --- a/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.cc +++ b/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.cc
@@ -33,9 +33,7 @@ SyncSessionsRouterTabHelper::SyncSessionsRouterTabHelper( content::WebContents* web_contents, SyncSessionsWebContentsRouter* router) - : content::WebContentsObserver(web_contents), - router_(router), - source_tab_id_(SessionID::InvalidValue()) { + : content::WebContentsObserver(web_contents), router_(router) { chrome_translate_client_ = ChromeTranslateClient::FromWebContents(web_contents); // A translate client is not always attached to web contents (e.g. tests). @@ -86,7 +84,9 @@ ui::PageTransition transition, bool started_from_context_menu, bool renderer_initiated) { - SetSourceTabIdForChild(new_contents); + // TODO(crbug.com/1007969): This is a relic from when we actually did change + // something about the tab here. It should be safe to remove now. + NotifyRouter(); } void SyncSessionsRouterTabHelper::OnLanguageDetermined( @@ -95,18 +95,6 @@ NotifyRouter(); } -void SyncSessionsRouterTabHelper::SetSourceTabIdForChild( - content::WebContents* child_contents) { - SessionID source_tab_id = SessionTabHelper::IdForTab(web_contents()); - if (child_contents && - SyncSessionsRouterTabHelper::FromWebContents(child_contents) && - child_contents != web_contents() && source_tab_id.is_valid()) { - SyncSessionsRouterTabHelper::FromWebContents(child_contents) - ->set_source_tab_id(source_tab_id); - } - NotifyRouter(); -} - void SyncSessionsRouterTabHelper::NotifyRouter(bool page_load_completed) { if (router_) router_->NotifyTabModified(web_contents(), page_load_completed);
diff --git a/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.h b/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.h index b76434b..fe9716a3 100644 --- a/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.h +++ b/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.h
@@ -22,8 +22,7 @@ // TabHelper class that forwards tab-level WebContentsObserver events to a // (per-profile) sessions router. The router is responsible for forwarding -// these events to sessions sync. This class also tracks the source tab id -// of its corresponding tab, if available. +// these events to sessions sync. // A TabHelper is a WebContentsObserver tied to the top level WebContents for a // browser tab. // https://chromium.googlesource.com/chromium/src/+/master/docs/tab_helpers.md @@ -67,35 +66,16 @@ bool icon_url_changed, const gfx::Image& image) override; - // Sets the source tab id for the given child WebContents to the id of the - // WebContents that owns this helper. - void SetSourceTabIdForChild(content::WebContents* child_contents); - - // Get the tab id of the tab responsible for creating the tab this helper - // corresponds to. Returns an invalid ID if there is no such tab. - SessionID source_tab_id() const { return source_tab_id_; } - private: friend class content::WebContentsUserData<SyncSessionsRouterTabHelper>; explicit SyncSessionsRouterTabHelper(content::WebContents* web_contents, SyncSessionsWebContentsRouter* router); - // Set the tab id of the tab reponsible for creating the tab this helper - // corresponds to. - void set_source_tab_id(SessionID id) { source_tab_id_ = id; } - void NotifyRouter(bool page_load_completed = false); // |router_| is a KeyedService and is guaranteed to outlive |this|. SyncSessionsWebContentsRouter* router_; - // Tab id of the tab from which this tab was created. Example events that - // create this relationship: - // * From context menu, "Open link in new tab". - // * From context menu, "Open link in new window". - // * Ctrl-click. - // * Click on a link with target='_blank'. - SessionID source_tab_id_; ChromeTranslateClient* chrome_translate_client_;
diff --git a/chrome/browser/sync/test/integration/enable_disable_test.cc b/chrome/browser/sync/test/integration/enable_disable_test.cc index 3aed8c6..ab0552b4 100644 --- a/chrome/browser/sync/test/integration/enable_disable_test.cc +++ b/chrome/browser/sync/test/integration/enable_disable_test.cc
@@ -171,14 +171,16 @@ << " for " << GetUserSelectableTypeName(type); if (syncer::CommitOnlyTypes().Has(grouped_type)) { - EXPECT_EQ(0, histogram_tester.GetBucketCount( - "Sync.PostedDataTypeGetUpdatesRequest", - ModelTypeToHistogramInt(grouped_type))) + EXPECT_EQ(0, + histogram_tester.GetBucketCount( + "Sync.PostedDataTypeGetUpdatesRequest", + static_cast<int>(ModelTypeHistogramValue(grouped_type)))) << " for " << ModelTypeToString(grouped_type); } else { - EXPECT_NE(0, histogram_tester.GetBucketCount( - "Sync.PostedDataTypeGetUpdatesRequest", - ModelTypeToHistogramInt(grouped_type))) + EXPECT_NE(0, + histogram_tester.GetBucketCount( + "Sync.PostedDataTypeGetUpdatesRequest", + static_cast<int>(ModelTypeHistogramValue(grouped_type)))) << " for " << ModelTypeToString(grouped_type); } }
diff --git a/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc b/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc index 8f6ede2..94eba27 100644 --- a/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc
@@ -289,7 +289,8 @@ EXPECT_EQ(1, histogram_tester.GetBucketCount( "Sync.USSMigrationSuccess", - syncer::ModelTypeToHistogramInt(syncer::PASSWORDS))); + static_cast<int>( + syncer::ModelTypeHistogramValue(syncer::PASSWORDS)))); EXPECT_THAT( histogram_tester.GetAllSamples("Sync.USSMigrationEntityCount.PASSWORD"), ElementsAre(base::Bucket(/*min=*/2, /*count=*/1)));
diff --git a/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc b/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc index 8520666..b2feacd 100644 --- a/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc
@@ -692,33 +692,6 @@ {{base_url.spec()}, {new_window_url.spec(), moved_tab_url.spec()}})); } -IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest, SourceTabIDSet) { - ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; - ASSERT_TRUE(CheckInitialState(0)); - - GURL base_url = GURL(kURL1); - ASSERT_TRUE(OpenTab(0, base_url)); - - WaitForURLOnServer(base_url); - - GURL new_tab_url = GURL(kURL2); - ASSERT_TRUE(OpenTabFromSourceIndex( - 0, 0, new_tab_url, WindowOpenDisposition::NEW_FOREGROUND_TAB)); - WaitForHierarchyOnServer( - SessionsHierarchy({{base_url.spec(), new_tab_url.spec()}})); - - content::WebContents* original_tab_contents = - GetBrowser(0)->tab_strip_model()->GetWebContentsAt(0); - content::WebContents* new_tab_contents = - GetBrowser(0)->tab_strip_model()->GetWebContentsAt(1); - - SessionID source_tab_id = SessionTabHelper::IdForTab(original_tab_contents); - sync_sessions::SyncSessionsRouterTabHelper* new_tab_helper = - sync_sessions::SyncSessionsRouterTabHelper::FromWebContents( - new_tab_contents); - EXPECT_EQ(new_tab_helper->source_tab_id(), source_tab_id); -} - IN_PROC_BROWSER_TEST_F(SingleClientSessionsSyncTest, CookieJarMismatch) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc index 52a028e..fc6efb7 100644 --- a/chrome/browser/themes/browser_theme_pack.cc +++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -62,7 +62,7 @@ // change default theme assets, if you need themes to recreate their generated // images (which are cached), or if you changed how missing values are // generated. -const int kThemePackVersion = 71; +const int kThemePackVersion = 72; // IDs that are in the DataPack won't clash with the positive integer // uint16_t. kHeaderID should always have the maximum value because we want the
diff --git a/chrome/browser/touch_to_fill/android/OWNERS b/chrome/browser/touch_to_fill/android/OWNERS index 6dfa6ec..ea9b03f9 100644 --- a/chrome/browser/touch_to_fill/android/OWNERS +++ b/chrome/browser/touch_to_fill/android/OWNERS
@@ -1,4 +1,5 @@ jdoerrie@chromium.org fhorschig@chromium.org +bsazonov@chromium.org # COMPONENT: UI>Browser>Passwords
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 9b9c939..f8a1d1e 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -2480,8 +2480,9 @@ // Browser, In-progress download termination handling (private): bool Browser::CanCloseWithInProgressDownloads() { -#if defined(OS_MACOSX) - // On Mac, non-incognito download can still continue after window is closed. +#if defined(OS_MACOSX) || defined(OS_CHROMEOS) + // On Mac and ChromeOS, non-incognito download can still continue after window + // is closed. if (!profile_->IsOffTheRecord()) return true; #endif
diff --git a/chrome/browser/ui/browser_close_unittest.cc b/chrome/browser/ui/browser_close_unittest.cc index b06a9bb..9faf1b7e 100644 --- a/chrome/browser/ui/browser_close_unittest.cc +++ b/chrome/browser/ui/browser_close_unittest.cc
@@ -269,7 +269,7 @@ EXPECT_EQ(Browser::DownloadCloseType::kBrowserShutdown, browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking)); EXPECT_EQ(num_downloads_blocking, 1); -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) || defined(OS_CHROMEOS) EXPECT_EQ(true, browser->CanCloseWithInProgressDownloads()); #else EXPECT_EQ(false, browser->CanCloseWithInProgressDownloads());
diff --git a/chrome/browser/ui/cocoa/tab_menu_bridge.mm b/chrome/browser/ui/cocoa/tab_menu_bridge.mm index 4832a1a..55ae27d 100644 --- a/chrome/browser/ui/cocoa/tab_menu_bridge.mm +++ b/chrome/browser/ui/cocoa/tab_menu_bridge.mm
@@ -131,6 +131,20 @@ DCHECK(tab_strip_model); DCHECK_EQ(tab_strip_model, model_); + // The menu doesn't represent selection in any way, so ignore it. + if (change.type() == TabStripModelChange::kSelectionOnly) + return; + + // If a single WebContents is being replaced, just regenerate that one menu + // item. + if (change.type() == TabStripModelChange::kReplaced) { + const TabStripModelChange::Replace* replace = change.GetReplace(); + int menu_index = replace->index + dynamic_items_start_; + UpdateItemForWebContents([menu_item_.submenu itemAtIndex:menu_index], + replace->new_contents); + return; + } + // Rather than doing clever updating from |change|, just destroy the dynamic // menu items and re-add them. RemoveAllDynamicItems();
diff --git a/chrome/browser/ui/cocoa/tab_menu_bridge_unittest.mm b/chrome/browser/ui/cocoa/tab_menu_bridge_unittest.mm index e7aec59..cfeedaa 100644 --- a/chrome/browser/ui/cocoa/tab_menu_bridge_unittest.mm +++ b/chrome/browser/ui/cocoa/tab_menu_bridge_unittest.mm
@@ -70,6 +70,10 @@ return contents; } + content::WebContents* GetModelWebContentsAt(int index) { + return model()->GetWebContentsAt(index); + } + void AddModelTabNamed(const std::string& name) { model()->AppendWebContents(CreateWebContents(name), true); } @@ -103,6 +107,16 @@ } } + void ReplaceModelTabNamed(const std::string& old_name, + const std::string& new_name) { + int index = ModelIndexForTabNamed(old_name); + if (index >= 0) { + std::unique_ptr<content::WebContents> old_contents = + model()->ReplaceWebContentsAt(index, CreateWebContents(new_name)); + // Let the old WebContents be destroyed here. + } + } + NSMenuItem* MenuItemForTabNamed(const std::string& name) { return [menu() itemWithTitle:base::SysUTF8ToNSString(name)]; } @@ -166,6 +180,11 @@ RenameModelTabNamed("Tab 1", "Tab 4"); ExpectDynamicTabsInMenuAre({"Tab 4", "Tab 3", "Tab 2"}); + + content::WebContents* old_contents = GetModelWebContentsAt(0); + ReplaceModelTabNamed("Tab 4", "Tab 5"); + ASSERT_NE(GetModelWebContentsAt(0), old_contents); + ExpectDynamicTabsInMenuAre({"Tab 5", "Tab 3", "Tab 2"}); } TEST_F(TabMenuBridgeTest, ClickingMenuActivatesTab) {
diff --git a/chrome/browser/ui/hats/hats_service.cc b/chrome/browser/ui/hats/hats_service.cc index dd374619..2edb44b 100644 --- a/chrome/browser/ui/hats/hats_service.cc +++ b/chrome/browser/ui/hats/hats_service.cc
@@ -136,6 +136,10 @@ return true; } + // Survey can not be loaded and shown if there is no network connection. + if (net::NetworkChangeNotifier::IsOffline()) + return false; + bool consent_given = g_browser_process->GetMetricsServicesManager()->IsMetricsConsentGiven(); if (!consent_given)
diff --git a/chrome/browser/ui/sync/browser_synced_tab_delegate.cc b/chrome/browser/ui/sync/browser_synced_tab_delegate.cc index a900e92..e003a56 100644 --- a/chrome/browser/ui/sync/browser_synced_tab_delegate.cc +++ b/chrome/browser/ui/sync/browser_synced_tab_delegate.cc
@@ -22,13 +22,6 @@ return SessionTabHelper::FromWebContents(web_contents())->session_id(); } -SessionID BrowserSyncedTabDelegate::GetSourceTabID() const { - const sync_sessions::SyncSessionsRouterTabHelper* helper = - sync_sessions::SyncSessionsRouterTabHelper::FromWebContents( - web_contents()); - return helper->source_tab_id(); -} - bool BrowserSyncedTabDelegate::IsPlaceholderTab() const { return false; }
diff --git a/chrome/browser/ui/sync/browser_synced_tab_delegate.h b/chrome/browser/ui/sync/browser_synced_tab_delegate.h index 49fc3407..0ec9d5c5 100644 --- a/chrome/browser/ui/sync/browser_synced_tab_delegate.h +++ b/chrome/browser/ui/sync/browser_synced_tab_delegate.h
@@ -25,7 +25,6 @@ // SyncedTabDelegate: SessionID GetWindowId() const override; SessionID GetSessionId() const override; - SessionID GetSourceTabID() const override; bool IsPlaceholderTab() const override; private:
diff --git a/chrome/browser/ui/sync/tab_contents_synced_tab_delegate_unittest.cc b/chrome/browser/ui/sync/tab_contents_synced_tab_delegate_unittest.cc index 1d9f20a..1b63782 100644 --- a/chrome/browser/ui/sync/tab_contents_synced_tab_delegate_unittest.cc +++ b/chrome/browser/ui/sync/tab_contents_synced_tab_delegate_unittest.cc
@@ -20,9 +20,6 @@ SessionID GetWindowId() const override { return SessionID::InvalidValue(); } SessionID GetSessionId() const override { return SessionID::InvalidValue(); } - SessionID GetSourceTabID() const override { - return SessionID::InvalidValue(); - } bool IsPlaceholderTab() const override { return false; } };
diff --git a/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.cc b/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.cc index 2780cb1..dd5237e 100644 --- a/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.cc +++ b/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.cc
@@ -14,7 +14,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/engine/model_type_processor.h" #include "components/sync/engine/non_blocking_sync_common.h" #include "components/sync/model/entity_data.h" @@ -309,9 +309,9 @@ *entity->specifics.mutable_session() = specifics; entity->creation_time = timestamp; entity->modification_time = timestamp; - entity->client_tag_hash = syncer::GenerateSyncableHash( + entity->client_tag_hash = syncer::ClientTagHash::FromUnhashed( syncer::SESSIONS, sync_sessions::SessionStore::GetClientTag(specifics)); - entity->id = entity->client_tag_hash; + entity->id = entity->client_tag_hash.value(); auto update = std::make_unique<syncer::UpdateResponseData>(); update->entity = std::move(entity);
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.cc b/chrome/browser/ui/views/profiles/profile_menu_view.cc index 663af44..ec038cc 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_view.cc
@@ -284,6 +284,11 @@ profiles::CloseProfileWindows(browser()->profile()); } +void ProfileMenuView::OnSyncSettingsButtonClicked() { + RecordClick(ActionableItem::kSyncSettingsButton); + chrome::ShowSettingsSubPage(browser(), chrome::kSyncSetupSubPage); +} + void ProfileMenuView::OnSyncErrorButtonClicked( sync_ui_util::AvatarSyncErrorType error) { RecordClick(ActionableItem::kSyncErrorButton); @@ -507,7 +512,32 @@ IdentityManagerFactory::GetForProfile(browser()->profile()); if (identity_manager->HasPrimaryAccount()) { - // TODO(crbug.com/995720): Implement sync-is-on state. + // Show sync state. + int description_string_id, button_string_id; + sync_ui_util::AvatarSyncErrorType error = + sync_ui_util::GetMessagesForAvatarSyncError( + browser()->profile(), &description_string_id, &button_string_id); + switch (error) { + case sync_ui_util::NO_SYNC_ERROR: + SetSyncInfo( + /*description=*/base::string16(), + l10n_util::GetStringUTF16(IDS_SETTINGS_SYNC_ADVANCED_PAGE_TITLE), + base::BindRepeating(&ProfileMenuView::OnSyncSettingsButtonClicked, + base::Unretained(this))); + break; + case sync_ui_util::MANAGED_USER_UNRECOVERABLE_ERROR: + case sync_ui_util::UNRECOVERABLE_ERROR: + case sync_ui_util::UPGRADE_CLIENT_ERROR: + case sync_ui_util::PASSPHRASE_ERROR: + case sync_ui_util::SETTINGS_UNCONFIRMED_ERROR: + case sync_ui_util::AUTH_ERROR: + SetSyncInfo( + l10n_util::GetStringUTF16(description_string_id), + l10n_util::GetStringUTF16(button_string_id), + base::BindRepeating(&ProfileMenuView::OnSyncErrorButtonClicked, + base::Unretained(this), error)); + break; + } return; }
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.h b/chrome/browser/ui/views/profiles/profile_menu_view.h index d6f0e02..d84ac154 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view.h +++ b/chrome/browser/ui/views/profiles/profile_menu_view.h
@@ -49,7 +49,8 @@ kOtherProfileButton = 13, kCookiesClearedOnExitLink = 14, kAddNewProfileButton = 15, - kMaxValue = kAddNewProfileButton, + kSyncSettingsButton = 16, + kMaxValue = kSyncSettingsButton, }; ProfileMenuView(views::Button* anchor_button, @@ -79,6 +80,7 @@ void OnManageProfilesButtonClicked(); void OnLockButtonClicked(); void OnExitProfileButtonClicked(); + void OnSyncSettingsButtonClicked(); void OnSyncErrorButtonClicked(sync_ui_util::AvatarSyncErrorType error); void OnCurrentProfileCardClicked(); void OnSigninButtonClicked();
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc index 0026389..8280958 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/profiles/profiles_state.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/scoped_account_consistency.h" +#include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/sync/test/integration/secondary_account_helper.h" #include "chrome/browser/themes/theme_service.h" #include "chrome/browser/themes/theme_service_factory.h" @@ -46,6 +47,8 @@ #include "components/prefs/pref_service.h" #include "components/signin/public/base/signin_pref_names.h" #include "components/signin/public/identity_manager/identity_test_utils.h" +#include "components/sync/driver/sync_service.h" +#include "components/sync/driver/sync_user_settings.h" #include "content/public/browser/notification_service.h" #include "content/public/test/test_utils.h" #include "extensions/browser/extension_registry.h" @@ -622,6 +625,14 @@ void SetTargetBrowser(Browser* browser) { target_browser_ = browser; } + signin::IdentityManager* identity_manager() { + return IdentityManagerFactory::GetForProfile(browser()->profile()); + } + + syncer::SyncService* sync_service() { + return ProfileSyncServiceFactory::GetForProfile(browser()->profile()); + } + private: void OpenProfileMenu() { BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser( @@ -716,14 +727,15 @@ base::size( ProfileMenuClickTest_MultipleProfiles::kOrderedActionableItems))); -class ProfileMenuClickTest_WithPrimaryAccount : public ProfileMenuClickTest { +class ProfileMenuClickTest_SyncEnabled : public ProfileMenuClickTest { public: // List of actionable items in the correct order as they appear in the menu. // If a new button is added to the menu, it should also be added to this list. - static constexpr ProfileMenuView::ActionableItem kOrderedActionableItems[8] = + static constexpr ProfileMenuView::ActionableItem kOrderedActionableItems[9] = {ProfileMenuView::ActionableItem::kPasswordsButton, ProfileMenuView::ActionableItem::kCreditCardsButton, ProfileMenuView::ActionableItem::kAddressesButton, + ProfileMenuView::ActionableItem::kSyncSettingsButton, ProfileMenuView::ActionableItem::kManageGoogleAccountButton, ProfileMenuView::ActionableItem::kManageProfilesButton, ProfileMenuView::ActionableItem::kGuestProfileButton, @@ -732,37 +744,92 @@ // there are no other buttons at the end. ProfileMenuView::ActionableItem::kPasswordsButton}; - ProfileMenuClickTest_WithPrimaryAccount() = default; + ProfileMenuClickTest_SyncEnabled() = default; ProfileMenuView::ActionableItem GetExpectedActionableItemAtIndex( size_t index) override { return kOrderedActionableItems[index]; } - DISALLOW_COPY_AND_ASSIGN(ProfileMenuClickTest_WithPrimaryAccount); + DISALLOW_COPY_AND_ASSIGN(ProfileMenuClickTest_SyncEnabled); }; // static constexpr ProfileMenuView::ActionableItem - ProfileMenuClickTest_WithPrimaryAccount::kOrderedActionableItems[]; + ProfileMenuClickTest_SyncEnabled::kOrderedActionableItems[]; -IN_PROC_BROWSER_TEST_P(ProfileMenuClickTest_WithPrimaryAccount, - SetupAndRunTest) { - signin::IdentityManager* identity_manager = - IdentityManagerFactory::GetForProfile(browser()->profile()); - ASSERT_FALSE(identity_manager->HasPrimaryAccount()); - signin::MakePrimaryAccountAvailable(identity_manager, "primary@example.com"); +IN_PROC_BROWSER_TEST_P(ProfileMenuClickTest_SyncEnabled, + DISABLED_SetupAndRunTest) { + // Set primary account. + ASSERT_FALSE(identity_manager()->HasPrimaryAccount()); + signin::MakePrimaryAccountAvailable(identity_manager(), + "primary@example.com"); + ASSERT_TRUE(identity_manager()->HasPrimaryAccount()); + // Start sync. + sync_service()->GetUserSettings()->SetSyncRequested(true); + sync_service()->GetUserSettings()->SetFirstSetupComplete( + syncer::SyncFirstSetupCompleteSource::BASIC_FLOW); + ASSERT_TRUE(sync_service()->IsSyncFeatureEnabled()); RunTest(); } INSTANTIATE_TEST_SUITE_P( , - ProfileMenuClickTest_WithPrimaryAccount, + ProfileMenuClickTest_SyncEnabled, ::testing::Range( size_t(0), - base::size( - ProfileMenuClickTest_WithPrimaryAccount::kOrderedActionableItems))); + base::size(ProfileMenuClickTest_SyncEnabled::kOrderedActionableItems))); + +class ProfileMenuClickTest_SyncError : public ProfileMenuClickTest { + public: + // List of actionable items in the correct order as they appear in the menu. + // If a new button is added to the menu, it should also be added to this list. + static constexpr ProfileMenuView::ActionableItem kOrderedActionableItems[9] = + {ProfileMenuView::ActionableItem::kPasswordsButton, + ProfileMenuView::ActionableItem::kCreditCardsButton, + ProfileMenuView::ActionableItem::kAddressesButton, + ProfileMenuView::ActionableItem::kSyncErrorButton, + ProfileMenuView::ActionableItem::kManageGoogleAccountButton, + ProfileMenuView::ActionableItem::kManageProfilesButton, + ProfileMenuView::ActionableItem::kGuestProfileButton, + ProfileMenuView::ActionableItem::kAddNewProfileButton, + // The first button is added again to finish the cycle and test that + // there are no other buttons at the end. + ProfileMenuView::ActionableItem::kPasswordsButton}; + + ProfileMenuClickTest_SyncError() = default; + + ProfileMenuView::ActionableItem GetExpectedActionableItemAtIndex( + size_t index) override { + return kOrderedActionableItems[index]; + } + + DISALLOW_COPY_AND_ASSIGN(ProfileMenuClickTest_SyncError); +}; + +// static +constexpr ProfileMenuView::ActionableItem + ProfileMenuClickTest_SyncError::kOrderedActionableItems[]; + +IN_PROC_BROWSER_TEST_P(ProfileMenuClickTest_SyncError, + DISABLED_SetupAndRunTest) { + // Set primary account without setting up sync. + ASSERT_FALSE(identity_manager()->HasPrimaryAccount()); + signin::MakePrimaryAccountAvailable(identity_manager(), + "primary@example.com"); + ASSERT_TRUE(identity_manager()->HasPrimaryAccount()); + ASSERT_FALSE(sync_service()->IsSyncFeatureEnabled()); + + RunTest(); +} + +INSTANTIATE_TEST_SUITE_P( + , + ProfileMenuClickTest_SyncError, + ::testing::Range( + size_t(0), + base::size(ProfileMenuClickTest_SyncError::kOrderedActionableItems))); class ProfileMenuClickTest_WithUnconsentedPrimaryAccount : public ProfileMenuClickTest {
diff --git a/chrome/browser/ui/views/toolbar/app_menu.cc b/chrome/browser/ui/views/toolbar/app_menu.cc index eea1608..775abda 100644 --- a/chrome/browser/ui/views/toolbar/app_menu.cc +++ b/chrome/browser/ui/views/toolbar/app_menu.cc
@@ -471,13 +471,6 @@ // the keyboard navigation to work. DCHECK(Button::AsButton(fullscreen_button_)); - fullscreen_button_->SetImage( - ImageButton::STATE_NORMAL, - gfx::CreateVectorIcon( - kFullscreenIcon, - GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor))); - // Since |fullscreen_button_| will reside in a menu, make it ALWAYS // focusable regardless of the platform. fullscreen_button_->SetFocusBehavior(FocusBehavior::ALWAYS); @@ -549,6 +542,13 @@ ui::NativeTheme* theme = GetNativeTheme(); zoom_label_->SetEnabledColor(theme->GetSystemColor( ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor)); + + fullscreen_button_->SetImage( + ImageButton::STATE_NORMAL, + gfx::CreateVectorIcon( + kFullscreenIcon, + GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor))); gfx::ImageSkia hovered_fullscreen_image = gfx::CreateVectorIcon( kFullscreenIcon, theme->GetSystemColor(
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index 49cc12d8..f93df85 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -2987,6 +2987,8 @@ IDS_SETTINGS_SITE_SETTINGS_THIRD_PARTY_COOKIE_REMOVE_CONFIRMATION}, {"siteSettingsCookiesClearThirdParty", IDS_SETTINGS_SITE_SETTINGS_CLEAR_THIRD_PARTY_COOKIES}, + {"siteSettingsCookiesThirdPartyExceptionLabel", + IDS_SETTINGS_SITE_SETTINGS_THIRD_PARTY_COOKIES_EXCEPTION_LABEL}, {"siteSettingsCookieRemoveDialogTitle", IDS_SETTINGS_SITE_SETTINGS_COOKIE_REMOVE_DIALOG_TITLE}, {"siteSettingsCookieRemoveMultipleConfirmation",
diff --git a/chrome/browser/web_applications/components/app_registrar.cc b/chrome/browser/web_applications/components/app_registrar.cc index b5c625e8..9025044 100644 --- a/chrome/browser/web_applications/components/app_registrar.cc +++ b/chrome/browser/web_applications/components/app_registrar.cc
@@ -45,6 +45,11 @@ RecordWebAppUninstallation(profile()->GetPrefs(), app_id); } +void AppRegistrar::NotifyWebAppProfileWillBeDeleted(const AppId& app_id) { + for (AppRegistrarObserver& observer : observers_) + observer.OnWebAppProfileWillBeDeleted(app_id); +} + void AppRegistrar::NotifyAppRegistrarShutdown() { for (AppRegistrarObserver& observer : observers_) observer.OnAppRegistrarShutdown();
diff --git a/chrome/browser/web_applications/components/app_registrar.h b/chrome/browser/web_applications/components/app_registrar.h index f4334f4d..06597c1 100644 --- a/chrome/browser/web_applications/components/app_registrar.h +++ b/chrome/browser/web_applications/components/app_registrar.h
@@ -102,6 +102,7 @@ Profile* profile() const { return profile_; } void NotifyWebAppUninstalled(const AppId& app_id); + void NotifyWebAppProfileWillBeDeleted(const AppId& app_id); void NotifyAppRegistrarShutdown(); private:
diff --git a/chrome/browser/web_applications/components/app_registrar_observer.h b/chrome/browser/web_applications/components/app_registrar_observer.h index 8462f1f5..08830d2b 100644 --- a/chrome/browser/web_applications/components/app_registrar_observer.h +++ b/chrome/browser/web_applications/components/app_registrar_observer.h
@@ -14,6 +14,7 @@ public: virtual void OnWebAppInstalled(const AppId& app_id) {} virtual void OnWebAppUninstalled(const AppId& app_id) {} + virtual void OnWebAppProfileWillBeDeleted(const AppId& app_id) {} virtual void OnAppRegistrarShutdown() {} virtual void OnAppRegistrarDestroyed() {} };
diff --git a/chrome/browser/web_applications/components/file_handler_manager.cc b/chrome/browser/web_applications/components/file_handler_manager.cc index 4b52699..44a8c4e 100644 --- a/chrome/browser/web_applications/components/file_handler_manager.cc +++ b/chrome/browser/web_applications/components/file_handler_manager.cc
@@ -42,6 +42,13 @@ } } +void FileHandlerManager::OnWebAppProfileWillBeDeleted(const AppId& app_id) { + if (base::FeatureList::IsEnabled(blink::features::kFileHandlingAPI) && + OsSupportsWebAppFileHandling()) { + UnregisterFileHandlersForWebApp(app_id, *profile_); + } +} + void FileHandlerManager::OnAppRegistrarDestroyed() { registrar_observer_.RemoveAll(); }
diff --git a/chrome/browser/web_applications/components/file_handler_manager.h b/chrome/browser/web_applications/components/file_handler_manager.h index a88aee9..d43e01a 100644 --- a/chrome/browser/web_applications/components/file_handler_manager.h +++ b/chrome/browser/web_applications/components/file_handler_manager.h
@@ -44,6 +44,7 @@ // AppRegistrarObserver: void OnWebAppInstalled(const AppId& app_id) override; void OnWebAppUninstalled(const AppId& app_id) override; + void OnWebAppProfileWillBeDeleted(const AppId& app_id) override; void OnAppRegistrarDestroyed() override; ScopedObserver<AppRegistrar, AppRegistrarObserver> registrar_observer_;
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc b/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc index 1c8317d..e076fbac 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc
@@ -70,13 +70,26 @@ void BookmarkAppRegistrar::OnExtensionUninstalled( content::BrowserContext* browser_context, - const extensions::Extension* extension, - extensions::UninstallReason reason) { + const Extension* extension, + UninstallReason reason) { DCHECK_EQ(browser_context, profile()); if (extension->from_bookmark()) NotifyWebAppUninstalled(extension->id()); } +void BookmarkAppRegistrar::OnExtensionUnloaded( + content::BrowserContext* browser_context, + const Extension* extension, + UnloadedExtensionReason reason) { + DCHECK_EQ(browser_context, profile()); + if (!extension->from_bookmark()) + return; + // If a profile is removed, notify the web app that it is uninstalled, so it + // can cleanup any state outside the profile dir (e.g., registry settings). + if (reason == UnloadedExtensionReason::PROFILE_SHUTDOWN) + NotifyWebAppProfileWillBeDeleted(extension->id()); +} + void BookmarkAppRegistrar::OnShutdown(ExtensionRegistry* registry) { NotifyAppRegistrarShutdown(); extension_observer_.RemoveAll();
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_registrar.h b/chrome/browser/web_applications/extensions/bookmark_app_registrar.h index 7b4f625a..d012abe5 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_registrar.h +++ b/chrome/browser/web_applications/extensions/bookmark_app_registrar.h
@@ -46,6 +46,9 @@ void OnExtensionUninstalled(content::BrowserContext* browser_context, const Extension* extension, UninstallReason reason) override; + void OnExtensionUnloaded(content::BrowserContext* browser_context, + const Extension* extension, + UnloadedExtensionReason reason) override; void OnShutdown(ExtensionRegistry* registry) override; private:
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc index cde3851..cb5c87d 100644 --- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc +++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -29,7 +29,6 @@ #include "components/autofill/core/common/form_field_data.h" #include "components/autofill/core/common/mojom/autofill_types.mojom.h" #include "components/autofill/core/common/password_form.h" -#include "components/autofill/core/common/password_form_field_prediction_map.h" #include "components/password_manager/core/common/password_manager_features.h" #include "components/safe_browsing/buildflags.h" #include "content/public/renderer/render_frame.h" @@ -62,6 +61,7 @@ using blink::WebFormElement; using blink::WebFrame; using blink::WebInputElement; +using blink::WebLocalFrame; using blink::WebString; using testing::_; @@ -262,6 +262,18 @@ read_only ? WebString::FromUTF8("true") : WebString()); } +bool FormHasFieldWithValue(const autofill::FormData& form, + const std::string& value) { + base::string16 value_16 = ASCIIToUTF16(value); + for (const auto& field : form.fields) { + if (field.value == value_16) + return true; + if (field.typed_value == value_16) + return true; + } + return false; +} + enum PasswordFormSourceType { PasswordFormSubmitted, PasswordFormSameDocumentNavigation, @@ -606,24 +618,6 @@ return fake_driver_.called_show_pw_suggestions(); } - void ExpectFormSubmittedWithUsernameAndPasswords( - const std::string& username_value, - const std::string& password_value, - const std::string& new_password_value) { - base::RunLoop().RunUntilIdle(); - ASSERT_TRUE(fake_driver_.called_password_form_submitted()); - ASSERT_TRUE(static_cast<bool>(fake_driver_.password_form_submitted())); - const autofill::PasswordForm& form = - *(fake_driver_.password_form_submitted()); - EXPECT_EQ(ASCIIToUTF16(username_value), form.username_value); - EXPECT_EQ(ASCIIToUTF16(password_value), form.password_value); - EXPECT_EQ(ASCIIToUTF16(new_password_value), form.new_password_value); - EXPECT_EQ(SubmissionIndicatorEvent::HTML_FORM_SUBMISSION, - form.submission_event); - EXPECT_EQ(SubmissionIndicatorEvent::HTML_FORM_SUBMISSION, - form.form_data.submission_event); - } - void ExpectFieldPropertiesMasks( PasswordFormSourceType expected_type, const std::map<base::string16, FieldPropertiesMask>& @@ -658,7 +652,45 @@ << "Some expected masks are missed in FormData"; } + uint32_t GetFormUniqueRendererId(const WebString& form_id) { + WebLocalFrame* frame = GetMainFrame(); + if (!frame) + return FormData::kNotSetFormRendererId; + WebFormElement web_form = + frame->GetDocument().GetElementById(form_id).To<WebFormElement>(); + return web_form.UniqueRendererFormId(); + } + + void ExpectFormWithUsernameAndPasswordsAndEvent( + const autofill::PasswordForm& form, + uint32_t form_rendere_id, + const std::string& username_value, + const std::string& password_value, + const std::string& new_password_value, + SubmissionIndicatorEvent event) { + EXPECT_EQ(form_rendere_id, form.form_data.unique_renderer_id); + EXPECT_TRUE(FormHasFieldWithValue(form.form_data, username_value)); + EXPECT_TRUE(FormHasFieldWithValue(form.form_data, password_value)); + EXPECT_TRUE(FormHasFieldWithValue(form.form_data, new_password_value)); + EXPECT_EQ(form.form_data.submission_event, event); + } + + void ExpectFormSubmittedWithUsernameAndPasswords( + uint32_t form_rendere_id, + const std::string& username_value, + const std::string& password_value, + const std::string& new_password_value) { + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(fake_driver_.called_password_form_submitted()); + ASSERT_TRUE(static_cast<bool>(fake_driver_.password_form_submitted())); + ExpectFormWithUsernameAndPasswordsAndEvent( + *(fake_driver_.password_form_submitted()), form_rendere_id, + username_value, password_value, new_password_value, + SubmissionIndicatorEvent::HTML_FORM_SUBMISSION); + } + void ExpectSameDocumentNavigationWithUsernameAndPasswords( + uint32_t form_rendere_id, const std::string& username_value, const std::string& password_value, const std::string& new_password_value, @@ -667,13 +699,9 @@ ASSERT_TRUE(fake_driver_.called_same_document_navigation()); ASSERT_TRUE( static_cast<bool>(fake_driver_.password_form_maybe_submitted())); - const autofill::PasswordForm& form = - *(fake_driver_.password_form_maybe_submitted()); - EXPECT_EQ(ASCIIToUTF16(username_value), form.username_value); - EXPECT_EQ(ASCIIToUTF16(password_value), form.password_value); - EXPECT_EQ(ASCIIToUTF16(new_password_value), form.new_password_value); - EXPECT_EQ(event, form.submission_event); - EXPECT_EQ(event, form.form_data.submission_event); + ExpectFormWithUsernameAndPasswordsAndEvent( + *(fake_driver_.password_form_maybe_submitted()), form_rendere_id, + username_value, password_value, new_password_value, event); } void CheckIfEventsAreCalled(const std::vector<base::string16>& checkers, @@ -1117,10 +1145,14 @@ fake_driver_.reset_password_forms_calls(); LoadHTML(kFormWithoutPasswordsHTML); base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(fake_driver_.called_password_forms_parsed()); + + EXPECT_TRUE(fake_driver_.called_password_forms_parsed()); + ASSERT_TRUE(fake_driver_.password_forms_parsed()); + EXPECT_FALSE(fake_driver_.password_forms_parsed()->empty()); + EXPECT_TRUE(fake_driver_.called_password_forms_rendered()); ASSERT_TRUE(fake_driver_.password_forms_rendered()); - EXPECT_TRUE(fake_driver_.password_forms_rendered()->empty()); + EXPECT_FALSE(fake_driver_.password_forms_rendered()->empty()); } TEST_F(PasswordAutofillAgentTest, @@ -1133,7 +1165,7 @@ "document.getElementById('random_field').type = 'password';"; ExecuteJavaScriptForTests(script.c_str()); base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(fake_driver_.called_password_forms_parsed()); + EXPECT_TRUE(fake_driver_.called_password_forms_parsed()); // When the user clicks on the field, a request to the store will be sent. EXPECT_TRUE(SimulateElementClick("random_field")); @@ -1141,6 +1173,10 @@ EXPECT_TRUE(fake_driver_.called_password_forms_parsed()); ASSERT_TRUE(fake_driver_.password_forms_parsed()); EXPECT_FALSE(fake_driver_.password_forms_parsed()->empty()); + + EXPECT_TRUE(fake_driver_.called_password_forms_rendered()); + ASSERT_TRUE(fake_driver_.password_forms_rendered()); + EXPECT_FALSE(fake_driver_.password_forms_rendered()->empty()); } TEST_F(PasswordAutofillAgentTest, SendPasswordFormsTest_NonDisplayedForm) { @@ -1909,7 +1945,8 @@ // Observe that the PasswordAutofillAgent still remembered the last non-empty // username and password and sent that to the browser. - ExpectFormSubmittedWithUsernameAndPasswords("username", "", "random"); + ExpectFormSubmittedWithUsernameAndPasswords(GetFormUniqueRendererId("form"), + "username", "", "random"); // Also check that |*_element| fields are correct. const autofill::PasswordForm& form = @@ -1938,7 +1975,8 @@ // Observe that the PasswordAutofillAgent respects the user having cleared the // password. - ExpectFormSubmittedWithUsernameAndPasswords("", "", ""); + ExpectFormSubmittedWithUsernameAndPasswords( + GetFormUniqueRendererId("LoginTestForm"), "", "", ""); } // Similar to RememberLastNonEmptyPasswordOnSubmit_ScriptCleared, but uses the @@ -1966,7 +2004,8 @@ // Observe that the PasswordAutofillAgent still remembered the last non-empty // password and sent that to the browser. - ExpectFormSubmittedWithUsernameAndPasswords("temp", "", "random"); + ExpectFormSubmittedWithUsernameAndPasswords( + GetFormUniqueRendererId("LoginTestForm"), "temp", "", "random"); } // The user first accepts a suggestion, but then overwrites the password. This @@ -2030,7 +2069,8 @@ // Observe that the PasswordAutofillAgent still remembered the last typed // username and password and sent that to the browser. - ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", ""); + ExpectFormSubmittedWithUsernameAndPasswords( + GetFormUniqueRendererId("LoginTestForm"), "temp", "random", ""); } TEST_F(PasswordAutofillAgentTest, RememberFieldPropertiesOnSubmit) { @@ -2130,8 +2170,9 @@ // Observe that the PasswordAutofillAgent still remembered the autofilled // username and password and sent that to the browser. - ExpectFormSubmittedWithUsernameAndPasswords(kAliceUsername, kAlicePassword, - ""); + ExpectFormSubmittedWithUsernameAndPasswords( + GetFormUniqueRendererId("LoginTestForm"), kAliceUsername, kAlicePassword, + ""); } // The username/password is autofilled by password manager then user types in a @@ -2155,7 +2196,8 @@ // Observe that the PasswordAutofillAgent still remembered the last typed // username and password and sent that to the browser. - ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", ""); + ExpectFormSubmittedWithUsernameAndPasswords( + GetFormUniqueRendererId("LoginTestForm"), "temp", "random", ""); } // The user starts typing username then it is autofilled. @@ -2171,7 +2213,8 @@ // Observe that the PasswordAutofillAgent still remembered the last typed // username and password and sent that to the browser. - ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", ""); + ExpectFormSubmittedWithUsernameAndPasswords( + GetFormUniqueRendererId("LoginTestForm"), "temp", "random", ""); } // The user starts typing username then javascript suggests to select another @@ -2194,7 +2237,8 @@ // Observe that the PasswordAutofillAgent still remembered the last typed // username and password and sent that to the browser. - ExpectFormSubmittedWithUsernameAndPasswords("foo.smith", "random", ""); + ExpectFormSubmittedWithUsernameAndPasswords( + GetFormUniqueRendererId("LoginTestForm"), "foo.smith", "random", ""); } // If credentials contain username+password but the form contains only a @@ -2315,7 +2359,8 @@ // Observe that the PasswordAutofillAgent can correctly process submitted // form. - ExpectFormSubmittedWithUsernameAndPasswords("temp", "random", ""); + ExpectFormSubmittedWithUsernameAndPasswords( + GetFormUniqueRendererId("LoginTestForm"), "temp", "random", ""); } // Verify that typed passwords are saved correctly when autofill and generation @@ -2335,7 +2380,8 @@ SaveAndSubmitForm(); - ExpectFormSubmittedWithUsernameAndPasswords("NewGuy", "NewPassword", ""); + ExpectFormSubmittedWithUsernameAndPasswords( + GetFormUniqueRendererId("LoginTestForm"), "NewGuy", "NewPassword", ""); } // Verify that generated passwords are saved correctly when autofill and @@ -2359,7 +2405,9 @@ SaveAndSubmitForm(); - ExpectFormSubmittedWithUsernameAndPasswords(kAliceUsername, "NewPass22", ""); + ExpectFormSubmittedWithUsernameAndPasswords( + GetFormUniqueRendererId("LoginTestForm"), kAliceUsername, "NewPass22", + ""); } TEST_F(PasswordAutofillAgentTest, @@ -2392,8 +2440,9 @@ SaveAndSubmitForm(); - ExpectFormSubmittedWithUsernameAndPasswords(kAliceUsername, kAlicePassword, - ""); + ExpectFormSubmittedWithUsernameAndPasswords( + GetFormUniqueRendererId("LoginTestForm"), kAliceUsername, kAlicePassword, + ""); } // If password generation is enabled for a field, password autofill should not @@ -2533,7 +2582,8 @@ FireAjaxSucceeded(); ExpectSameDocumentNavigationWithUsernameAndPasswords( - "Bob", "mypassword", "", SubmissionIndicatorEvent::XHR_SUCCEEDED); + FormData::kNotSetFormRendererId, "Bob", "mypassword", "", + SubmissionIndicatorEvent::XHR_SUCCEEDED); } TEST_F(PasswordAutofillAgentTest, @@ -2556,7 +2606,7 @@ base::RunLoop().RunUntilIdle(); ExpectSameDocumentNavigationWithUsernameAndPasswords( - "Bob", "mypassword", "", + FormData::kNotSetFormRendererId, "Bob", "mypassword", "", SubmissionIndicatorEvent::DOM_MUTATION_AFTER_XHR); } @@ -2580,7 +2630,7 @@ base::RunLoop().RunUntilIdle(); ExpectSameDocumentNavigationWithUsernameAndPasswords( - "Bob", "mypassword", "", + GetFormUniqueRendererId("form"), "Bob", "mypassword", "", SubmissionIndicatorEvent::DOM_MUTATION_AFTER_XHR); } @@ -2591,6 +2641,7 @@ PromptForAJAXSubmitAfterDeletingParentElement) { LoadHTML(kDivWrappedFormHTML); UpdateUsernameAndPasswordElements(); + uint32_t renderer_id = GetFormUniqueRendererId("form"); SimulateUsernameTyping("Bob"); SimulatePasswordTyping("mypassword"); @@ -2606,7 +2657,7 @@ base::RunLoop().RunUntilIdle(); ExpectSameDocumentNavigationWithUsernameAndPasswords( - "Bob", "mypassword", "", + renderer_id, "Bob", "mypassword", "", SubmissionIndicatorEvent::DOM_MUTATION_AFTER_XHR); } @@ -2980,7 +3031,8 @@ // Observe that the PasswordAutofillAgent sends to the browser selected // credentials. - ExpectFormSubmittedWithUsernameAndPasswords(kBobUsername, kBobPassword, ""); + ExpectFormSubmittedWithUsernameAndPasswords( + GetFormUniqueRendererId("LoginTestForm"), kBobUsername, kBobPassword, ""); } // Tests that we can correctly suggest to autofill two forms without username @@ -3023,7 +3075,8 @@ FireAjaxSucceeded(); ExpectSameDocumentNavigationWithUsernameAndPasswords( - "Alice", "mypassword", "", SubmissionIndicatorEvent::XHR_SUCCEEDED); + FormData::kNotSetFormRendererId, "Alice", "mypassword", "", + SubmissionIndicatorEvent::XHR_SUCCEEDED); } } @@ -3048,7 +3101,7 @@ base::RunLoop().RunUntilIdle(); ExpectSameDocumentNavigationWithUsernameAndPasswords( - "Alice", "mypassword", "", + FormData::kNotSetFormRendererId, "Alice", "mypassword", "", SubmissionIndicatorEvent::DOM_MUTATION_AFTER_XHR); } @@ -3075,7 +3128,8 @@ SaveAndSubmitForm(); - ExpectFormSubmittedWithUsernameAndPasswords("Alice", "mypassword", ""); + ExpectFormSubmittedWithUsernameAndPasswords( + GetFormUniqueRendererId("LoginTestForm"), "Alice", "mypassword", ""); } } @@ -3187,6 +3241,7 @@ SameDocumentNavigationSubmissionUsernameIsEmpty) { username_element_.SetValue(WebString()); SimulatePasswordTyping("random"); + uint32_t renderer_id = GetFormUniqueRendererId("LoginTestForm"); // Simulate that JavaScript removes the submitted form from DOM. That means // that a submission was successful. @@ -3198,15 +3253,17 @@ FireDidCommitProvisionalLoad(); ExpectSameDocumentNavigationWithUsernameAndPasswords( - std::string(), "random", std::string(), + renderer_id, std::string(), "random", std::string(), SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION); } #if BUILDFLAG(SAFE_BROWSING_DB_LOCAL) // Verify CheckSafeBrowsingReputation() is called when user starts filling // username or password field, and that this function is only called once. -TEST_F(PasswordAutofillAgentTest, - CheckSafeBrowsingReputationWhenUserStartsFillingUsernamePassword) { +// TODO(crbug.com/1008402): Enable this test after fixing the linked bug. +TEST_F( + PasswordAutofillAgentTest, + DISABLED_CheckSafeBrowsingReputationWhenUserStartsFillingUsernamePassword) { ASSERT_EQ(0, fake_driver_.called_check_safe_browsing_reputation_cnt()); // Simulate a click on password field to set its on focus, // CheckSafeBrowsingReputation() should be called.
diff --git a/chrome/renderer/autofill/password_generation_agent_browsertest.cc b/chrome/renderer/autofill/password_generation_agent_browsertest.cc index 2494458..96a335c 100644 --- a/chrome/renderer/autofill/password_generation_agent_browsertest.cc +++ b/chrome/renderer/autofill/password_generation_agent_browsertest.cc
@@ -381,11 +381,6 @@ blink::WebString form_signature_in_username = username_element.GetAttribute( blink::WebString::FromUTF8("form_signature")); EXPECT_EQ(kFormSignature, form_signature_in_username.Ascii()); - EXPECT_EQ( - "username_element", - username_element - .GetAttribute(blink::WebString::FromUTF8("pm_parser_annotation")) - .Ascii()); blink::WebElement password_element = document.GetElementById(blink::WebString::FromUTF8("first_password")); @@ -397,14 +392,6 @@ blink::WebString form_signature_in_password = password_element.GetAttribute( blink::WebString::FromUTF8("form_signature")); EXPECT_EQ(kFormSignature, form_signature_in_password.Ascii()); - // The parser annotation is based on local heuristics, but not server side - // prediction. So, the new password element is classified as the current - // password. - EXPECT_EQ( - "password_element", - password_element - .GetAttribute(blink::WebString::FromUTF8("pm_parser_annotation")) - .Ascii()); // Check the generation element is marked. blink::WebString generation_mark = password_element.GetAttribute( @@ -414,14 +401,6 @@ blink::WebElement confirmation_password_element = document.GetElementById(blink::WebString::FromUTF8("second_password")); - // The parser annotation is based on local heuristics, but not server side - // prediction. So, the confirmation password element is classified as the - // new password. - EXPECT_EQ( - "new_password_element", - confirmation_password_element - .GetAttribute(blink::WebString::FromUTF8("pm_parser_annotation")) - .Ascii()); } TEST_F(PasswordGenerationAgentTest, HiddenSecondPasswordDetectionTest) {
diff --git a/chrome/test/data/password/captured_sites/testcases.json b/chrome/test/data/password/captured_sites/testcases.json index c2534b8..0c4cdf54 100644 --- a/chrome/test/data/password/captured_sites/testcases.json +++ b/chrome/test/data/password/captured_sites/testcases.json
@@ -6,7 +6,7 @@ { "scenario_dir":"capture_update_pass", "site_name":"autodesk" }, { "scenario_dir":"capture_update_pass", "site_name":"clever", "disabled":true, "bug_number":984662 }, { "scenario_dir":"capture_update_pass", "site_name":"github", "disabled":true, "bug_number":951847 }, - { "scenario_dir":"capture_update_pass", "site_name":"go_daddy", "disabled":true, "bug_number":984662 }, + { "scenario_dir":"capture_update_pass", "site_name":"go_daddy" }, { "scenario_dir":"capture_update_pass", "site_name":"grammarly" }, { "scenario_dir":"capture_update_pass", "site_name":"indeed" }, { "scenario_dir":"capture_update_pass", "site_name":"librus" }, @@ -21,7 +21,7 @@ { "scenario_dir":"capture_update_pass", "site_name":"steam" }, { "scenario_dir":"capture_update_pass", "site_name":"the_sims_resource" }, { "scenario_dir":"capture_update_pass", "site_name":"united" }, - { "scenario_dir":"capture_update_pass", "site_name":"wargaming", "disabled":true, "bug_number":984662 }, + { "scenario_dir":"capture_update_pass", "site_name":"wargaming" }, { "scenario_dir":"capture_update_pass", "site_name":"yahoo" }, { "scenario_dir":"sign_in_pass", "site_name":"4shared" }, { "scenario_dir":"sign_in_pass", "site_name":"airbnb", "disabled":true, "bug_number":951847 },
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index d641af6..a61de386 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -4060,6 +4060,12 @@ "DeviceLoginScreenCursorHighlightEnabled" : { }, + "DeviceLoginScreenCaretHighlightEnabled" : { + }, + + "DeviceLoginScreenMonoAudioEnabled" : { + }, + "DeviceLoginScreenLocales" : { },
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index ffaa061..4cc02d6e 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -2531,7 +2531,13 @@ } }; -TEST_F('CrSettingsSplitSettingsFlagTest', 'All', function() { +// Test is consistently failing. http://crbug.com/1008916 +GEN('#if !defined(NDEBUG)'); +GEN('#define MAYBE_All3 DISABLED_All'); +GEN('#else'); +GEN('#define MAYBE_All3 All'); +GEN('#endif'); +TEST_F('CrSettingsSplitSettingsFlagTest', 'MAYBE_All3', function() { mocha.run(); });
diff --git a/chromecast/browser/android/BUILD.gn b/chromecast/browser/android/BUILD.gn index 7f15cb25..55140db4 100644 --- a/chromecast/browser/android/BUILD.gn +++ b/chromecast/browser/android/BUILD.gn
@@ -69,6 +69,10 @@ android_library("cast_audio_manager_java") { java_src_dir = "//chromecast/browser/android/apk/src" + + alternative_android_sdk_dep = + "//third_party/android_sdk:public_framework_system_java" + java_files = [ "$java_src_dir/org/chromium/chromecast/shell/CastAudioManager.java", "$java_src_dir/org/chromium/chromecast/shell/CastAudioFocusRequest.java",
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioManager.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioManager.java index d1b7246..43bbf7e7 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioManager.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastAudioManager.java
@@ -6,6 +6,7 @@ import android.content.Context; import android.media.AudioManager; +import android.media.audiopolicy.AudioPolicy; import android.os.Build; import android.support.annotation.Nullable; @@ -116,6 +117,14 @@ return mInternal.getStreamMaxVolume(streamType); } + public int registerAudioPolicy(AudioPolicy audioPolicy) { + return mInternal.registerAudioPolicy(audioPolicy); + } + + public void unregisterAudioPolicyAsync(AudioPolicy audioPolicy) { + mInternal.unregisterAudioPolicyAsync(audioPolicy); + } + // TODO(sanfin): Do not expose this. All needed AudioManager methods can be adapted with // CastAudioManager. public AudioManager getInternal() {
diff --git a/chromecast/media/audio/BUILD.gn b/chromecast/media/audio/BUILD.gn index 337825e..98225e55 100644 --- a/chromecast/media/audio/BUILD.gn +++ b/chromecast/media/audio/BUILD.gn
@@ -23,6 +23,8 @@ "cast_audio_mixer.h", "cast_audio_output_stream.cc", "cast_audio_output_stream.h", + "cma_audio_output_stream.cc", + "cma_audio_output_stream.h", ] deps = [
diff --git a/chromecast/media/audio/cast_audio_output_stream.cc b/chromecast/media/audio/cast_audio_output_stream.cc index 3186245..a517348c 100644 --- a/chromecast/media/audio/cast_audio_output_stream.cc +++ b/chromecast/media/audio/cast_audio_output_stream.cc
@@ -4,8 +4,6 @@ #include "chromecast/media/audio/cast_audio_output_stream.h" -#include <algorithm> -#include <limits> #include <string> #include <utility> @@ -22,23 +20,22 @@ #include "chromecast/base/metrics/cast_metrics_helper.h" #include "chromecast/common/mojom/constants.mojom.h" #include "chromecast/media/audio/cast_audio_manager.h" +#include "chromecast/media/audio/cma_audio_output_stream.h" #include "chromecast/media/audio/mixer_service/mixer_service.pb.h" #include "chromecast/media/audio/mixer_service/output_stream_connection.h" -#include "chromecast/media/base/monotonic_clock.h" #include "chromecast/media/cma/backend/cma_backend_factory.h" #include "chromecast/public/cast_media_shlib.h" #include "chromecast/public/media/decoder_config.h" #include "chromecast/public/media/media_pipeline_device_params.h" #include "chromecast/public/volume_control.h" #include "media/audio/audio_device_description.h" -#include "media/base/decoder_buffer.h" #define POST_TO_CMA_WRAPPER(method, ...) \ do { \ DCHECK(cma_wrapper_); \ audio_manager_->media_task_runner()->PostTask( \ FROM_HERE, \ - base::BindOnce(&CmaWrapper::method, \ + base::BindOnce(&CmaAudioOutputStream::method, \ base::Unretained(cma_wrapper_.get()), ##__VA_ARGS__)); \ } while (0) @@ -57,7 +54,6 @@ constexpr base::TimeDelta kFadeTime = base::TimeDelta::FromMilliseconds(5); constexpr base::TimeDelta kMixerStartThreshold = base::TimeDelta::FromMilliseconds(60); -constexpr base::TimeDelta kRenderBufferSize = base::TimeDelta::FromSeconds(4); } // namespace namespace chromecast { @@ -96,377 +92,6 @@ } // namespace -class CastAudioOutputStream::CmaWrapper : public CmaBackend::Decoder::Delegate { - public: - CmaWrapper(scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, - const ::media::AudioParameters& audio_params, - const std::string& device_id, - CmaBackendFactory* cma_backend_factory); - - void SetRunning(bool running); - void Initialize(const std::string& application_session_id, - chromecast::mojom::MultiroomInfoPtr multiroom_info); - void Start(AudioSourceCallback* source_callback); - void Stop(base::WaitableEvent* finished); - void Flush(base::WaitableEvent* finished); - void Close(base::OnceClosure closure); - void SetVolume(double volume); - - private: - enum class CmaBackendState { - kUinitialized, - kStopped, - kPaused, - kStarted, - }; - - void PushBuffer(); - - // CmaBackend::Decoder::Delegate implementation: - void OnEndOfStream() override {} - void OnDecoderError() override; - void OnKeyStatusChanged(const std::string& key_id, - CastKeyStatus key_status, - uint32_t system_code) override {} - void OnVideoResolutionChanged(const Size& size) override {} - void OnPushBufferComplete(BufferStatus status) override; - - const bool is_audio_prefetch_; - - scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_; - const ::media::AudioParameters audio_params_; - const std::string device_id_; - CmaBackendFactory* const cma_backend_factory_; - - base::Lock running_lock_; - bool running_ = true; - AudioOutputState media_thread_state_; - CmaBackendState cma_backend_state_ = CmaBackendState::kUinitialized; - ::media::AudioTimestampHelper timestamp_helper_; - const base::TimeDelta buffer_duration_; - std::unique_ptr<TaskRunnerImpl> cma_backend_task_runner_; - std::unique_ptr<CmaBackend> cma_backend_; - std::unique_ptr<::media::AudioBus> audio_bus_; - base::OneShotTimer push_timer_; - bool push_in_progress_; - bool encountered_error_; - base::TimeTicks next_push_time_; - base::TimeTicks last_push_complete_time_; - base::TimeDelta last_rendering_delay_; - base::TimeDelta render_buffer_size_estimate_ = kRenderBufferSize; - CmaBackend::AudioDecoder* audio_decoder_; - AudioSourceCallback* source_callback_; - - THREAD_CHECKER(media_thread_checker_); - - DISALLOW_COPY_AND_ASSIGN(CmaWrapper); -}; - -CastAudioOutputStream::CmaWrapper::CmaWrapper( - scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner, - const ::media::AudioParameters& audio_params, - const std::string& device_id, - CmaBackendFactory* cma_backend_factory) - : is_audio_prefetch_(audio_params.effects() & - ::media::AudioParameters::AUDIO_PREFETCH), - audio_task_runner_(audio_task_runner), - audio_params_(audio_params), - device_id_(device_id), - cma_backend_factory_(cma_backend_factory), - media_thread_state_(kClosed), - timestamp_helper_(audio_params_.sample_rate()), - buffer_duration_(audio_params_.GetBufferDuration()), - render_buffer_size_estimate_(kRenderBufferSize) { - DETACH_FROM_THREAD(media_thread_checker_); - DCHECK(audio_task_runner_); - DCHECK(cma_backend_factory_); - - LOG(INFO) << "Enable audio prefetch: " << is_audio_prefetch_; - - // Set the default state. - push_in_progress_ = false; - encountered_error_ = false; - audio_decoder_ = nullptr; - source_callback_ = nullptr; -} - -void CastAudioOutputStream::CmaWrapper::SetRunning(bool running) { - base::AutoLock lock(running_lock_); - running_ = running; -} - -void CastAudioOutputStream::CmaWrapper::Initialize( - const std::string& application_session_id, - chromecast::mojom::MultiroomInfoPtr multiroom_info) { - DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); - DCHECK(cma_backend_factory_); - - if (media_thread_state_ != kClosed) - return; - media_thread_state_ = kOpened; - - cma_backend_task_runner_ = std::make_unique<TaskRunnerImpl>(); - MediaPipelineDeviceParams device_params( - MediaPipelineDeviceParams::kModeIgnorePts, - MediaPipelineDeviceParams::kAudioStreamNormal, - cma_backend_task_runner_.get(), GetContentType(device_id_), device_id_); - device_params.session_id = application_session_id; - device_params.multiroom = multiroom_info->multiroom; - device_params.audio_channel = multiroom_info->audio_channel; - device_params.output_delay_us = multiroom_info->output_delay.InMicroseconds(); - cma_backend_ = cma_backend_factory_->CreateBackend(device_params); - if (!cma_backend_) { - encountered_error_ = true; - return; - } - - audio_decoder_ = cma_backend_->CreateAudioDecoder(); - if (!audio_decoder_) { - encountered_error_ = true; - return; - } - audio_decoder_->SetDelegate(this); - - AudioConfig audio_config; - audio_config.codec = kCodecPCM; - audio_config.channel_layout = - ChannelLayoutFromChannelNumber(audio_params_.channels()); - audio_config.sample_format = kSampleFormatS16; - audio_config.bytes_per_channel = 2; - audio_config.channel_number = audio_params_.channels(); - audio_config.samples_per_second = audio_params_.sample_rate(); - DCHECK(IsValidConfig(audio_config)); - if (!audio_decoder_->SetConfig(audio_config)) { - encountered_error_ = true; - return; - } - - if (!cma_backend_->Initialize()) { - encountered_error_ = true; - return; - } - cma_backend_state_ = CmaBackendState::kStopped; - - audio_bus_ = ::media::AudioBus::Create(audio_params_); - timestamp_helper_.SetBaseTimestamp(base::TimeDelta()); -} - -void CastAudioOutputStream::CmaWrapper::Start( - AudioSourceCallback* source_callback) { - DCHECK(source_callback); - DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); - if (media_thread_state_ == kPendingClose) - return; - - source_callback_ = source_callback; - if (encountered_error_) { - source_callback_->OnError(); - return; - } - - if (media_thread_state_ == kOpened) { - DCHECK(cma_backend_state_ == CmaBackendState::kPaused || - cma_backend_state_ == CmaBackendState::kStopped); - if (cma_backend_state_ == CmaBackendState::kPaused) { - cma_backend_->Resume(); - } else { - cma_backend_->Start(0); - render_buffer_size_estimate_ = kRenderBufferSize; - } - next_push_time_ = base::TimeTicks::Now(); - last_push_complete_time_ = base::TimeTicks::Now(); - cma_backend_state_ = CmaBackendState::kStarted; - media_thread_state_ = kStarted; - } - - if (!push_in_progress_) { - push_in_progress_ = true; - PushBuffer(); - } -} - -void CastAudioOutputStream::CmaWrapper::Stop(base::WaitableEvent* finished) { - DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); - // Prevent further pushes to the audio buffer after stopping. - push_timer_.Stop(); - // Don't actually stop the backend. Stop() gets called when the stream is - // paused. We rely on Flush() to stop the backend. - if (cma_backend_) { - cma_backend_->Pause(); - cma_backend_state_ = CmaBackendState::kPaused; - } - push_in_progress_ = false; - media_thread_state_ = kOpened; - source_callback_ = nullptr; - finished->Signal(); -} - -void CastAudioOutputStream::CmaWrapper::Flush(base::WaitableEvent* finished) { - DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); - // Prevent further pushes to the audio buffer after stopping. - push_timer_.Stop(); - - if (cma_backend_ && - (media_thread_state_ == kStarted || media_thread_state_ == kOpened)) { - if (cma_backend_state_ == CmaBackendState::kPaused || - cma_backend_state_ == CmaBackendState::kStarted) { - cma_backend_->Stop(); - cma_backend_state_ = CmaBackendState::kStopped; - } - } - push_in_progress_ = false; - media_thread_state_ = kOpened; - source_callback_ = nullptr; - finished->Signal(); -} - -void CastAudioOutputStream::CmaWrapper::Close(base::OnceClosure closure) { - DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); - // Prevent further pushes to the audio buffer after stopping. - push_timer_.Stop(); - // Only stop the backend if it was started. - if (cma_backend_ && cma_backend_state_ != CmaBackendState::kStopped) { - cma_backend_->Stop(); - cma_backend_state_ = CmaBackendState::kStopped; - } - push_in_progress_ = false; - media_thread_state_ = kPendingClose; - - cma_backend_task_runner_.reset(); - cma_backend_.reset(); - audio_bus_.reset(); - - audio_task_runner_->PostTask(FROM_HERE, std::move(closure)); -} - -void CastAudioOutputStream::CmaWrapper::SetVolume(double volume) { - DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); - if (!audio_decoder_) { - return; - } - if (encountered_error_) { - return; - } - audio_decoder_->SetVolume(volume); -} - -void CastAudioOutputStream::CmaWrapper::PushBuffer() { - DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); - - // Acquire running_lock_ for the scope of this push call to - // prevent the source callback from closing the output stream - // mid-push. - base::AutoLock lock(running_lock_); - - // Do not fill more buffers if we have stopped running. - if (!running_) - return; - - // It is possible that this function is called when we are stopped. - // Return quickly if so. - if (!source_callback_ || encountered_error_ || - media_thread_state_ != kStarted) { - push_in_progress_ = false; - return; - } - DCHECK(push_in_progress_); - - CmaBackend::AudioDecoder::RenderingDelay rendering_delay = - audio_decoder_->GetRenderingDelay(); - - base::TimeDelta delay; - if (rendering_delay.delay_microseconds < 0 || - rendering_delay.timestamp_microseconds < 0) { - // This occurs immediately after start/resume when there isn't a good - // estimate of the buffer delay. Use the last known good delay. - delay = last_rendering_delay_; - } else { - // The rendering delay to account for buffering is not included in - // rendering_delay.delay_microseconds but is in delay_timestamp which isn't - // used by AudioOutputStreamImpl. - delay = base::TimeDelta::FromMicroseconds( - rendering_delay.delay_microseconds + - rendering_delay.timestamp_microseconds - MonotonicClockNow()); - if (delay.InMicroseconds() < 0) { - delay = base::TimeDelta(); - } - } - last_rendering_delay_ = delay; - - int frame_count = source_callback_->OnMoreData(delay, base::TimeTicks(), 0, - audio_bus_.get()); - - DVLOG(3) << "frames_filled=" << frame_count << " with latency=" << delay; - - if (frame_count == 0) { - OnPushBufferComplete(CmaBackend::BufferStatus::kBufferFailed); - return; - } - auto decoder_buffer = - base::MakeRefCounted<DecoderBufferAdapter>(new ::media::DecoderBuffer( - audio_params_.GetBytesPerBuffer(::media::kSampleFormatS16))); - audio_bus_->ToInterleaved<::media::SignedInt16SampleTypeTraits>( - frame_count, reinterpret_cast<int16_t*>(decoder_buffer->writable_data())); - decoder_buffer->set_timestamp(timestamp_helper_.GetTimestamp()); - timestamp_helper_.AddFrames(frame_count); - - BufferStatus status = audio_decoder_->PushBuffer(std::move(decoder_buffer)); - if (status != CmaBackend::BufferStatus::kBufferPending) - OnPushBufferComplete(status); -} - -void CastAudioOutputStream::CmaWrapper::OnPushBufferComplete( - BufferStatus status) { - DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); - DCHECK_NE(status, CmaBackend::BufferStatus::kBufferPending); - - DCHECK(push_in_progress_); - push_in_progress_ = false; - - if (!source_callback_ || encountered_error_) - return; - - if (status != CmaBackend::BufferStatus::kBufferSuccess) { - source_callback_->OnError(); - return; - } - - // Schedule next push buffer. - const base::TimeTicks now = base::TimeTicks::Now(); - base::TimeDelta delay; - if (is_audio_prefetch_) { - // For multizone-playback, we don't care about AV sync and want to pre-fetch - // audio. - render_buffer_size_estimate_ -= buffer_duration_; - render_buffer_size_estimate_ += now - last_push_complete_time_; - last_push_complete_time_ = now; - - if (render_buffer_size_estimate_ >= buffer_duration_) { - delay = base::TimeDelta::FromSeconds(0); - } else { - delay = buffer_duration_; - } - } else { - next_push_time_ = std::max(now, next_push_time_ + buffer_duration_); - delay = next_push_time_ - now; - } - - DVLOG(3) << "render_buffer_size_estimate_=" << render_buffer_size_estimate_ - << " delay=" << delay << " buffer_duration_=" << buffer_duration_; - - push_timer_.Start(FROM_HERE, delay, this, &CmaWrapper::PushBuffer); - push_in_progress_ = true; -} - -void CastAudioOutputStream::CmaWrapper::OnDecoderError() { - DVLOG(1) << this << ": " << __func__; - DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); - - encountered_error_ = true; - if (source_callback_) - source_callback_->OnError(); -} - class CastAudioOutputStream::MixerServiceWrapper : public mixer_service::OutputStreamConnection::Delegate { public: @@ -642,7 +267,7 @@ const std::string& device_id_or_group_id, bool use_mixer_service) : volume_(1.0), - audio_thread_state_(kClosed), + audio_thread_state_(AudioOutputState::kClosed), audio_manager_(audio_manager), connector_(connector), audio_params_(audio_params), @@ -659,6 +284,7 @@ DETACH_FROM_THREAD(audio_thread_checker_); DVLOG(1) << __func__ << " " << this << " created from group_id=" << group_id_ << " with audio_params=" << audio_params_.AsHumanReadableString(); + audio_weak_this_ = audio_weak_factory_.GetWeakPtr(); } CastAudioOutputStream::~CastAudioOutputStream() { @@ -668,7 +294,7 @@ bool CastAudioOutputStream::Open() { DCHECK_CALLED_ON_VALID_THREAD(audio_thread_checker_); DVLOG(1) << this << ": " << __func__; - if (audio_thread_state_ != kClosed) + if (audio_thread_state_ != AudioOutputState::kClosed) return false; // Sanity check the audio parameters. @@ -692,16 +318,15 @@ // Connect to the Multiroom interface and fetch the current info. connector_->Connect(chromecast::mojom::kChromecastServiceName, multiroom_manager_.BindNewPipeAndPassReceiver()); - multiroom_manager_.set_disconnect_handler( - base::BindOnce(&CastAudioOutputStream::OnGetMultiroomInfo, - audio_weak_factory_.GetWeakPtr(), "error", - chromecast::mojom::MultiroomInfo::New())); + multiroom_manager_.set_disconnect_handler(base::BindOnce( + &CastAudioOutputStream::OnGetMultiroomInfo, audio_weak_this_, "error", + chromecast::mojom::MultiroomInfo::New())); multiroom_manager_->GetMultiroomInfo( application_session_id, base::BindOnce(&CastAudioOutputStream::OnGetMultiroomInfo, - audio_weak_factory_.GetWeakPtr(), application_session_id)); + audio_weak_this_, application_session_id)); - audio_thread_state_ = kOpened; + audio_thread_state_ = AudioOutputState::kOpened; // Always return success on the audio thread even though we are unsure at this // point if the backend has opened successfully. Errors will be reported via @@ -717,9 +342,9 @@ DCHECK_CALLED_ON_VALID_THREAD(audio_thread_checker_); DVLOG(1) << this << ": " << __func__; - audio_thread_state_ = kPendingClose; - base::OnceClosure finish_callback = base::BindOnce( - &CastAudioOutputStream::FinishClose, audio_weak_factory_.GetWeakPtr()); + audio_thread_state_ = AudioOutputState::kPendingClose; + base::OnceClosure finish_callback = BindToCurrentThread( + base::BindOnce(&CastAudioOutputStream::FinishClose, audio_weak_this_)); if (mixer_service_wrapper_) { // Synchronously set running to false to guarantee that @@ -749,9 +374,9 @@ DCHECK(source_callback); DCHECK_CALLED_ON_VALID_THREAD(audio_thread_checker_); // We allow calls to start even in the unopened state. - DCHECK(audio_thread_state_ != kPendingClose); + DCHECK_NE(audio_thread_state_, AudioOutputState::kPendingClose); DVLOG(2) << this << ": " << __func__; - audio_thread_state_ = kStarted; + audio_thread_state_ = AudioOutputState::kStarted; metrics::CastMetricsHelper::GetInstance()->LogTimeToFirstAudio(); if (!cma_wrapper_ && !mixer_service_wrapper_) { @@ -775,9 +400,9 @@ DCHECK_CALLED_ON_VALID_THREAD(audio_thread_checker_); DVLOG(2) << this << ": " << __func__; // We allow calls to stop even in the unstarted/unopened state. - if (audio_thread_state_ != kStarted) + if (audio_thread_state_ != AudioOutputState::kStarted) return; - audio_thread_state_ = kOpened; + audio_thread_state_ = AudioOutputState::kOpened; pending_start_.Reset(); pending_volume_.Reset(); @@ -815,7 +440,7 @@ void CastAudioOutputStream::SetVolume(double volume) { DCHECK_CALLED_ON_VALID_THREAD(audio_thread_checker_); - DCHECK(audio_thread_state_ != kPendingClose); + DCHECK_NE(audio_thread_state_, AudioOutputState::kPendingClose); DVLOG(2) << this << ": " << __func__ << "(" << volume << ")"; volume_ = volume; @@ -851,13 +476,12 @@ // Close the MultiroomManager message pipe so that a connection error does // not trigger a second call to this function. multiroom_manager_.reset(); - if (audio_thread_state_ == kPendingClose) + if (audio_thread_state_ == AudioOutputState::kPendingClose) return; if (!use_mixer_service_) { - cma_wrapper_ = std::make_unique<CmaWrapper>( - audio_manager_->GetTaskRunner(), audio_params_, device_id_, - audio_manager_->cma_backend_factory()); + cma_wrapper_ = std::make_unique<CmaAudioOutputStream>( + audio_params_, device_id_, audio_manager_->cma_backend_factory()); POST_TO_CMA_WRAPPER(Initialize, application_session_id, std::move(multiroom_info)); } else {
diff --git a/chromecast/media/audio/cast_audio_output_stream.h b/chromecast/media/audio/cast_audio_output_stream.h index e85c64e..c383668 100644 --- a/chromecast/media/audio/cast_audio_output_stream.h +++ b/chromecast/media/audio/cast_audio_output_stream.h
@@ -16,8 +16,6 @@ #include "build/build_config.h" #include "chromecast/base/task_runner_impl.h" #include "chromecast/common/mojom/multiroom.mojom.h" -#include "chromecast/media/cma/backend/cma_backend.h" -#include "chromecast/media/cma/base/decoder_buffer_adapter.h" #include "media/audio/audio_io.h" #include "media/base/audio_parameters.h" #include "media/base/audio_timestamp_helper.h" @@ -27,13 +25,7 @@ namespace chromecast { namespace media { -enum AudioOutputState { - kClosed = 0, - kOpened = 1, - kStarted = 2, - kPendingClose = 3, -}; - +class CmaAudioOutputStream; class CastAudioManager; // Chromecast implementation of AudioOutputStream. @@ -128,14 +120,18 @@ void Flush() override; private: - class CmaWrapper; + enum class AudioOutputState { + kClosed, + kOpened, + kStarted, + kPendingClose, + }; + class MixerServiceWrapper; void FinishClose(); void OnGetMultiroomInfo(const std::string& application_session_id, chromecast::mojom::MultiroomInfoPtr multiroom_info); - void InitializeCmaBackend(const std::string& application_session_id, - chromecast::mojom::MultiroomInfoPtr multiroom_info); double volume_; AudioOutputState audio_thread_state_; @@ -149,7 +145,7 @@ const std::string group_id_; const bool use_mixer_service_; mojo::Remote<chromecast::mojom::MultiroomManager> multiroom_manager_; - std::unique_ptr<CmaWrapper> cma_wrapper_; + std::unique_ptr<CmaAudioOutputStream> cma_wrapper_; std::unique_ptr<MixerServiceWrapper> mixer_service_wrapper_; // Hold bindings to Start and SetVolume if they were called before Open @@ -159,6 +155,7 @@ base::OnceCallback<void()> pending_volume_; THREAD_CHECKER(audio_thread_checker_); + base::WeakPtr<CastAudioOutputStream> audio_weak_this_; base::WeakPtrFactory<CastAudioOutputStream> audio_weak_factory_; DISALLOW_COPY_AND_ASSIGN(CastAudioOutputStream);
diff --git a/chromecast/media/audio/cma_audio_output_stream.cc b/chromecast/media/audio/cma_audio_output_stream.cc new file mode 100644 index 0000000..031b3be --- /dev/null +++ b/chromecast/media/audio/cma_audio_output_stream.cc
@@ -0,0 +1,329 @@ +// 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 "chromecast/media/audio/cma_audio_output_stream.h" + +#include <algorithm> +#include <limits> +#include <utility> + +#include "base/bind.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/synchronization/waitable_event.h" +#include "chromecast/base/task_runner_impl.h" +#include "chromecast/media/base/monotonic_clock.h" +#include "chromecast/media/cma/backend/cma_backend_factory.h" +#include "chromecast/media/cma/base/decoder_buffer_adapter.h" +#include "chromecast/public/media/media_pipeline_device_params.h" +#include "chromecast/public/volume_control.h" +#include "media/audio/audio_device_description.h" +#include "media/base/audio_bus.h" +#include "media/base/decoder_buffer.h" + +namespace chromecast { +namespace media { + +namespace { + +constexpr base::TimeDelta kRenderBufferSize = base::TimeDelta::FromSeconds(4); + +AudioContentType GetContentType(const std::string& device_id) { + if (::media::AudioDeviceDescription::IsCommunicationsDevice(device_id)) { + return AudioContentType::kCommunication; + } + return AudioContentType::kMedia; +} + +} // namespace + +CmaAudioOutputStream::CmaAudioOutputStream( + const ::media::AudioParameters& audio_params, + const std::string& device_id, + CmaBackendFactory* cma_backend_factory) + : is_audio_prefetch_(audio_params.effects() & + ::media::AudioParameters::AUDIO_PREFETCH), + audio_params_(audio_params), + device_id_(device_id), + cma_backend_factory_(cma_backend_factory), + timestamp_helper_(audio_params_.sample_rate()), + buffer_duration_(audio_params_.GetBufferDuration()), + render_buffer_size_estimate_(kRenderBufferSize) { + DCHECK(cma_backend_factory_); + DETACH_FROM_THREAD(media_thread_checker_); + + LOG(INFO) << "Enable audio prefetch: " << is_audio_prefetch_; +} + +CmaAudioOutputStream::~CmaAudioOutputStream() = default; + +void CmaAudioOutputStream::SetRunning(bool running) { + base::AutoLock lock(running_lock_); + running_ = running; +} + +void CmaAudioOutputStream::Initialize( + const std::string& application_session_id, + chromecast::mojom::MultiroomInfoPtr multiroom_info) { + DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); + DCHECK(cma_backend_factory_); + + if (cma_backend_state_ != CmaBackendState::kUninitialized) + return; + + cma_backend_task_runner_ = std::make_unique<TaskRunnerImpl>(); + MediaPipelineDeviceParams device_params( + MediaPipelineDeviceParams::kModeIgnorePts, + MediaPipelineDeviceParams::kAudioStreamNormal, + cma_backend_task_runner_.get(), GetContentType(device_id_), device_id_); + device_params.session_id = application_session_id; + device_params.multiroom = multiroom_info->multiroom; + device_params.audio_channel = multiroom_info->audio_channel; + device_params.output_delay_us = multiroom_info->output_delay.InMicroseconds(); + cma_backend_ = cma_backend_factory_->CreateBackend(device_params); + if (!cma_backend_) { + encountered_error_ = true; + return; + } + + audio_decoder_ = cma_backend_->CreateAudioDecoder(); + if (!audio_decoder_) { + encountered_error_ = true; + return; + } + audio_decoder_->SetDelegate(this); + + AudioConfig audio_config; + audio_config.codec = kCodecPCM; + audio_config.channel_layout = + ChannelLayoutFromChannelNumber(audio_params_.channels()); + audio_config.sample_format = kSampleFormatS16; + audio_config.bytes_per_channel = 2; + audio_config.channel_number = audio_params_.channels(); + audio_config.samples_per_second = audio_params_.sample_rate(); + DCHECK(IsValidConfig(audio_config)); + if (!audio_decoder_->SetConfig(audio_config)) { + encountered_error_ = true; + return; + } + + if (!cma_backend_->Initialize()) { + encountered_error_ = true; + return; + } + cma_backend_state_ = CmaBackendState::kStopped; + + audio_bus_ = ::media::AudioBus::Create(audio_params_); + timestamp_helper_.SetBaseTimestamp(base::TimeDelta()); +} + +void CmaAudioOutputStream::Start( + ::media::AudioOutputStream::AudioSourceCallback* source_callback) { + DCHECK(source_callback); + DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); + if (cma_backend_state_ == CmaBackendState::kPendingClose) + return; + + source_callback_ = source_callback; + if (encountered_error_) { + source_callback_->OnError(); + return; + } + + if (cma_backend_state_ == CmaBackendState::kPaused || + cma_backend_state_ == CmaBackendState::kStopped) { + if (cma_backend_state_ == CmaBackendState::kPaused) { + cma_backend_->Resume(); + } else { + cma_backend_->Start(0); + render_buffer_size_estimate_ = kRenderBufferSize; + } + next_push_time_ = base::TimeTicks::Now(); + last_push_complete_time_ = base::TimeTicks::Now(); + cma_backend_state_ = CmaBackendState::kStarted; + } + + if (!push_in_progress_) { + push_in_progress_ = true; + PushBuffer(); + } +} + +void CmaAudioOutputStream::Stop(base::WaitableEvent* finished) { + DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); + // Prevent further pushes to the audio buffer after stopping. + push_timer_.Stop(); + // Don't actually stop the backend. Stop() gets called when the stream is + // paused. We rely on Flush() to stop the backend. + if (cma_backend_) { + cma_backend_->Pause(); + cma_backend_state_ = CmaBackendState::kPaused; + } + push_in_progress_ = false; + source_callback_ = nullptr; + finished->Signal(); +} + +void CmaAudioOutputStream::Flush(base::WaitableEvent* finished) { + DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); + // Prevent further pushes to the audio buffer after stopping. + push_timer_.Stop(); + + if (cma_backend_ && (cma_backend_state_ == CmaBackendState::kPaused || + cma_backend_state_ == CmaBackendState::kStarted)) { + cma_backend_->Stop(); + cma_backend_state_ = CmaBackendState::kStopped; + } + push_in_progress_ = false; + source_callback_ = nullptr; + finished->Signal(); +} + +void CmaAudioOutputStream::Close(base::OnceClosure closure) { + DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); + // Prevent further pushes to the audio buffer after stopping. + push_timer_.Stop(); + // Only stop the backend if it was started. + if (cma_backend_ && cma_backend_state_ != CmaBackendState::kStopped) { + cma_backend_->Stop(); + } + push_in_progress_ = false; + cma_backend_state_ = CmaBackendState::kPendingClose; + + cma_backend_task_runner_.reset(); + cma_backend_.reset(); + audio_bus_.reset(); + + std::move(closure).Run(); +} + +void CmaAudioOutputStream::SetVolume(double volume) { + DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); + if (!audio_decoder_) { + return; + } + if (encountered_error_) { + return; + } + audio_decoder_->SetVolume(volume); +} + +void CmaAudioOutputStream::PushBuffer() { + DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); + + // Acquire running_lock_ for the scope of this push call to + // prevent the source callback from closing the output stream + // mid-push. + base::AutoLock lock(running_lock_); + + // Do not fill more buffers if we have stopped running. + if (!running_) + return; + + // It is possible that this function is called when we are stopped. + // Return quickly if so. + if (!source_callback_ || encountered_error_ || + cma_backend_state_ != CmaBackendState::kStarted) { + push_in_progress_ = false; + return; + } + DCHECK(push_in_progress_); + + CmaBackend::AudioDecoder::RenderingDelay rendering_delay = + audio_decoder_->GetRenderingDelay(); + + base::TimeDelta delay; + if (rendering_delay.delay_microseconds < 0 || + rendering_delay.timestamp_microseconds < 0) { + // This occurs immediately after start/resume when there isn't a good + // estimate of the buffer delay. Use the last known good delay. + delay = last_rendering_delay_; + } else { + // The rendering delay to account for buffering is not included in + // rendering_delay.delay_microseconds but is in delay_timestamp which isn't + // used by AudioOutputStreamImpl. + delay = base::TimeDelta::FromMicroseconds( + rendering_delay.delay_microseconds + + rendering_delay.timestamp_microseconds - MonotonicClockNow()); + if (delay.InMicroseconds() < 0) { + delay = base::TimeDelta(); + } + } + last_rendering_delay_ = delay; + + int frame_count = source_callback_->OnMoreData(delay, base::TimeTicks(), 0, + audio_bus_.get()); + + DVLOG(3) << "frames_filled=" << frame_count << " with latency=" << delay; + + if (frame_count == 0) { + OnPushBufferComplete(CmaBackend::BufferStatus::kBufferFailed); + return; + } + auto decoder_buffer = + base::MakeRefCounted<DecoderBufferAdapter>(new ::media::DecoderBuffer( + audio_params_.GetBytesPerBuffer(::media::kSampleFormatS16))); + audio_bus_->ToInterleaved<::media::SignedInt16SampleTypeTraits>( + frame_count, reinterpret_cast<int16_t*>(decoder_buffer->writable_data())); + decoder_buffer->set_timestamp(timestamp_helper_.GetTimestamp()); + timestamp_helper_.AddFrames(frame_count); + + BufferStatus status = audio_decoder_->PushBuffer(std::move(decoder_buffer)); + if (status != CmaBackend::BufferStatus::kBufferPending) + OnPushBufferComplete(status); +} + +void CmaAudioOutputStream::OnPushBufferComplete(BufferStatus status) { + DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); + DCHECK_NE(status, CmaBackend::BufferStatus::kBufferPending); + + DCHECK(push_in_progress_); + push_in_progress_ = false; + + if (!source_callback_ || encountered_error_) + return; + + if (status != CmaBackend::BufferStatus::kBufferSuccess) { + source_callback_->OnError(); + return; + } + + // Schedule next push buffer. + const base::TimeTicks now = base::TimeTicks::Now(); + base::TimeDelta delay; + if (is_audio_prefetch_) { + // For multizone-playback, we don't care about AV sync and want to pre-fetch + // audio. + render_buffer_size_estimate_ -= buffer_duration_; + render_buffer_size_estimate_ += now - last_push_complete_time_; + last_push_complete_time_ = now; + + if (render_buffer_size_estimate_ >= buffer_duration_) { + delay = base::TimeDelta::FromSeconds(0); + } else { + delay = buffer_duration_; + } + } else { + next_push_time_ = std::max(now, next_push_time_ + buffer_duration_); + delay = next_push_time_ - now; + } + + DVLOG(3) << "render_buffer_size_estimate_=" << render_buffer_size_estimate_ + << " delay=" << delay << " buffer_duration_=" << buffer_duration_; + + push_timer_.Start(FROM_HERE, delay, this, &CmaAudioOutputStream::PushBuffer); + push_in_progress_ = true; +} + +void CmaAudioOutputStream::OnDecoderError() { + DLOG(INFO) << this << ": " << __func__; + DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); + + encountered_error_ = true; + if (source_callback_) + source_callback_->OnError(); +} + +} // namespace media +} // namespace chromecast
diff --git a/chromecast/media/audio/cma_audio_output_stream.h b/chromecast/media/audio/cma_audio_output_stream.h new file mode 100644 index 0000000..f4afe7a --- /dev/null +++ b/chromecast/media/audio/cma_audio_output_stream.h
@@ -0,0 +1,109 @@ +// 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 CHROMECAST_MEDIA_AUDIO_CMA_AUDIO_OUTPUT_STREAM_H_ +#define CHROMECAST_MEDIA_AUDIO_CMA_AUDIO_OUTPUT_STREAM_H_ + +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/synchronization/lock.h" +#include "base/threading/thread_checker.h" +#include "base/time/time.h" +#include "base/timer/timer.h" +#include "chromecast/common/mojom/multiroom.mojom.h" +#include "chromecast/media/cma/backend/cma_backend.h" +#include "media/audio/audio_io.h" +#include "media/base/audio_parameters.h" +#include "media/base/audio_timestamp_helper.h" + +namespace base { +class WaitableEvent; +} // namespace base + +namespace media { +class AudioBus; +} // namespace media + +namespace chromecast { + +class TaskRunnerImpl; + +namespace media { + +class CmaBackendFactory; + +class CmaAudioOutputStream : public CmaBackend::Decoder::Delegate { + public: + CmaAudioOutputStream(const ::media::AudioParameters& audio_params, + const std::string& device_id, + CmaBackendFactory* cma_backend_factory); + ~CmaAudioOutputStream() override; + + void SetRunning(bool running); + void Initialize(const std::string& application_session_id, + chromecast::mojom::MultiroomInfoPtr multiroom_info); + void Start(::media::AudioOutputStream::AudioSourceCallback* source_callback); + void Stop(base::WaitableEvent* finished); + void Flush(base::WaitableEvent* finished); + void Close(base::OnceClosure closure); + void SetVolume(double volume); + + private: + enum class CmaBackendState { + kUninitialized, + kStopped, + kPaused, + kStarted, + kPendingClose, + }; + + void PushBuffer(); + + // CmaBackend::Decoder::Delegate implementation: + void OnEndOfStream() override {} + void OnDecoderError() override; + void OnKeyStatusChanged(const std::string& key_id, + CastKeyStatus key_status, + uint32_t system_code) override {} + void OnVideoResolutionChanged(const Size& size) override {} + void OnPushBufferComplete(BufferStatus status) override; + + const bool is_audio_prefetch_; + + const ::media::AudioParameters audio_params_; + const std::string device_id_; + CmaBackendFactory* const cma_backend_factory_; + + base::Lock running_lock_; + bool running_ = true; + CmaBackendState cma_backend_state_ = CmaBackendState::kUninitialized; + ::media::AudioTimestampHelper timestamp_helper_; + const base::TimeDelta buffer_duration_; + std::unique_ptr<TaskRunnerImpl> cma_backend_task_runner_; + std::unique_ptr<CmaBackend> cma_backend_; + std::unique_ptr<::media::AudioBus> audio_bus_; + base::OneShotTimer push_timer_; + bool push_in_progress_ = false; + bool encountered_error_ = false; + base::TimeTicks next_push_time_; + base::TimeTicks last_push_complete_time_; + base::TimeDelta last_rendering_delay_; + base::TimeDelta render_buffer_size_estimate_; + CmaBackend::AudioDecoder* audio_decoder_ = nullptr; + ::media::AudioOutputStream::AudioSourceCallback* source_callback_ = nullptr; + + THREAD_CHECKER(media_thread_checker_); + + DISALLOW_COPY_AND_ASSIGN(CmaAudioOutputStream); +}; + +} // namespace media +} // namespace chromecast + +#endif // CHROMECAST_MEDIA_AUDIO_CMA_AUDIO_OUTPUT_STREAM_H_
diff --git a/chromeos/dbus/debug_daemon_client.cc b/chromeos/dbus/debug_daemon_client.cc index cd4c4fb..686ecf0 100644 --- a/chromeos/dbus/debug_daemon_client.cc +++ b/chromeos/dbus/debug_daemon_client.cc
@@ -567,6 +567,20 @@ weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } + void SetSchedulerConfigurationV2(const std::string& config_name, + bool lock_policy, + VoidDBusMethodCallback callback) override { + dbus::MethodCall method_call(debugd::kDebugdInterface, + debugd::kSetSchedulerConfigurationV2); + dbus::MessageWriter writer(&method_call); + writer.AppendString(config_name); + writer.AppendBool(lock_policy); + debugdaemon_proxy_->CallMethod( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::BindOnce(&DebugDaemonClientImpl::OnVoidMethod, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + } + void SetU2fFlags(const std::set<std::string>& flags, VoidDBusMethodCallback callback) override { dbus::MethodCall method_call(debugd::kDebugdInterface,
diff --git a/chromeos/dbus/debug_daemon_client.h b/chromeos/dbus/debug_daemon_client.h index b67dc797..507a027 100644 --- a/chromeos/dbus/debug_daemon_client.h +++ b/chromeos/dbus/debug_daemon_client.h
@@ -248,12 +248,19 @@ // to 0. virtual void SetRlzPingSent(SetRlzPingSentCallback callback) = 0; - // Request switching to the scheduler configuration profile indicated. The - // profile names are defined by debugd, which adjusts various knobs affecting - // kernel level task scheduling (see debugd source code for details). + // Deprecated. Use SetSchedulerConfigurationV2 instead. + // TODO(abhishekbh): Remove the method. virtual void SetSchedulerConfiguration(const std::string& config_name, VoidDBusMethodCallback callback) = 0; + // Request switching to the scheduler configuration profile indicated. The + // profile names are defined by debugd, which adjusts various knobs affecting + // kernel level task scheduling (see debugd source code for details). When + // |lock_policy| is true, the policy is locked until the device is rebooted. + virtual void SetSchedulerConfigurationV2(const std::string& config_name, + bool lock_policy, + VoidDBusMethodCallback callback) = 0; + // Set U2F flags. virtual void SetU2fFlags(const std::set<std::string>& flags, VoidDBusMethodCallback callback) = 0;
diff --git a/chromeos/dbus/fake_debug_daemon_client.cc b/chromeos/dbus/fake_debug_daemon_client.cc index f144e53..45e0a35 100644 --- a/chromeos/dbus/fake_debug_daemon_client.cc +++ b/chromeos/dbus/fake_debug_daemon_client.cc
@@ -268,6 +268,15 @@ FROM_HERE, base::BindOnce(std::move(callback), true)); } +void FakeDebugDaemonClient::SetSchedulerConfigurationV2( + const std::string& config_name, + bool lock_policy, + VoidDBusMethodCallback callback) { + scheduler_configuration_name_ = config_name; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), true)); +} + void FakeDebugDaemonClient::SetU2fFlags(const std::set<std::string>& flags, VoidDBusMethodCallback callback) { u2f_flags_ = flags;
diff --git a/chromeos/dbus/fake_debug_daemon_client.h b/chromeos/dbus/fake_debug_daemon_client.h index a920f8ad..e467cb3 100644 --- a/chromeos/dbus/fake_debug_daemon_client.h +++ b/chromeos/dbus/fake_debug_daemon_client.h
@@ -91,6 +91,9 @@ void SetRlzPingSent(SetRlzPingSentCallback callback) override; void SetSchedulerConfiguration(const std::string& config_name, VoidDBusMethodCallback callback) override; + void SetSchedulerConfigurationV2(const std::string& config_name, + bool lock_policy, + VoidDBusMethodCallback callback) override; void SetU2fFlags(const std::set<std::string>& flags, VoidDBusMethodCallback callback) override; void GetU2fFlags(DBusMethodCallback<std::set<std::string>> callback) override;
diff --git a/components/BUILD.gn b/components/BUILD.gn index a426bb0f..61d4b09 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -503,6 +503,7 @@ "autofill/content/browser/risk/fingerprint_browsertest.cc", "autofill/content/renderer/field_data_manager_browsertest.cc", "autofill/content/renderer/form_autofill_util_browsertest.cc", + "autofill/content/renderer/form_cache_browsertest.cc", "autofill/content/renderer/password_form_conversion_utils_browsertest.cc", "dom_distiller/content/browser/distillable_page_utils_browsertest.cc", "dom_distiller/content/browser/distiller_page_web_contents_browsertest.cc",
diff --git a/components/arc/mojom/BUILD.gn b/components/arc/mojom/BUILD.gn index 11f97dd8..b08ccf02 100644 --- a/components/arc/mojom/BUILD.gn +++ b/components/arc/mojom/BUILD.gn
@@ -70,6 +70,7 @@ ":camera_intent", ":media", ":notifications", + "//components/chromeos_camera/common:camera_app_helper", "//media/capture/video/chromeos/mojom:cros_camera", "//mojo/public/mojom/base", "//services/device/public/mojom:usb",
diff --git a/components/arc/mojom/video_accelerator_mojom_traits.cc b/components/arc/mojom/video_accelerator_mojom_traits.cc index 07add4c1..54ebd05 100644 --- a/components/arc/mojom/video_accelerator_mojom_traits.cc +++ b/components/arc/mojom/video_accelerator_mojom_traits.cc
@@ -239,9 +239,9 @@ // static bool StructTraits<arc::mojom::MediaVideoFramePlaneDataView, - media::VideoFrameLayout::Plane>:: + media::ColorPlaneLayout>:: Read(arc::mojom::MediaVideoFramePlaneDataView data, - media::VideoFrameLayout::Plane* out) { + media::ColorPlaneLayout* out) { out->offset = data.offset(); out->stride = data.stride(); out->size = data.size(); @@ -255,7 +255,7 @@ std::unique_ptr<media::VideoFrameLayout>* out) { media::VideoPixelFormat format; gfx::Size coded_size; - std::vector<media::VideoFrameLayout::Plane> planes; + std::vector<media::ColorPlaneLayout> planes; if (!data.ReadFormat(&format) || !data.ReadCodedSize(&coded_size) || !data.ReadPlanes(&planes)) { return false;
diff --git a/components/arc/mojom/video_accelerator_mojom_traits.h b/components/arc/mojom/video_accelerator_mojom_traits.h index 2ad0341..7a714cc 100644 --- a/components/arc/mojom/video_accelerator_mojom_traits.h +++ b/components/arc/mojom/video_accelerator_mojom_traits.h
@@ -13,6 +13,7 @@ #include "components/arc/mojom/video_common.mojom.h" #include "components/arc/video_accelerator/decoder_buffer.h" #include "components/arc/video_accelerator/video_frame_plane.h" +#include "media/base/color_plane_layout.h" #include "media/base/decode_status.h" #include "media/base/video_codecs.h" #include "media/base/video_frame.h" @@ -73,21 +74,15 @@ template <> struct StructTraits<arc::mojom::MediaVideoFramePlaneDataView, - media::VideoFrameLayout::Plane> { - static int32_t stride(const media::VideoFrameLayout::Plane& r) { - return r.stride; - } + media::ColorPlaneLayout> { + static int32_t stride(const media::ColorPlaneLayout& r) { return r.stride; } - static uint32_t offset(const media::VideoFrameLayout::Plane& r) { - return r.offset; - } + static uint32_t offset(const media::ColorPlaneLayout& r) { return r.offset; } - static uint32_t size(const media::VideoFrameLayout::Plane& r) { - return r.size; - } + static uint32_t size(const media::ColorPlaneLayout& r) { return r.size; } static bool Read(arc::mojom::MediaVideoFramePlaneDataView data, - media::VideoFrameLayout::Plane* out); + media::ColorPlaneLayout* out); }; // Because `media::VideoFrameLayout` doesn't have default constructor, we cannot @@ -116,7 +111,7 @@ return input->coded_size(); } - static const std::vector<media::VideoFrameLayout::Plane>& planes( + static const std::vector<media::ColorPlaneLayout>& planes( const std::unique_ptr<media::VideoFrameLayout>& input) { DCHECK(input); return input->planes();
diff --git a/components/arc/mojom/video_accelerator_mojom_traits_unittest.cc b/components/arc/mojom/video_accelerator_mojom_traits_unittest.cc index 0ce4fc4..ad091dd 100644 --- a/components/arc/mojom/video_accelerator_mojom_traits_unittest.cc +++ b/components/arc/mojom/video_accelerator_mojom_traits_unittest.cc
@@ -27,7 +27,7 @@ } // namespace TEST(VideoAcceleratorStructTraitsTest, ConvertVideoFrameLayout) { - std::vector<media::VideoFrameLayout::Plane> planes; + std::vector<media::ColorPlaneLayout> planes; planes.emplace_back(kWidth, 0, kWidth * kHeight); planes.emplace_back(kWidth / 2, kWidth * kHeight, kWidth * kHeight / 4); planes.emplace_back(kWidth / 2, kWidth * kHeight + kWidth * kHeight / 4,
diff --git a/components/arc/mojom/video_common.typemap b/components/arc/mojom/video_common.typemap index c06a852..9d7b7f2 100644 --- a/components/arc/mojom/video_common.typemap +++ b/components/arc/mojom/video_common.typemap
@@ -6,10 +6,10 @@ public_headers = [ "//components/arc/video_accelerator/decoder_buffer.h", "//components/arc/video_accelerator/video_frame_plane.h", + "//media/base/color_plane_layout.h", "//media/base/decode_status.h", "//media/base/video_codecs.h", "//media/base/video_frame.h", - "//media/base/video_frame_layout.h", "//media/base/video_types.h", "//ui/gfx/geometry/size.h", ] @@ -33,7 +33,7 @@ type_mappings = [ "arc.mojom.DecoderBuffer=arc::DecoderBuffer[move_only]", "arc.mojom.DecodeStatus=media::DecodeStatus", - "arc.mojom.MediaVideoFramePlane=media::VideoFrameLayout::Plane", + "arc.mojom.MediaVideoFramePlane=media::ColorPlaneLayout", "arc.mojom.Size=gfx::Size", "arc.mojom.VideoCodecProfile=media::VideoCodecProfile", "arc.mojom.VideoFrame=scoped_refptr<media::VideoFrame>[nullable_is_same_type]",
diff --git a/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc b/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc index 1af2343..4e3f09f 100644 --- a/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc +++ b/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc
@@ -14,6 +14,7 @@ #include "base/numerics/safe_conversions.h" #include "base/system/sys_info.h" #include "components/arc/video_accelerator/arc_video_accelerator_util.h" +#include "media/base/color_plane_layout.h" #include "media/base/format_utils.h" #include "media/base/video_types.h" #include "media/gpu/gpu_video_encode_accelerator_factory.h" @@ -31,7 +32,7 @@ const gfx::GpuMemoryBufferHandle& gmb_handle) { const size_t num_planes = gmb_handle.native_pixmap_handle.planes.size(); - std::vector<media::VideoFrameLayout::Plane> layout_planes(num_planes); + std::vector<media::ColorPlaneLayout> layout_planes(num_planes); for (size_t i = 0; i < num_planes; i++) { const auto& plane = gmb_handle.native_pixmap_handle.planes[i]; if (!base::IsValueInRangeForNumericType<int32_t>(plane.stride)) {
diff --git a/components/autofill/content/renderer/form_autofill_util.h b/components/autofill/content/renderer/form_autofill_util.h index 8bbe645..ac542f3d5 100644 --- a/components/autofill/content/renderer/form_autofill_util.h +++ b/components/autofill/content/renderer/form_autofill_util.h
@@ -10,10 +10,13 @@ #include <set> #include <vector> +#include "base/i18n/rtl.h" #include "base/macros.h" #include "base/strings/string16.h" #include "components/autofill/core/common/autofill_constants.h" -#include "components/autofill/core/common/password_form_field_prediction_map.h" +#include "components/autofill/core/common/form_data.h" +#include "components/autofill/core/common/form_field_data.h" +#include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h" #include "third_party/blink/public/platform/web_vector.h" #include "third_party/blink/public/web/web_element_collection.h" #include "ui/gfx/geometry/rect_f.h"
diff --git a/components/autofill/content/renderer/form_autofill_util_browsertest.cc b/components/autofill/content/renderer/form_autofill_util_browsertest.cc index bbec17a5..a0a8c93 100644 --- a/components/autofill/content/renderer/form_autofill_util_browsertest.cc +++ b/components/autofill/content/renderer/form_autofill_util_browsertest.cc
@@ -7,6 +7,7 @@ #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h" #include "content/public/test/render_view_test.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/web_string.h"
diff --git a/components/autofill/content/renderer/form_cache.cc b/components/autofill/content/renderer/form_cache.cc index 0e67646..cb6edb1 100644 --- a/components/autofill/content/renderer/form_cache.cc +++ b/components/autofill/content/renderer/form_cache.cc
@@ -5,6 +5,7 @@ #include "components/autofill/content/renderer/form_cache.h" #include <algorithm> +#include <set> #include <string> #include <utility> @@ -12,6 +13,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/stl_util.h" +#include "base/strings/strcat.h" #include "base/strings/string_piece.h" #include "base/strings/string_split.h" #include "base/strings/stringprintf.h" @@ -161,15 +163,16 @@ for (const char* str : deprecated) { if (autocomplete_attribute.find(str) == std::string::npos) continue; - std::string msg = std::string("autocomplete='") + str + - "' is deprecated and will soon be ignored. See http://goo.gl/YjeSsW"; + std::string msg = base::StrCat( + {"autocomplete='", str, + "' is deprecated and will soon be ignored. See http://goo.gl/YjeSsW"}); WebConsoleMessage console_message = WebConsoleMessage( blink::mojom::ConsoleMessageLevel::kWarning, WebString::FromASCII(msg)); element.GetDocument().GetFrame()->AddMessageToConsole(console_message); } } -// Determines whether the form is interesting enough to send to the browser +// Determines whether the form is interesting enough to be sent to the browser // for further operations. bool IsFormInteresting(const FormData& form, size_t num_editable_elements) { if (form.fields.empty()) @@ -199,9 +202,7 @@ } // namespace FormCache::FormCache(WebLocalFrame* frame) : frame_(frame) {} - -FormCache::~FormCache() { -} +FormCache::~FormCache() = default; std::vector<FormData> FormCache::ExtractNewForms() { std::vector<FormData> forms; @@ -214,6 +215,8 @@ WebVector<WebFormElement> web_forms; document.Forms(web_forms); + std::set<uint32_t> observed_unique_renderer_ids; + // Log an error message for deprecated attributes, but only the first time // the form is parsed. bool log_deprecation_messages = parsed_forms_.empty(); @@ -223,14 +226,12 @@ form_util::EXTRACT_OPTIONS); size_t num_fields_seen = 0; - for (size_t i = 0; i < web_forms.size(); ++i) { - const WebFormElement& form_element = web_forms[i]; - + for (const WebFormElement& form_element : web_forms) { std::vector<WebFormControlElement> control_elements = form_util::ExtractAutofillableElementsInForm(form_element); + size_t num_editable_elements = ScanFormControlElements(control_elements, log_deprecation_messages); - if (num_editable_elements == 0) continue; @@ -240,9 +241,14 @@ continue; } + for (const auto& field : form.fields) + observed_unique_renderer_ids.insert(field.unique_renderer_id); + num_fields_seen += form.fields.size(); - if (num_fields_seen > form_util::kMaxParseableFields) + if (num_fields_seen > form_util::kMaxParseableFields) { + PruneInitialValueCaches(observed_unique_renderer_ids); return forms; + } if (!base::Contains(parsed_forms_, form) && IsFormInteresting(form, num_editable_elements)) { @@ -267,22 +273,29 @@ size_t num_editable_elements = ScanFormControlElements(control_elements, log_deprecation_messages); - - if (num_editable_elements == 0) + if (num_editable_elements == 0) { + PruneInitialValueCaches(observed_unique_renderer_ids); return forms; + } FormData synthetic_form; if (!UnownedCheckoutFormElementsAndFieldSetsToFormData( fieldsets, control_elements, nullptr, document, extract_mask, &synthetic_form, nullptr)) { + PruneInitialValueCaches(observed_unique_renderer_ids); return forms; } - num_fields_seen += synthetic_form.fields.size(); - if (num_fields_seen > form_util::kMaxParseableFields) - return forms; + for (const auto& field : synthetic_form.fields) + observed_unique_renderer_ids.insert(field.unique_renderer_id); - if (!parsed_forms_.count(synthetic_form) && + num_fields_seen += synthetic_form.fields.size(); + if (num_fields_seen > form_util::kMaxParseableFields) { + PruneInitialValueCaches(observed_unique_renderer_ids); + return forms; + } + + if (!base::Contains(parsed_forms_, synthetic_form) && IsFormInteresting(synthetic_form, num_editable_elements)) { SaveInitialValues(control_elements); forms.push_back(synthetic_form); @@ -290,6 +303,8 @@ parsed_forms_.erase(synthetic_form_); synthetic_form_ = synthetic_form; } + + PruneInitialValueCaches(observed_unique_renderer_ids); return forms; } @@ -302,16 +317,13 @@ bool FormCache::ClearSectionWithElement(const WebFormControlElement& element) { WebFormElement form_element = element.Form(); - std::vector<WebFormControlElement> control_elements; - if (form_element.IsNull()) { - control_elements = form_util::GetUnownedAutofillableFormFieldElements( - element.GetDocument().All(), nullptr); - } else { - control_elements = - form_util::ExtractAutofillableElementsInForm(form_element); - } - for (size_t i = 0; i < control_elements.size(); ++i) { - WebFormControlElement control_element = control_elements[i]; + std::vector<WebFormControlElement> control_elements = + form_element.IsNull() + ? form_util::GetUnownedAutofillableFormFieldElements( + element.GetDocument().All(), nullptr) + : form_util::ExtractAutofillableElementsInForm(form_element); + + for (WebFormControlElement& control_element : control_elements) { // Don't modify the value of disabled fields. if (!control_element.IsEnabled()) continue; @@ -341,8 +353,8 @@ } else if (form_util::IsSelectElement(control_element)) { WebSelectElement select_element = control_element.To<WebSelectElement>(); - std::map<const WebSelectElement, base::string16>::const_iterator - initial_value_iter = initial_select_values_.find(select_element); + auto initial_value_iter = initial_select_values_.find( + select_element.UniqueRendererFormControlId()); if (initial_value_iter != initial_select_values_.end() && select_element.Value().Utf16() != initial_value_iter->second) { select_element.SetAutofillValue( @@ -351,11 +363,11 @@ } else { WebInputElement input_element = control_element.To<WebInputElement>(); DCHECK(form_util::IsCheckableElement(&input_element)); - std::map<const WebInputElement, bool>::const_iterator it = - initial_checked_state_.find(input_element); - if (it != initial_checked_state_.end() && - input_element.IsChecked() != it->second) { - input_element.SetChecked(it->second, true); + auto checkable_element_it = initial_checked_state_.find( + input_element.UniqueRendererFormControlId()); + if (checkable_element_it != initial_checked_state_.end() && + input_element.IsChecked() != checkable_element_it->second) { + input_element.SetChecked(checkable_element_it->second, true); } } } @@ -381,12 +393,10 @@ if (!found_synthetic_form) { // Find the real form by searching through the WebDocuments. bool found_form = false; - WebFormElement form_element; WebVector<WebFormElement> web_forms; frame_->GetDocument().Forms(web_forms); - for (size_t i = 0; i < web_forms.size(); ++i) { - form_element = web_forms[i]; + for (const WebFormElement& form_element : web_forms) { // To match two forms, we look for the form's name and the number of // fields on that form. (Form names may not be unique.) // Note: WebString() == WebString(string16()) does not evaluate to |true| @@ -445,32 +455,15 @@ const base::string16 truncated_label = field_data.label.substr( 0, std::min(field_data.label.length(), kMaxLabelSize)); - // A rough estimate of the maximum title size is: - // 8 field titles at <17 chars each - // + 7 values at <40 chars each - // + 1 truncated label at <kMaxLabelSize; - // = 516 chars, rounded up to the next multiple of 64 = 576 - // A particularly large parseable name could blow through this and cause - // another allocation, but that's OK. - constexpr size_t kMaxTitleSize = 576; - std::string title; - title.reserve(kMaxTitleSize); - title += "overall type: "; - title += field.overall_type; - title += "\nserver type: "; - title += field.server_type; - title += "\nheuristic type: "; - title += field.heuristic_type; - title += "\nlabel: "; - title += base::UTF16ToUTF8(truncated_label); - title += "\nparseable name: "; - title += field.parseable_name; - title += "\nsection: "; - title += field.section; - title += "\nfield signature: "; - title += field.signature; - title += "\nform signature: "; - title += form.signature; + std::string title = + base::StrCat({"overall type: ", field.overall_type, // + "\nserver type: ", field.server_type, // + "\nheuristic type: ", field.heuristic_type, // + "\nlabel: ", base::UTF16ToUTF8(truncated_label), // + "\nparseable name: ", field.parseable_name, // + "\nsection: ", field.section, // + "\nfield signature: ", field.signature, // + "\nform signature: ", form.signature}); // Set this debug string to the title so that a developer can easily debug // by hovering the mouse over the input field. @@ -494,9 +487,7 @@ const std::vector<WebFormControlElement>& control_elements, bool log_deprecation_messages) { size_t num_editable_elements = 0; - for (size_t i = 0; i < control_elements.size(); ++i) { - const WebFormControlElement& element = control_elements[i]; - + for (const WebFormControlElement& element : control_elements) { if (log_deprecation_messages) LogDeprecationMessages(element); @@ -521,12 +512,14 @@ const WebSelectElement select_element = element.ToConst<WebSelectElement>(); initial_select_values_.insert( - std::make_pair(select_element, select_element.Value().Utf16())); + std::make_pair(select_element.UniqueRendererFormControlId(), + select_element.Value().Utf16())); } else { const WebInputElement* input_element = ToWebInputElement(&element); if (form_util::IsCheckableElement(input_element)) { initial_checked_state_.insert( - std::make_pair(*input_element, input_element->IsChecked())); + std::make_pair(input_element->UniqueRendererFormControlId(), + input_element->IsChecked())); } } } @@ -564,4 +557,25 @@ return false; } +void FormCache::PruneInitialValueCaches( + const std::set<uint32_t> ids_to_retain) { + // Prune initial_select_values_. + for (auto iter = initial_select_values_.begin(); + iter != initial_select_values_.end();) { + if (!base::Contains(ids_to_retain, iter->first)) + iter = initial_select_values_.erase(iter); + else + ++iter; + } + + // Prune initial_checked_state_. + for (auto iter = initial_checked_state_.begin(); + iter != initial_checked_state_.end();) { + if (!base::Contains(ids_to_retain, iter->first)) + iter = initial_checked_state_.erase(iter); + else + ++iter; + } +} + } // namespace autofill
diff --git a/components/autofill/content/renderer/form_cache.h b/components/autofill/content/renderer/form_cache.h index c4db022d..9cc7da6 100644 --- a/components/autofill/content/renderer/form_cache.h +++ b/components/autofill/content/renderer/form_cache.h
@@ -18,13 +18,12 @@ namespace blink { class WebFormControlElement; -class WebInputElement; class WebLocalFrame; -class WebSelectElement; } namespace autofill { +struct FormData; struct FormDataPredictions; // Manages the forms in a single RenderFrame. @@ -34,7 +33,8 @@ ~FormCache(); // Scans the DOM in |frame_| extracting and storing forms that have not been - // seen before. Returns the extracted forms. + // seen before. Returns the extracted forms. Note that modified forms are + // considered new forms. std::vector<FormData> ExtractNewForms(); // Resets the forms. @@ -57,10 +57,10 @@ ShouldShowAutocompleteConsoleWarnings_Enabled); FRIEND_TEST_ALL_PREFIXES(FormCacheTest, ShouldShowAutocompleteConsoleWarnings_Disabled); + FRIEND_TEST_ALL_PREFIXES(FormCacheBrowserTest, FreeDataOnElementRemoval); // Scans |control_elements| and returns the number of editable elements. - // Also remembers the initial <select> and <input> element states, and - // logs warning messages for deprecated attribute if + // Also logs warning messages for deprecated attribute if // |log_deprecation_messages| is set. size_t ScanFormControlElements( const std::vector<blink::WebFormControlElement>& control_elements, @@ -78,6 +78,10 @@ const std::string& predicted_autocomplete, const std::string& actual_autocomplete); + // Clears all entries from |initial_select_values_| and + // |initial_checked_state_| whose keys not contained in |ids_to_retain|. + void PruneInitialValueCaches(const std::set<uint32_t> ids_to_retain); + // The frame this FormCache is associated with. Weak reference. blink::WebLocalFrame* frame_; @@ -88,12 +92,13 @@ // form owner. FormData synthetic_form_; - // The cached initial values for <select> elements. - std::map<const blink::WebSelectElement, base::string16> - initial_select_values_; + // The cached initial values for <select> elements. Entries are keyed by + // unique_renderer_form_control_id of the WebSelectElements. + std::map<uint32_t, base::string16> initial_select_values_; - // The cached initial values for checkable <input> elements. - std::map<const blink::WebInputElement, bool> initial_checked_state_; + // The cached initial values for checkable <input> elements. Entries are + // keyed by the unique_renderer_form_control_id of the WebInputElements. + std::map<uint32_t, bool> initial_checked_state_; DISALLOW_COPY_AND_ASSIGN(FormCache); };
diff --git a/components/autofill/content/renderer/form_cache_browsertest.cc b/components/autofill/content/renderer/form_cache_browsertest.cc new file mode 100644 index 0000000..f55fadb --- /dev/null +++ b/components/autofill/content/renderer/form_cache_browsertest.cc
@@ -0,0 +1,194 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/content/renderer/form_cache.h" + +#include "base/strings/utf_string_conversions.h" +#include "components/autofill/content/renderer/form_autofill_util.h" +#include "components/autofill/core/common/form_field_data.h" +#include "content/public/test/render_view_test.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/web/web_document.h" +#include "third_party/blink/public/web/web_input_element.h" +#include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_select_element.h" + +using base::ASCIIToUTF16; +using blink::WebDocument; +using blink::WebElement; +using blink::WebInputElement; +using blink::WebSelectElement; +using blink::WebString; + +namespace autofill { + +const FormData* GetFormByName(const std::vector<FormData>& forms, + base::StringPiece name) { + for (const FormData& form : forms) { + if (form.name == ASCIIToUTF16(name)) + return &form; + } + return nullptr; +} + +class FormCacheBrowserTest : public content::RenderViewTest { + public: + FormCacheBrowserTest() = default; + ~FormCacheBrowserTest() override = default; +}; + +TEST_F(FormCacheBrowserTest, ExtractForms) { + LoadHTML(R"( + <form id="form1"> + <input type="text" name="foo1"> + <input type="text" name="foo2"> + <input type="text" name="foo3"> + </form> + <input type="text" name="unowned_element"> + )"); + + FormCache form_cache(GetMainFrame()); + std::vector<FormData> forms = form_cache.ExtractNewForms(); + + const FormData* form1 = GetFormByName(forms, "form1"); + ASSERT_TRUE(form1); + EXPECT_EQ(3u, form1->fields.size()); + + const FormData* unowned_form = GetFormByName(forms, ""); + ASSERT_TRUE(unowned_form); + EXPECT_EQ(1u, unowned_form->fields.size()); +} + +TEST_F(FormCacheBrowserTest, ExtractFormsTwice) { + LoadHTML(R"( + <form id="form1"> + <input type="text" name="foo1"> + <input type="text" name="foo2"> + <input type="text" name="foo3"> + </form> + <input type="text" name="unowned_element"> + )"); + + FormCache form_cache(GetMainFrame()); + std::vector<FormData> forms = form_cache.ExtractNewForms(); + + forms = form_cache.ExtractNewForms(); + // As nothing has changed, there are no new forms and |forms| should be empty. + EXPECT_TRUE(forms.empty()); +} + +TEST_F(FormCacheBrowserTest, ExtractFormsAfterModification) { + LoadHTML(R"( + <form id="form1"> + <input type="text" name="foo1"> + <input type="text" name="foo2"> + <input type="text" name="foo3"> + </form> + <input type="text" name="unowned_element"> + )"); + + FormCache form_cache(GetMainFrame()); + std::vector<FormData> forms = form_cache.ExtractNewForms(); + + // Append an input element to the form and to the list of unowned inputs. + ExecuteJavaScriptForTests(R"( + var new_input_1 = document.createElement("input"); + new_input_1.setAttribute("type", "text"); + new_input_1.setAttribute("name", "foo4"); + + var form1 = document.getElementById("form1"); + form1.appendChild(new_input_1); + + var new_input_2 = document.createElement("input"); + new_input_2.setAttribute("type", "text"); + new_input_2.setAttribute("name", "unowned_element_2"); + document.body.appendChild(new_input_2); + )"); + + forms = form_cache.ExtractNewForms(); + + const FormData* form1 = GetFormByName(forms, "form1"); + ASSERT_TRUE(form1); + EXPECT_EQ(4u, form1->fields.size()); + + const FormData* unowned_form = GetFormByName(forms, ""); + ASSERT_TRUE(unowned_form); + EXPECT_EQ(2u, unowned_form->fields.size()); +} + +TEST_F(FormCacheBrowserTest, FillAndClear) { + LoadHTML(R"( + <input type="text" name="text" id="text"> + <input type="checkbox" checked name="checkbox" id="checkbox"> + <select name="select" id="select"> + <option value="first">first</option> + <option value="second" selected>second</option> + </select> + )"); + + FormCache form_cache(GetMainFrame()); + std::vector<FormData> forms = form_cache.ExtractNewForms(); + + ASSERT_EQ(1u, forms.size()); + FormData values_to_fill = forms[0]; + values_to_fill.fields[0].value = ASCIIToUTF16("test"); + values_to_fill.fields[0].is_autofilled = true; + values_to_fill.fields[1].check_status = + FormFieldData::CheckStatus::kCheckableButUnchecked; + values_to_fill.fields[1].is_autofilled = true; + values_to_fill.fields[2].value = ASCIIToUTF16("first"); + values_to_fill.fields[2].is_autofilled = true; + + WebDocument doc = GetMainFrame()->GetDocument(); + auto text = doc.GetElementById("text").To<WebInputElement>(); + auto checkbox = doc.GetElementById("checkbox").To<WebInputElement>(); + auto select_element = doc.GetElementById("select").To<WebSelectElement>(); + + form_util::FillForm(values_to_fill, text); + + EXPECT_EQ("test", text.Value().Ascii()); + EXPECT_FALSE(checkbox.IsChecked()); + EXPECT_EQ("first", select_element.Value().Ascii()); + + // Validate that clearing works, in particular that the previous values + // were saved correctly. + form_cache.ClearSectionWithElement(text); + + EXPECT_EQ("", text.Value().Ascii()); + EXPECT_TRUE(checkbox.IsChecked()); + EXPECT_EQ("second", select_element.Value().Ascii()); +} + +TEST_F(FormCacheBrowserTest, FreeDataOnElementRemoval) { + LoadHTML(R"( + <div id="container"> + <input type="text" name="text" id="text"> + <input type="checkbox" checked name="checkbox" id="checkbox"> + <select name="select" id="select"> + <option value="first">first</option> + <option value="second" selected>second</option> + </select> + </div> + )"); + + FormCache form_cache(GetMainFrame()); + form_cache.ExtractNewForms(); + + EXPECT_EQ(1u, form_cache.initial_select_values_.size()); + EXPECT_EQ(1u, form_cache.initial_checked_state_.size()); + + ExecuteJavaScriptForTests(R"( + const container = document.getElementById('container'); + while (container.childElementCount > 0) { + container.removeChild(container.children.item(0)); + } + )"); + + std::vector<FormData> forms = form_cache.ExtractNewForms(); + EXPECT_EQ(0u, forms.size()); + EXPECT_EQ(0u, form_cache.initial_select_values_.size()); + EXPECT_EQ(0u, form_cache.initial_checked_state_.size()); +} + +} // namespace autofill
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index 54e9884..011f1b8 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -84,13 +84,9 @@ // The size above which we stop triggering autocomplete. const size_t kMaximumTextSizeForAutocomplete = 1000; -const char kDummyUsernameField[] = "anonymous_username"; -const char kDummyPasswordField[] = "anonymous_password"; - // Names of HTML attributes to show form and field signatures for debugging. const char kDebugAttributeForFormSignature[] = "form_signature"; const char kDebugAttributeForFieldSignature[] = "field_signature"; -const char kDebugAttributeForParserAnnotations[] = "pm_parser_annotation"; // Maps element names to the actual elements to simplify form filling. typedef std::map<base::string16, WebInputElement> FormInputElementMap; @@ -102,24 +98,6 @@ typedef std::vector<FormInputElementMap> FormElementsList; -bool FillDataContainsFillableUsername(const PasswordFormFillData& fill_data) { - return !fill_data.username_field.name.empty() && - (!fill_data.additional_logins.empty() || - !fill_data.username_field.value.empty()); -} - -// Returns true if password form has username and password fields with either -// same or no name and id attributes supplied. -bool DoesFormContainAmbiguousOrEmptyNames( - const PasswordFormFillData& fill_data) { - return (fill_data.username_field.name == fill_data.password_field.name) || - (fill_data.password_field.name == - base::ASCIIToUTF16(kDummyPasswordField) && - (!FillDataContainsFillableUsername(fill_data) || - fill_data.username_field.name == - base::ASCIIToUTF16(kDummyUsernameField))); -} - bool IsElementEditable(const WebInputElement& element) { return element.IsEnabled() && !element.IsReadOnly(); } @@ -263,32 +241,11 @@ base::NumberToString(CalculateFormSignature(password_form.form_data))); } -// Add parser annotations saved in |password_form| to |element|. -void AddParserAnnotations(PasswordForm* password_form, - blink::WebFormControlElement* element) { - base::string16 element_name = element->NameForAutofill().Utf16(); - std::string attribute_value; - if (password_form->username_element == element_name) { - attribute_value = "username_element"; - } else if (password_form->password_element == element_name) { - attribute_value = "password_element"; - } else if (password_form->new_password_element == element_name) { - attribute_value = "new_password_element"; - } else if (password_form->confirmation_password_element == element_name) { - attribute_value = "confirmation_password_element"; - } - element->SetAttribute( - blink::WebString::FromASCII(kDebugAttributeForParserAnnotations), - attribute_value.empty() ? blink::WebString() - : blink::WebString::FromASCII(attribute_value)); -} - // Annotate |fields| with field signatures and form signature as HTML // attributes. void AnnotateFieldsWithSignatures( std::vector<blink::WebFormControlElement>* fields, - const blink::WebString& form_signature, - PasswordForm* password_form) { + const blink::WebString& form_signature) { for (blink::WebFormControlElement& control_element : *fields) { FieldSignature field_signature = CalculateFieldSignatureByNameAndType( control_element.NameForAutofill().Utf16(), @@ -299,8 +256,6 @@ control_element.SetAttribute( blink::WebString::FromASCII(kDebugAttributeForFormSignature), form_signature); - if (password_form) - AddParserAnnotations(password_form, &control_element); } } @@ -310,7 +265,9 @@ WebVector<WebFormElement>* forms) { for (WebFormElement& form : *forms) { std::unique_ptr<PasswordForm> password_form( - CreatePasswordFormFromWebForm(form, nullptr, nullptr, nullptr)); + CreateSimplifiedPasswordFormFromWebForm( + form, /*field_data_manager=*/nullptr, + /*username_detector_cache=*/nullptr)); WebString form_signature; if (password_form) { form_signature = GetFormSignatureAsWebString(*password_form); @@ -319,21 +276,20 @@ } std::vector<WebFormControlElement> form_fields = form_util::ExtractAutofillableElementsInForm(form); - AnnotateFieldsWithSignatures(&form_fields, form_signature, - password_form ? password_form.get() : nullptr); + AnnotateFieldsWithSignatures(&form_fields, form_signature); } std::vector<WebFormControlElement> unowned_elements = form_util::GetUnownedAutofillableFormFieldElements( frame->GetDocument().All(), nullptr); std::unique_ptr<PasswordForm> password_form( - CreatePasswordFormFromUnownedInputElements(*frame, nullptr, nullptr, - nullptr)); + CreateSimplifiedPasswordFormFromUnownedInputElements( + *frame, /*field_data_manager=*/nullptr, + /*username_detector_cache=*/nullptr)); WebString form_signature; if (password_form) form_signature = GetFormSignatureAsWebString(*password_form); - AnnotateFieldsWithSignatures(&unowned_elements, form_signature, - password_form ? password_form.get() : nullptr); + AnnotateFieldsWithSignatures(&unowned_elements, form_signature); } // Returns true iff there is a password field in |frame|. @@ -413,6 +369,17 @@ return false; } +// Whether any of the fields in |form) is a non-empty password field. +bool FormHasNonEmptyPasswordField(const FormData& form) { + for (const auto& field : form.fields) { + if (field.IsPasswordInputElement()) { + if (!field.value.empty() || !field.typed_value.empty()) + return true; + } + } + return false; +} + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -844,11 +811,6 @@ return true; } - if (element.NameForAutofill().IsEmpty() && - !DoesFormContainAmbiguousOrEmptyNames(password_info->fill_data)) { - return false; // If the field has no name, then we won't have values. - } - // Don't attempt to autofill with values that are too large. if (element.Value().length() > kMaximumTextSizeForAutocomplete) return false; @@ -1274,16 +1236,15 @@ std::unique_ptr<PasswordForm> PasswordAutofillAgent::GetPasswordFormFromWebForm( const WebFormElement& web_form) { - return CreatePasswordFormFromWebForm(web_form, &field_data_manager_, - &form_predictions_, - &username_detector_cache_); + return CreateSimplifiedPasswordFormFromWebForm(web_form, &field_data_manager_, + &username_detector_cache_); } std::unique_ptr<PasswordForm> PasswordAutofillAgent::GetSimplifiedPasswordFormFromWebForm( const WebFormElement& web_form) { - return CreateSimplifiedPasswordFormFromWebForm(web_form, - &field_data_manager_); + return CreateSimplifiedPasswordFormFromWebForm(web_form, &field_data_manager_, + &username_detector_cache_); } std::unique_ptr<PasswordForm> @@ -1298,9 +1259,8 @@ WebLocalFrame* web_frame = frame->GetWebFrame(); if (!web_frame) return nullptr; - return CreatePasswordFormFromUnownedInputElements( - *web_frame, &field_data_manager_, &form_predictions_, - &username_detector_cache_); + return CreateSimplifiedPasswordFormFromUnownedInputElements( + *web_frame, &field_data_manager_, &username_detector_cache_); } std::unique_ptr<PasswordForm> @@ -1312,7 +1272,7 @@ if (!web_frame) return nullptr; return CreateSimplifiedPasswordFormFromUnownedInputElements( - *web_frame, &field_data_manager_); + *web_frame, &field_data_manager_, &username_detector_cache_); } // mojom::PasswordAutofillAgent: @@ -1375,7 +1335,6 @@ sent_request_to_store_ = false; checked_safe_browsing_reputation_ = false; username_query_prefix_.clear(); - form_predictions_.clear(); username_detector_cache_.clear(); forms_structure_cache_.clear(); autofilled_elements_cache_.clear(); @@ -1415,15 +1374,13 @@ if (!password_form) return; - bool has_password = !password_form->password_value.empty() || - !password_form->new_password_value.empty(); + bool has_password = FormHasNonEmptyPasswordField(password_form->form_data); if (restriction == RESTRICTION_NON_EMPTY_PASSWORD && !has_password) return; if (!FrameCanAccessPasswordManager()) return; - if (has_password) { GetPasswordManagerDriver()->ShowManualFallbackForSaving(*password_form); } else { @@ -1794,8 +1751,6 @@ WebString::FromUTF16(value)); } -void SetLastUpdatedFormAndField(const blink::WebFormElement& Form, - const blink::WebFormControlElement& input); void PasswordAutofillAgent::SetLastUpdatedFormAndField( const WebFormElement& form, const WebFormControlElement& input) {
diff --git a/components/autofill/content/renderer/password_autofill_agent.h b/components/autofill/content/renderer/password_autofill_agent.h index 6bb319ac..b62e536 100644 --- a/components/autofill/content/renderer/password_autofill_agent.h +++ b/components/autofill/content/renderer/password_autofill_agent.h
@@ -20,10 +20,8 @@ #include "components/autofill/content/renderer/field_data_manager.h" #include "components/autofill/content/renderer/form_tracker.h" #include "components/autofill/content/renderer/html_based_username_detector.h" -#include "components/autofill/core/common/form_data_predictions.h" #include "components/autofill/core/common/mojom/autofill_types.mojom.h" #include "components/autofill/core/common/password_form.h" -#include "components/autofill/core/common/password_form_field_prediction_map.h" #include "components/autofill/core/common/password_form_fill_data.h" #include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_view_observer.h" @@ -494,10 +492,6 @@ // Records the username typed before suggestions preview. base::string16 username_query_prefix_; - // Contains server predictions for username, password and/or new password - // fields for individual forms. - FormsPredictionsMap form_predictions_; - // The HTML based username detector's cache which maps form elements to // username predictions. UsernameDetectorCache username_detector_cache_;
diff --git a/components/autofill/content/renderer/password_form_conversion_utils.cc b/components/autofill/content/renderer/password_form_conversion_utils.cc index 9e6c94e..597a023 100644 --- a/components/autofill/content/renderer/password_form_conversion_utils.cc +++ b/components/autofill/content/renderer/password_form_conversion_utils.cc
@@ -4,34 +4,17 @@ #include "components/autofill/content/renderer/password_form_conversion_utils.h" -#include <stddef.h> - -#include <algorithm> -#include <set> -#include <string> - -#include "base/i18n/case_conversion.h" #include "base/lazy_instance.h" #include "base/macros.h" -#include "base/metrics/histogram_macros.h" #include "base/no_destructor.h" -#include "base/stl_util.h" -#include "base/strings/string16.h" #include "base/strings/string_piece.h" #include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" #include "components/autofill/content/renderer/form_autofill_util.h" #include "components/autofill/content/renderer/html_based_username_detector.h" -#include "components/autofill/core/common/autofill_regex_constants.h" -#include "components/autofill/core/common/autofill_regexes.h" -#include "components/autofill/core/common/autofill_util.h" #include "components/autofill/core/common/password_form.h" -#include "components/autofill/core/common/password_form_field_prediction_map.h" #include "google_apis/gaia/gaia_urls.h" #include "net/base/url_util.h" #include "third_party/blink/public/platform/web_string.h" -#include "third_party/blink/public/platform/web_vector.h" #include "third_party/blink/public/web/web_document.h" #include "third_party/blink/public/web/web_form_control_element.h" #include "third_party/blink/public/web/web_input_element.h" @@ -48,8 +31,6 @@ namespace autofill { -using mojom::PasswordFormFieldPredictionType; - namespace { constexpr char kAutocompleteUsername[] = "username"; @@ -129,136 +110,6 @@ return it->second; } -// Describes fields filtering criteria. More priority criteria has higher value -// in the enum. The fields with the maximal criteria are considered in a form, -// others are ignored. Criteria for password and username fields are calculated -// separately. For example, if there is a password field with user input, the -// password fields without user input are ignored (independently whether the -// fields are visible or not). -enum class FieldFilteringLevel { - NO_FILTER = 0, - VISIBILITY = 1, - USER_INPUT = 2 -}; - -// Helper to determine which password is the main (current) one, and which is -// the new password (e.g., on a sign-up or change password form), if any. If the -// new password is found and there is another password field with the same user -// input, the function also sets |confirmation_password| to this field. -void LocateSpecificPasswords(std::vector<const FormFieldData*> passwords, - const FormFieldData** current_password, - const FormFieldData** new_password, - const FormFieldData** confirmation_password, - const AutocompleteCache& autocomplete_cache) { - DCHECK(!passwords.empty()); - DCHECK(current_password && !*current_password); - DCHECK(new_password && !*new_password); - DCHECK(confirmation_password && !*confirmation_password); - - // First, look for elements marked with either autocomplete='current-password' - // or 'new-password' -- if we find any, take the hint, and treat the first of - // each kind as the element we are looking for. - for (const FormFieldData* password : passwords) { - const AutocompleteFlag flag = autocomplete_cache.RetrieveFor(password); - if (flag == AutocompleteFlag::CURRENT_PASSWORD && !*current_password) { - *current_password = password; - } else if (flag == AutocompleteFlag::NEW_PASSWORD && !*new_password) { - *new_password = password; - } else if (*new_password && ((*new_password)->value == password->value)) { - *confirmation_password = password; - } - } - - // If we have seen an element with either of autocomplete attributes above, - // take that as a signal that the page author must have intentionally left the - // rest of the password fields unmarked. Perhaps they are used for other - // purposes, e.g., PINs, OTPs, and the like. So we skip all the heuristics we - // normally do, and ignore the rest of the password fields. - if (*current_password || *new_password) - return; - - switch (passwords.size()) { - case 1: - // Single password, easy. - *current_password = passwords[0]; - break; - case 2: - if (!passwords[0]->value.empty() && - passwords[0]->value == passwords[1]->value) { - // Two identical non-empty passwords: assume we are seeing a new - // password with a confirmation. This can be either a sign-up form or a - // password change form that does not ask for the old password. - *new_password = passwords[0]; - *confirmation_password = passwords[1]; - } else { - // Assume first is old password, second is new (no choice but to guess). - // This case also includes empty passwords in order to allow filling of - // password change forms (that also could autofill for sign up form, but - // we can't do anything with this using only client side information). - *current_password = passwords[0]; - *new_password = passwords[1]; - } - break; - default: - if (!passwords[0]->value.empty() && - passwords[0]->value == passwords[1]->value && - passwords[0]->value == passwords[2]->value) { - // All three passwords are the same and non-empty? It may be a change - // password form where old and new passwords are the same. It doesn't - // matter what field is correct, let's save the value. - *current_password = passwords[0]; - } else if (passwords[1]->value == passwords[2]->value) { - // New password is the duplicated one, and comes second; or empty form - // with 3 password fields, in which case we will assume this layout. - *current_password = passwords[0]; - *new_password = passwords[1]; - *confirmation_password = passwords[2]; - } else if (passwords[0]->value == passwords[1]->value) { - // It is strange that the new password comes first, but trust more which - // fields are duplicated than the ordering of fields. Assume that - // any password fields after the new password contain sensitive - // information that isn't actually a password (security hint, SSN, etc.) - *new_password = passwords[0]; - *confirmation_password = passwords[1]; - } else { - // Three different passwords, or first and last match with middle - // different. No idea which is which. Let's save the first password. - // Password selection in a prompt will allow to correct the choice. - *current_password = passwords[0]; - } - } -} - -void FindPredictedElements( - const FormData& form_data, - const FormsPredictionsMap& form_predictions, - std::map<const FormFieldData*, PasswordFormFieldPredictionType>* - predicted_fields) { - // Matching only requires that action and name of the form match to allow - // the username to be updated even if the form is changed after page load. - // See https://crbug.com/476092 for more details. - auto field_predictions = std::find_if( - form_predictions.begin(), form_predictions.end(), - [&form_data](const auto& form_predictions_pair) { - return form_predictions_pair.first.action == form_data.action && - form_predictions_pair.first.name == form_data.name; - }); - - if (field_predictions == form_predictions.end()) - return; - - for (const auto& prediction : field_predictions->second) { - const FormFieldData& target_field = prediction.first; - const PasswordFormFieldPredictionType& type = prediction.second; - for (const FormFieldData& field : form_data.fields) { - if (field.name == target_field.name) { - (*predicted_fields)[&field] = type; - break; - } - } - } -} - const char kPasswordSiteUrlRegex[] = "passwords(?:-[a-z-]+\\.corp)?\\.google\\.com"; @@ -272,116 +123,6 @@ base::LazyInstance<re2::RE2, PasswordSiteUrlLazyInstanceTraits> g_password_site_matcher = LAZY_INSTANCE_INITIALIZER; -// Returns the |input_field| name if its non-empty; otherwise a |dummy_name|. -base::string16 FieldName(const FormFieldData* input_field, - const char* dummy_name) { - return input_field->name.empty() ? base::ASCIIToUTF16(dummy_name) - : input_field->name; -} - -// Return the maximal filtering criteria that |field| passes. -// If |ignore_autofilled_values|, autofilled value isn't considered user input. -FieldFilteringLevel GetFiltertingLevelForField(const FormFieldData& field, - bool ignore_autofilled_values) { - FieldPropertiesMask user_input_mask = - ignore_autofilled_values - ? FieldPropertiesFlags::USER_TYPED - : FieldPropertiesFlags::USER_TYPED | FieldPropertiesFlags::AUTOFILLED; - if (field.properties_mask & user_input_mask) - return FieldFilteringLevel::USER_INPUT; - return field.is_focusable ? FieldFilteringLevel::VISIBILITY - : FieldFilteringLevel::NO_FILTER; -} - -// Calculates the maximal filtering levels for password and username fields and -// saves them to |username_fields_level| and |password_fields_level|. The -// criteria for username fields considers only the fields before the first -// password field that has the maximal filtering level. -void GetFieldFilteringLevels(const std::vector<FormFieldData>& fields, - FieldFilteringLevel* username_fields_level, - FieldFilteringLevel* password_fields_level) { - DCHECK(password_fields_level); - DCHECK(username_fields_level); - *username_fields_level = FieldFilteringLevel::NO_FILTER; - *password_fields_level = FieldFilteringLevel::NO_FILTER; - - FieldFilteringLevel max_level_found_for_username_fields = - FieldFilteringLevel::NO_FILTER; - for (const FormFieldData& field : fields) { - if (!field.is_enabled || !field.IsTextInputElement()) - continue; - - // TODO(crbug.com/789917): Ignore autofilled values here because if there - // are only autofilled values then a form may not be filled completely (i.e. - // some user input is still expected). So, user input shouldn't be used for - // fields filtering. Once the bug is resolved, autofilled values will not be - // ignored. - FieldFilteringLevel current_field_filtering_level = - GetFiltertingLevelForField(field, true /* ignore_autofilled_values */); - - if (field.form_control_type == "password") { - if (*password_fields_level < current_field_filtering_level) { - *password_fields_level = current_field_filtering_level; - *username_fields_level = max_level_found_for_username_fields; - } - } else { - max_level_found_for_username_fields = std::max( - max_level_found_for_username_fields, current_field_filtering_level); - } - } -} - -ValueElementPair MakePossibleUsernamePair(const FormFieldData* input) { - base::string16 trimmed_input_value; - base::TrimString(input->value, base::ASCIIToUTF16(" "), &trimmed_input_value); - return {trimmed_input_value, input->name}; -} - -bool StringMatchesCVC(const base::string16& str) { - static const base::NoDestructor<base::string16> kCardCvcReCached( - base::UTF8ToUTF16(kCardCvcRe)); - - return MatchesPattern(str, *kCardCvcReCached); -} - -// Which types of password fields are present in a form? -enum class PasswordContents { - kEnabled, // At least one enabled password field. - kOnlyDisabled, // At least one password field, but not enabled. - kNone // No password fields present. -}; - -// Returns the PasswordContents reflecting the contents of |fields|. -PasswordContents GetPasswordContents(const std::vector<FormFieldData>& fields) { - PasswordContents result = PasswordContents::kNone; - for (const FormFieldData& field : fields) { - if (field.form_control_type != "password") - continue; - result = PasswordContents::kOnlyDisabled; - if (field.is_enabled) - return PasswordContents::kEnabled; - } - return result; -} - -// Find the first element in |username_predictions| (i.e. the most reliable -// prediction) that occurs in |possible_usernames|. -const FormFieldData* FindUsernameInPredictions( - const std::vector<uint32_t>& username_predictions, - const std::vector<const FormFieldData*>& possible_usernames) { - for (uint32_t predicted_id : username_predictions) { - auto iter = - std::find_if(possible_usernames.begin(), possible_usernames.end(), - [predicted_id](const FormFieldData* field) { - return field->unique_renderer_id == predicted_id; - }); - if (iter != possible_usernames.end()) { - return *iter; - } - } - return nullptr; -} - // Extracts the username predictions. |control_elements| should be all the DOM // elements of the form, |form_data| should be the already extracted FormData // representation of that form. |username_detector_cache| is optional, and can @@ -401,387 +142,6 @@ username_detector_cache); } -// Get information about a login form encapsulated in a PasswordForm struct. -// If an element of |form| has an entry in |nonscript_modified_values|, the -// associated string is used instead of the element's value to create -// the PasswordForm. -bool GetPasswordForm(const GURL& form_origin, - const std::vector<WebFormControlElement>& control_elements, - PasswordForm* password_form, - const FormsPredictionsMap* form_predictions, - UsernameDetectorCache* username_detector_cache) { - DCHECK(!control_elements.empty()); - - const FormData& form_data = password_form->form_data; - PasswordContents password_contents = GetPasswordContents(form_data.fields); - switch (password_contents) { - case PasswordContents::kEnabled: - // All well, continue parsing. - break; - case PasswordContents::kOnlyDisabled: - // The current parser gives up, but returns a fallback form so that the - // newer parser can try parsing as well. - password_form->scheme = PasswordForm::Scheme::kHtml; - password_form->origin = form_origin; - password_form->signon_realm = GetSignOnRealm(password_form->origin); - return true; - case PasswordContents::kNone: - return false; - } - // Evaluate the context of the fields. - password_form->form_data.username_predictions = GetUsernamePredictions( - control_elements, form_data, username_detector_cache); - - // Narrow the scope to enabled text inputs. - std::vector<const FormFieldData*> enabled_fields; - enabled_fields.reserve(form_data.fields.size()); - for (const FormFieldData& field : form_data.fields) { - if (field.is_enabled && field.IsTextInputElement()) - enabled_fields.push_back(&field); - } - - // Remember the list of password fields without any heuristics applied in case - // the heuristics fail and a fall-back is needed: - // All password fields. - std::vector<const FormFieldData*> passwords_without_heuristics; - // Map from all password fields to the most recent non-password text input. - std::map<const FormFieldData*, const FormFieldData*> - preceding_text_input_for_password_without_heuristics; - const FormFieldData* most_recent_text_input = nullptr; // Just a temporary. - for (const FormFieldData* input : enabled_fields) { - if (input->form_control_type == "password") { - passwords_without_heuristics.push_back(input); - preceding_text_input_for_password_without_heuristics[input] = - most_recent_text_input; - } else { - most_recent_text_input = input; - } - } - - // Fill the cache with autocomplete flags. - AutocompleteCache autocomplete_cache; - for (const FormFieldData* input : enabled_fields) { - autocomplete_cache.Store(input); - } - - // Narrow the scope further: drop credit-card fields. - std::vector<const FormFieldData*> plausible_inputs; - plausible_inputs.reserve(enabled_fields.size()); - for (const FormFieldData* input : enabled_fields) { - const AutocompleteFlag flag = autocomplete_cache.RetrieveFor(input); - if (flag == AutocompleteFlag::CURRENT_PASSWORD || - flag == AutocompleteFlag::NEW_PASSWORD) { - // A field marked as a password is considered not a credit-card field, no - // matter what. - plausible_inputs.push_back(input); - } else if (flag != AutocompleteFlag::CREDIT_CARD) { - const bool is_credit_card_verification = - input->form_control_type == "password" && - (StringMatchesCVC(input->name_attribute) || - StringMatchesCVC(input->id_attribute)); - if (!is_credit_card_verification) { - // Otherwise ensure that nothing hints that |input| is a credit-card - // field. - plausible_inputs.push_back(input); - } - } - } - - // Further narrow to interesting fields (e.g., with user input, visible), if - // present. - // Compute the best filtering levels for usernames and for passwords. - FieldFilteringLevel username_fields_level = FieldFilteringLevel::NO_FILTER; - FieldFilteringLevel password_fields_level = FieldFilteringLevel::NO_FILTER; - GetFieldFilteringLevels(form_data.fields, &username_fields_level, - &password_fields_level); - // Remove all fields with filtering level below the best. - base::EraseIf( - plausible_inputs, [password_fields_level, - username_fields_level](const FormFieldData* input) { - FieldFilteringLevel current_field_level = GetFiltertingLevelForField( - *input, false /* ignore_autofilled_values */); - if (input->form_control_type == "password") - return current_field_level < password_fields_level; - return current_field_level < username_fields_level; - }); - - // Further, remove all readonly passwords. If the password field is readonly, - // the page is likely using a virtual keyboard and bypassing the password - // field value (see http://crbug.com/475488). There is nothing Chrome can do - // to fill passwords for now. Notable exceptions: if the password field was - // made readonly by JavaScript before submission, it remains interesting. If - // the password was marked via the autocomplete attribute, it also remains - // interesting. - base::EraseIf(plausible_inputs, [&autocomplete_cache]( - const FormFieldData* input) { - if (!input->is_readonly) - return false; - if (input->form_control_type != "password") - return false; - // Check if the field was only made readonly before submission. - if (input->properties_mask & - (FieldPropertiesFlags::USER_TYPED | FieldPropertiesFlags::AUTOFILLED)) { - return false; - } - // Check whether the field was explicitly marked as password. - const AutocompleteFlag flag = autocomplete_cache.RetrieveFor(input); - if (flag == AutocompleteFlag::CURRENT_PASSWORD || - flag == AutocompleteFlag::NEW_PASSWORD) { - return false; - } - return true; - }); - - // Evaluate available server-side predictions. - std::map<const FormFieldData*, PasswordFormFieldPredictionType> - predicted_fields; - const FormFieldData* predicted_username_field = nullptr; - if (form_predictions) { - FindPredictedElements(password_form->form_data, *form_predictions, - &predicted_fields); - - for (const auto& predicted_pair : predicted_fields) { - if (predicted_pair.second == PasswordFormFieldPredictionType::kUsername) { - predicted_username_field = predicted_pair.first; - break; - } - } - } - - // Finally, remove all password fields for which we have a negative - // prediction, unless they are explicitly marked by the autocomplete attribute - // as a password. - base::EraseIf(plausible_inputs, [&predicted_fields, &autocomplete_cache]( - const FormFieldData* input) { - if (input->form_control_type != "password") - return false; - const AutocompleteFlag flag = autocomplete_cache.RetrieveFor(input); - if (flag == AutocompleteFlag::CURRENT_PASSWORD || - flag == AutocompleteFlag::NEW_PASSWORD) { - return false; - } - auto possible_password_field_iterator = predicted_fields.find(input); - return possible_password_field_iterator != predicted_fields.end() && - possible_password_field_iterator->second == - PasswordFormFieldPredictionType::kNotPassword; - }); - - // Derive the list of all plausible passwords, usernames and the non-password - // inputs preceding the plausible passwords. - std::vector<const FormFieldData*> plausible_passwords; - std::vector<const FormFieldData*> plausible_usernames; - std::map<const FormFieldData*, const FormFieldData*> - preceding_text_input_for_plausible_password; - most_recent_text_input = nullptr; - plausible_usernames.reserve(plausible_inputs.size()); - for (const FormFieldData* input : plausible_inputs) { - if (input->form_control_type == "password") { - plausible_passwords.push_back(input); - preceding_text_input_for_plausible_password[input] = - most_recent_text_input; - } else { - plausible_usernames.push_back(input); - most_recent_text_input = input; - } - } - - // Evaluate autocomplete attributes for username. - const FormFieldData* username_by_attribute = nullptr; - for (const FormFieldData* input : plausible_inputs) { - if (input->form_control_type != "password") { - if (autocomplete_cache.RetrieveFor(input) == AutocompleteFlag::USERNAME) { - // Only consider the first occurrence of autocomplete='username'. - // Multiple occurences hint at the attribute being used incorrectly, in - // which case sticking to the first one is just a bet. - if (!username_by_attribute) { - username_by_attribute = input; - break; - } - } - } - } - - // Evaluate the context of the fields. - const FormFieldData* username_field_by_context = nullptr; - // Use HTML based username detector only if neither server predictions nor - // autocomplete attributes were useful to detect the username. - if (!predicted_username_field && !username_by_attribute) { - username_field_by_context = FindUsernameInPredictions( - form_data.username_predictions, plausible_usernames); - } - - // Populate all_possible_passwords and form_has_autofilled_value in - // |password_form|. - // Contains the first password element for each non-empty password value. - std::vector<ValueElementPair> all_possible_passwords; - // Reserve enough space to prevent re-allocation. A re-allocation would - // invalidate the contents of |seen_values|. - all_possible_passwords.reserve(passwords_without_heuristics.size()); - std::set<base::StringPiece16> seen_values; - // Pretend that an empty value has been already seen, so that empty-valued - // password elements won't get added to |all_possible_passwords|. - seen_values.insert(base::StringPiece16()); - for (const FormFieldData* password_field : passwords_without_heuristics) { - if (seen_values.count(password_field->value) > 0) - continue; - all_possible_passwords.push_back( - {password_field->value, password_field->name}); - seen_values.insert( - base::StringPiece16(all_possible_passwords.back().first)); - } - - bool form_has_autofilled_value = false; - for (const FormFieldData* password_field : passwords_without_heuristics) { - bool field_has_autofilled_value = - password_field->properties_mask & FieldPropertiesFlags::AUTOFILLED; - form_has_autofilled_value |= field_has_autofilled_value; - } - - if (!all_possible_passwords.empty()) { - password_form->all_possible_passwords = std::move(all_possible_passwords); - password_form->form_has_autofilled_value = form_has_autofilled_value; - } - - // If for some reason (e.g. only credit card fields, confusing autocomplete - // attributes) the passwords list is empty, build list based on user input (if - // there is any non-empty password field) and the type of a field. Also mark - // that the form should be available only for fallback saving (automatic - // bubble will not pop up) and filling. - password_form->only_for_fallback = plausible_passwords.empty(); - if (plausible_passwords.empty()) { - plausible_passwords = std::move(passwords_without_heuristics); - preceding_text_input_for_plausible_password = - std::move(preceding_text_input_for_password_without_heuristics); - } - - // Find the password fields. - const FormFieldData* password = nullptr; - const FormFieldData* new_password = nullptr; - const FormFieldData* confirmation_password = nullptr; - LocateSpecificPasswords(std::move(plausible_passwords), &password, - &new_password, &confirmation_password, - autocomplete_cache); - - // Choose the username element. - const FormFieldData* username_field = nullptr; - UsernameDetectionMethod username_detection_method = - UsernameDetectionMethod::NO_USERNAME_DETECTED; - password_form->username_marked_by_site = false; - - if (predicted_username_field) { - // Server predictions are most trusted, so try them first. Only if the form - // already has user input and the predicted username field has an empty - // value, then don't trust the prediction (can be caused by, e.g., a <form> - // actually contains several forms). - if (password_fields_level < FieldFilteringLevel::USER_INPUT || - !predicted_username_field->value.empty()) { - username_field = predicted_username_field; - password_form->was_parsed_using_autofill_predictions = true; - username_detection_method = - UsernameDetectionMethod::SERVER_SIDE_PREDICTION; - } - } - - if (!username_field && username_by_attribute) { - // Next in the trusted queue: autocomplete attributes. - username_field = username_by_attribute; - username_detection_method = UsernameDetectionMethod::AUTOCOMPLETE_ATTRIBUTE; - } - - if (!username_field && username_field_by_context) { - // Last step before base heuristics: HTML-based classifier. - username_field = username_field_by_context; - username_detection_method = UsernameDetectionMethod::HTML_BASED_CLASSIFIER; - } - - // Compute base heuristic for username detection. - const FormFieldData* base_heuristic_username = nullptr; - if (password) { - base_heuristic_username = - preceding_text_input_for_plausible_password[password]; - } - if (!base_heuristic_username && new_password) { - base_heuristic_username = - preceding_text_input_for_plausible_password[new_password]; - } - - // Apply base heuristic for username detection. - if (!username_field) { - username_field = base_heuristic_username; - if (username_field) - username_detection_method = UsernameDetectionMethod::BASE_HEURISTIC; - } else if (base_heuristic_username == username_field && - username_detection_method != - UsernameDetectionMethod::AUTOCOMPLETE_ATTRIBUTE) { - // TODO(crbug.com/786404): when the bug is fixed, remove this block and - // calculate |base_heuristic_username| only if |username_field| is null. - // This block was added to measure the impact of server-side predictions and - // HTML based classifier compared to "old classifiers" (the based heuristic - // and 'autocomplete' attribute). - username_detection_method = UsernameDetectionMethod::BASE_HEURISTIC; - } - UMA_HISTOGRAM_ENUMERATION( - "PasswordManager.UsernameDetectionMethod", username_detection_method, - UsernameDetectionMethod::USERNAME_DETECTION_METHOD_COUNT); - - // Populate the username fields in |password_form|. - if (username_field) { - password_form->username_element = - FieldName(username_field, "anonymous_username"); - password_form->username_value = username_field->value; - if ((username_field->properties_mask & - (FieldPropertiesFlags::USER_TYPED | - FieldPropertiesFlags::AUTOFILLED)) && - !username_field->typed_value.empty()) { - password_form->username_value = username_field->typed_value; - } - } - - // Populate the password fields in |password_form|. - if (password) { - password_form->password_element = FieldName(password, "anonymous_password"); - password_form->password_value = password->value; - if ((password->properties_mask & (FieldPropertiesFlags::USER_TYPED | - FieldPropertiesFlags::AUTOFILLED)) && - !password->typed_value.empty()) { - password_form->password_value = password->typed_value; - } - } - if (new_password) { - password_form->new_password_element = - FieldName(new_password, "anonymous_new_password"); - password_form->new_password_value = new_password->value; - if (autocomplete_cache.RetrieveFor(new_password) == - AutocompleteFlag::NEW_PASSWORD) { - password_form->new_password_marked_by_site = true; - } - if (confirmation_password) { - password_form->confirmation_password_element = - FieldName(confirmation_password, "anonymous_confirmation_password"); - } - } - - // Populate |all_possible_usernames| in |password_form|. - ValueElementVector all_possible_usernames; - for (const FormFieldData* plausible_username : plausible_usernames) { - if (plausible_username == username_field) - continue; - auto pair = MakePossibleUsernamePair(plausible_username); - if (!pair.first.empty()) - all_possible_usernames.push_back(std::move(pair)); - } - password_form->all_possible_usernames = std::move(all_possible_usernames); - - password_form->origin = std::move(form_origin); - password_form->signon_realm = GetSignOnRealm(password_form->origin); - password_form->scheme = PasswordForm::Scheme::kHtml; - password_form->preferred = false; - password_form->blacklisted_by_user = false; - password_form->type = PasswordForm::Type::kManual; - - return true; -} - bool HasGaiaSchemeAndHost(const WebFormElement& form) { GURL form_url = form.GetDocument().Url(); GURL gaia_url = GaiaUrls::GetInstance()->gaia_url(); @@ -854,7 +214,8 @@ std::unique_ptr<PasswordForm> CreateSimplifiedPasswordFormFromWebForm( const WebFormElement& web_form, - const FieldDataManager* field_data_manager) { + const FieldDataManager* field_data_manager, + UsernameDetectorCache* username_detector_cache) { if (web_form.IsNull()) return nullptr; @@ -867,32 +228,6 @@ IsGaiaWithSkipSavePasswordForm(web_form) || IsGaiaReauthenticationForm(web_form); - if (!WebFormElementToFormData(web_form, WebFormControlElement(), - field_data_manager, form_util::EXTRACT_VALUE, - &password_form->form_data, - nullptr /* FormFieldData */)) { - return nullptr; - } - - return password_form; -} - -std::unique_ptr<PasswordForm> CreatePasswordFormFromWebForm( - const WebFormElement& web_form, - const FieldDataManager* field_data_manager, - const FormsPredictionsMap* form_predictions, - UsernameDetectorCache* username_detector_cache) { - if (web_form.IsNull()) - return nullptr; - - auto password_form = std::make_unique<PasswordForm>(); - password_form->action = form_util::GetCanonicalActionForForm(web_form); - if (!password_form->action.is_valid()) - return nullptr; - password_form->form_data.is_gaia_with_skip_save_password_form = - IsGaiaWithSkipSavePasswordForm(web_form) || - IsGaiaReauthenticationForm(web_form); - blink::WebVector<WebFormControlElement> control_elements; web_form.GetFormControlElements(control_elements); if (control_elements.empty()) @@ -904,20 +239,18 @@ nullptr /* FormFieldData */)) { return nullptr; } + password_form->form_data.username_predictions = + GetUsernamePredictions(control_elements.ReleaseVector(), + password_form->form_data, username_detector_cache); - if (!GetPasswordForm( - form_util::GetCanonicalOriginForDocument(web_form.GetDocument()), - control_elements.ReleaseVector(), password_form.get(), - form_predictions, username_detector_cache)) { - return nullptr; - } return password_form; } std::unique_ptr<PasswordForm> CreateSimplifiedPasswordFormFromUnownedInputElements( const WebLocalFrame& frame, - const FieldDataManager* field_data_manager) { + const FieldDataManager* field_data_manager, + UsernameDetectorCache* username_detector_cache) { std::vector<WebElement> fieldsets; std::vector<WebFormControlElement> control_elements = form_util::GetUnownedFormFieldElements(frame.GetDocument().All(), @@ -936,38 +269,8 @@ password_form->origin = form_util::GetCanonicalOriginForDocument(frame.GetDocument()); password_form->signon_realm = GetSignOnRealm(password_form->origin); - return password_form; -} - -std::unique_ptr<PasswordForm> CreatePasswordFormFromUnownedInputElements( - const WebLocalFrame& frame, - const FieldDataManager* field_data_manager, - const FormsPredictionsMap* form_predictions, - UsernameDetectorCache* username_detector_cache) { - std::vector<WebElement> fieldsets; - std::vector<WebFormControlElement> control_elements = - form_util::GetUnownedFormFieldElements(frame.GetDocument().All(), - &fieldsets); - if (control_elements.empty()) - return nullptr; - - auto password_form = std::make_unique<PasswordForm>(); - if (!UnownedPasswordFormElementsAndFieldSetsToFormData( - fieldsets, control_elements, nullptr, frame.GetDocument(), - field_data_manager, form_util::EXTRACT_VALUE, - &password_form->form_data, nullptr /* FormFieldData */)) { - return nullptr; - } - - if (!GetPasswordForm( - form_util::GetCanonicalOriginForDocument(frame.GetDocument()), - control_elements, password_form.get(), form_predictions, - username_detector_cache)) { - return nullptr; - } - - // No actual action on the form, so use the the origin as the action. - password_form->action = password_form->origin; + password_form->form_data.username_predictions = GetUsernamePredictions( + control_elements, password_form->form_data, username_detector_cache); return password_form; }
diff --git a/components/autofill/content/renderer/password_form_conversion_utils.h b/components/autofill/content/renderer/password_form_conversion_utils.h index e02034c8..40585c4 100644 --- a/components/autofill/content/renderer/password_form_conversion_utils.h +++ b/components/autofill/content/renderer/password_form_conversion_utils.h
@@ -14,7 +14,6 @@ #include "base/strings/string_piece.h" #include "components/autofill/content/renderer/html_based_username_detector.h" #include "components/autofill/core/common/password_form.h" -#include "components/autofill/core/common/password_form_field_prediction_map.h" #include "third_party/blink/public/platform/web_string.h" #include "url/gurl.h" @@ -34,15 +33,6 @@ class FieldDataManager; -enum UsernameDetectionMethod { - NO_USERNAME_DETECTED, - BASE_HEURISTIC, - HTML_BASED_CLASSIFIER, - AUTOCOMPLETE_ATTRIBUTE, - SERVER_SIDE_PREDICTION, - USERNAME_DETECTION_METHOD_COUNT -}; - // The susbset of autocomplete flags related to passwords. enum class AutocompleteFlag { NONE, @@ -66,34 +56,11 @@ // Tests whether the given form is a GAIA form with a skip password argument. bool IsGaiaWithSkipSavePasswordForm(const blink::WebFormElement& form); -// Create a PasswordForm from DOM form. Webkit doesn't allow storing -// custom metadata to DOM nodes, so we have to do this every time an event -// happens with a given form and compare against previously Create'd forms -// to identify..which sucks. -// If an element of |form| has an entry in |field_data_manager|, the associated -// string is used instead of the element's value to create the PasswordForm. -// |form_predictions| is Autofill server response, if present it's used for -// overwriting default username element selection. -// |username_detector_cache| is used by the built-in HTML based username -// detector to cache results. Can be null. -std::unique_ptr<PasswordForm> CreatePasswordFormFromWebForm( - const blink::WebFormElement& form, - const FieldDataManager* field_data_manager, - const FormsPredictionsMap* form_predictions, - UsernameDetectorCache* username_detector_cache); - // Creates a |PasswordForm| from DOM which only contains the |form_data| as well // as origin, action and gaia flags. std::unique_ptr<PasswordForm> CreateSimplifiedPasswordFormFromWebForm( const blink::WebFormElement& form, - const FieldDataManager* field_data_manager); - -// Same as CreatePasswordFormFromWebForm() but for input elements that are not -// enclosed in <form> element. -std::unique_ptr<PasswordForm> CreatePasswordFormFromUnownedInputElements( - const blink::WebLocalFrame& frame, const FieldDataManager* field_data_manager, - const FormsPredictionsMap* form_predictions, UsernameDetectorCache* username_detector_cache); // Same as CreateSimlePasswordFormFromWebForm() but for input elements that are @@ -101,7 +68,8 @@ std::unique_ptr<PasswordForm> CreateSimplifiedPasswordFormFromUnownedInputElements( const blink::WebLocalFrame& frame, - const FieldDataManager* field_data_manager); + const FieldDataManager* field_data_manager, + UsernameDetectorCache* username_detector_cache); // The "Realm" for the sign-on. This is scheme, host, port. std::string GetSignOnRealm(const GURL& origin);
diff --git a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc index 02b36b862..7b67bc5 100644 --- a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc +++ b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
@@ -5,47 +5,24 @@ #include <stddef.h> #include <memory> -#include "base/stl_util.h" -#include "base/strings/string16.h" -#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" -#include "build/build_config.h" -#include "components/autofill/content/renderer/field_data_manager.h" -#include "components/autofill/content/renderer/form_autofill_util.h" #include "components/autofill/content/renderer/password_form_conversion_utils.h" -#include "components/autofill/core/browser/form_structure.h" -#include "components/autofill/core/common/form_field_data.h" -#include "components/autofill/core/common/password_form.h" #include "content/public/test/render_view_test.h" #include "google_apis/gaia/gaia_urls.h" -#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/web_vector.h" #include "third_party/blink/public/web/web_document.h" -#include "third_party/blink/public/web/web_form_control_element.h" #include "third_party/blink/public/web/web_form_element.h" -#include "third_party/blink/public/web/web_input_element.h" #include "third_party/blink/public/web/web_local_frame.h" -using blink::WebElement; -using blink::WebFormControlElement; using blink::WebFormElement; -using blink::WebInputElement; using blink::WebLocalFrame; -using blink::WebString; using blink::WebVector; namespace autofill { -using mojom::PasswordFormFieldPredictionType; - namespace { -const char kTestFormActionURL[] = "http://cnn.com"; - // A builder to produce HTML code for a password form composed of the desired // number and kinds of username and password fields. class PasswordFormBuilder { @@ -73,20 +50,6 @@ name_and_id, name_and_id, value, autocomplete_attribute.c_str()); } - // Add a text field with name, id, value, label and placeholder, - // without autocomplete. - void AddTextFieldWithoutAutocomplete(const char* name, - const char* id, - const char* value, - const char* label, - const char* placeholder) { - base::StringAppendF(&html_, - "<LABEL for=\"%s\">%s</LABEL>" - "<INPUT type=\"text\" name=\"%s\" id=\"%s\" " - "value=\"%s\" placeholder=\"%s\"/>", - id, label, name, id, value, placeholder); - } - // Appends a new password-type field at the end of the form, having the // specified |name_and_id|, |value|, and |autocomplete| attributes. Special // values for |autocomplete| are the same as in AddTextField. @@ -102,19 +65,6 @@ name_and_id, name_and_id, value, autocomplete_attribute.c_str()); } - // Appends a disabled text-type field at the end of the form. - void AddDisabledUsernameField() { - html_ += "<INPUT name=\"disabled field\" type=\"text\" disabled/>"; - } - - // Appends a disabled password-type field at the end of the form. - void AddDisabledPasswordField() { - html_ += "<INPUT name=\"disabled field\" type=\"password\" disabled/>"; - } - - // Appends a hidden field at the end of the form. - void AddHiddenField() { html_ += "<INPUT type=\"hidden\"/>"; } - // Appends a new hidden-type field at the end of the form, having the // specified |name_and_id| and |value| attributes. void AddHiddenField(const char* name_and_id, const char* value) { @@ -123,68 +73,10 @@ name_and_id, name_and_id, value); } - // Append a text field with "display: none". - void AddNonDisplayedTextField(const char* name_and_id, const char* value) { - base::StringAppendF( - &html_, - "<INPUT type=\"text\" name=\"%s\" id=\"%s\" value=\"%s\"" - "style=\"display: none;\"/>", - name_and_id, name_and_id, value); - } - - // Append a password field with "display: none". - void AddNonDisplayedPasswordField(const char* name_and_id, - const char* value) { - base::StringAppendF( - &html_, - "<INPUT type=\"password\" name=\"%s\" id=\"%s\" value=\"%s\"" - "style=\"display: none;\"/>", - name_and_id, name_and_id, value); - } - - // Append a text field with "visibility: hidden". - void AddNonVisibleTextField(const char* name_and_id, const char* value) { - base::StringAppendF( - &html_, - "<INPUT type=\"text\" name=\"%s\" id=\"%s\" value=\"%s\"" - "style=\"visibility: hidden;\"/>", - name_and_id, name_and_id, value); - } - - // Append a password field with "visibility: hidden". - void AddNonVisiblePasswordField(const char* name_and_id, const char* value) { - base::StringAppendF( - &html_, - "<INPUT type=\"password\" name=\"%s\" id=\"%s\" value=\"%s\"" - "style=\"visibility: hidden;\"/>", - name_and_id, name_and_id, value); - } - - // Add a field with a given type. Useful to add non-text fields. - void AddFieldWithType(const char* name_and_id, const char* type) { - base::StringAppendF(&html_, "<INPUT type=\"%s\" name=\"%s\" id=\"%s\"/>", - type, name_and_id, name_and_id); - } - - // Appends a new submit-type field at the end of the form with the specified - // |name|. - void AddSubmitButton(const char* name) { - base::StringAppendF( - &html_, "<INPUT type=\"submit\" name=\"%s\" value=\"Submit\"/>", name); - } - // Returns the HTML code for the form containing the fields that have been // added so far. std::string ProduceHTML() const { return html_ + "</FORM>"; } - // Appends a field of |type| without name or id attribute at the end of the - // form. - void AddAnonymousInputField(const char* type) { - std::string type_attribute(type ? base::StringPrintf("type=\"%s\"", type) - : ""); - base::StringAppendF(&html_, "<INPUT %s/>", type_attribute.c_str()); - } - private: std::string html_; @@ -197,74 +89,6 @@ ~PasswordFormConversionUtilsTest() override = default; protected: - // Loads the given |html|, retrieves the sole WebFormElement from it, and then - // calls CreatePasswordForm(), passing it the |predictions| to convert it to - // a PasswordForm. If |with_user_input| == true it's considered that all - // values in the form elements came from the user input. - std::unique_ptr<PasswordForm> LoadHTMLAndConvertForm( - const std::string& html, - FormsPredictionsMap* predictions, - bool with_user_input) { - WebFormElement form; - LoadWebFormFromHTML(html, &form, nullptr); - - WebVector<WebFormControlElement> control_elements; - form.GetFormControlElements(control_elements); - FieldDataManager field_data_manager; - for (size_t i = 0; i < control_elements.size(); ++i) { - WebInputElement* input_element = ToWebInputElement(&control_elements[i]); - if (input_element->HasAttribute("set-activated-submit")) - input_element->SetActivatedSubmit(true); - if (with_user_input) { - field_data_manager.UpdateFieldDataMap(control_elements[i], - input_element->Value().Utf16(), - FieldPropertiesFlags::USER_TYPED); - } - } - - return CreatePasswordFormFromWebForm( - form, with_user_input ? &field_data_manager : nullptr, predictions, - &username_detector_cache_); - } - - // Iterates on the form generated by the |html| and adds the fields and type - // predictions corresponding to |predictions_positions| to |predictions|. - void SetPredictions(const std::string& html, - FormsPredictionsMap* predictions, - const std::map<int, PasswordFormFieldPredictionType>& - predictions_positions) { - WebFormElement form; - LoadWebFormFromHTML(html, &form, nullptr); - - FormData form_data; - ASSERT_TRUE(form_util::WebFormElementToFormData( - form, WebFormControlElement(), nullptr, form_util::EXTRACT_NONE, - &form_data, nullptr)); - - FormStructure form_structure(form_data); - - int field_index = 0; - for (auto field = form_structure.begin(); field != form_structure.end(); - ++field, ++field_index) { - if (predictions_positions.find(field_index) != - predictions_positions.end()) { - (*predictions)[form_data][*(*field)] = - predictions_positions.find(field_index)->second; - } - } - } - - void GetFirstForm(WebFormElement* form) { - WebLocalFrame* frame = GetMainFrame(); - ASSERT_TRUE(frame); - - WebVector<WebFormElement> forms; - frame->GetDocument().Forms(forms); - ASSERT_LE(1U, forms.size()); - - *form = forms[0]; - } - // Loads the given |html| and retrieves the sole WebFormElement from it. void LoadWebFormFromHTML(const std::string& html, WebFormElement* form, @@ -277,1799 +101,27 @@ GetFirstForm(form); } - bool ExtractFormDataForFirstForm(FormData* data) { - WebFormElement form; - GetFirstForm(&form); - return form_util::ExtractFormData(form, data); - } - void TearDown() override { - username_detector_cache_.clear(); content::RenderViewTest::TearDown(); } - uint32_t GetRendererIdFromWebElementId(WebString id) { + private: + void GetFirstForm(WebFormElement* form) { WebLocalFrame* frame = GetMainFrame(); - if (!frame || frame->GetDocument().IsNull()) - return FormData::kNotSetFormRendererId; - WebElement element = frame->GetDocument().GetElementById(id); - if (element.IsNull()) - return FormData::kNotSetFormRendererId; - return element.To<WebInputElement>().UniqueRendererFormControlId(); + ASSERT_TRUE(frame); + + WebVector<WebFormElement> forms; + frame->GetDocument().Forms(forms); + ASSERT_LE(1U, forms.size()); + + *form = forms[0]; } - UsernameDetectorCache username_detector_cache_; - - private: DISALLOW_COPY_AND_ASSIGN(PasswordFormConversionUtilsTest); }; } // namespace -TEST_F(PasswordFormConversionUtilsTest, BasicFormAttributes) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("username", "johnsmith", nullptr); - builder.AddSubmitButton("inactive_submit"); - builder.AddSubmitButton("active_submit"); - builder.AddSubmitButton("inactive_submit2"); - builder.AddPasswordField("password", "secret", nullptr); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ("data:", password_form->signon_realm); - EXPECT_EQ(GURL(kTestFormActionURL), password_form->action); - EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value); - EXPECT_EQ(PasswordForm::Scheme::kHtml, password_form->scheme); - EXPECT_FALSE(password_form->preferred); - EXPECT_FALSE(password_form->blacklisted_by_user); - EXPECT_EQ(PasswordForm::Type::kManual, password_form->type); -} - -TEST_F(PasswordFormConversionUtilsTest, DisabledFieldsAreIgnored) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("username", "johnsmith", nullptr); - builder.AddDisabledUsernameField(); - builder.AddDisabledPasswordField(); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value); -} - -// When not enough fields are enabled to parse the form, the result should still -// be not null. It must contain only minimal information, so that it is not used -// for fill on load, for example. It must contain the full FormData, so that the -// new parser can be run as well. -TEST_F(PasswordFormConversionUtilsTest, OnlyDisabledFields) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddDisabledUsernameField(); - builder.AddDisabledPasswordField(); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - EXPECT_TRUE(password_form->username_element.empty()); - EXPECT_TRUE(password_form->password_element.empty()); - EXPECT_TRUE(password_form->new_password_element.empty()); - EXPECT_EQ(2u, password_form->form_data.fields.size()); -} - -TEST_F(PasswordFormConversionUtilsTest, HTMLDetector_DeveloperGroupAttributes) { - // Each test case consists of a set of parameters to be plugged into the - // PasswordFormBuilder below, plus the corresponding expectations. - // The test data contains cases that are identified by HTML detector, and not - // by base heuristic. Thus, username field does not necessarely have to be - // right before password field. - // These tests basically check searching in developer group (i.e. name and id - // attribute, concatenated, with "$" guard in between). - struct TestCase { - // Field parameters represent, in order of appearance, field name, field id - // and field value. - const char* first_text_field_parameters[3]; - const char* second_text_field_parameters[3]; - const char* expected_username_element; - const WebString expected_username_id; - const char* expected_username_value; - } cases[] = { - // There are both field name and id. - {{"username", "x1d", "johnsmith"}, - {"email", "y1d", "js@google.com"}, - "username", - "x1d", - "johnsmith"}, - // there is no field id. - {{"username", "x1d", "johnsmith"}, - {"email", "y1d", "js@google.com"}, - "username", - "x1d", - "johnsmith"}, - // Upper or mixed case shouldn't matter. - {{"uSeRnAmE", "x1d", "johnsmith"}, - {"email", "y1d", "js@google.com"}, - "uSeRnAmE", - "x1d", - "johnsmith"}, - // Check removal of special characters. - {{"u1_s2-e3~r4/n5(a)6m#e", "x1d", "johnsmith"}, - {"email", "y1d", "js@google.com"}, - "u1_s2-e3~r4/n5(a)6m#e", - "x1d", - "johnsmith"}, - // Check guard between field name and field id. - {{"us", "ername", "johnsmith"}, - {"email", "id", "js@google.com"}, - "email", - "id", - "js@google.com"}, - // Check removal of fields with latin negative words in developer group. - {{"email", "x", "js@google.com"}, - {"fake_username", "y", "johnsmith"}, - "email", - "x", - "js@google.com"}, - {{"email", "mail", "js@google.com"}, - {"user_name", "fullname", "johnsmith"}, - "email", - "mail", - "js@google.com"}, - // Identify latin translations of "username". - {{"benutzername", "x", "johnsmith"}, - {"email", "y", "js@google.com"}, - "benutzername", - "x", - "johnsmith"}, - // Identify latin translations of "user". - {{"utilizator", "x1d", "johnsmith"}, - {"email", "y1d", "js@google.com"}, - "utilizator", - "x1d", - "johnsmith"}, - // Identify technical words. - {{"loginid", "x1d", "johnsmith"}, - {"email", "y1d", "js@google.com"}, - "loginid", - "x1d", - "johnsmith"}, - // Identify weak words. - {{"usrname", "x1d", "johnsmith"}, - {"email", "y1d", "js@google.com"}, - "email", - "y1d", - "js@google.com"}, - // If a word matches in maximum 2 fields, it is accepted. - // First encounter is selected as username. - {{"username", "x1d", "johnsmith"}, - {"repeat_username", "y1d", "johnsmith"}, - "username", - "x1d", - "johnsmith"}, - // A short word should be enclosed between delimiters. Otherwise, an - // Occurrence doesn't count. - {{"identity_name", "idn", "johnsmith"}, - {"id", "xid", "123"}, - "id", - "xid", - "123"}}; - - for (size_t i = 0; i < base::size(cases); ++i) { - SCOPED_TRACE(testing::Message() << "Iteration " << i); - - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextFieldWithoutAutocomplete( - cases[i].first_text_field_parameters[0], - cases[i].first_text_field_parameters[1], - cases[i].first_text_field_parameters[2], "", ""); - builder.AddTextFieldWithoutAutocomplete( - cases[i].second_text_field_parameters[0], - cases[i].second_text_field_parameters[1], - cases[i].second_text_field_parameters[2], "", ""); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - username_detector_cache_.clear(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - - uint32_t username_renderer_id = - GetRendererIdFromWebElementId(cases[i].expected_username_id); - - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_element), - password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_value), - password_form->username_value); - // Check that the username field was found by HTML detector. - ASSERT_EQ(1u, username_detector_cache_.size()); - ASSERT_FALSE(username_detector_cache_.begin()->second.empty()); - EXPECT_EQ(username_renderer_id, - username_detector_cache_.begin()->second[0]); - } -} - -TEST_F(PasswordFormConversionUtilsTest, HTMLDetector_SeveralDetections) { - // If word matches in more than 2 fields, we don't match on it. - // We search for match with another word. - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextFieldWithoutAutocomplete("address", "xuser", "someaddress", "", - ""); - builder.AddTextFieldWithoutAutocomplete("loginid", "yuser", "johnsmith", "", - ""); - builder.AddTextFieldWithoutAutocomplete("tel", "zuser", "sometel", "", ""); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - DCHECK(username_detector_cache_.empty()); - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - - uint32_t username_renderer_id = GetRendererIdFromWebElementId("yuser"); - - ASSERT_TRUE(password_form); - - EXPECT_EQ(base::UTF8ToUTF16("loginid"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value); - // Check that the username field was found by HTML detector. - ASSERT_EQ(1u, username_detector_cache_.size()); - ASSERT_EQ(1u, username_detector_cache_.begin()->second.size()); - EXPECT_EQ(username_renderer_id, username_detector_cache_.begin()->second[0]); -} - -TEST_F(PasswordFormConversionUtilsTest, HTMLDetector_UserGroupAttributes) { - // Each test case consists of a set of parameters to be plugged into the - // PasswordFormBuilder below, plus the corresponding expectations. - // The test data contains cases that are identified by HTML detector, and not - // by base heuristic. Thus, username field does not necessarely have to be - // right before password field. - // These tests basically check searching in user group. - struct TestCase { - // Field parameters represent, in order of appearance, field name, field - // id, field value and field label or placeholder. - // Field name and field id don't contain any significant information. - const char* first_text_field_parameters[4]; - const char* second_text_field_parameters[4]; - const char* expected_username_element; - const WebString expected_username_id; - const char* expected_username_value; - } cases[] = { - // Label information will decide username. - {{"name1", "id1", "johnsmith", "Username:"}, - {"name2", "id2", "js@google.com", "Email:"}, - "name1", - "id1", - "johnsmith"}, - // Placeholder information will decide username. - {{"name1", "id1", "js@google.com", "Email:"}, - {"name2", "id2", "johnsmith", "Username:"}, - "name2", - "id2", - "johnsmith"}, - // Check removal of special characters. - {{"name1", "id1", "johnsmith", "U s er n a m e:"}, - {"name2", "id2", "js@google.com", "Email:"}, - "name1", - "id1", - "johnsmith"}, - // Check removal of fields with latin negative words in user group. - {{"name1", "id1", "johnsmith", "Username password:"}, - {"name2", "id2", "js@google.com", "Email:"}, - "name2", - "id2", - "js@google.com"}, - // Check removal of fields with non-latin negative words in user group. - {{"name1", "id1", "js@google.com", "Email:"}, - {"name2", "id2", "johnsmith", "የይለፍቃልየይለፍቃል:"}, - "name1", - "id1", - "js@google.com"}, - // Identify latin translations of "username". - {{"name1", "id1", "johnsmith", "Username:"}, - {"name2", "id2", "js@google.com", "Email:"}, - "name1", - "id1", - "johnsmith"}, - // Identify non-latin translations of "username". - {{"name1", "id1", "johnsmith", "用户名:"}, - {"name2", "id2", "js@google.com", "Email:"}, - "name1", - "id1", - "johnsmith"}, - // Identify latin translations of "user". - {{"name1", "id1", "johnsmith", "Wosuta:"}, - {"name2", "id2", "js@google.com", "Email:"}, - "name1", - "id1", - "johnsmith"}, - // Identify non-latin translations of "user". - {{"name1", "id1", "johnsmith", "истифода:"}, - {"name2", "id2", "js@google.com", "Email:"}, - "name1", - "id1", - "johnsmith"}, - // Identify weak words. - {{"name1", "id1", "johnsmith", "Insert your login details:"}, - {"name2", "id2", "js@google.com", "Insert your email:"}, - "name1", - "id1", - "johnsmith"}, - // Check user group priority, compared to developer group. - // User group should have higher priority than developer group. - {{"email", "id1", "js@google.com", "Username:"}, - {"username", "id2", "johnsmith", "Email:"}, - "email", - "id1", - "js@google.com"}, - // Check treatment for short dictionary words. "uid" has higher priority, - // but its occurrence is ignored because it is a part of another word. - {{"name1", "noword", "johnsmith", "Insert your id:"}, - {"name2", "uidentical", "js@google.com", "Insert something:"}, - "name1", - "noword", - "johnsmith"}}; - - for (size_t i = 0; i < base::size(cases); ++i) { - SCOPED_TRACE(testing::Message() << "Iteration " << i); - - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextFieldWithoutAutocomplete( - cases[i].first_text_field_parameters[0], - cases[i].first_text_field_parameters[1], - cases[i].first_text_field_parameters[2], - cases[i].first_text_field_parameters[3], ""); - builder.AddTextFieldWithoutAutocomplete( - cases[i].second_text_field_parameters[0], - cases[i].second_text_field_parameters[1], - cases[i].second_text_field_parameters[2], "", - cases[i].second_text_field_parameters[3]); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - username_detector_cache_.clear(); - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - - uint32_t username_renderer_id = - GetRendererIdFromWebElementId(cases[i].expected_username_id); - - ASSERT_TRUE(password_form); - - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_element), - password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_value), - password_form->username_value); - // Check that the username field was found by HTML detector. - ASSERT_EQ(1u, username_detector_cache_.size()); - ASSERT_FALSE(username_detector_cache_.begin()->second.empty()); - EXPECT_EQ(username_renderer_id, - username_detector_cache_.begin()->second[0]); - } -} - -TEST_F(PasswordFormConversionUtilsTest, HTMLDetectorCache) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("unknown", "12345", nullptr); - builder.AddTextField("something", "smith", nullptr); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - WebFormElement form; - LoadWebFormFromHTML(html, &form, nullptr); - UsernameDetectorCache detector_cache; - - // No signals from HTML attributes. The classifier found nothing and cached - // it. - base::HistogramTester histogram_tester; - std::unique_ptr<PasswordForm> password_form = - CreatePasswordFormFromWebForm(form, nullptr, nullptr, &detector_cache); - - EXPECT_TRUE(password_form); - ASSERT_EQ(1u, detector_cache.size()); - EXPECT_EQ(form.UniqueRendererFormId(), detector_cache.begin()->first); - EXPECT_TRUE(detector_cache.begin()->second.empty()); - histogram_tester.ExpectUniqueSample("PasswordManager.UsernameDetectionMethod", - UsernameDetectionMethod::BASE_HEURISTIC, - 1); - - // Changing attributes would change the classifier's output. But the output - // will be the same because it was cached in |username_detector_cache|. - WebVector<WebFormControlElement> control_elements; - form.GetFormControlElements(control_elements); - control_elements[0].SetAttribute("name", "id"); - password_form = - CreatePasswordFormFromWebForm(form, nullptr, nullptr, &detector_cache); - EXPECT_TRUE(password_form); - ASSERT_EQ(1u, detector_cache.size()); - EXPECT_EQ(form.UniqueRendererFormId(), detector_cache.begin()->first); - EXPECT_TRUE(detector_cache.begin()->second.empty()); - histogram_tester.ExpectUniqueSample("PasswordManager.UsernameDetectionMethod", - UsernameDetectionMethod::BASE_HEURISTIC, - 2); - - // Clear the cache. The classifier will find username field and cache it. - detector_cache.clear(); - ASSERT_EQ(4u, control_elements.size()); - password_form = - CreatePasswordFormFromWebForm(form, nullptr, nullptr, &detector_cache); - EXPECT_TRUE(password_form); - ASSERT_EQ(1u, detector_cache.size()); - EXPECT_EQ(form.UniqueRendererFormId(), detector_cache.begin()->first); - ASSERT_EQ(1u, detector_cache.begin()->second.size()); - EXPECT_EQ(control_elements[0].UniqueRendererFormControlId(), - detector_cache.begin()->second[0]); - EXPECT_THAT( - histogram_tester.GetAllSamples("PasswordManager.UsernameDetectionMethod"), - testing::UnorderedElementsAre( - base::Bucket(UsernameDetectionMethod::BASE_HEURISTIC, 2), - base::Bucket(UsernameDetectionMethod::HTML_BASED_CLASSIFIER, 1))); - - // Change the attributes again ("username" is stronger signal than "login"), - // but keep the cache. The classifier's output should be the same. - control_elements[1].SetAttribute("name", "username"); - password_form = - CreatePasswordFormFromWebForm(form, nullptr, nullptr, &detector_cache); - EXPECT_TRUE(password_form); - ASSERT_EQ(1u, detector_cache.size()); - EXPECT_EQ(form.UniqueRendererFormId(), detector_cache.begin()->first); - ASSERT_EQ(1u, detector_cache.begin()->second.size()); - EXPECT_EQ(control_elements[0].UniqueRendererFormControlId(), - detector_cache.begin()->second[0]); - EXPECT_THAT( - histogram_tester.GetAllSamples("PasswordManager.UsernameDetectionMethod"), - testing::UnorderedElementsAre( - base::Bucket(UsernameDetectionMethod::BASE_HEURISTIC, 2), - base::Bucket(UsernameDetectionMethod::HTML_BASED_CLASSIFIER, 2))); -} - -TEST_F(PasswordFormConversionUtilsTest, HTMLDetectorCache_SkipSomePredictions) { - // The cache of HTML based username detector may contain several predictions - // (in the order of decreasing reliability) for the given form, but the - // detector should consider only |possible_usernames| passed to - // GetUsernameFieldBasedOnHtmlAttributes. For example, if a field has no user - // input while others has, the field cannot be an username field. - - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("username", "12345", nullptr); - builder.AddTextField("email", "smith@google.com", nullptr); - builder.AddTextField("id", "12345", nullptr); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - WebFormElement form; - LoadWebFormFromHTML(html, &form, nullptr); - WebVector<WebFormControlElement> control_elements; - form.GetFormControlElements(control_elements); - ASSERT_FALSE(control_elements.empty()); - - // Add predictions for "email" and "id" fields to the cache. - UsernameDetectorCache username_detector_cache; - username_detector_cache[control_elements[0].Form().UniqueRendererFormId()] = { - ToWebInputElement(&control_elements[1]) - ->UniqueRendererFormControlId(), // email - ToWebInputElement(&control_elements[2]) - ->UniqueRendererFormControlId()}; // id - - // A user typed only into "id" and "password" fields. So, the prediction for - // "email" field should be ignored despite it is more reliable than prediction - // for "id" field. - FieldDataManager field_data_manager; - field_data_manager.UpdateFieldDataMap( - control_elements[2], control_elements[2].Value().Utf16(), - FieldPropertiesFlags::USER_TYPED); // id - field_data_manager.UpdateFieldDataMap( - control_elements[3], control_elements[3].Value().Utf16(), - FieldPropertiesFlags::USER_TYPED); // password - - std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm( - form, &field_data_manager, nullptr, &username_detector_cache); - - ASSERT_TRUE(password_form); - EXPECT_EQ(base::UTF8ToUTF16("id"), password_form->username_element); -} - -TEST_F(PasswordFormConversionUtilsTest, - IdentifyingUsernameFieldsWithBaseHeuristic) { - // Each test case consists of a set of parameters to be plugged into the - // PasswordFormBuilder below, plus the corresponding expectations. - // The test data should not contain field names that are identified by the - // HTML based username detector, because with these tests only the base - // heuristic (i.e. select as username the field before the password field) - // is tested. - struct TestCase { - const char* autocomplete[3]; - const char* expected_username_element; - const char* expected_username_value; - const char* expected_all_possible_usernames; - } cases[] = { - // When no elements are marked with autocomplete='username', the text-type - // input field before the first password element should get selected as - // the username, and the rest should be marked as alternatives. - {{nullptr, nullptr, nullptr}, - "usrname2", - "William", - "John+usrname1, Smith+usrname3"}, - // When a sole element is marked with autocomplete='username', it should - // be treated as the username, but other text fields should be added to - // |all_possible_usernames|. - {{"username", nullptr, nullptr}, - "usrname1", - "John", - "William+usrname2, Smith+usrname3"}, - {{nullptr, "username", nullptr}, - "usrname2", - "William", - "John+usrname1, Smith+usrname3"}, - {{nullptr, nullptr, "username"}, - "usrname3", - "Smith", - "John+usrname1, William+usrname2"}, - // When >=2 elements have the attribute, the first should be selected as - // the username, and the rest should go to |all_possible_usernames|. - {{"username", "username", nullptr}, - "usrname1", - "John", - "William+usrname2, Smith+usrname3"}, - {{nullptr, "username", "username"}, - "usrname2", - "William", - "John+usrname1, Smith+usrname3"}, - {{"username", nullptr, "username"}, - "usrname1", - "John", - "William+usrname2, Smith+usrname3"}, - {{"username", "username", "username"}, - "usrname1", - "John", - "William+usrname2, Smith+usrname3"}, - // When there is an empty autocomplete attribute (i.e. autocomplete=""), - // it should have the same effect as having no attribute whatsoever. - {{"", "", ""}, "usrname2", "William", "John+usrname1, Smith+usrname3"}, - {{"", "", "username"}, - "usrname3", - "Smith", - "John+usrname1, William+usrname2"}, - {{"username", "", "username"}, - "usrname1", - "John", - "William+usrname2, Smith+usrname3"}, - // It should not matter if attribute values are upper or mixed case. - {{"USERNAME", nullptr, "uSeRNaMe"}, - "usrname1", - "John", - "William+usrname2, Smith+usrname3"}, - {{"uSeRNaMe", nullptr, "USERNAME"}, - "usrname1", - "John", - "William+usrname2, Smith+usrname3"}}; - - for (size_t i = 0; i < base::size(cases); ++i) { - for (size_t nonempty_username_fields = 0; nonempty_username_fields < 2; - ++nonempty_username_fields) { - SCOPED_TRACE(testing::Message() - << "Iteration " << i << " " - << (nonempty_username_fields ? "nonempty" : "empty")); - - // Repeat each test once with empty, and once with non-empty usernames. - // In the former case, no empty all_possible_usernames should be saved. - const char* names[3]; - if (nonempty_username_fields) { - names[0] = "John"; - names[1] = "William"; - names[2] = "Smith"; - } else { - names[0] = names[1] = names[2] = ""; - } - - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("usrname1", names[0], cases[i].autocomplete[0]); - builder.AddTextField("usrname2", names[1], cases[i].autocomplete[1]); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddTextField("usrname3", names[2], cases[i].autocomplete[2]); - builder.AddPasswordField("password2", "othersecret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_element), - password_form->username_element); - - if (nonempty_username_fields) { - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_value), - password_form->username_value); - EXPECT_EQ( - base::UTF8ToUTF16(cases[i].expected_all_possible_usernames), - ValueElementVectorToString(password_form->all_possible_usernames)); - } else { - EXPECT_TRUE(password_form->username_value.empty()); - EXPECT_TRUE(password_form->all_possible_usernames.empty()); - } - - // Do a basic sanity check that we are still having a password field. - EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value); - } - } -} - -TEST_F(PasswordFormConversionUtilsTest, IdentifyingTwoPasswordFields) { - // Each test case consists of a set of parameters to be plugged into the - // PasswordFormBuilder below, plus the corresponding expectations. - struct TestCase { - const char* password_values[2]; - const char* expected_password_element; - const char* expected_password_value; - const char* expected_new_password_element; - const char* expected_new_password_value; - const char* expected_confirmation_element; - } cases[] = { - // Two non-empty fields with the same value should be treated as a new - // password field plus a confirmation field for the new password. - {{"alpha", "alpha"}, "", "", "password1", "alpha", "password2"}, - // The same goes if the fields are yet empty: we speculate that we will - // identify them as new password fields once they are filled out, and we - // want to keep our abstract interpretation of the form less flaky. - {{"", ""}, "password1", "", "password2", "", ""}, - // Two different values should be treated as a password change form, one - // that also asks for the current password, but only once for the new. - {{"alpha", ""}, "password1", "alpha", "password2", "", ""}, - {{"", "beta"}, "password1", "", "password2", "beta", ""}, - {{"alpha", "beta"}, "password1", "alpha", "password2", "beta", ""}}; - - for (size_t i = 0; i < base::size(cases); ++i) { - SCOPED_TRACE(testing::Message() << "Iteration " << i); - - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("usrname1", "William", nullptr); - builder.AddPasswordField("password1", cases[i].password_values[0], nullptr); - builder.AddTextField("usrname2", "Smith", nullptr); - builder.AddPasswordField("password2", cases[i].password_values[1], nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_element), - password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_value), - password_form->password_value); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_element), - password_form->new_password_element); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_value), - password_form->new_password_value); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_confirmation_element), - password_form->confirmation_password_element); - - // Do a basic sanity check that we are still selecting the right username. - EXPECT_EQ(base::UTF8ToUTF16("usrname1"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value); - EXPECT_THAT( - password_form->all_possible_usernames, - testing::ElementsAre(ValueElementPair(base::UTF8ToUTF16("Smith"), - base::UTF8ToUTF16("usrname2")))); - } -} - -TEST_F(PasswordFormConversionUtilsTest, IdentifyingThreePasswordFields) { - // Each test case consists of a set of parameters to be plugged into the - // PasswordFormBuilder below, plus the corresponding expectations. - struct TestCase { - const char* password_values[3]; - const char* expected_password_element; - const char* expected_password_value; - const char* expected_new_password_element; - const char* expected_new_password_value; - const char* expected_confirmation_element; - } cases[] = { - // Two fields with the same value, and one different: we should treat this - // as a password change form with confirmation for the new password. Note - // that we only recognize (current + new + new) and (new + new + current) - // without autocomplete attributes. - {{"alpha", "", ""}, "password1", "alpha", "password2", "", "password3"}, - {{"", "beta", "beta"}, "password1", "", "password2", "beta", "password3"}, - {{"alpha", "beta", "beta"}, - "password1", - "alpha", - "password2", - "beta", - "password3"}, - // If confirmed password comes first, assume that the third password - // field is related to security question, SSN, or credit card and ignore - // it. - {{"beta", "beta", "alpha"}, "", "", "password1", "beta", "password2"}, - // If the fields are yet empty, we speculate that we will identify them as - // (current + new + new) once they are filled out, so we should classify - // them the same for now to keep our abstract interpretation less flaky. - {{"", "", ""}, "password1", "", "password2", "", "password3"}}; - - for (size_t i = 0; i < base::size(cases); ++i) { - SCOPED_TRACE(testing::Message() << "Iteration " << i); - - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("usrname1", "William", nullptr); - builder.AddPasswordField("password1", cases[i].password_values[0], nullptr); - builder.AddPasswordField("password2", cases[i].password_values[1], nullptr); - builder.AddTextField("usrname2", "Smith", nullptr); - builder.AddPasswordField("password3", cases[i].password_values[2], nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_element), - password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_value), - password_form->password_value); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_element), - password_form->new_password_element); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_value), - password_form->new_password_value); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_confirmation_element), - password_form->confirmation_password_element); - - // Do a basic sanity check that we are still selecting the right username. - EXPECT_EQ(base::UTF8ToUTF16("usrname1"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value); - EXPECT_THAT( - password_form->all_possible_usernames, - testing::ElementsAre(ValueElementPair(base::UTF8ToUTF16("Smith"), - base::UTF8ToUTF16("usrname2")))); - } -} - -TEST_F(PasswordFormConversionUtilsTest, - IdentifyingPasswordFieldsWithAutocompleteAttributes) { - // Each test case consists of a set of parameters to be plugged into the - // PasswordFormBuilder below, plus the corresponding expectations. - // The test data should not contain field names that are identified by the - // HTML based username detector, because with these tests only the base - // heuristic (i.e. select as username the field before the password field) - // is tested. - struct TestCase { - const char* autocomplete[3]; - const char* expected_password_element; - const char* expected_password_value; - const char* expected_new_password_element; - const char* expected_new_password_value; - bool expected_new_password_marked_by_site; - const char* expected_username_element; - const char* expected_username_value; - } cases[] = { - // When there are elements marked with autocomplete='current-password', - // but no elements with 'new-password', we should treat the first of the - // former kind as the current password, and ignore all other password - // fields, assuming they are not intentionally not marked. They might be - // for other purposes, such as PINs, OTPs, and the like. Actual values in - // the password fields should be ignored in all cases below. - // Username is the element just before the first 'current-password' (even - // if 'new-password' comes earlier). If no 'current-password', then the - // element just before the first 'new-passwords'. - {{"current-password", nullptr, nullptr}, - "password1", - "alpha", - "", - "", - false, - "usrname1", - "William"}, - {{nullptr, "current-password", nullptr}, - "password2", - "beta", - "", - "", - false, - "usrname2", - "Smith"}, - {{nullptr, nullptr, "current-password"}, - "password3", - "gamma", - "", - "", - false, - "usrname2", - "Smith"}, - {{nullptr, "current-password", "current-password"}, - "password2", - "beta", - "", - "", - false, - "usrname2", - "Smith"}, - {{"current-password", nullptr, "current-password"}, - "password1", - "alpha", - "", - "", - false, - "usrname1", - "William"}, - {{"current-password", "current-password", nullptr}, - "password1", - "alpha", - "", - "", - false, - "usrname1", - "William"}, - {{"current-password", "current-password", "current-password"}, - "password1", - "alpha", - "", - "", - false, - "usrname1", - "William"}, - // The same goes vice versa for autocomplete='new-password'. - {{"new-password", nullptr, nullptr}, - "", - "", - "password1", - "alpha", - true, - "usrname1", - "William"}, - {{nullptr, "new-password", nullptr}, - "", - "", - "password2", - "beta", - true, - "usrname2", - "Smith"}, - {{nullptr, nullptr, "new-password"}, - "", - "", - "password3", - "gamma", - true, - "usrname2", - "Smith"}, - {{nullptr, "new-password", "new-password"}, - "", - "", - "password2", - "beta", - true, - "usrname2", - "Smith"}, - {{"new-password", nullptr, "new-password"}, - "", - "", - "password1", - "alpha", - true, - "usrname1", - "William"}, - {{"new-password", "new-password", nullptr}, - "", - "", - "password1", - "alpha", - true, - "usrname1", - "William"}, - {{"new-password", "new-password", "new-password"}, - "", - "", - "password1", - "alpha", - true, - "usrname1", - "William"}, - // When there is one element marked with autocomplete='current-password', - // and one with 'new-password', just comply. Ignore the unmarked password - // field(s) for the same reason as above. - {{"current-password", "new-password", nullptr}, - "password1", - "alpha", - "password2", - "beta", - true, - "usrname1", - "William"}, - {{"current-password", nullptr, "new-password"}, - "password1", - "alpha", - "password3", - "gamma", - true, - "usrname1", - "William"}, - {{nullptr, "current-password", "new-password"}, - "password2", - "beta", - "password3", - "gamma", - true, - "usrname2", - "Smith"}, - {{"new-password", "current-password", nullptr}, - "password2", - "beta", - "password1", - "alpha", - true, - "usrname2", - "Smith"}, - {{"new-password", nullptr, "current-password"}, - "password3", - "gamma", - "password1", - "alpha", - true, - "usrname2", - "Smith"}, - {{nullptr, "new-password", "current-password"}, - "password3", - "gamma", - "password2", - "beta", - true, - "usrname2", - "Smith"}, - // In case of duplicated elements of either kind, go with the first one of - // its kind. - {{"current-password", "current-password", "new-password"}, - "password1", - "alpha", - "password3", - "gamma", - true, - "usrname1", - "William"}, - {{"current-password", "new-password", "current-password"}, - "password1", - "alpha", - "password2", - "beta", - true, - "usrname1", - "William"}, - {{"new-password", "current-password", "current-password"}, - "password2", - "beta", - "password1", - "alpha", - true, - "usrname2", - "Smith"}, - {{"current-password", "new-password", "new-password"}, - "password1", - "alpha", - "password2", - "beta", - true, - "usrname1", - "William"}, - {{"new-password", "current-password", "new-password"}, - "password2", - "beta", - "password1", - "alpha", - true, - "usrname2", - "Smith"}, - {{"new-password", "new-password", "current-password"}, - "password3", - "gamma", - "password1", - "alpha", - true, - "usrname2", - "Smith"}, - // When there is an empty autocomplete attribute (i.e. autocomplete=""), - // it should have the same effect as having no attribute whatsoever. - {{"current-password", "", ""}, - "password1", - "alpha", - "", - "", - false, - "usrname1", - "William"}, - {{"", "", "new-password"}, - "", - "", - "password3", - "gamma", - true, - "usrname2", - "Smith"}, - {{"", "new-password", ""}, - "", - "", - "password2", - "beta", - true, - "usrname2", - "Smith"}, - {{"", "current-password", "current-password"}, - "password2", - "beta", - "", - "", - false, - "usrname2", - "Smith"}, - {{"new-password", "", "new-password"}, - "", - "", - "password1", - "alpha", - true, - "usrname1", - "William"}, - {{"new-password", "", "current-password"}, - "password3", - "gamma", - "password1", - "alpha", - true, - "usrname2", - "Smith"}, - // It should not matter if attribute values are upper or mixed case. - {{nullptr, "current-password", nullptr}, - "password2", - "beta", - "", - "", - false, - "usrname2", - "Smith"}, - {{nullptr, "CURRENT-PASSWORD", nullptr}, - "password2", - "beta", - "", - "", - false, - "usrname2", - "Smith"}, - {{nullptr, "new-password", nullptr}, - "", - "", - "password2", - "beta", - true, - "usrname2", - "Smith"}, - {{nullptr, "nEw-PaSsWoRd", nullptr}, - "", - "", - "password2", - "beta", - true, - "usrname2", - "Smith"}}; - - for (size_t i = 0; i < base::size(cases); ++i) { - SCOPED_TRACE(testing::Message() << "Iteration " << i); - - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddPasswordField("pin1", "123456", nullptr); - builder.AddPasswordField("pin2", "789101", nullptr); - builder.AddTextField("usrname1", "William", nullptr); - builder.AddPasswordField("password1", "alpha", cases[i].autocomplete[0]); - builder.AddTextField("usrname2", "Smith", nullptr); - builder.AddPasswordField("password2", "beta", cases[i].autocomplete[1]); - builder.AddPasswordField("password3", "gamma", cases[i].autocomplete[2]); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - - EXPECT_FALSE(password_form->only_for_fallback); - // In the absence of username autocomplete attributes, the username should - // be the text input field just before 'current-password' or before - // 'new-password', if there is no 'current-password'. - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_element), - password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_value), - password_form->username_value); - if (strcmp(cases[i].expected_username_value, "William") == 0) { - EXPECT_THAT( - password_form->all_possible_usernames, - testing::ElementsAre(ValueElementPair( - base::UTF8ToUTF16("Smith"), base::UTF8ToUTF16("usrname2")))); - } else { - EXPECT_THAT( - password_form->all_possible_usernames, - testing::ElementsAre(ValueElementPair( - base::UTF8ToUTF16("William"), base::UTF8ToUTF16("usrname1")))); - } - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_element), - password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_value), - password_form->password_value); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_element), - password_form->new_password_element); - EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_value), - password_form->new_password_value); - EXPECT_EQ(cases[i].expected_new_password_marked_by_site, - password_form->new_password_marked_by_site); - } -} - -TEST_F(PasswordFormConversionUtilsTest, - UsernameDetection_AutocompleteAttribute) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("username", "JohnSmith", "username"); - builder.AddTextField("Full name", "John A. Smith", nullptr); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - base::HistogramTester histogram_tester; - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("JohnSmith"), password_form->username_value); - histogram_tester.ExpectUniqueSample( - "PasswordManager.UsernameDetectionMethod", - UsernameDetectionMethod::AUTOCOMPLETE_ATTRIBUTE, 1); -} - -TEST_F(PasswordFormConversionUtilsTest, IgnoreInvisibledTextFields) { - PasswordFormBuilder builder(kTestFormActionURL); - - builder.AddNonDisplayedTextField("nondisplayed1", "nodispalyed_value1"); - builder.AddNonVisibleTextField("nonvisible1", "nonvisible_value1"); - builder.AddTextField("username", "johnsmith", nullptr); - builder.AddNonDisplayedTextField("nondisplayed2", "nodispalyed_value2"); - builder.AddNonVisiblePasswordField("nonvisible2", "nonvisible_value2"); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16(""), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->new_password_element); - EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->new_password_value); -} - -TEST_F(PasswordFormConversionUtilsTest, IgnoreInvisiblLoginPairs) { - PasswordFormBuilder builder(kTestFormActionURL); - - builder.AddNonDisplayedTextField("nondisplayed1", "nodispalyed_value1"); - builder.AddNonDisplayedPasswordField("nondisplayed2", "nodispalyed_value2"); - builder.AddNonVisibleTextField("nonvisible1", "nonvisible_value1"); - builder.AddNonVisiblePasswordField("nonvisible2", "nonvisible_value2"); - builder.AddTextField("username", "johnsmith", nullptr); - builder.AddNonVisibleTextField("nonvisible3", "nonvisible_value3"); - builder.AddNonVisiblePasswordField("nonvisible4", "nonvisible_value4"); - builder.AddNonDisplayedTextField("nondisplayed3", "nodispalyed_value3"); - builder.AddNonDisplayedPasswordField("nondisplayed4", "nodispalyed_value4"); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16(""), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->new_password_element); - EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->new_password_value); -} - -TEST_F(PasswordFormConversionUtilsTest, OnlyNonDisplayedLoginPair) { - PasswordFormBuilder builder(kTestFormActionURL); - - builder.AddNonDisplayedTextField("username", "William"); - builder.AddNonDisplayedPasswordField("password", "secret"); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("username"), - password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("William"), - password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("password"), - password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("secret"), - password_form->password_value); -} - -TEST_F(PasswordFormConversionUtilsTest, OnlyNonVisibleLoginPair) { - PasswordFormBuilder builder(kTestFormActionURL); - - builder.AddNonVisibleTextField("username", "William"); - builder.AddNonVisiblePasswordField("password", "secret"); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value); -} - -TEST_F(PasswordFormConversionUtilsTest, VisiblePasswordAndInvisibleUsername) { - PasswordFormBuilder builder(kTestFormActionURL); - - builder.AddNonDisplayedTextField("username", "William"); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value); -} - -TEST_F(PasswordFormConversionUtilsTest, - InvisiblePassword_LatestUsernameIsVisible) { - PasswordFormBuilder builder(kTestFormActionURL); - - builder.AddNonDisplayedTextField("search", "query"); - builder.AddTextField("username", "William", nullptr); - builder.AddNonDisplayedPasswordField("password", "secret"); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value); -} - -TEST_F(PasswordFormConversionUtilsTest, - InvisiblePassword_LatestUsernameIsInvisible) { - PasswordFormBuilder builder(kTestFormActionURL); - - builder.AddTextField("search", "query", nullptr); - builder.AddNonDisplayedTextField("username", "William"); - builder.AddNonDisplayedPasswordField("password", "secret"); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value); -} - -// Checks that username/password fields are detected based on user input even if -// visibility heuristics disagree. -TEST_F(PasswordFormConversionUtilsTest, UserInput) { - PasswordFormBuilder builder(kTestFormActionURL); - - builder.AddNonVisibleTextField("nonvisible_text", "actual_username"); - builder.AddTextField("visible_text", "fake_username", nullptr); - - builder.AddNonVisiblePasswordField("nonvisible_password", "actual_password"); - builder.AddPasswordField("visible_password", "fake_password", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - WebFormElement form; - LoadWebFormFromHTML(html, &form, nullptr); - - FieldDataManager field_data_manager; - WebVector<WebFormControlElement> control_elements; - form.GetFormControlElements(control_elements); - ASSERT_EQ("nonvisible_text", control_elements[0].NameForAutofill().Utf8()); - field_data_manager.UpdateFieldDataMap(control_elements[0], - control_elements[0].Value().Utf16(), - FieldPropertiesFlags::USER_TYPED); - ASSERT_EQ("nonvisible_password", - control_elements[2].NameForAutofill().Utf8()); - field_data_manager.UpdateFieldDataMap(control_elements[2], - control_elements[2].Value().Utf16(), - FieldPropertiesFlags::USER_TYPED); - - std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm( - form, &field_data_manager, nullptr, nullptr); - - ASSERT_TRUE(password_form); - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("nonvisible_text"), - password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("actual_username"), - password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("nonvisible_password"), - password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("actual_password"), - password_form->password_value); - EXPECT_EQ(base::UTF8ToUTF16(""), password_form->new_password_element); - EXPECT_EQ(base::UTF8ToUTF16(""), password_form->new_password_value); -} - -TEST_F(PasswordFormConversionUtilsTest, TypedPasswordAndUsernameCachedOnPage) { - PasswordFormBuilder builder(kTestFormActionURL); - // The heuristics should consider only password field with user input (i.e. - // password_with_user_input?) and visible username fields (i.e. nickname, - // visible_text, captcha) since there is no username field with user input. - builder.AddNonDisplayedPasswordField("nondisplayed1", "fake_password"); - builder.AddNonDisplayedTextField("nondisplayed1", "fake_username1"); - builder.AddTextField("nickname", "bob", nullptr); - builder.AddTextField("visible_text", "cached_username", - nullptr); // Username. - builder.AddNonVisibleTextField("nonvisible_text", "fake_username2"); - builder.AddNonVisiblePasswordField("nonvisible_password", "not_password"); - builder.AddNonVisibleTextField("nonvisible_text", "fake_username2"); - builder.AddPasswordField("password_wo_user_input", "", nullptr); - builder.AddNonVisibleTextField("nonvisible_text", ""); - builder.AddPasswordField("password_with_user_input1", "actual_password", - nullptr); // Password to save. - builder.AddPasswordField("password_with_user_input2", "actual_password", - nullptr); - builder.AddTextField("captcha", "12345", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - WebFormElement form; - LoadWebFormFromHTML(html, &form, nullptr); - - FieldDataManager field_data_manager; - WebVector<WebFormControlElement> control_elements; - form.GetFormControlElements(control_elements); - ASSERT_EQ("password_with_user_input1", - control_elements[9].NameForAutofill().Utf8()); - field_data_manager.UpdateFieldDataMap(control_elements[9], - control_elements[9].Value().Utf16(), - FieldPropertiesFlags::USER_TYPED); - ASSERT_EQ("password_with_user_input2", - control_elements[10].NameForAutofill().Utf8()); - field_data_manager.UpdateFieldDataMap(control_elements[10], - control_elements[10].Value().Utf16(), - FieldPropertiesFlags::USER_TYPED); - - std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm( - form, &field_data_manager, nullptr, nullptr); - - ASSERT_TRUE(password_form); - EXPECT_FALSE(password_form->only_for_fallback); - - EXPECT_EQ(base::UTF8ToUTF16("visible_text"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("cached_username"), - password_form->username_value); - - EXPECT_EQ(base::string16(), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16(""), password_form->password_value); - - EXPECT_EQ(base::UTF8ToUTF16("password_with_user_input1"), - password_form->new_password_element); - EXPECT_EQ(base::UTF8ToUTF16("actual_password"), - password_form->new_password_value); -} - -TEST_F(PasswordFormConversionUtilsTest, TypedPasswordAndInvisibleUsername) { - PasswordFormBuilder builder(kTestFormActionURL); - // The heuristics should consider only password field with user input (i.e. - // password_with_user_input?) and invisible username fields since all username - // fields have no user input and are invisible. - builder.AddNonDisplayedPasswordField("nondisplayed1", "fake_password"); - builder.AddNonDisplayedTextField("nondisplayed1", "fake_username1"); - builder.AddNonVisibleTextField("nickname", "bob"); - builder.AddNonVisibleTextField("this_is_username", "invisible_username"); - builder.AddNonVisiblePasswordField("nonvisible_password", "not_password"); - builder.AddPasswordField("password_wo_user_input", "", nullptr); - builder.AddNonVisiblePasswordField("nonvisible_password2", ""); - builder.AddPasswordField("password_with_user_input1", "actual_password", - nullptr); // Password to save. - builder.AddNonVisibleTextField("nonvisible_text3", "---H09-$%"); - builder.AddPasswordField("password_with_user_input2", "actual_password", - nullptr); - builder.AddNonVisibleTextField("nonvisible_text3", "debug_info"); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - WebFormElement form; - LoadWebFormFromHTML(html, &form, nullptr); - - FieldDataManager field_data_manager; - WebVector<WebFormControlElement> control_elements; - form.GetFormControlElements(control_elements); - ASSERT_EQ("password_with_user_input1", - control_elements[7].NameForAutofill().Utf8()); - field_data_manager.UpdateFieldDataMap(control_elements[7], - control_elements[7].Value().Utf16(), - FieldPropertiesFlags::USER_TYPED); - ASSERT_EQ("password_with_user_input2", - control_elements[9].NameForAutofill().Utf8()); - field_data_manager.UpdateFieldDataMap(control_elements[9], - control_elements[9].Value().Utf16(), - FieldPropertiesFlags::USER_TYPED); - - std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm( - form, &field_data_manager, nullptr, nullptr); - - ASSERT_TRUE(password_form); - EXPECT_FALSE(password_form->only_for_fallback); - - EXPECT_EQ(base::UTF8ToUTF16("this_is_username"), - password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("invisible_username"), - password_form->username_value); - - EXPECT_EQ(base::string16(), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16(""), password_form->password_value); - - EXPECT_EQ(base::UTF8ToUTF16("password_with_user_input1"), - password_form->new_password_element); - EXPECT_EQ(base::UTF8ToUTF16("actual_password"), - password_form->new_password_value); -} - -TEST_F(PasswordFormConversionUtilsTest, InvalidFormDueToBadActionURL) { - PasswordFormBuilder builder("invalid_target"); - builder.AddTextField("username", "JohnSmith", nullptr); - builder.AddSubmitButton("submit"); - builder.AddPasswordField("password", "secret", nullptr); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - EXPECT_FALSE(password_form); -} - -TEST_F(PasswordFormConversionUtilsTest, InvalidFormDueToNoPasswordFields) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("username1", "John", nullptr); - builder.AddTextField("username2", "Smith", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - EXPECT_FALSE(password_form); -} - -TEST_F(PasswordFormConversionUtilsTest, ConfusingPasswordFields) { - // Each test case consists of a set of parameters to be plugged into the - // PasswordFormBuilder below. - const char* cases[][3] = { - // No autocomplete attributes to guide us, and we see: - // * three password values that are all different, - // * three password values that are all the same; - // * three password values with the first and last matching. - // In any case, we should just give up on this form. - {"alpha", "beta", "gamma"}, - {"alpha", "alpha", "alpha"}, - {"alpha", "beta", "alpha"}}; - - for (size_t i = 0; i < base::size(cases); ++i) { - SCOPED_TRACE(testing::Message() << "Iteration " << i); - - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("username1", "John", nullptr); - builder.AddPasswordField("password1", cases[i][0], nullptr); - builder.AddPasswordField("password2", cases[i][1], nullptr); - builder.AddPasswordField("password3", cases[i][2], nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("username1"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("John"), password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("password1"), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16(cases[i][0]), password_form->password_value); - } -} - -TEST_F(PasswordFormConversionUtilsTest, - ManyPasswordFieldsWithoutAutocompleteAttributes) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("username1", "John", nullptr); - builder.AddPasswordField("password1", "alpha", nullptr); - builder.AddPasswordField("password2", "alpha", nullptr); - builder.AddPasswordField("password3", "alpha", nullptr); - builder.AddPasswordField("password4", "alpha", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("username1"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("John"), password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("password1"), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("alpha"), password_form->password_value); -} - -TEST_F(PasswordFormConversionUtilsTest, SetOtherPossiblePasswords) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("username1", "John", nullptr); - builder.AddPasswordField("password1", "alpha1", nullptr); - builder.AddPasswordField("password2", "alpha2", nullptr); - builder.AddPasswordField("password3", "alpha3", nullptr); - builder.AddPasswordField("password4", "alpha4", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - EXPECT_FALSE(password_form->form_has_autofilled_value); - - // Make sure we have all possible passwords along with the username info. - EXPECT_EQ(base::ASCIIToUTF16("username1"), password_form->username_element); - EXPECT_EQ(base::ASCIIToUTF16("John"), password_form->username_value); - EXPECT_EQ(base::ASCIIToUTF16("alpha1"), password_form->password_value); - EXPECT_THAT( - password_form->all_possible_passwords, - testing::ElementsAre(ValueElementPair(base::ASCIIToUTF16("alpha1"), - base::ASCIIToUTF16("password1")), - ValueElementPair(base::ASCIIToUTF16("alpha2"), - base::ASCIIToUTF16("password2")), - ValueElementPair(base::ASCIIToUTF16("alpha3"), - base::ASCIIToUTF16("password3")), - ValueElementPair(base::ASCIIToUTF16("alpha4"), - base::ASCIIToUTF16("password4")))); - EXPECT_EQ(base::ASCIIToUTF16("alpha1+password1, alpha2+password2, " - "alpha3+password3, alpha4+password4"), - ValueElementVectorToString(password_form->all_possible_passwords)); -} - -TEST_F(PasswordFormConversionUtilsTest, - AllPossiblePasswordsIncludeAutofilledValue) { - for (bool autofilled_value_was_modified_by_user : {false, true}) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("username1", "John", nullptr); - builder.AddPasswordField("old-password", "autofilled_value", nullptr); - builder.AddPasswordField("new-password", "user_value", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - WebFormElement form; - LoadWebFormFromHTML(html, &form, nullptr); - WebVector<WebFormControlElement> control_elements; - form.GetFormControlElements(control_elements); - - FieldDataManager field_data_manager; - FieldPropertiesMask mask = FieldPropertiesFlags::AUTOFILLED; - if (autofilled_value_was_modified_by_user) - mask |= FieldPropertiesFlags::USER_TYPED; - field_data_manager.UpdateFieldDataMap( - control_elements[1], base::ASCIIToUTF16("autofilled_value"), mask); - field_data_manager.UpdateFieldDataMap(control_elements[2], - base::ASCIIToUTF16("user_value"), - FieldPropertiesFlags::USER_TYPED); - - std::unique_ptr<PasswordForm> password_form(CreatePasswordFormFromWebForm( - form, &field_data_manager, nullptr, nullptr)); - ASSERT_TRUE(password_form); - EXPECT_TRUE(password_form->form_has_autofilled_value); - } -} - -TEST_F(PasswordFormConversionUtilsTest, CreditCardNumberWithTypePasswordForm) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("Credit-card-owner-name", "John Smith", nullptr); - builder.AddPasswordField("Credit-card-number", "0000 0000 0000 0000", - nullptr); - builder.AddTextField("cvc", "000", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::map<int, PasswordFormFieldPredictionType> predictions_positions; - predictions_positions[1] = PasswordFormFieldPredictionType::kNotPassword; - - FormsPredictionsMap predictions; - SetPredictions(html, &predictions, predictions_positions); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, &predictions, false); - EXPECT_TRUE(password_form); - EXPECT_TRUE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("Credit-card-owner-name"), - password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("John Smith"), password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("Credit-card-number"), - password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("0000 0000 0000 0000"), - password_form->password_value); -} - -TEST_F(PasswordFormConversionUtilsTest, UsernamePredictionFromServer) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("username", "JohnSmith", nullptr); - // 'autocomplete' attribute cannot override server's prediction. - builder.AddTextField("Full name", "John A. Smith", "username"); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::map<int, PasswordFormFieldPredictionType> predictions_positions; - predictions_positions[0] = PasswordFormFieldPredictionType::kUsername; - FormsPredictionsMap predictions; - SetPredictions(html, &predictions, predictions_positions); - - base::HistogramTester histogram_tester; - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, &predictions, false); - ASSERT_TRUE(password_form); - EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("JohnSmith"), password_form->username_value); - histogram_tester.ExpectUniqueSample( - "PasswordManager.UsernameDetectionMethod", - UsernameDetectionMethod::SERVER_SIDE_PREDICTION, 1); -} - -TEST_F(PasswordFormConversionUtilsTest, - UsernamePredictionFromServerToEmptyField) { - // Tests that if a form has user input and the username prediction by the - // server points to an empty field, then the prediction is ignored. - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("empty-field", "", ""); // The prediction points here. - builder.AddTextField("full-name", "John A. Smith", nullptr); - builder.AddTextField("username", "JohnSmith", nullptr); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::map<int, PasswordFormFieldPredictionType> predictions_positions; - predictions_positions[0] = PasswordFormFieldPredictionType::kUsername; - FormsPredictionsMap predictions; - SetPredictions(html, &predictions, predictions_positions); - - // The password field has user input. - WebFormElement form; - LoadWebFormFromHTML(html, &form, nullptr); - WebVector<WebFormControlElement> control_elements; - form.GetFormControlElements(control_elements); - FieldDataManager field_data_manager; - field_data_manager.UpdateFieldDataMap(control_elements[3], - control_elements[3].Value().Utf16(), - FieldPropertiesFlags::USER_TYPED); - - std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm( - form, &field_data_manager, &predictions, &username_detector_cache_); - ASSERT_TRUE(password_form); - EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("JohnSmith"), password_form->username_value); -} - -TEST_F(PasswordFormConversionUtilsTest, - CreditCardVerificationNumberWithTypePasswordForm) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("Credit-card-owner-name", "John Smith", nullptr); - builder.AddTextField("Credit-card-number", "0000 0000 0000 0000", nullptr); - builder.AddPasswordField("cvc", "000", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::map<int, PasswordFormFieldPredictionType> predictions_positions; - predictions_positions[2] = PasswordFormFieldPredictionType::kNotPassword; - - FormsPredictionsMap predictions; - SetPredictions(html, &predictions, predictions_positions); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, &predictions, false); - EXPECT_TRUE(password_form); - EXPECT_TRUE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("Credit-card-number"), - password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("0000 0000 0000 0000"), - password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("cvc"), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("000"), password_form->password_value); -} - -TEST_F(PasswordFormConversionUtilsTest, - CreditCardNumberWithTypePasswordFormWithAutocomplete) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("Credit-card-owner-name", "John Smith", nullptr); - builder.AddPasswordField("Credit-card-number", "0000 0000 0000 0000", - "current-password"); - builder.AddTextField("cvc", "000", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::map<int, PasswordFormFieldPredictionType> predictions_positions; - predictions_positions[1] = PasswordFormFieldPredictionType::kNotPassword; - - FormsPredictionsMap predictions; - SetPredictions(html, &predictions, predictions_positions); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, &predictions, false); - EXPECT_TRUE(password_form); - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("Credit-card-owner-name"), - password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("John Smith"), password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("Credit-card-number"), - password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("0000 0000 0000 0000"), - password_form->password_value); -} - -TEST_F(PasswordFormConversionUtilsTest, - CreditCardVerificationNumberWithTypePasswordFormWithAutocomplete) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("Credit-card-owner-name", "John Smith", nullptr); - builder.AddTextField("Credit-card-number", "0000 0000 0000 0000", nullptr); - builder.AddPasswordField("cvc", "000", "new-password"); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::map<int, PasswordFormFieldPredictionType> predictions_positions; - predictions_positions[2] = PasswordFormFieldPredictionType::kNotPassword; - - FormsPredictionsMap predictions; - SetPredictions(html, &predictions, predictions_positions); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, &predictions, false); - ASSERT_TRUE(password_form); - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("Credit-card-number"), - password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("0000 0000 0000 0000"), - password_form->username_value); - EXPECT_TRUE(password_form->password_element.empty()); - EXPECT_TRUE(password_form->password_value.empty()); - EXPECT_EQ(base::UTF8ToUTF16("cvc"), password_form->new_password_element); - EXPECT_EQ(base::UTF8ToUTF16("000"), password_form->new_password_value); -} - TEST_F(PasswordFormConversionUtilsTest, IsGaiaReauthFormIgnored) { struct TestCase { const char* origin; @@ -2201,255 +253,4 @@ } } -TEST_F(PasswordFormConversionUtilsTest, - IdentifyingFieldsWithoutNameOrIdAttributes) { - const char* kEmpty = nullptr; - const struct { - const char* username_fieldname; - const char* password_fieldname; - const char* new_password_fieldname; - const char* expected_username_element; - const char* expected_password_element; - const char* expected_new_password_element; - } test_cases[] = { - {"username", "password", "new_password", "username", "password", - "new_password"}, - {"username", "password", kEmpty, "username", "password", - "anonymous_new_password"}, - {"username", kEmpty, kEmpty, "username", "anonymous_password", - "anonymous_new_password"}, - {kEmpty, kEmpty, kEmpty, "anonymous_username", "anonymous_password", - "anonymous_new_password"}, - }; - - for (size_t i = 0; i < base::size(test_cases); ++i) { - SCOPED_TRACE(testing::Message() - << "Iteration " << i << ", expected_username " - << test_cases[i].expected_username_element - << ", expected_password" - << test_cases[i].expected_password_element - << ", expected_new_password " - << test_cases[i].expected_new_password_element); - - PasswordFormBuilder builder(kTestFormActionURL); - if (test_cases[i].username_fieldname == kEmpty) { - builder.AddAnonymousInputField("text"); - } else { - builder.AddTextField(test_cases[i].username_fieldname, "", kEmpty); - } - - if (test_cases[i].password_fieldname == kEmpty) { - builder.AddAnonymousInputField("password"); - } else { - builder.AddPasswordField(test_cases[i].password_fieldname, "", kEmpty); - } - - if (test_cases[i].new_password_fieldname == kEmpty) { - builder.AddAnonymousInputField("password"); - } else { - builder.AddPasswordField(test_cases[i].new_password_fieldname, "", - kEmpty); - } - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - EXPECT_TRUE(password_form); - - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16(test_cases[i].expected_username_element), - password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16(test_cases[i].expected_password_element), - password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16(test_cases[i].expected_new_password_element), - password_form->new_password_element); - } -} - -TEST_F(PasswordFormConversionUtilsTest, TooManyFieldsToParseForm) { - PasswordFormBuilder builder(kTestFormActionURL); - for (size_t i = 0; i < form_util::kMaxParseableFields + 1; ++i) - builder.AddTextField("id", "value", "autocomplete"); - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(builder.ProduceHTML(), nullptr, false); - EXPECT_FALSE(password_form); -} - -TEST_F(PasswordFormConversionUtilsTest, OnlyCreditCardFields) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("ccname", "johnsmith", "cc-name"); - builder.AddPasswordField("cc_security_code", "0123456789", "cc-csc"); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - EXPECT_TRUE(password_form); - EXPECT_TRUE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("ccname"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("cc_security_code"), - password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("0123456789"), password_form->password_value); -} - -TEST_F(PasswordFormConversionUtilsTest, - FieldsWithAndWithoutCreditCardAttributes) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("username", "johnsmith", nullptr); - builder.AddTextField("ccname", "john_smith", "cc-name"); - builder.AddPasswordField("cc_security_code", "0123456789", "random cc-csc"); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - - ASSERT_TRUE(password_form); - - EXPECT_FALSE(password_form->only_for_fallback); - EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element); - EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value); -} - -TEST_F(PasswordFormConversionUtilsTest, ResetPasswordForm) { - // GetPassword (including HTML classifier) should process correctly forms - // without any text fields. - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - base::HistogramTester histogram_tester; - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - - ASSERT_TRUE(password_form); - - EXPECT_TRUE(password_form->username_element.empty()); - EXPECT_TRUE(password_form->username_value.empty()); - EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element); - EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value); - histogram_tester.ExpectUniqueSample( - "PasswordManager.UsernameDetectionMethod", - UsernameDetectionMethod::NO_USERNAME_DETECTED, 1); -} - -TEST_F(PasswordFormConversionUtilsTest, StickyPasswordType) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("username", "johnsmith", nullptr); - builder.AddPasswordField("password", "secret", nullptr); - builder.AddSubmitButton("submit"); - std::string html = builder.ProduceHTML(); - - std::unique_ptr<PasswordForm> password_form = - LoadHTMLAndConvertForm(html, nullptr, false); - ASSERT_TRUE(password_form); - - FormData old_form_data; - ASSERT_TRUE(ExtractFormDataForFirstForm(&old_form_data)); - - // Change password field to type="text". - ExecuteJavaScriptForTests( - "document.getElementById(\"password\").type = \"text\";"); - - // Validate that - despite the change - the old password field is still - // recognized as a password field. - WebFormElement new_form; - GetFirstForm(&new_form); - std::unique_ptr<PasswordForm> new_password_form = - CreatePasswordFormFromWebForm(new_form, nullptr, nullptr, - &username_detector_cache_); - ASSERT_TRUE(new_password_form); - - EXPECT_EQ(*password_form, *new_password_form); - - FormData new_form_data; - ASSERT_TRUE(ExtractFormDataForFirstForm(&new_form_data)); - - EXPECT_EQ(old_form_data, new_form_data); -} - -// Check that Chrome remembers the value typed by the user in cases when it gets -// overridden by the page. -TEST_F(PasswordFormConversionUtilsTest, TypedValuePreserved) { - PasswordFormBuilder builder(kTestFormActionURL); - builder.AddTextField("fine", "", "username"); - builder.AddPasswordField("mangled", "", "current-password"); - builder.AddTextField("completed_for_user", "", nullptr); - std::string html = builder.ProduceHTML(); - - WebFormElement form; - LoadWebFormFromHTML(html, &form, nullptr); - - FieldDataManager field_data_manager; - WebVector<WebFormControlElement> control_elements; - form.GetFormControlElements(control_elements); - - ASSERT_EQ(3u, control_elements.size()); - ASSERT_EQ("fine", control_elements[0].NameForAutofill().Utf8()); - control_elements[0].SetAutofillValue("same_value"); - field_data_manager.UpdateFieldDataMap(control_elements[0], - control_elements[0].Value().Utf16(), - FieldPropertiesFlags::USER_TYPED); - - ASSERT_EQ("mangled", control_elements[1].NameForAutofill().Utf8()); - control_elements[1].SetAutofillValue("mangled_value"); - field_data_manager.UpdateFieldDataMap(control_elements[1], - base::UTF8ToUTF16("original_value"), - FieldPropertiesFlags::USER_TYPED); - - ASSERT_EQ("completed_for_user", control_elements[2].NameForAutofill().Utf8()); - control_elements[2].SetAutofillValue("email@gmail.com"); - field_data_manager.UpdateFieldDataMap(control_elements[2], - base::UTF8ToUTF16("email"), - FieldPropertiesFlags::USER_TYPED); - - std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm( - form, &field_data_manager, nullptr, nullptr); - - ASSERT_TRUE(password_form); - - EXPECT_EQ(base::UTF8ToUTF16("same_value"), password_form->username_value); - EXPECT_EQ(base::UTF8ToUTF16("original_value"), password_form->password_value); - - ASSERT_EQ(3u, password_form->form_data.fields.size()); - - EXPECT_EQ(base::UTF8ToUTF16("same_value"), - password_form->form_data.fields[0].value); - EXPECT_EQ(base::string16(), password_form->form_data.fields[0].typed_value); - - EXPECT_EQ(base::UTF8ToUTF16("mangled_value"), - password_form->form_data.fields[1].value); - EXPECT_EQ(base::UTF8ToUTF16("original_value"), - password_form->form_data.fields[1].typed_value); - - EXPECT_EQ(base::UTF8ToUTF16("email@gmail.com"), - password_form->form_data.fields[2].value); - EXPECT_EQ(base::string16(), password_form->form_data.fields[2].typed_value); -} - -// Check that non-text fields are ignored. -TEST_F(PasswordFormConversionUtilsTest, NonTextFields) { - PasswordFormBuilder builder(kTestFormActionURL); - // Avoid calling the text fields anything related to "username" to prevent the - // local HTML classifier from influencing the test result. - builder.AddTextField("textField", "", ""); - builder.AddFieldWithType("radioInput", "radio"); - builder.AddPasswordField("password", "", ""); - std::string html = builder.ProduceHTML(); - - WebFormElement form; - LoadWebFormFromHTML(html, &form, nullptr); - - std::unique_ptr<PasswordForm> password_form = - CreatePasswordFormFromWebForm(form, nullptr, nullptr, nullptr); - - ASSERT_TRUE(password_form); - EXPECT_EQ(base::UTF8ToUTF16("textField"), password_form->username_element); -} - } // namespace autofill
diff --git a/components/autofill/core/browser/autofill_data_util.cc b/components/autofill/core/browser/autofill_data_util.cc index fde2484..35620873 100644 --- a/components/autofill/core/browser/autofill_data_util.cc +++ b/components/autofill/core/browser/autofill_data_util.cc
@@ -458,59 +458,6 @@ return base::JoinString(full_name, base::ASCIIToUTF16(separator)); } -bool ProfileMatchesFullName(base::StringPiece16 full_name, - const autofill::AutofillProfile& profile) { - const base::string16 kSpace = base::ASCIIToUTF16(" "); - const base::string16 kPeriodSpace = base::ASCIIToUTF16(". "); - - // First Last - base::string16 candidate = profile.GetRawInfo(autofill::NAME_FIRST) + kSpace + - profile.GetRawInfo(autofill::NAME_LAST); - if (!full_name.compare(candidate)) { - return true; - } - - // First Middle Last - candidate = profile.GetRawInfo(autofill::NAME_FIRST) + kSpace + - profile.GetRawInfo(autofill::NAME_MIDDLE) + kSpace + - profile.GetRawInfo(autofill::NAME_LAST); - if (!full_name.compare(candidate)) { - return true; - } - - // First M Last - candidate = profile.GetRawInfo(autofill::NAME_FIRST) + kSpace + - profile.GetRawInfo(autofill::NAME_MIDDLE_INITIAL) + kSpace + - profile.GetRawInfo(autofill::NAME_LAST); - if (!full_name.compare(candidate)) { - return true; - } - - // First M. Last - candidate = profile.GetRawInfo(autofill::NAME_FIRST) + kSpace + - profile.GetRawInfo(autofill::NAME_MIDDLE_INITIAL) + kPeriodSpace + - profile.GetRawInfo(autofill::NAME_LAST); - if (!full_name.compare(candidate)) { - return true; - } - - // Last First - candidate = profile.GetRawInfo(autofill::NAME_LAST) + kSpace + - profile.GetRawInfo(autofill::NAME_FIRST); - if (!full_name.compare(candidate)) { - return true; - } - - // LastFirst - candidate = profile.GetRawInfo(autofill::NAME_LAST) + - profile.GetRawInfo(autofill::NAME_FIRST); - if (!full_name.compare(candidate)) { - return true; - } - - return false; -} - const PaymentRequestData& GetPaymentRequestData( const std::string& issuer_network) { for (const PaymentRequestData& data : kPaymentRequestData) {
diff --git a/components/autofill/core/browser/autofill_data_util.h b/components/autofill/core/browser/autofill_data_util.h index a6060345..d99dc253 100644 --- a/components/autofill/core/browser/autofill_data_util.h +++ b/components/autofill/core/browser/autofill_data_util.h
@@ -96,11 +96,6 @@ base::StringPiece16 middle, base::StringPiece16 family); -// Returns true iff |full_name| is a concatenation of some combination of the -// first/middle/last (incl. middle initial) in |profile|. -bool ProfileMatchesFullName(base::StringPiece16 full_name, - const autofill::AutofillProfile& profile); - // Returns the Payment Request API basic card payment spec data for the provided // autofill credit card |network|. Will set the network and the icon to // "generic" for any unrecognized type.
diff --git a/components/autofill/core/browser/autofill_data_util_unittest.cc b/components/autofill/core/browser/autofill_data_util_unittest.cc index 7b1ea28..2646b113 100644 --- a/components/autofill/core/browser/autofill_data_util_unittest.cc +++ b/components/autofill/core/browser/autofill_data_util_unittest.cc
@@ -233,33 +233,6 @@ // Has a middle-name, too unusual )); -TEST(AutofillDataUtilTest, ProfileMatchesFullName) { - autofill::AutofillProfile profile; - autofill::test::SetProfileInfo( - &profile, "First", "Middle", "Last", "fml@example.com", "Acme inc", - "123 Main", "Apt 2", "Laredo", "TX", "77300", "US", "832-555-1000"); - - EXPECT_TRUE(ProfileMatchesFullName(base::UTF8ToUTF16("First Last"), profile)); - - EXPECT_TRUE( - ProfileMatchesFullName(base::UTF8ToUTF16("First Middle Last"), profile)); - - EXPECT_TRUE( - ProfileMatchesFullName(base::UTF8ToUTF16("First M Last"), profile)); - - EXPECT_TRUE( - ProfileMatchesFullName(base::UTF8ToUTF16("First M. Last"), profile)); - - EXPECT_TRUE( - ProfileMatchesFullName(base::UTF8ToUTF16("Last First"), profile)); - - EXPECT_TRUE( - ProfileMatchesFullName(base::UTF8ToUTF16("LastFirst"), profile)); - - EXPECT_FALSE( - ProfileMatchesFullName(base::UTF8ToUTF16("Kirby Puckett"), profile)); -} - struct ValidCountryCodeTestCase { std::string country_code; bool expected_result;
diff --git a/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc index 50b4ab8..66e412c 100644 --- a/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc +++ b/components/autofill/core/browser/webdata/autocomplete_sync_bridge_unittest.cc
@@ -23,7 +23,7 @@ #include "components/autofill/core/browser/webdata/autofill_entry.h" #include "components/autofill/core/browser/webdata/autofill_table.h" #include "components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/model/data_batch.h" #include "components/sync/model/data_type_activation_request.h" #include "components/sync/model/metadata_batch.h" @@ -245,7 +245,7 @@ const AutofillSpecifics& specifics) { auto data = std::make_unique<EntityData>(); *data->specifics.mutable_autofill() = specifics; - data->client_tag_hash = syncer::GenerateSyncableHash( + data->client_tag_hash = syncer::ClientTagHash::FromUnhashed( syncer::AUTOFILL, bridge()->GetClientTag(*data)); return data; }
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc index 8e303e2..0ebf17d 100644 --- a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc +++ b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
@@ -28,7 +28,7 @@ #include "components/autofill/core/browser/webdata/autofill_table.h" #include "components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h" #include "components/autofill/core/common/autofill_constants.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/model/data_batch.h" #include "components/sync/model/data_type_activation_request.h" #include "components/sync/model/entity_data.h" @@ -296,7 +296,7 @@ const AutofillProfileSpecifics& specifics) { auto data = std::make_unique<EntityData>(); *data->specifics.mutable_autofill_profile() = specifics; - data->client_tag_hash = syncer::GenerateSyncableHash( + data->client_tag_hash = syncer::ClientTagHash::FromUnhashed( syncer::AUTOFILL_PROFILE, bridge()->GetClientTag(*data)); return data; }
diff --git a/components/autofill/core/browser/webdata/autofill_sync_bridge_util_unittest.cc b/components/autofill/core/browser/webdata/autofill_sync_bridge_util_unittest.cc index 0ca087c..997d51b1 100644 --- a/components/autofill/core/browser/webdata/autofill_sync_bridge_util_unittest.cc +++ b/components/autofill/core/browser/webdata/autofill_sync_bridge_util_unittest.cc
@@ -14,7 +14,7 @@ #include "components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.h" #include "components/autofill/core/browser/webdata/autofill_table.h" #include "components/autofill/core/common/autofill_constants.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/model/entity_data.h" #include "components/sync/protocol/sync.pb.h" #include "testing/gtest/include/gtest/gtest.h" @@ -50,8 +50,8 @@ const std::string& client_tag) { auto data = std::make_unique<syncer::EntityData>(); *data->specifics.mutable_autofill_wallet() = specifics; - data->client_tag_hash = - syncer::GenerateSyncableHash(syncer::AUTOFILL_WALLET_DATA, client_tag); + data->client_tag_hash = syncer::ClientTagHash::FromUnhashed( + syncer::AUTOFILL_WALLET_DATA, client_tag); return data; }
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc index e3b3e953..c6448b4 100644 --- a/components/autofill/core/browser/webdata/autofill_table.cc +++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -2595,11 +2595,12 @@ "SELECT ?, storage_key, value " "FROM autofill_sync_metadata")); // Note: This uses the *wrong* ID for the ModelType - instead of - // |syncer::ModelTypeToHistogramInt|, this should be |GetKeyValueForModelType| + // |syncer::ModelTypeHistogramValue|, this should be |GetKeyValueForModelType| // aka |syncer::ModelTypeToStableIdentifier|. But at this point, fixing it // here would just make an even bigger mess. Instead, we clean this up in the // migration to version 81. See also crbug.com/895826. - insert_metadata.BindInt(0, syncer::ModelTypeToHistogramInt(syncer::AUTOFILL)); + insert_metadata.BindInt( + 0, static_cast<int>(syncer::ModelTypeHistogramValue(syncer::AUTOFILL))); // Prior to this migration, the table was a singleton, containing only one // entry with id being hard-coded to 1. @@ -2608,7 +2609,8 @@ "(model_type, value) SELECT ?, value " "FROM autofill_model_type_state WHERE id=1")); // Note: Like above, this uses the *wrong* ID for the ModelType. - insert_state.BindInt(0, syncer::ModelTypeToHistogramInt(syncer::AUTOFILL)); + insert_state.BindInt( + 0, static_cast<int>(syncer::ModelTypeHistogramValue(syncer::AUTOFILL))); if (!insert_metadata.Run() || !insert_state.Run()) { return false; @@ -2641,7 +2643,7 @@ // in trying to recover anything, since by now it'll have been redownloaded // anyway. const int bad_model_type_id = - syncer::ModelTypeToHistogramInt(syncer::AUTOFILL); + static_cast<int>(syncer::ModelTypeHistogramValue(syncer::AUTOFILL)); DCHECK_NE(bad_model_type_id, GetKeyValueForModelType(syncer::AUTOFILL)); sql::Transaction transaction(db_);
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc index 2452ca9..0f78f82 100644 --- a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc +++ b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc
@@ -29,7 +29,7 @@ #include "components/autofill/core/browser/webdata/autofill_table.h" #include "components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h" #include "components/autofill/core/common/autofill_constants.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/model/data_batch.h" #include "components/sync/model/entity_data.h" #include "components/sync/model/mock_model_type_change_processor.h" @@ -353,7 +353,7 @@ bool is_deleted = false) { auto data = std::make_unique<EntityData>(); *data->specifics.mutable_wallet_metadata() = specifics; - data->client_tag_hash = syncer::GenerateSyncableHash( + data->client_tag_hash = syncer::ClientTagHash::FromUnhashed( syncer::AUTOFILL_WALLET_METADATA, bridge()->GetClientTag(*data)); if (is_deleted) { // Specifics had to be set in order to generate the client tag. Since
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc index c733a43..12e7e536 100644 --- a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc +++ b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge_unittest.cc
@@ -31,7 +31,7 @@ #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h" #include "components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h" #include "components/autofill/core/common/autofill_constants.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/driver/sync_driver_switches.h" #include "components/sync/model/entity_data.h" #include "components/sync/model/mock_model_type_change_processor.h" @@ -269,7 +269,7 @@ const AutofillWalletSpecifics& specifics) { auto data = std::make_unique<EntityData>(); *data->specifics.mutable_autofill_wallet() = specifics; - data->client_tag_hash = syncer::GenerateSyncableHash( + data->client_tag_hash = syncer::ClientTagHash::FromUnhashed( syncer::AUTOFILL_WALLET_DATA, bridge()->GetClientTag(*data)); return data; }
diff --git a/components/autofill/core/common/BUILD.gn b/components/autofill/core/common/BUILD.gn index 88abc76..d0d4d220d 100644 --- a/components/autofill/core/common/BUILD.gn +++ b/components/autofill/core/common/BUILD.gn
@@ -43,7 +43,6 @@ "logging/log_buffer.h", "password_form.cc", "password_form.h", - "password_form_field_prediction_map.h", "password_form_fill_data.cc", "password_form_fill_data.h", "password_form_generation_data.cc",
diff --git a/components/autofill/core/common/mojom/autofill_types.mojom b/components/autofill/core/common/mojom/autofill_types.mojom index 8e8a3c3..2b26b1b 100644 --- a/components/autofill/core/common/mojom/autofill_types.mojom +++ b/components/autofill/core/common/mojom/autofill_types.mojom
@@ -294,17 +294,3 @@ SubmissionIndicatorEvent submission_event; bool only_for_fallback; }; - -// Note: Even though https://crbug.com/628104 is solved, we still can not use a -// map directly as long as https://crbug.com/914074 is not fixed. -struct PasswordFormFieldPredictionMap { - array<FormFieldData> keys; - array<PasswordFormFieldPredictionType> values; -}; - -// Note: Even though https://crbug.com/628104 is solved, we still can not use a -// map directly as long as https://crbug.com/914074 is not fixed. -struct FormsPredictionsMap { - array<FormData> keys; - array<PasswordFormFieldPredictionMap> values; -};
diff --git a/components/autofill/core/common/mojom/autofill_types.typemap b/components/autofill/core/common/mojom/autofill_types.typemap index 6b444c3..7d801ef 100644 --- a/components/autofill/core/common/mojom/autofill_types.typemap +++ b/components/autofill/core/common/mojom/autofill_types.typemap
@@ -9,7 +9,6 @@ "//components/autofill/core/common/form_field_data.h", "//components/autofill/core/common/form_field_data_predictions.h", "//components/autofill/core/common/password_form.h", - "//components/autofill/core/common/password_form_field_prediction_map.h", "//components/autofill/core/common/password_form_fill_data.h", "//components/autofill/core/common/password_form_generation_data.h", "//components/autofill/core/common/password_generation_util.h",
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc b/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc index 9128a85..dead49b5 100644 --- a/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc +++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
@@ -298,92 +298,6 @@ } // static -std::vector<autofill::FormFieldData> -StructTraits<autofill::mojom::PasswordFormFieldPredictionMapDataView, - autofill::PasswordFormFieldPredictionMap>:: - keys(const autofill::PasswordFormFieldPredictionMap& r) { - std::vector<autofill::FormFieldData> data; - for (const auto& i : r) - data.push_back(i.first); - return data; -} - -// static -std::vector<autofill::mojom::PasswordFormFieldPredictionType> -StructTraits<autofill::mojom::PasswordFormFieldPredictionMapDataView, - autofill::PasswordFormFieldPredictionMap>:: - values(const autofill::PasswordFormFieldPredictionMap& r) { - std::vector<autofill::mojom::PasswordFormFieldPredictionType> types; - for (const auto& i : r) - types.push_back(i.second); - return types; -} - -// static -bool StructTraits<autofill::mojom::PasswordFormFieldPredictionMapDataView, - autofill::PasswordFormFieldPredictionMap>:: - Read(autofill::mojom::PasswordFormFieldPredictionMapDataView data, - autofill::PasswordFormFieldPredictionMap* out) { - // Combines keys vector and values vector to the map. - std::vector<autofill::FormFieldData> keys; - if (!data.ReadKeys(&keys)) - return false; - std::vector<autofill::mojom::PasswordFormFieldPredictionType> values; - if (!data.ReadValues(&values)) - return false; - if (keys.size() != values.size()) - return false; - out->clear(); - for (size_t i = 0; i < keys.size(); ++i) - out->insert({keys[i], values[i]}); - - return true; -} - -// static -std::vector<autofill::FormData> StructTraits< - autofill::mojom::FormsPredictionsMapDataView, - autofill::FormsPredictionsMap>::keys(const autofill::FormsPredictionsMap& - r) { - std::vector<autofill::FormData> data; - for (const auto& i : r) - data.push_back(i.first); - return data; -} - -// static -std::vector<autofill::PasswordFormFieldPredictionMap> StructTraits< - autofill::mojom::FormsPredictionsMapDataView, - autofill::FormsPredictionsMap>::values(const autofill::FormsPredictionsMap& - r) { - std::vector<autofill::PasswordFormFieldPredictionMap> maps; - for (const auto& i : r) - maps.push_back(i.second); - return maps; -} - -// static -bool StructTraits<autofill::mojom::FormsPredictionsMapDataView, - autofill::FormsPredictionsMap>:: - Read(autofill::mojom::FormsPredictionsMapDataView data, - autofill::FormsPredictionsMap* out) { - // Combines keys vector and values vector to the map. - std::vector<autofill::FormData> keys; - if (!data.ReadKeys(&keys)) - return false; - std::vector<autofill::PasswordFormFieldPredictionMap> values; - if (!data.ReadValues(&values)) - return false; - if (keys.size() != values.size()) - return false; - out->clear(); - for (size_t i = 0; i < keys.size(); ++i) - out->insert({keys[i], values[i]}); - - return true; -} - -// static bool StructTraits<autofill::mojom::ValueElementPairDataView, autofill::ValueElementPair>:: Read(autofill::mojom::ValueElementPairDataView data,
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits.h b/components/autofill/core/common/mojom/autofill_types_mojom_traits.h index 6a1ca29d..2b7b914 100644 --- a/components/autofill/core/common/mojom/autofill_types_mojom_traits.h +++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
@@ -18,7 +18,6 @@ #include "components/autofill/core/common/form_field_data_predictions.h" #include "components/autofill/core/common/mojom/autofill_types.mojom.h" #include "components/autofill/core/common/password_form.h" -#include "components/autofill/core/common/password_form_field_prediction_map.h" #include "components/autofill/core/common/password_form_fill_data.h" #include "components/autofill/core/common/password_form_generation_data.h" #include "components/autofill/core/common/password_generation_util.h" @@ -578,32 +577,6 @@ }; template <> -struct StructTraits<autofill::mojom::PasswordFormFieldPredictionMapDataView, - autofill::PasswordFormFieldPredictionMap> { - static std::vector<autofill::FormFieldData> keys( - const autofill::PasswordFormFieldPredictionMap& r); - - static std::vector<autofill::mojom::PasswordFormFieldPredictionType> values( - const autofill::PasswordFormFieldPredictionMap& r); - - static bool Read(autofill::mojom::PasswordFormFieldPredictionMapDataView data, - autofill::PasswordFormFieldPredictionMap* out); -}; - -template <> -struct StructTraits<autofill::mojom::FormsPredictionsMapDataView, - autofill::FormsPredictionsMap> { - static std::vector<autofill::FormData> keys( - const autofill::FormsPredictionsMap& r); - - static std::vector<autofill::PasswordFormFieldPredictionMap> values( - const autofill::FormsPredictionsMap& r); - - static bool Read(autofill::mojom::FormsPredictionsMapDataView data, - autofill::FormsPredictionsMap* out); -}; - -template <> struct StructTraits<autofill::mojom::ValueElementPairDataView, autofill::ValueElementPair> { static base::string16 value(const autofill::ValueElementPair& r) {
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc b/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc index b1b17958..24061ea 100644 --- a/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc +++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc
@@ -110,39 +110,6 @@ mojom::SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION; } -void CreateTestFormsPredictionsMap(FormsPredictionsMap* predictions) { - FormsPredictionsMap& result_map = *predictions; - // 1st element. - FormData form_data; - test::CreateTestAddressFormData(&form_data); - ASSERT_TRUE(form_data.fields.size() >= 4); - result_map[form_data][form_data.fields[0]] = - PasswordFormFieldPredictionType::kUsername; - result_map[form_data][form_data.fields[1]] = - PasswordFormFieldPredictionType::kCurrentPassword; - result_map[form_data][form_data.fields[2]] = - PasswordFormFieldPredictionType::kNewPassword; - result_map[form_data][form_data.fields[3]] = - PasswordFormFieldPredictionType::kNotPassword; - - // 2nd element. - form_data.fields.clear(); - result_map[form_data] = {}; - - // 3rd element. - FormFieldData field_data; - test::CreateTestSelectField("TestLabel1", "TestName1", "TestValue1", kOptions, - kOptions, 4, &field_data); - form_data.fields.push_back(field_data); - test::CreateTestSelectField("TestLabel2", "TestName2", "TestValue2", kOptions, - kOptions, 4, &field_data); - form_data.fields.push_back(field_data); - result_map[form_data][form_data.fields[0]] = - PasswordFormFieldPredictionType::kNewPassword; - result_map[form_data][form_data.fields[1]] = - PasswordFormFieldPredictionType::kCurrentPassword; -} - void CreatePasswordGenerationUIData( password_generation::PasswordGenerationUIData* data) { data->bounds = gfx::RectF(1, 1, 200, 100); @@ -248,12 +215,6 @@ std::move(callback).Run(s); } - void PassFormsPredictionsMap( - const FormsPredictionsMap& s, - PassFormsPredictionsMapCallback callback) override { - std::move(callback).Run(s); - } - private: base::test::TaskEnvironment task_environment_; @@ -322,13 +283,6 @@ std::move(closure).Run(); } -void ExpectFormsPredictionsMap(const FormsPredictionsMap& expected, - base::OnceClosure closure, - const FormsPredictionsMap& passed) { - EXPECT_EQ(expected, passed); - std::move(closure).Run(); -} - TEST_F(AutofillTypeTraitsTestImpl, PassFormFieldData) { FormFieldData input; test::CreateTestSelectField("TestLabel", "TestName", "TestValue", kOptions, @@ -453,16 +407,4 @@ loop.Run(); } -TEST_F(AutofillTypeTraitsTestImpl, PassFormsPredictionsMap) { - FormsPredictionsMap input; - CreateTestFormsPredictionsMap(&input); - - base::RunLoop loop; - mojo::Remote<mojom::TypeTraitsTest> remote(GetTypeTraitsTestRemote()); - remote->PassFormsPredictionsMap( - input, - base::BindOnce(&ExpectFormsPredictionsMap, input, loop.QuitClosure())); - loop.Run(); -} - } // namespace autofill
diff --git a/components/autofill/core/common/mojom/test_autofill_types.mojom b/components/autofill/core/common/mojom/test_autofill_types.mojom index 9f5be9e..dd13926 100644 --- a/components/autofill/core/common/mojom/test_autofill_types.mojom +++ b/components/autofill/core/common/mojom/test_autofill_types.mojom
@@ -16,8 +16,6 @@ PassPasswordForm(PasswordForm s) => (PasswordForm passed); PassPasswordFormFillData(PasswordFormFillData s) => (PasswordFormFillData passed); - PassFormsPredictionsMap(FormsPredictionsMap s) => - (FormsPredictionsMap passed); PassPasswordFormGenerationData(PasswordFormGenerationData s) => (PasswordFormGenerationData passed); PassPasswordGenerationUIData(PasswordGenerationUIData s) =>
diff --git a/components/autofill/core/common/password_form_field_prediction_map.h b/components/autofill/core/common/password_form_field_prediction_map.h deleted file mode 100644 index b0d149c..0000000 --- a/components/autofill/core/common/password_form_field_prediction_map.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_FORM_FIELD_PREDICTION_MAP_H_ -#define COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_FORM_FIELD_PREDICTION_MAP_H_ - -#include "base/containers/flat_map.h" -#include "components/autofill/core/common/form_data.h" -#include "components/autofill/core/common/form_field_data.h" -#include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h" - -namespace autofill { - -using PasswordFormFieldPredictionMap = - base::flat_map<FormFieldData, mojom::PasswordFormFieldPredictionType>; -using FormsPredictionsMap = - base::flat_map<FormData, PasswordFormFieldPredictionMap>; - -} // namespace autofill - -#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_FORM_FIELD_PREDICTION_MAP_H_
diff --git a/components/autofill_assistant/browser/client_settings.cc b/components/autofill_assistant/browser/client_settings.cc index f375b67..9b9bffed 100644 --- a/components/autofill_assistant/browser/client_settings.cc +++ b/components/autofill_assistant/browser/client_settings.cc
@@ -44,13 +44,6 @@ if (proto.has_document_ready_check_count()) { document_ready_check_count = proto.document_ready_check_count(); } - if (proto.has_enable_graceful_shutdown()) { - enable_graceful_shutdown = proto.enable_graceful_shutdown(); - } - if (proto.has_graceful_shutdown_delay_ms()) { - graceful_shutdown_delay = - base::TimeDelta::FromMilliseconds(proto.graceful_shutdown_delay_ms()); - } if (proto.has_cancel_delay_ms()) { cancel_delay = base::TimeDelta::FromMilliseconds(proto.cancel_delay_ms()); }
diff --git a/components/autofill_assistant/browser/client_settings.h b/components/autofill_assistant/browser/client_settings.h index f007b58..8fd70fc 100644 --- a/components/autofill_assistant/browser/client_settings.h +++ b/components/autofill_assistant/browser/client_settings.h
@@ -61,14 +61,6 @@ // ready. int document_ready_check_count = 50; - // Whether graceful shutdown should be enabled. If false, the UI stays - // up until it's dismissed. - bool enable_graceful_shutdown = true; - - // How long to wait before shutting down during graceful shutdown. If 0 - // shutdown happens immediately. - base::TimeDelta graceful_shutdown_delay = base::TimeDelta::FromSeconds(5); - // How much time to give users to tap undo when they tap a cancel button. base::TimeDelta cancel_delay = base::TimeDelta::FromSeconds(5);
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index 50d7769..e6f242b 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -74,6 +74,8 @@ } message ClientSettingsProto { + reserved 10, 11; + // Time between two periodic script precondition checks. optional int32 periodic_script_check_interval_ms = 1; @@ -108,14 +110,6 @@ // ready. optional int32 document_ready_check_count = 9; - // Whether graceful shutdown should be enabled. If false, the UI stays - // up until it's dismissed. - optional bool enable_graceful_shutdown = 10; - - // How long to wait before shutting down during graceful shutdown. If 0 - // shutdown happens immediately. - optional int32 graceful_shutdown_delay_ms = 11; - // How much time to give users to tap undo when they tap a cancel button. optional int32 cancel_delay_ms = 12; @@ -440,6 +434,8 @@ // script finishes with this action. It has no effect if there is any other // action sent to the client after this one. Default is false. optional bool clean_contextual_ui = 33; + + reserved 47; } // Result of |CollectUserDataProto| to be sent to the server.
diff --git a/components/autofill_assistant/browser/state.h b/components/autofill_assistant/browser/state.h index d7479a72..3cad37da 100644 --- a/components/autofill_assistant/browser/state.h +++ b/components/autofill_assistant/browser/state.h
@@ -81,14 +81,13 @@ // Autofill assistant is stopped, but the controller is still available. // // This is a final state for the UI, which, when entering this state, detaches - // itself from the controller, waits for a few seconds to let the user read - // the message and then disappears. + // itself from the controller and lets the user read the message. // // In that scenario, the status message at the time of transition to STOPPED // is supposed to contain the final message. // - // Next states: TRACKING. - STOPPED + // Next states: TRACKING + STOPPED, }; inline std::ostream& operator<<(std::ostream& out,
diff --git a/components/chromeos_camera/BUILD.gn b/components/chromeos_camera/BUILD.gn index 33ce314..ed195d1f 100644 --- a/components/chromeos_camera/BUILD.gn +++ b/components/chromeos_camera/BUILD.gn
@@ -202,8 +202,8 @@ ] deps = [ + "common:camera_app_helper", "//ash/public/cpp", - "//media/capture/video/chromeos/mojom:cros_camera", ] }
diff --git a/components/chromeos_camera/camera_app_helper_impl.h b/components/chromeos_camera/camera_app_helper_impl.h index 599602b..fd478e21 100644 --- a/components/chromeos_camera/camera_app_helper_impl.h +++ b/components/chromeos_camera/camera_app_helper_impl.h
@@ -7,11 +7,11 @@ #include <vector> -#include "media/capture/video/chromeos/mojom/camera_app.mojom.h" +#include "components/chromeos_camera/common/camera_app_helper.mojom.h" namespace chromeos_camera { -class CameraAppHelperImpl : public cros::mojom::CameraAppHelper { +class CameraAppHelperImpl : public chromeos_camera::mojom::CameraAppHelper { public: using CameraResultCallback = base::RepeatingCallback<void(uint32_t, @@ -22,7 +22,7 @@ explicit CameraAppHelperImpl(CameraResultCallback camera_result_callback); ~CameraAppHelperImpl() override; - // cros::mojom::CameraAppHelper implementations. + // chromeos_camera::mojom::CameraAppHelper implementations. void HandleCameraResult(uint32_t intent_id, arc::mojom::CameraIntentAction action, const std::vector<uint8_t>& data, @@ -37,4 +37,4 @@ } // namespace chromeos_camera -#endif // COMPONENTS_CHROMEOS_CAMERA_CAMERA_APP_HELPER_IMPL_H_ \ No newline at end of file +#endif // COMPONENTS_CHROMEOS_CAMERA_CAMERA_APP_HELPER_IMPL_H_
diff --git a/components/chromeos_camera/common/BUILD.gn b/components/chromeos_camera/common/BUILD.gn index d49f9e7..a2ca91d 100644 --- a/components/chromeos_camera/common/BUILD.gn +++ b/components/chromeos_camera/common/BUILD.gn
@@ -17,3 +17,12 @@ "//ui/gfx/geometry/mojom", ] } + +mojom("camera_app_helper") { + sources = [ + "camera_app_helper.mojom", + ] + deps = [ + "//components/arc/mojom:camera_intent", + ] +}
diff --git a/components/chromeos_camera/common/camera_app_helper.mojom b/components/chromeos_camera/common/camera_app_helper.mojom new file mode 100644 index 0000000..a0b8c822 --- /dev/null +++ b/components/chromeos_camera/common/camera_app_helper.mojom
@@ -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. + +module chromeos_camera.mojom; + +import "components/arc/mojom/camera_intent.mojom"; + +// Interface for communication between Chrome Camera App (Remote) and Chrome +// (Receiver). +interface CameraAppHelper { + // Sends the captured result |data| for corresponding intent recognized by + // |intent_id| back to ARC. The handler should handle |data| and may notify + // the intent caller according to the intention of the |action|. |is_success| + // will be set to true if the ARC received the result and set to false for + // invalid input. + HandleCameraResult(uint32 intent_id, + arc.mojom.CameraIntentAction action, + array<uint8> data) => (bool is_success); + + // Checks if device is under tablet mode currently. + IsTabletMode() => (bool is_tablet_mode); +};
diff --git a/components/chromeos_camera/dmabuf_utils.cc b/components/chromeos_camera/dmabuf_utils.cc index dd420e15..3c63e9f 100644 --- a/components/chromeos_camera/dmabuf_utils.cc +++ b/components/chromeos_camera/dmabuf_utils.cc
@@ -10,6 +10,7 @@ #include "base/logging.h" #include "base/numerics/safe_conversions.h" #include "base/time/time.h" +#include "media/base/color_plane_layout.h" #include "media/base/video_frame.h" #include "media/base/video_frame_layout.h" #include "mojo/public/cpp/system/platform_handle.h" @@ -34,7 +35,7 @@ const gfx::Rect visible_rect(coded_size); std::vector<base::ScopedFD> dma_buf_fds(num_planes); - std::vector<media::VideoFrameLayout::Plane> planes(num_planes); + std::vector<media::ColorPlaneLayout> planes(num_planes); for (size_t i = 0; i < num_planes; ++i) { mojo::PlatformHandle handle = mojo::UnwrapPlatformHandle(std::move(dma_buf_planes[i]->fd_handle)); @@ -43,7 +44,7 @@ return nullptr; } dma_buf_fds[i] = handle.TakeFD(); - planes[i] = media::VideoFrameLayout::Plane( + planes[i] = media::ColorPlaneLayout( dma_buf_planes[i]->stride, base::strict_cast<size_t>(dma_buf_planes[i]->offset), base::strict_cast<size_t>(dma_buf_planes[i]->size));
diff --git a/components/chromeos_camera/jpeg_encode_accelerator_unittest.cc b/components/chromeos_camera/jpeg_encode_accelerator_unittest.cc index fe3ff09..fc9889e 100644 --- a/components/chromeos_camera/jpeg_encode_accelerator_unittest.cc +++ b/components/chromeos_camera/jpeg_encode_accelerator_unittest.cc
@@ -26,6 +26,7 @@ #include "build/build_config.h" #include "components/chromeos_camera/gpu_jpeg_encode_accelerator_factory.h" #include "components/chromeos_camera/jpeg_encode_accelerator.h" +#include "media/base/color_plane_layout.h" #include "media/base/test_data_util.h" #include "media/capture/video/chromeos/local_gpu_memory_buffer_manager.h" #include "media/gpu/buildflags.h" @@ -92,7 +93,7 @@ auto buffer_handle = buffer->CloneHandle().native_pixmap_handle; size_t num_planes = media::VideoFrame::NumPlanes(format); - std::vector<media::VideoFrameLayout::Plane> planes(num_planes); + std::vector<media::ColorPlaneLayout> planes(num_planes); std::vector<base::ScopedFD> fds(num_planes); for (size_t i = 0; i < num_planes; i++) { auto& plane = buffer_handle.planes[i];
diff --git a/components/chromeos_camera/mjpeg_decode_accelerator_unittest.cc b/components/chromeos_camera/mjpeg_decode_accelerator_unittest.cc index 0fd7c1b4..a2f8f2e5 100644 --- a/components/chromeos_camera/mjpeg_decode_accelerator_unittest.cc +++ b/components/chromeos_camera/mjpeg_decode_accelerator_unittest.cc
@@ -36,6 +36,7 @@ #include "build/build_config.h" #include "components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.h" #include "components/chromeos_camera/mjpeg_decode_accelerator.h" +#include "media/base/color_plane_layout.h" #include "media/base/format_utils.h" #include "media/base/test_data_util.h" #include "media/base/video_frame_layout.h" @@ -348,7 +349,7 @@ gmb->Unmap(); // Create a VideoFrame from the NativePixmapHandle. - std::vector<media::VideoFrameLayout::Plane> planes; + std::vector<media::ColorPlaneLayout> planes; std::vector<base::ScopedFD> dmabuf_fds; for (size_t i = 0; i < num_planes; i++) { gfx::NativePixmapPlane& plane = gmb_handle.native_pixmap_handle.planes[i];
diff --git a/components/dom_distiller/core/dom_distiller_model.cc b/components/dom_distiller/core/dom_distiller_model.cc index 81d2667..ea60747e 100644 --- a/components/dom_distiller/core/dom_distiller_model.cc +++ b/components/dom_distiller/core/dom_distiller_model.cc
@@ -89,14 +89,6 @@ return entries_list; } -SyncDataList DomDistillerModel::GetAllSyncData() const { - SyncDataList data; - for (auto it = entries_.begin(); it != entries_.end(); ++it) { - data.push_back(CreateLocalData(it->second)); - } - return data; -} - void DomDistillerModel::CalculateChangesForMerge( const SyncDataList& data, SyncChangeList* changes_to_apply,
diff --git a/components/dom_distiller/core/dom_distiller_model.h b/components/dom_distiller/core/dom_distiller_model.h index e74bd26a..2b5d0614 100644 --- a/components/dom_distiller/core/dom_distiller_model.h +++ b/components/dom_distiller/core/dom_distiller_model.h
@@ -16,7 +16,6 @@ #include "base/macros.h" #include "components/dom_distiller/core/article_entry.h" #include "components/sync/model/sync_change.h" -#include "components/sync/model/sync_change_processor.h" // syncer::SyncChangeList #include "components/sync/model/sync_data.h" #include "url/gurl.h" @@ -41,8 +40,6 @@ std::vector<ArticleEntry> GetEntries() const; size_t GetNumEntries() const; - syncer::SyncDataList GetAllSyncData() const; - // Convert a SyncDataList to a SyncChangeList of add or update changes based // on the state of the model. Also calculate the entries missing from the // SyncDataList.
diff --git a/components/dom_distiller/core/dom_distiller_store.cc b/components/dom_distiller/core/dom_distiller_store.cc index bfaa2b3..2cd9dce 100644 --- a/components/dom_distiller/core/dom_distiller_store.cc +++ b/components/dom_distiller/core/dom_distiller_store.cc
@@ -11,23 +11,13 @@ #include "base/bind.h" #include "base/location.h" #include "base/logging.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" #include "components/dom_distiller/core/article_entry.h" #include "components/sync/model/sync_change.h" -#include "components/sync/protocol/article_specifics.pb.h" -#include "components/sync/protocol/sync.pb.h" using leveldb_proto::ProtoDatabase; -using sync_pb::ArticleSpecifics; -using sync_pb::EntitySpecifics; -using syncer::ModelType; using syncer::SyncChange; using syncer::SyncChangeList; -using syncer::SyncData; using syncer::SyncDataList; -using syncer::SyncError; -using syncer::SyncMergeResult; namespace dom_distiller { @@ -227,48 +217,17 @@ return true; } -SyncMergeResult DomDistillerStore::MergeDataWithModel( - const SyncDataList& data, - SyncChangeList* changes_applied, - SyncChangeList* changes_missing) { +void DomDistillerStore::MergeDataWithModel(const SyncDataList& data, + SyncChangeList* changes_applied, + SyncChangeList* changes_missing) { // TODO(cjhopman): This naive merge algorithm could cause flip-flopping // between database/sync of multiple clients. DCHECK(changes_applied); DCHECK(changes_missing); - SyncMergeResult result(syncer::DEPRECATED_ARTICLES); - result.set_num_items_before_association(model_.GetNumEntries()); - SyncChangeList changes_to_apply; model_.CalculateChangesForMerge(data, &changes_to_apply, changes_missing); - SyncError error; ApplyChangesToModel(changes_to_apply, changes_applied, changes_missing); - - int num_added = 0; - int num_modified = 0; - for (SyncChangeList::const_iterator it = changes_applied->begin(); - it != changes_applied->end(); ++it) { - DCHECK(it->IsValid()); - switch (it->change_type()) { - case SyncChange::ACTION_ADD: - num_added++; - break; - case SyncChange::ACTION_UPDATE: - num_modified++; - break; - default: - NOTREACHED(); - } - } - result.set_num_items_added(num_added); - result.set_num_items_modified(num_modified); - result.set_num_items_deleted(0); - - result.set_pre_association_version(0); - result.set_num_items_after_association(model_.GetNumEntries()); - result.set_error(error); - - return result; } } // namespace dom_distiller
diff --git a/components/dom_distiller/core/dom_distiller_store.h b/components/dom_distiller/core/dom_distiller_store.h index 77385e1..ae2ac1f 100644 --- a/components/dom_distiller/core/dom_distiller_store.h +++ b/components/dom_distiller/core/dom_distiller_store.h
@@ -17,15 +17,11 @@ #include "components/leveldb_proto/public/proto_database.h" #include "components/sync/model/sync_change.h" #include "components/sync/model/sync_data.h" -#include "components/sync/model/sync_error.h" -#include "components/sync/model/sync_error_factory.h" -#include "components/sync/model/sync_merge_result.h" -#include "components/sync/model/syncable_service.h" #include "url/gurl.h" namespace dom_distiller { -// Interface for accessing the stored/synced DomDistiller entries. +// Interface for accessing the stored DomDistiller entries. class DomDistillerStoreInterface { public: virtual ~DomDistillerStoreInterface() {} @@ -100,17 +96,9 @@ bool ChangeEntry(const ArticleEntry& entry, syncer::SyncChange::SyncChangeType changeType); - syncer::SyncMergeResult MergeDataWithModel( - const syncer::SyncDataList& data, - syncer::SyncChangeList* changes_applied, - syncer::SyncChangeList* changes_missing); - - // Convert a SyncDataList to a SyncChangeList of add or update changes based - // on the state of the in-memory model. Also calculate the entries missing - // from the SyncDataList. - void CalculateChangesForMerge(const syncer::SyncDataList& data, - syncer::SyncChangeList* changes_to_apply, - syncer::SyncChangeList* changes_missing); + void MergeDataWithModel(const syncer::SyncDataList& data, + syncer::SyncChangeList* changes_applied, + syncer::SyncChangeList* changes_missing); bool ApplyChangesToDatabase(const syncer::SyncChangeList& change_list); @@ -122,8 +110,6 @@ void NotifyObservers(const syncer::SyncChangeList& changes); - std::unique_ptr<syncer::SyncChangeProcessor> sync_processor_; - std::unique_ptr<syncer::SyncErrorFactory> error_factory_; std::unique_ptr<leveldb_proto::ProtoDatabase<ArticleEntry>> database_; bool database_loaded_; base::ObserverList<DomDistillerObserver>::Unchecked observers_;
diff --git a/components/dom_distiller/core/dom_distiller_store_unittest.cc b/components/dom_distiller/core/dom_distiller_store_unittest.cc index 7ba9ae5..32db73b 100644 --- a/components/dom_distiller/core/dom_distiller_store_unittest.cc +++ b/components/dom_distiller/core/dom_distiller_store_unittest.cc
@@ -19,21 +19,11 @@ #include "components/dom_distiller/core/article_entry.h" #include "components/dom_distiller/core/dom_distiller_test_util.h" #include "components/leveldb_proto/testing/fake_db.h" -#include "components/sync/protocol/sync.pb.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" using base::Time; using leveldb_proto::test::FakeDB; -using sync_pb::EntitySpecifics; -using syncer::ModelType; -using syncer::SyncChange; -using syncer::SyncChangeList; -using syncer::SyncChangeProcessor; -using syncer::SyncData; -using syncer::SyncDataList; -using syncer::SyncError; -using syncer::SyncErrorFactory; using testing::_; using testing::AssertionFailure; using testing::AssertionResult; @@ -50,35 +40,6 @@ (*map)[e.entry_id()] = e; } -class FakeSyncErrorFactory : public syncer::SyncErrorFactory { - public: - syncer::SyncError CreateAndUploadError(const base::Location& location, - const std::string& message) override { - return syncer::SyncError(); - } -}; - -class FakeSyncChangeProcessor : public syncer::SyncChangeProcessor { - public: - explicit FakeSyncChangeProcessor(EntryMap* model) : model_(model) {} - - syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override { - ADD_FAILURE() << "FakeSyncChangeProcessor::GetAllSyncData not implemented."; - return syncer::SyncDataList(); - } - - SyncError ProcessSyncChanges(const base::Location&, - const syncer::SyncChangeList& changes) override { - for (auto it = changes.begin(); it != changes.end(); ++it) { - AddEntry(GetEntryFromChange(*it), model_); - } - return SyncError(); - } - - private: - EntryMap* model_; -}; - ArticleEntry CreateEntry(const std::string& entry_id, const std::string& page_url1, const std::string& page_url2, @@ -128,9 +89,7 @@ public: void SetUp() override { db_model_.clear(); - sync_model_.clear(); store_model_.clear(); - next_sync_id_ = 1; } void TearDown() override { @@ -146,31 +105,15 @@ } protected: - SyncData CreateSyncData(const ArticleEntry& entry) { - EntitySpecifics specifics = SpecificsFromEntry(entry); - return SyncData::CreateRemoteData(next_sync_id_++, specifics); - } - - SyncDataList SyncDataFromEntryMap(const EntryMap& model) { - SyncDataList data; - for (auto it = model.begin(); it != model.end(); ++it) { - data.push_back(CreateSyncData(it->second)); - } - return data; - } - base::test::SingleThreadTaskEnvironment task_environment_; EntryMap db_model_; - EntryMap sync_model_; FakeDB<ArticleEntry>::EntryMap store_model_; std::unique_ptr<DomDistillerStore> store_; // Both owned by |store_|. FakeDB<ArticleEntry>* fake_db_; - - int64_t next_sync_id_; }; AssertionResult AreEntriesEqual(const DomDistillerStore::EntryVector& entries,
diff --git a/components/domain_reliability/util.cc b/components/domain_reliability/util.cc index 815e4ee..5c61a4e0 100644 --- a/components/domain_reliability/util.cc +++ b/components/domain_reliability/util.cc
@@ -134,6 +134,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_46: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_47: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_48: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_49: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_999: return "QUIC";
diff --git a/components/download/internal/common/download_job_factory.cc b/components/download/internal/common/download_job_factory.cc index cd6274c..daa7b44a 100644 --- a/components/download/internal/common/download_job_factory.cc +++ b/components/download/internal/common/download_job_factory.cc
@@ -58,6 +58,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_46: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_47: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_48: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_49: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_999: return ConnectionType::kQUIC;
diff --git a/components/history/core/browser/history_backend.cc b/components/history/core/browser/history_backend.cc index 2b39cfc..d4040fe46 100644 --- a/components/history/core/browser/history_backend.cc +++ b/components/history/core/browser/history_backend.cc
@@ -1427,11 +1427,8 @@ url_filter); MostVisitedURLList result; - for (const std::unique_ptr<PageUsageData>& current_data : data) { - RedirectList redirects = QueryRedirectsFrom(current_data->GetURL()); - result.emplace_back(current_data->GetURL(), current_data->GetTitle(), - redirects); - } + for (const std::unique_ptr<PageUsageData>& current_data : data) + result.emplace_back(current_data->GetURL(), current_data->GetTitle()); UMA_HISTOGRAM_TIMES("History.QueryMostVisitedURLsTime", base::TimeTicks::Now() - begin_time);
diff --git a/components/history/core/browser/history_service_unittest.cc b/components/history/core/browser/history_service_unittest.cc index 1baac2af..4c54e51 100644 --- a/components/history/core/browser/history_service_unittest.cc +++ b/components/history/core/browser/history_service_unittest.cc
@@ -556,7 +556,6 @@ EXPECT_EQ(url2, most_visited_urls_[1].url); EXPECT_EQ(url0, most_visited_urls_[2].url); EXPECT_EQ(url3, most_visited_urls_[3].url); - EXPECT_EQ(2U, most_visited_urls_[3].redirects.size()); } namespace {
diff --git a/components/history/core/browser/history_types.cc b/components/history/core/browser/history_types.cc index 530831a..7915c4b 100644 --- a/components/history/core/browser/history_types.cc +++ b/components/history/core/browser/history_types.cc
@@ -195,33 +195,11 @@ MostVisitedURL::MostVisitedURL(const GURL& url, const base::string16& title) : url(url), title(title) {} -MostVisitedURL::MostVisitedURL(const GURL& url, - const base::string16& title, - const RedirectList& preceding_redirects) - : url(url), title(title) { - InitRedirects(preceding_redirects); -} - MostVisitedURL::MostVisitedURL(const MostVisitedURL& other) = default; MostVisitedURL::MostVisitedURL(MostVisitedURL&& other) noexcept = default; -MostVisitedURL::~MostVisitedURL() {} - -void MostVisitedURL::InitRedirects(const RedirectList& redirects_from) { - redirects.clear(); - - if (redirects_from.empty()) { - // Redirects must contain at least the target URL. - redirects.push_back(url); - } else { - redirects = redirects_from; - if (redirects.back() != url) { - // The last url must be the target URL. - redirects.push_back(url); - } - } -} +MostVisitedURL::~MostVisitedURL() = default; MostVisitedURL& MostVisitedURL::operator=(const MostVisitedURL&) = default;
diff --git a/components/history/core/browser/history_types.h b/components/history/core/browser/history_types.h index 63f801d..3e57793 100644 --- a/components/history/core/browser/history_types.h +++ b/components/history/core/browser/history_types.h
@@ -305,27 +305,18 @@ struct MostVisitedURL { MostVisitedURL(); MostVisitedURL(const GURL& url, const base::string16& title); - MostVisitedURL(const GURL& url, - const base::string16& title, - const RedirectList& preceding_redirects); MostVisitedURL(const MostVisitedURL& other); MostVisitedURL(MostVisitedURL&& other) noexcept; ~MostVisitedURL(); - // Initializes |redirects| from |preceding_redirects|, ensuring that |url| is - // always present as the last item. - void InitRedirects(const RedirectList& preceding_redirects); - - GURL url; - base::string16 title; - - RedirectList redirects; - MostVisitedURL& operator=(const MostVisitedURL&); bool operator==(const MostVisitedURL& other) const { return url == other.url; } + + GURL url; + base::string16 title; }; // FilteredURL -----------------------------------------------------------------
diff --git a/components/history/core/browser/top_sites.cc b/components/history/core/browser/top_sites.cc index 3f5ead1c..5446d5c 100644 --- a/components/history/core/browser/top_sites.cc +++ b/components/history/core/browser/top_sites.cc
@@ -17,14 +17,11 @@ : most_visited(url, title), favicon_id(favicon_id), color(color) { - most_visited.redirects.push_back(url); } -TopSites::TopSites() { -} +TopSites::TopSites() = default; -TopSites::~TopSites() { -} +TopSites::~TopSites() = default; void TopSites::AddObserver(TopSitesObserver* observer) { observer_list_.AddObserver(observer);
diff --git a/components/history/core/browser/top_sites_database.cc b/components/history/core/browser/top_sites_database.cc index 42607274..54fcfbe 100644 --- a/components/history/core/browser/top_sites_database.cc +++ b/components/history/core/browser/top_sites_database.cc
@@ -32,7 +32,8 @@ // will be the next one evicted. // title The title to display under that site. // redirects A space separated list of URLs that are known to redirect -// to this url. +// to this url. As of 9/2019 this column is not used. It will +// be removed shortly. namespace { @@ -67,25 +68,6 @@ return db->Execute(kTopSitesSql); } -// Encodes redirects into a string. -std::string GetRedirects(const MostVisitedURL& url) { - std::vector<base::StringPiece> redirects; - for (const auto& redirect : url.redirects) - redirects.push_back(redirect.spec()); - return base::JoinString(redirects, " "); -} - -// Decodes redirects from a string and sets them for the url. -void SetRedirects(const std::string& redirects, MostVisitedURL* url) { - for (const std::string& redirect : base::SplitString( - redirects, base::kWhitespaceASCII, - base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) { - GURL redirect_url(redirect); - if (redirect_url.is_valid()) - url->redirects.push_back(redirect_url); - } -} - // Track various failure (and success) cases in recovery code. // // TODO(shess): The recovery code is complete, but by nature runs in challenging @@ -430,7 +412,7 @@ void TopSitesDatabase::GetSites(MostVisitedURLList* urls) { sql::Statement statement( db_->GetCachedStatement(SQL_FROM_HERE, - "SELECT url, url_rank, title, redirects " + "SELECT url, url_rank, title " "FROM top_sites ORDER BY url_rank")); if (!statement.is_valid()) { @@ -446,8 +428,6 @@ GURL gurl(statement.ColumnString(0)); url.url = gurl; url.title = statement.ColumnString16(2); - std::string redirects = statement.ColumnString(3); - SetRedirects(redirects, &url); urls->push_back(url); } } @@ -467,12 +447,11 @@ sql::Statement statement( db_->GetCachedStatement(SQL_FROM_HERE, "INSERT OR REPLACE INTO top_sites " - "(url, url_rank, title, redirects) " - "VALUES (?, ?, ?, ?)")); + "(url, url_rank, title) " + "VALUES (?, ?, ?)")); statement.BindString(0, url.url.spec()); statement.BindInt(1, kRankOfNewURL); statement.BindString16(2, url.title); - statement.BindString(3, GetRedirects(url)); if (!statement.Run()) return; @@ -483,10 +462,9 @@ bool TopSitesDatabase::UpdateSite(const MostVisitedURL& url) { sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, "UPDATE top_sites SET " - "title = ?, redirects = ?" + "title = ? " "WHERE url = ?")); statement.BindString16(0, url.title); - statement.BindString(1, GetRedirects(url)); return statement.Run(); }
diff --git a/components/history/core/browser/top_sites_impl_unittest.cc b/components/history/core/browser/top_sites_impl_unittest.cc index ffd99d1..f06649b4 100644 --- a/components/history/core/browser/top_sites_impl_unittest.cc +++ b/components/history/core/browser/top_sites_impl_unittest.cc
@@ -160,34 +160,17 @@ } // Adds a page to history. - void AddPageToHistory(const GURL& url) { - RedirectList redirects; - redirects.push_back(url); - history_service()->AddPage( - url, base::Time::Now(), reinterpret_cast<ContextID>(1), 0, GURL(), - redirects, ui::PAGE_TRANSITION_TYPED, history::SOURCE_BROWSED, false); - } - - // Adds a page to history. - void AddPageToHistory(const GURL& url, const base::string16& title) { - RedirectList redirects; - redirects.push_back(url); - history_service()->AddPage( - url, base::Time::Now(), reinterpret_cast<ContextID>(1), 0, GURL(), - redirects, ui::PAGE_TRANSITION_TYPED, history::SOURCE_BROWSED, false); - history_service()->SetPageTitle(url, title); - } - - // Adds a page to history. void AddPageToHistory(const GURL& url, - const base::string16& title, - const history::RedirectList& redirects, - base::Time time) { - history_service()->AddPage( - url, time, reinterpret_cast<ContextID>(1), 0, GURL(), - redirects, ui::PAGE_TRANSITION_TYPED, history::SOURCE_BROWSED, - false); - history_service()->SetPageTitle(url, title); + const base::string16& title = base::string16(), + base::Time time = base::Time::Now(), + RedirectList redirects = RedirectList()) { + if (redirects.empty()) + redirects.emplace_back(url); + history_service()->AddPage(url, time, reinterpret_cast<ContextID>(1), 0, + GURL(), redirects, ui::PAGE_TRANSITION_TYPED, + history::SOURCE_BROWSED, false); + if (!title.empty()) + history_service()->SetPageTitle(url, title); } // Delets a url. @@ -269,39 +252,6 @@ DISALLOW_COPY_AND_ASSIGN(TopSitesImplTest); }; // Class TopSitesImplTest -// Helper function for appending a URL to a vector of "most visited" URLs, -// using the default values for everything but the URL. -void AppendMostVisitedURL(const GURL& url, std::vector<MostVisitedURL>* list) { - MostVisitedURL mv; - mv.url = url; - mv.redirects.push_back(url); - list->push_back(mv); -} - -// Same as AppendMostVisitedURL except that it adds a redirect from the first -// URL to the second. -void AppendMostVisitedURLWithRedirect(const GURL& redirect_source, - const GURL& redirect_dest, - std::vector<MostVisitedURL>* list) { - MostVisitedURL mv; - mv.url = redirect_dest; - mv.redirects.push_back(redirect_source); - mv.redirects.push_back(redirect_dest); - list->push_back(mv); -} - -// Helper function for appending a URL to a vector of "most visited" URLs, -// using the default values for everything but the URL and the title. -void AppendMostVisitedURLwithTitle(const GURL& url, - const base::string16& title, - std::vector<MostVisitedURL>* list) { - MostVisitedURL mv; - mv.url = url; - mv.title = title; - mv.redirects.push_back(url); - list->push_back(mv); -} - class MockTopSitesObserver : public TopSitesObserver { public: MockTopSitesObserver() {} @@ -334,7 +284,7 @@ // TopSites has a new list of sites and should notify its observers. std::vector<MostVisitedURL> list_1; - AppendMostVisitedURLwithTitle(url_1, title_1, &list_1); + list_1.emplace_back(url_1, title_1); SetTopSites(list_1); EXPECT_TRUE(observer.is_notified()); observer.ResetIsNotifiedState(); @@ -343,8 +293,8 @@ // list_1 and list_2 have different sizes. TopSites should notify its // observers. std::vector<MostVisitedURL> list_2; - AppendMostVisitedURLwithTitle(url_1, title_1, &list_2); - AppendMostVisitedURLwithTitle(url_2, title_2, &list_2); + list_2.emplace_back(url_1, title_1); + list_2.emplace_back(url_2, title_2); SetTopSites(list_2); EXPECT_TRUE(observer.is_notified()); observer.ResetIsNotifiedState(); @@ -352,14 +302,14 @@ // list_1 and list_2 are exactly the same now. TopSites should not notify its // observers. - AppendMostVisitedURLwithTitle(url_2, title_2, &list_1); + list_1.emplace_back(url_2, title_2); SetTopSites(list_1); EXPECT_FALSE(observer.is_notified()); // Change |url_2|'s title to |title_1| in list_2. The two lists are different // in titles now. TopSites should notify its observers. list_2.pop_back(); - AppendMostVisitedURLwithTitle(url_2, title_1, &list_2); + list_2.emplace_back(url_2, title_1); SetTopSites(list_2); EXPECT_TRUE(observer.is_notified()); @@ -375,15 +325,15 @@ GURL gets_moved_1("http://getsmoved1/"); std::vector<MostVisitedURL> old_list; - AppendMostVisitedURL(stays_the_same, &old_list); // 0 (unchanged) - AppendMostVisitedURL(gets_deleted_1, &old_list); // 1 (deleted) - AppendMostVisitedURL(gets_moved_1, &old_list); // 2 (moved to 3) + old_list.emplace_back(stays_the_same, base::string16()); // 0 (unchanged) + old_list.emplace_back(gets_deleted_1, base::string16()); // 1 (deleted) + old_list.emplace_back(gets_moved_1, base::string16()); // 2 (moved to 3) std::vector<MostVisitedURL> new_list; - AppendMostVisitedURL(stays_the_same, &new_list); // 0 (unchanged) - AppendMostVisitedURL(gets_added_1, &new_list); // 1 (added) - AppendMostVisitedURL(gets_added_2, &new_list); // 2 (added) - AppendMostVisitedURL(gets_moved_1, &new_list); // 3 (moved from 2) + new_list.emplace_back(stays_the_same, base::string16()); // 0 (unchanged) + new_list.emplace_back(gets_added_1, base::string16()); // 1 (added) + new_list.emplace_back(gets_added_2, base::string16()); // 2 (added) + new_list.emplace_back(gets_moved_1, base::string16()); // 3 (moved from 2) history::TopSitesDelta delta; TopSitesImpl::DiffMostVisited(old_list, new_list, &delta); @@ -431,9 +381,8 @@ GURL www("https://www.cnn.com/"); GURL edition("https://edition.cnn.com/"); - AddPageToHistory(edition, base::ASCIIToUTF16("CNN"), - history::RedirectList{bare, www, edition}, - base::Time::Now()); + AddPageToHistory(edition, base::ASCIIToUTF16("CNN"), base::Time::Now(), + history::RedirectList{bare, www, edition}); AddPageToHistory(edition); StartQueryForMostVisited(); @@ -492,7 +441,6 @@ MostVisitedURL url2; url2.url = google_url; url2.title = google_title; - url2.redirects.push_back(url2.url); AddPageToHistory(url2.url, url2.title); @@ -525,10 +473,9 @@ url.url = asdf_url; url.title = asdf_title; - url.redirects.push_back(url.url); base::Time add_time(base::Time::Now()); - AddPageToHistory(url.url, url.title, url.redirects, add_time); + AddPageToHistory(url.url, url.title, add_time); RefreshTopSitesAndRecreate(); @@ -545,15 +492,16 @@ MostVisitedURL url2; url2.url = google3_url; url2.title = google_title; - url2.redirects.push_back(google1_url); - url2.redirects.push_back(google2_url); - url2.redirects.push_back(google3_url); + history::RedirectList url2_redirects; + url2_redirects.push_back(google1_url); + url2_redirects.push_back(google2_url); + url2_redirects.push_back(google3_url); - AddPageToHistory(google3_url, url2.title, url2.redirects, - add_time - base::TimeDelta::FromMinutes(1)); + AddPageToHistory(google3_url, url2.title, + add_time - base::TimeDelta::FromMinutes(1), url2_redirects); // Add google twice so that it becomes the first visited site. - AddPageToHistory(google3_url, url2.title, url2.redirects, - add_time - base::TimeDelta::FromMinutes(2)); + AddPageToHistory(google3_url, url2.title, + add_time - base::TimeDelta::FromMinutes(2), url2_redirects); RefreshTopSitesAndRecreate(); @@ -565,7 +513,6 @@ ASSERT_EQ(2u + GetPrepopulatedPages().size(), querier.urls().size()); EXPECT_EQ(google1_url, querier.urls()[0].url); EXPECT_EQ(google_title, querier.urls()[0].title); - ASSERT_EQ(3u, querier.urls()[0].redirects.size()); EXPECT_EQ(asdf_url, querier.urls()[1].url); EXPECT_EQ(asdf_title, querier.urls()[1].title); @@ -687,10 +634,8 @@ MostVisitedURLList pages; MostVisitedURL url; url.url = GURL("http://1.com/"); - url.redirects.push_back(url.url); pages.push_back(url); url.url = GURL("http://2.com/"); - url.redirects.push_back(url.url); pages.push_back(url); SetTopSites(pages); @@ -720,7 +665,6 @@ // Reset the top sites again, this time don't reload. url.url = GURL("http://3.com/"); - url.redirects.push_back(url.url); pages.push_back(url); SetTopSites(pages); @@ -774,10 +718,8 @@ MostVisitedURLList pages; MostVisitedURL url, url1; url.url = GURL("http://bbc.com/"); - url.redirects.push_back(url.url); pages.push_back(url); url1.url = GURL("http://google.com/"); - url1.redirects.push_back(url1.url); pages.push_back(url1); SetTopSites(pages); @@ -838,10 +780,8 @@ MostVisitedURLList pages; MostVisitedURL url, url1; url.url = GURL("http://bbc.com/"); - url.redirects.push_back(url.url); pages.push_back(url); url1.url = GURL("http://google.com/"); - url1.redirects.push_back(url1.url); pages.push_back(url1); SetTopSites(pages);
diff --git a/components/offline_pages/core/offline_clock.cc b/components/offline_pages/core/offline_clock.cc index 60fc4b0..e39d794b 100644 --- a/components/offline_pages/core/offline_clock.cc +++ b/components/offline_pages/core/offline_clock.cc
@@ -11,16 +11,16 @@ namespace offline_pages { namespace { -base::Clock* custom_clock_ = nullptr; +const base::Clock* custom_clock_ = nullptr; } -base::Clock* OfflineClock() { +const base::Clock* OfflineClock() { if (custom_clock_) return custom_clock_; return base::DefaultClock::GetInstance(); } -void SetOfflineClockForTesting(base::Clock* clock) { +void SetOfflineClockForTesting(const base::Clock* clock) { DCHECK(clock == nullptr || custom_clock_ == nullptr) << "Offline clock is being overridden a second time, which might " "indicate a bug.";
diff --git a/components/offline_pages/core/offline_clock.h b/components/offline_pages/core/offline_clock.h index 5cf384c..695ee67 100644 --- a/components/offline_pages/core/offline_clock.h +++ b/components/offline_pages/core/offline_clock.h
@@ -14,11 +14,11 @@ // Returns the clock to be used for obtaining the current time. This function // can be called from any threads. -base::Clock* OfflineClock(); +const base::Clock* OfflineClock(); // Allows tests to override the clock returned by |OfflineClock()|. For safety, // use |TestScopedOfflineClock| instead if possible. -void SetOfflineClockForTesting(base::Clock* clock); +void SetOfflineClockForTesting(const base::Clock* clock); // Returns the current time given by |OfflineClock|. This used as a shortcut // for calls to |OfflineClock()->Now()|
diff --git a/components/offline_pages/core/prefetch/store/prefetch_downloader_quota.cc b/components/offline_pages/core/prefetch/store/prefetch_downloader_quota.cc index c6b4ac7..3f6edc3 100644 --- a/components/offline_pages/core/prefetch/store/prefetch_downloader_quota.cc +++ b/components/offline_pages/core/prefetch/store/prefetch_downloader_quota.cc
@@ -36,7 +36,7 @@ } // namespace PrefetchDownloaderQuota::PrefetchDownloaderQuota(sql::Database* db, - base::Clock* clock) + const base::Clock* clock) : db_(db), clock_(clock) { DCHECK(db_); DCHECK(clock_);
diff --git a/components/offline_pages/core/prefetch/store/prefetch_downloader_quota.h b/components/offline_pages/core/prefetch/store/prefetch_downloader_quota.h index 7abb791..411aafff 100644 --- a/components/offline_pages/core/prefetch/store/prefetch_downloader_quota.h +++ b/components/offline_pages/core/prefetch/store/prefetch_downloader_quota.h
@@ -25,7 +25,7 @@ // Public for unit tests. static const int64_t kDefaultMaxDailyQuotaBytes; - PrefetchDownloaderQuota(sql::Database* db, base::Clock* clock); + PrefetchDownloaderQuota(sql::Database* db, const base::Clock* clock); ~PrefetchDownloaderQuota(); // Gets the max daily quota from Finch. @@ -44,7 +44,7 @@ sql::Database* db_; // Clock used for time related calculation and quota updates in DB. Not owned. - base::Clock* clock_; + const base::Clock* clock_; DISALLOW_COPY_AND_ASSIGN(PrefetchDownloaderQuota); };
diff --git a/components/offline_pages/core/test_scoped_offline_clock.cc b/components/offline_pages/core/test_scoped_offline_clock.cc index 1374c3d9..0166d64 100644 --- a/components/offline_pages/core/test_scoped_offline_clock.cc +++ b/components/offline_pages/core/test_scoped_offline_clock.cc
@@ -9,7 +9,7 @@ namespace offline_pages { TestScopedOfflineClockOverride::TestScopedOfflineClockOverride( - base::Clock* clock) { + const base::Clock* clock) { SetOfflineClockForTesting(clock); }
diff --git a/components/offline_pages/core/test_scoped_offline_clock.h b/components/offline_pages/core/test_scoped_offline_clock.h index 00a5775..322afe9 100644 --- a/components/offline_pages/core/test_scoped_offline_clock.h +++ b/components/offline_pages/core/test_scoped_offline_clock.h
@@ -14,7 +14,7 @@ // |OfflineClock()| to its original state upon destruction. class TestScopedOfflineClockOverride { public: - explicit TestScopedOfflineClockOverride(base::Clock* clock); + explicit TestScopedOfflineClockOverride(const base::Clock* clock); ~TestScopedOfflineClockOverride(); private:
diff --git a/components/page_load_metrics/browser/protocol_util.cc b/components/page_load_metrics/browser/protocol_util.cc index 3769048..3dc0c31 100644 --- a/components/page_load_metrics/browser/protocol_util.cc +++ b/components/page_load_metrics/browser/protocol_util.cc
@@ -40,6 +40,7 @@ case net::HttpResponseInfo::CONNECTION_INFO_QUIC_46: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_47: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_48: + case net::HttpResponseInfo::CONNECTION_INFO_QUIC_49: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_99: case net::HttpResponseInfo::CONNECTION_INFO_QUIC_999: return NetworkProtocol::kQuic;
diff --git a/components/paint_preview/common/BUILD.gn b/components/paint_preview/common/BUILD.gn index 270c99e..a8ab99b 100644 --- a/components/paint_preview/common/BUILD.gn +++ b/components/paint_preview/common/BUILD.gn
@@ -11,6 +11,8 @@ "file_stream.h", "glyph_usage.cc", "glyph_usage.h", + "serial_utils.cc", + "serial_utils.h", "subset_font.cc", "subset_font.h", ] @@ -28,6 +30,7 @@ sources = [ "file_stream_unittest.cc", "glyph_usage_unittest.cc", + "serial_utils_unittest.cc", "subset_font_unittest.cc", ]
diff --git a/components/paint_preview/common/serial_utils.cc b/components/paint_preview/common/serial_utils.cc new file mode 100644 index 0000000..e74c492 --- /dev/null +++ b/components/paint_preview/common/serial_utils.cc
@@ -0,0 +1,99 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/paint_preview/common/serial_utils.h" + +#include "components/paint_preview/common/subset_font.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkPictureRecorder.h" + +namespace paint_preview { + +namespace { + +// Serializes a SkPicture representing a subframe as a custom data placeholder. +sk_sp<SkData> SerializeSubframe(SkPicture* picture, void* ctx) { + const PictureSerializationContext* context = + reinterpret_cast<PictureSerializationContext*>(ctx); + uint32_t content_id = picture->uniqueID(); + if (context->count(content_id)) + return SkData::MakeWithCopy(&content_id, sizeof(content_id)); + // Defers picture serialization behavior to Skia. + return nullptr; +} + +// De-duplicates and subsets used typefaces and discards any unused typefaces. +sk_sp<SkData> SerializeTypeface(SkTypeface* typeface, void* ctx) { + TypefaceSerializationContext* context = + reinterpret_cast<TypefaceSerializationContext*>(ctx); + + if (context->finished.count(typeface->uniqueID())) + return typeface->serialize(SkTypeface::SerializeBehavior::kDontIncludeData); + context->finished.insert(typeface->uniqueID()); + + auto usage_it = context->usage->find(typeface->uniqueID()); + if (usage_it == context->usage->end()) + return typeface->serialize(SkTypeface::SerializeBehavior::kDontIncludeData); + + auto subset_data = SubsetFont(typeface, *usage_it->second); + // This will fail if the font cannot be subsetted properly. In such cases + // all typeface data should be added for portability. + if (!subset_data) + return typeface->serialize(SkTypeface::SerializeBehavior::kDoIncludeData); + return subset_data; +} + +// Deserializies a SkPicture within the main SkPicture. These represent +// subframes and require special decoding as they are custom data rather than a +// valid SkPicture. +// Precondition: the version of the SkPicture should be checked prior to +// invocation to ensure deserialization will succeed. +sk_sp<SkPicture> DeserializeSubframe(const void* data, + size_t length, + void* ctx) { + uint32_t content_id; + if (length < sizeof(content_id)) + return MakeEmptyPicture(); + memcpy(&content_id, data, sizeof(content_id)); + auto* context = reinterpret_cast<DeserializationContext*>(ctx); + auto it = context->find(content_id); + if (it == context->end() || !it->second) + return MakeEmptyPicture(); + return it->second; +} + +} // namespace + +TypefaceSerializationContext::TypefaceSerializationContext( + TypefaceUsageMap* usage) + : usage(usage) {} +TypefaceSerializationContext::~TypefaceSerializationContext() = default; + +sk_sp<SkPicture> MakeEmptyPicture() { + // Effectively a no-op. + SkPictureRecorder rec; + rec.beginRecording(1, 1); + return rec.finishRecordingAsPicture(); +} + +SkSerialProcs MakeSerialProcs(PictureSerializationContext* picture_ctx, + TypefaceSerializationContext* typeface_ctx) { + SkSerialProcs procs; + procs.fPictureProc = SerializeSubframe; + procs.fPictureCtx = picture_ctx; + procs.fTypefaceProc = SerializeTypeface; + procs.fTypefaceCtx = typeface_ctx; + // TODO(crbug/1008875): find a consistently smaller and low-memory overhead + // image downsampling method to use as fImageProc. + return procs; +} + +SkDeserialProcs MakeDeserialProcs(DeserializationContext* ctx) { + SkDeserialProcs procs; + procs.fPictureProc = DeserializeSubframe; + procs.fPictureCtx = ctx; + return procs; +} + +} // namespace paint_preview
diff --git a/components/paint_preview/common/serial_utils.h b/components/paint_preview/common/serial_utils.h new file mode 100644 index 0000000..5a61c4af --- /dev/null +++ b/components/paint_preview/common/serial_utils.h
@@ -0,0 +1,53 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_PAINT_PREVIEW_COMMON_SERIAL_UTILS_H_ +#define COMPONENTS_PAINT_PREVIEW_COMMON_SERIAL_UTILS_H_ + +#include <memory> + +#include "base/containers/flat_map.h" +#include "base/containers/flat_set.h" +#include "base/files/file.h" +#include "components/paint_preview/common/glyph_usage.h" +#include "third_party/skia/include/core/SkPicture.h" +#include "third_party/skia/include/core/SkRefCnt.h" +#include "third_party/skia/include/core/SkSerialProcs.h" +#include "third_party/skia/include/core/SkTypeface.h" + +namespace paint_preview { + +// Maps a content ID to a frame ID (Process ID || Routing ID). +using PictureSerializationContext = base::flat_map<uint32_t, int64_t>; + +// Maps a typeface ID to a glyph usage tracker. +using TypefaceUsageMap = base::flat_map<SkFontID, std::unique_ptr<GlyphUsage>>; + +// Tracks typeface deduplication and handles subsetting. +struct TypefaceSerializationContext { + TypefaceSerializationContext(TypefaceUsageMap* usage); + ~TypefaceSerializationContext(); + + TypefaceUsageMap* usage; + base::flat_set<SkFontID> finished; // Should be empty on first use. +}; + +// Maps a content ID to a SkPicture. +using DeserializationContext = base::flat_map<uint32_t, sk_sp<SkPicture>>; + +// Creates a no-op SkPicture. +sk_sp<SkPicture> MakeEmptyPicture(); + +// Creates a SkSerialProcs object. The object *does not* copy |picture_ctx| or +// |typeface_ctx| so they must outlive the use of the returned object. +SkSerialProcs MakeSerialProcs(PictureSerializationContext* picture_ctx, + TypefaceSerializationContext* typeface_ctx); + +// Creates a SkDeserialProcs object. The object *does not* copy |ctx| so |ctx| +// must outlive the use of the returned object. +SkDeserialProcs MakeDeserialProcs(DeserializationContext* ctx); + +} // namespace paint_preview + +#endif // COMPONENTS_PAINT_PREVIEW_COMMON_SERIAL_UTILS_H_
diff --git a/components/paint_preview/common/serial_utils_unittest.cc b/components/paint_preview/common/serial_utils_unittest.cc new file mode 100644 index 0000000..5795f11 --- /dev/null +++ b/components/paint_preview/common/serial_utils_unittest.cc
@@ -0,0 +1,137 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/paint_preview/common/serial_utils.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkPicture.h" +#include "third_party/skia/include/core/SkRefCnt.h" +#include "third_party/skia/include/core/SkSerialProcs.h" +#include "third_party/skia/include/core/SkTypeface.h" + +namespace paint_preview { + +TEST(PaintPreviewSerialUtils, TestMakeEmptyPicture) { + sk_sp<SkPicture> pic = MakeEmptyPicture(); + ASSERT_NE(pic, nullptr); + auto data = pic->serialize(); + ASSERT_NE(data, nullptr); + EXPECT_GE(data->size(), 0U); +} + +TEST(PaintPreviewSerialUtils, TestPictureProcs) { + auto pic = MakeEmptyPicture(); + uint32_t content_id = pic->uniqueID(); + const uint64_t kFrameGuid = 2; + PictureSerializationContext picture_ctx; + EXPECT_TRUE( + picture_ctx.insert(std::make_pair(content_id, kFrameGuid)).second); + + DeserializationContext deserial_ctx; + EXPECT_TRUE(deserial_ctx.insert(std::make_pair(content_id, pic)).second); + + TypefaceUsageMap usage_map; + TypefaceSerializationContext typeface_ctx(&usage_map); + + SkSerialProcs serial_procs = MakeSerialProcs(&picture_ctx, &typeface_ctx); + EXPECT_EQ(serial_procs.fPictureCtx, &picture_ctx); + EXPECT_EQ(serial_procs.fTypefaceCtx, &typeface_ctx); + + SkDeserialProcs deserial_procs = MakeDeserialProcs(&deserial_ctx); + EXPECT_EQ(deserial_procs.fPictureCtx, &deserial_ctx); + + // Check that serializing then deserialize the picture works. + sk_sp<SkData> serial_pic_data = + serial_procs.fPictureProc(pic.get(), serial_procs.fPictureCtx); + sk_sp<SkPicture> deserial_pic = deserial_procs.fPictureProc( + serial_pic_data->data(), serial_pic_data->size(), + deserial_procs.fPictureCtx); + EXPECT_EQ(deserial_pic->uniqueID(), content_id); +} + +TEST(PaintPreviewSerialUtils, TestSerialPictureNotInMap) { + PictureSerializationContext picture_ctx; + + TypefaceUsageMap usage_map; + TypefaceSerializationContext typeface_ctx(&usage_map); + + SkSerialProcs serial_procs = MakeSerialProcs(&picture_ctx, &typeface_ctx); + EXPECT_EQ(serial_procs.fPictureCtx, &picture_ctx); + EXPECT_EQ(serial_procs.fTypefaceCtx, &typeface_ctx); + + auto pic = MakeEmptyPicture(); + EXPECT_EQ(serial_procs.fPictureProc(pic.get(), serial_procs.fPictureCtx), + nullptr); +} + +TEST(PaintPreviewSerialUtils, TestDeserialPictureNotInMap) { + uint32_t empty_content_id = 5; + DeserializationContext deserial_ctx; + EXPECT_TRUE( + deserial_ctx.insert(std::make_pair(empty_content_id, nullptr)).second); + SkDeserialProcs deserial_procs = MakeDeserialProcs(&deserial_ctx); + EXPECT_EQ(deserial_procs.fPictureCtx, &deserial_ctx); + + sk_sp<SkPicture> deserial_pic = + deserial_procs.fPictureProc(nullptr, 0U, deserial_procs.fPictureCtx); + EXPECT_NE(deserial_pic, nullptr); // Produce empty pic rather than nullptr. + + uint32_t missing_content_id = 5; + deserial_pic = deserial_procs.fPictureProc(&missing_content_id, + sizeof(missing_content_id), + deserial_procs.fPictureCtx); + EXPECT_NE(deserial_pic, nullptr); // Produce empty pic rather than nullptr. + + deserial_pic = deserial_procs.fPictureProc( + &empty_content_id, sizeof(empty_content_id), deserial_procs.fPictureCtx); + EXPECT_NE(deserial_pic, nullptr); // Produce empty pic rather than nullptr. +} + +TEST(PaintPreviewSerialUtils, TestSerialTypeface) { + PictureSerializationContext picture_ctx; + + auto typeface = SkTypeface::MakeDefault(); + TypefaceUsageMap usage_map; + std::unique_ptr<GlyphUsage> usage = + std::make_unique<SparseGlyphUsage>(typeface->countGlyphs()); + usage->Set(0); + usage->Set('a'); + usage->Set('b'); + EXPECT_TRUE( + usage_map.insert(std::make_pair(typeface->uniqueID(), std::move(usage))) + .second); + TypefaceSerializationContext typeface_ctx(&usage_map); + + SkSerialProcs serial_procs = MakeSerialProcs(&picture_ctx, &typeface_ctx); + EXPECT_EQ(serial_procs.fPictureCtx, &picture_ctx); + EXPECT_EQ(serial_procs.fTypefaceCtx, &typeface_ctx); + + EXPECT_NE( + serial_procs.fTypefaceProc(typeface.get(), serial_procs.fTypefaceCtx), + nullptr); + EXPECT_GT(typeface_ctx.finished.count(typeface->uniqueID()), 0U); +} + +TEST(PaintPreviewSerialUtils, TestSerialNoTypefaceInMap) { + PictureSerializationContext picture_ctx; + + auto typeface = SkTypeface::MakeDefault(); + TypefaceUsageMap usage_map; + TypefaceSerializationContext typeface_ctx(&usage_map); + + SkSerialProcs serial_procs = MakeSerialProcs(&picture_ctx, &typeface_ctx); + EXPECT_EQ(serial_procs.fPictureCtx, &picture_ctx); + EXPECT_EQ(serial_procs.fTypefaceCtx, &typeface_ctx); + + EXPECT_NE( + serial_procs.fTypefaceProc(typeface.get(), serial_procs.fTypefaceCtx), + nullptr); + EXPECT_GT(typeface_ctx.finished.count(typeface->uniqueID()), 0U); + // Still serialize font metadata for lookup if the font is serialized again. + EXPECT_NE( + serial_procs.fTypefaceProc(typeface.get(), serial_procs.fTypefaceCtx), + nullptr); +} + +} // namespace paint_preview
diff --git a/components/password_manager/content/browser/content_password_manager_driver.h b/components/password_manager/content/browser/content_password_manager_driver.h index e9bece9..46e35d2 100644 --- a/components/password_manager/content/browser/content_password_manager_driver.h +++ b/components/password_manager/content/browser/content_password_manager_driver.h
@@ -13,7 +13,6 @@ #include "base/macros.h" #include "components/autofill/content/common/mojom/autofill_agent.mojom.h" #include "components/autofill/content/common/mojom/autofill_driver.mojom.h" -#include "components/autofill/core/common/password_form_field_prediction_map.h" #include "components/autofill/core/common/password_form_generation_data.h" #include "components/password_manager/core/browser/password_autofill_manager.h" #include "components/password_manager/core/browser/password_generation_frame_helper.h"
diff --git a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc index 447b6f3c..6bcae96 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -421,8 +421,8 @@ TEST(FormParserTest, NotPasswordForm) { CheckTestData({ { - "No fields", - {}, + .description_for_logging = "No fields", + .fields = {}, }, { .description_for_logging = "No password fields", @@ -440,13 +440,15 @@ TEST(FormParserTest, SkipNotTextFields) { CheckTestData({ { - "A 'select' between username and password fields", - { - {.role = ElementRole::USERNAME}, - {.form_control_type = "select"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = + "A 'select' between username and password fields", + .fields = + { + {.role = ElementRole::USERNAME}, + {.form_control_type = "select"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, .number_of_all_possible_passwords = 1, .number_of_all_possible_usernames = 1, }, @@ -466,42 +468,48 @@ .number_of_all_possible_usernames = 0, }, { - "2 password fields, new and confirmation password", - { - {.role = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .value = "pw"}, - {.role = ElementRole::CONFIRMATION_PASSWORD, - .form_control_type = "password", - .value = "pw"}, - }, + .description_for_logging = + "2 password fields, new and confirmation password", + .fields = + { + {.role = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .value = "pw"}, + {.role = ElementRole::CONFIRMATION_PASSWORD, + .form_control_type = "password", + .value = "pw"}, + }, .is_new_password_reliable = false, }, { - "2 password fields, current and new password", - { - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .value = "pw1"}, - {.role = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .value = "pw2"}, - }, + .description_for_logging = + "2 password fields, current and new password", + .fields = + { + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .value = "pw1"}, + {.role = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .value = "pw2"}, + }, .is_new_password_reliable = false, }, { - "3 password fields, current, new, confirm password", - { - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .value = "pw1"}, - {.role = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .value = "pw2"}, - {.role = ElementRole::CONFIRMATION_PASSWORD, - .form_control_type = "password", - .value = "pw2"}, - }, + .description_for_logging = + "3 password fields, current, new, confirm password", + .fields = + { + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .value = "pw1"}, + {.role = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .value = "pw2"}, + {.role = ElementRole::CONFIRMATION_PASSWORD, + .form_control_type = "password", + .value = "pw2"}, + }, .is_new_password_reliable = false, }, { @@ -517,46 +525,51 @@ .number_of_all_possible_passwords = 3, }, { - "4 password fields, only the first 3 are considered", - { - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .value = "pw1"}, - {.role = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .value = "pw2"}, - {.role = ElementRole::CONFIRMATION_PASSWORD, - .form_control_type = "password", - .value = "pw2"}, - {.form_control_type = "password", .value = "pw3"}, - }, + .description_for_logging = + "4 password fields, only the first 3 are considered", + .fields = + { + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .value = "pw1"}, + {.role = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .value = "pw2"}, + {.role = ElementRole::CONFIRMATION_PASSWORD, + .form_control_type = "password", + .value = "pw2"}, + {.form_control_type = "password", .value = "pw3"}, + }, }, { - "4 password fields, 4th same value as 3rd and 2nd, only the first 3 " - "are considered", - { - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .value = "pw1"}, - {.role = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .value = "pw2"}, - {.role = ElementRole::CONFIRMATION_PASSWORD, - .form_control_type = "password", - .value = "pw2"}, - {.form_control_type = "password", .value = "pw2"}, - }, + .description_for_logging = "4 password fields, 4th same value as 3rd " + "and 2nd, only the first 3 " + "are considered", + .fields = + { + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .value = "pw1"}, + {.role = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .value = "pw2"}, + {.role = ElementRole::CONFIRMATION_PASSWORD, + .form_control_type = "password", + .value = "pw2"}, + {.form_control_type = "password", .value = "pw2"}, + }, }, { - "4 password fields, all same value", - { - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .value = "pw"}, - {.form_control_type = "password", .value = "pw"}, - {.form_control_type = "password", .value = "pw"}, - {.form_control_type = "password", .value = "pw"}, - }, + .description_for_logging = "4 password fields, all same value", + .fields = + { + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .value = "pw"}, + {.form_control_type = "password", .value = "pw"}, + {.form_control_type = "password", .value = "pw"}, + {.form_control_type = "password", .value = "pw"}, + }, }, }); } @@ -564,50 +577,58 @@ TEST(FormParserTest, TestFocusability) { CheckTestData({ { - "non-focusable fields are considered when there are no focusable " - "fields", - { - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .is_focusable = false}, - {.role = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .is_focusable = false}, - }, + .description_for_logging = + "non-focusable fields are considered when there are no focusable " + "fields", + .fields = + { + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .is_focusable = false}, + {.role = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .is_focusable = false}, + }, }, { - "non-focusable should be skipped when there are focusable fields", - { - {.form_control_type = "password", .is_focusable = false}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .is_focusable = true}, - }, + .description_for_logging = + "non-focusable should be skipped when there are focusable fields", + .fields = + { + {.form_control_type = "password", .is_focusable = false}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .is_focusable = true}, + }, }, { - "non-focusable text fields before password", - { - {.form_control_type = "text", .is_focusable = false}, - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .is_focusable = false}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .is_focusable = true}, - }, + .description_for_logging = + "non-focusable text fields before password", + .fields = + { + {.form_control_type = "text", .is_focusable = false}, + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .is_focusable = false}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .is_focusable = true}, + }, .number_of_all_possible_usernames = 2, }, { - "focusable and non-focusable text fields before password", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .is_focusable = true}, - {.form_control_type = "text", .is_focusable = false}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .is_focusable = true}, - }, + .description_for_logging = + "focusable and non-focusable text fields before password", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .is_focusable = true}, + {.form_control_type = "text", .is_focusable = false}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .is_focusable = true}, + }, }, { .description_for_logging = "many passwords, some of them focusable", @@ -641,17 +662,18 @@ TEST(FormParserTest, TextAndPasswordFields) { CheckTestData({ { - "Simple empty sign-in form", + .description_for_logging = "Simple empty sign-in form", // Forms with empty fields cannot be saved, so the parsing result for // saving is empty. - { - {.role_filling = ElementRole::USERNAME, - .form_control_type = "text", - .value = ""}, - {.role_filling = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .value = ""}, - }, + .fields = + { + {.role_filling = ElementRole::USERNAME, + .form_control_type = "text", + .value = ""}, + {.role_filling = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .value = ""}, + }, // all_possible_* only count fields with non-empty values. .number_of_all_possible_passwords = 0, .number_of_all_possible_usernames = 0, @@ -667,87 +689,103 @@ .number_of_all_possible_passwords = 1, }, { - "Empty sign-in form with an extra text field", - { - {.form_control_type = "text", .value = ""}, - {.role_filling = ElementRole::USERNAME, - .form_control_type = "text", - .value = ""}, - {.role_filling = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .value = ""}, - }, + .description_for_logging = + "Empty sign-in form with an extra text field", + .fields = + { + {.form_control_type = "text", .value = ""}, + {.role_filling = ElementRole::USERNAME, + .form_control_type = "text", + .value = ""}, + {.role_filling = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .value = ""}, + }, }, { - "Non-empty sign-in form with an extra text field", - { - {.role_saving = ElementRole::USERNAME, - .form_control_type = "text"}, - {.role_filling = ElementRole::USERNAME, - .form_control_type = "text", - .value = ""}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = + "Non-empty sign-in form with an extra text field", + .fields = + { + {.role_saving = ElementRole::USERNAME, + .form_control_type = "text"}, + {.role_filling = ElementRole::USERNAME, + .form_control_type = "text", + .value = ""}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, }, { - "Empty sign-in form with an extra invisible text field", - { - {.role_filling = ElementRole::USERNAME, - .form_control_type = "text", - .value = ""}, - {.form_control_type = "text", .is_focusable = false, .value = ""}, - {.role_filling = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .value = ""}, - }, + .description_for_logging = + "Empty sign-in form with an extra invisible text field", + .fields = + { + {.role_filling = ElementRole::USERNAME, + .form_control_type = "text", + .value = ""}, + {.form_control_type = "text", + .is_focusable = false, + .value = ""}, + {.role_filling = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .value = ""}, + }, }, { - "Non-empty sign-in form with an extra invisible text field", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.form_control_type = "text", .is_focusable = false}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = + "Non-empty sign-in form with an extra invisible text field", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.form_control_type = "text", .is_focusable = false}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, }, { - "Simple empty sign-in form with empty username", + .description_for_logging = + "Simple empty sign-in form with empty username", // Filled forms with a username field which is left empty are // suspicious. The parser will just omit the username altogether. - { - {.role_filling = ElementRole::USERNAME, - .form_control_type = "text", - .value = ""}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .fields = + { + {.role_filling = ElementRole::USERNAME, + .form_control_type = "text", + .value = ""}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, }, { - "Simple empty sign-in form with empty password", + .description_for_logging = + "Simple empty sign-in form with empty password", // Empty password, nothing to save. - { - {.role_filling = ElementRole::USERNAME, - .form_control_type = "text"}, - {.role_filling = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .value = ""}, - }, + .fields = + { + {.role_filling = ElementRole::USERNAME, + .form_control_type = "text"}, + {.role_filling = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .value = ""}, + }, }, }); } TEST(FormParserTest, TextFieldValueIsNotUsername) { CheckTestData({{ - "Text field value is unlikely username so it should be ignored on saving", - { - {.role_filling = ElementRole::USERNAME, - .form_control_type = "text", - .value = "12"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .value = "strong_pw"}, - }, + .description_for_logging = "Text field value is unlikely username so it " + "should be ignored on saving", + .fields = + { + {.role_filling = ElementRole::USERNAME, + .form_control_type = "text", + .value = "12"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .value = "strong_pw"}, + }, }}); } @@ -805,109 +843,122 @@ .number_of_all_possible_usernames = 2, }, { - "Basic heuristics kick in if autocomplete analysis fails", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .autocomplete_attribute = "email"}, - // NB: 'password' is not a valid autocomplete type hint. - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .autocomplete_attribute = "password"}, - {.role = ElementRole::NEW_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = + "Basic heuristics kick in if autocomplete analysis fails", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .autocomplete_attribute = "email"}, + // NB: 'password' is not a valid autocomplete type hint. + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .autocomplete_attribute = "password"}, + {.role = ElementRole::NEW_PASSWORD, + .form_control_type = "password"}, + }, }, { - "Partial autocomplete analysis doesn't fail if no passwords are " - "found", + .description_for_logging = + "Partial autocomplete analysis doesn't fail if no passwords are " + "found", // The attribute 'username' is used even if there was no password // marked up. - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .autocomplete_attribute = "username"}, - {.form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .autocomplete_attribute = "username"}, + {.form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, }, { - "Multiple username autocomplete attributes, fallback to base " - "heuristics", - { - {.form_control_type = "text", - .autocomplete_attribute = "username"}, - {.form_control_type = "text", - .autocomplete_attribute = "username"}, - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.form_control_type = "password"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .autocomplete_attribute = "current-password"}, - }, + .description_for_logging = + "Multiple username autocomplete attributes, fallback to base " + "heuristics", + .fields = + { + {.form_control_type = "text", + .autocomplete_attribute = "username"}, + {.form_control_type = "text", + .autocomplete_attribute = "username"}, + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.form_control_type = "password"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .autocomplete_attribute = "current-password"}, + }, }, { - "Parsing complex autocomplete attributes", - { - // Valid information about form sections, in addition to the - // username hint. - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .autocomplete_attribute = "section-test billing username"}, - {.form_control_type = "text"}, - // Invalid composition, but the parser is simplistic and just - // grabs the last token. - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .autocomplete_attribute = "new-password current-password"}, - {.form_control_type = "password"}, - }, + .description_for_logging = "Parsing complex autocomplete attributes", + .fields = + { + // Valid information about form sections, in addition to the + // username hint. + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .autocomplete_attribute = "section-test billing username"}, + {.form_control_type = "text"}, + // Invalid composition, but the parser is simplistic and just + // grabs the last token. + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .autocomplete_attribute = "new-password current-password"}, + {.form_control_type = "password"}, + }, }, { - "Ignored autocomplete attributes", - { - // 'off' is ignored. - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .autocomplete_attribute = "off"}, - // Invalid composition, the parser ignores all but the last token. - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .autocomplete_attribute = "new-password abc"}, - {.role = ElementRole::NEW_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = "Ignored autocomplete attributes", + .fields = + { + // 'off' is ignored. + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .autocomplete_attribute = "off"}, + // Invalid composition, the parser ignores all but the last + // token. + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .autocomplete_attribute = "new-password abc"}, + {.role = ElementRole::NEW_PASSWORD, + .form_control_type = "password"}, + }, }, { - "Swapped username/password autocomplete attributes", + .description_for_logging = + "Swapped username/password autocomplete attributes", // Swap means ignoring autocomplete analysis and falling back to basic // heuristics. - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .autocomplete_attribute = "current-password"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - {.role = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .autocomplete_attribute = "username"}, - }, + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .autocomplete_attribute = "current-password"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + {.role = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .autocomplete_attribute = "username"}, + }, }, { - "Autocomplete mark-up overrides visibility", - { - {.role = ElementRole::USERNAME, - .is_focusable = false, - .form_control_type = "text", - .autocomplete_attribute = "username"}, - {.is_focusable = true, .form_control_type = "text"}, - {.is_focusable = true, .form_control_type = "password"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .is_focusable = false, - .autocomplete_attribute = "current-password"}, - }, + .description_for_logging = + "Autocomplete mark-up overrides visibility", + .fields = + { + {.role = ElementRole::USERNAME, + .is_focusable = false, + .form_control_type = "text", + .autocomplete_attribute = "username"}, + {.is_focusable = true, .form_control_type = "text"}, + {.is_focusable = true, .form_control_type = "password"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .is_focusable = false, + .autocomplete_attribute = "current-password"}, + }, }, }); } @@ -937,13 +988,14 @@ TEST(FormParserTest, SkippingFieldsWithCreditCardFields) { CheckTestData({ { - "Simple form, all fields are credit-card-related", - {{.role = ElementRole::USERNAME, - .form_control_type = "text", - .autocomplete_attribute = "cc-name"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .autocomplete_attribute = "cc-any-string"}}, + .description_for_logging = + "Simple form, all fields are credit-card-related", + .fields = {{.role = ElementRole::USERNAME, + .form_control_type = "text", + .autocomplete_attribute = "cc-name"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .autocomplete_attribute = "cc-any-string"}}, .fallback_only = true, }, { @@ -966,46 +1018,51 @@ TEST(FormParserTest, ReadonlyFields) { CheckTestData({ { - "For usernames, readonly does not matter", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .is_readonly = true}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = "For usernames, readonly does not matter", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .is_readonly = true}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, }, { - "For passwords, readonly means: 'give up', perhaps there is a " - "virtual keyboard, filling might be ignored", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .is_readonly = true}, - }, + .description_for_logging = + "For passwords, readonly means: 'give up', perhaps there is a " + "virtual keyboard, filling might be ignored", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .is_readonly = true}, + }, // And "give-up" means "fallback-only". .fallback_only = true, }, { - "But correctly marked passwords are accepted even if readonly", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .autocomplete_attribute = "username"}, - {.role = ElementRole::NEW_PASSWORD, - .autocomplete_attribute = "new-password", - .form_control_type = "password", - .is_readonly = true}, - {.role = ElementRole::CONFIRMATION_PASSWORD, - .autocomplete_attribute = "new-password", - .form_control_type = "password", - .is_readonly = true}, - {.role = ElementRole::CURRENT_PASSWORD, - .autocomplete_attribute = "current-password", - .form_control_type = "password", - .is_readonly = true}, - }, + .description_for_logging = + "But correctly marked passwords are accepted even if readonly", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .autocomplete_attribute = "username"}, + {.role = ElementRole::NEW_PASSWORD, + .autocomplete_attribute = "new-password", + .form_control_type = "password", + .is_readonly = true}, + {.role = ElementRole::CONFIRMATION_PASSWORD, + .autocomplete_attribute = "new-password", + .form_control_type = "password", + .is_readonly = true}, + {.role = ElementRole::CURRENT_PASSWORD, + .autocomplete_attribute = "current-password", + .form_control_type = "password", + .is_readonly = true}, + }, .is_new_password_reliable = true, }, { @@ -1056,81 +1113,98 @@ TEST(FormParserTest, ServerPredictionsForClearTextPasswordFields) { CheckTestData({ { - "Server prediction for account change password and username field.", - { + .description_for_logging = "Server prediction for account change " + "password and username field.", + .fields = { - .role_filling = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME_AND_EMAIL_ADDRESS}, + { + .role_filling = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = + autofill::USERNAME_AND_EMAIL_ADDRESS}, + }, + { + .role_filling = ElementRole::NEW_PASSWORD, + .form_control_type = "text", + .prediction = {.type = autofill::NEW_PASSWORD}, + }, }, - { - .role_filling = ElementRole::NEW_PASSWORD, - .form_control_type = "text", - .prediction = {.type = autofill::NEW_PASSWORD}, - }, - }, }, { - "Server prediction for account change password field only.", - { - {.role_filling = ElementRole::USERNAME, - .form_control_type = "text"}, + .description_for_logging = + "Server prediction for account change password field only.", + .fields = { - .role_filling = ElementRole::NEW_PASSWORD, - .form_control_type = "text", - .prediction = {.type = autofill::NEW_PASSWORD}, + {.role_filling = ElementRole::USERNAME, + .form_control_type = "text"}, + { + .role_filling = ElementRole::NEW_PASSWORD, + .form_control_type = "text", + .prediction = {.type = autofill::NEW_PASSWORD}, + }, }, - }, }, { - "Server prediction for account password and username field.", - { + .description_for_logging = + "Server prediction for account password and username field.", + .fields = { - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME_AND_EMAIL_ADDRESS}, + { + .form_control_type = "text", + .prediction = {.type = + autofill::USERNAME_AND_EMAIL_ADDRESS}, + }, + { + .form_control_type = "text", + .prediction = {.type = autofill::PASSWORD}, + }, }, - { - .form_control_type = "text", - .prediction = {.type = autofill::PASSWORD}, - }, - }, }, { - "Server prediction for account password field only.", - { - {.form_control_type = "text"}, + .description_for_logging = + "Server prediction for account password field only.", + .fields = { - .form_control_type = "text", - .prediction = {.type = autofill::PASSWORD}, + {.form_control_type = "text"}, + { + .form_control_type = "text", + .prediction = {.type = autofill::PASSWORD}, + }, }, - }, }, { - "Server prediction for account creation password and username field.", - { + .description_for_logging = "Server prediction for account creation " + "password and username field.", + .fields = { - .role_filling = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME_AND_EMAIL_ADDRESS}, + { + .role_filling = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = + autofill::USERNAME_AND_EMAIL_ADDRESS}, + }, + { + .role_filling = ElementRole::NEW_PASSWORD, + .form_control_type = "text", + .prediction = {.type = + autofill::ACCOUNT_CREATION_PASSWORD}, + }, }, - { - .role_filling = ElementRole::NEW_PASSWORD, - .form_control_type = "text", - .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}, - }, - }, }, { - "Server prediction for account creation password field only.", - { - {.role_filling = ElementRole::USERNAME, - .form_control_type = "text"}, + .description_for_logging = + "Server prediction for account creation password field only.", + .fields = { - .role_filling = ElementRole::NEW_PASSWORD, - .form_control_type = "text", - .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}, + {.role_filling = ElementRole::USERNAME, + .form_control_type = "text"}, + { + .role_filling = ElementRole::NEW_PASSWORD, + .form_control_type = "text", + .prediction = {.type = + autofill::ACCOUNT_CREATION_PASSWORD}, + }, }, - }, }, }); } @@ -1138,41 +1212,45 @@ TEST(FormParserTest, ServerHints) { CheckTestData({ { - "Empty predictions don't cause panic", - { - {.form_control_type = "text"}, - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = "Empty predictions don't cause panic", + .fields = + { + {.form_control_type = "text"}, + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, }, { - "Username-only predictions are not ignored", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = + "Username-only predictions are not ignored", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, }, { - "Simple predictions work", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME_AND_EMAIL_ADDRESS, - .may_use_prefilled_placeholder = true}}, - {.form_control_type = "text"}, - {.role_saving = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - {.role_filling = ElementRole::CURRENT_PASSWORD, - .role_saving = ElementRole::NEW_PASSWORD, - .prediction = {.type = autofill::PASSWORD, - .may_use_prefilled_placeholder = true}, - .form_control_type = "password"}, - }, + .description_for_logging = "Simple predictions work", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::USERNAME_AND_EMAIL_ADDRESS, + .may_use_prefilled_placeholder = true}}, + {.form_control_type = "text"}, + {.role_saving = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + {.role_filling = ElementRole::CURRENT_PASSWORD, + .role_saving = ElementRole::NEW_PASSWORD, + .prediction = {.type = autofill::PASSWORD, + .may_use_prefilled_placeholder = true}, + .form_control_type = "password"}, + }, .username_may_use_prefilled_placeholder = true, }, { @@ -1199,14 +1277,16 @@ .is_new_password_reliable = true, }, { - "password prediction for a non-password field is ignored", - { - {.role = ElementRole::USERNAME, - .prediction = {.type = autofill::PASSWORD}, - .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = + "password prediction for a non-password field is ignored", + .fields = + { + {.role = ElementRole::USERNAME, + .prediction = {.type = autofill::PASSWORD}, + .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, }, }); } @@ -1214,19 +1294,21 @@ TEST(FormParserTest, Interactability) { CheckTestData({ { - "If all fields are hidden, all are considered", - { - {.form_control_type = "text", .is_focusable = false}, - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .is_focusable = false}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .is_focusable = false}, - {.role = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .is_focusable = false}, - }, + .description_for_logging = + "If all fields are hidden, all are considered", + .fields = + { + {.form_control_type = "text", .is_focusable = false}, + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .is_focusable = false}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .is_focusable = false}, + {.role = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .is_focusable = false}, + }, }, { .description_for_logging = @@ -1269,37 +1351,44 @@ .form_has_autofilled_value = true, }, { - "Interactability for usernames is only considered before the first " - "relevant password. That way, if, e.g., the username gets filled and " - "hidden (to let the user enter password), and there is another text " - "field visible below, the maximum Interactability won't end up being " - "kPossible, which would exclude the hidden username.", - { - {.role = ElementRole::USERNAME, - .properties_mask = FieldPropertiesFlags::AUTOFILLED, - .form_control_type = "text", - .is_focusable = false}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .properties_mask = FieldPropertiesFlags::AUTOFILLED, - .is_focusable = true}, - {.form_control_type = "text", .is_focusable = true, .value = ""}, - }, + .description_for_logging = + "Interactability for usernames is only considered before the " + "first relevant password. That way, if, e.g., the username gets " + "filled and hidden (to let the user enter password), and there " + "is another text field visible below, the maximum " + "Interactability won't end up being kPossible, which would " + "exclude the hidden username.", + .fields = + { + {.role = ElementRole::USERNAME, + .properties_mask = FieldPropertiesFlags::AUTOFILLED, + .form_control_type = "text", + .is_focusable = false}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .properties_mask = FieldPropertiesFlags::AUTOFILLED, + .is_focusable = true}, + {.form_control_type = "text", + .is_focusable = true, + .value = ""}, + }, .form_has_autofilled_value = true, }, { - "Interactability also matters for HTML classifier.", - { - {.form_control_type = "text", - .is_focusable = false, - .predicted_username = 0}, - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .is_focusable = true}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .is_focusable = true}, - }, + .description_for_logging = + "Interactability also matters for HTML classifier.", + .fields = + { + {.form_control_type = "text", + .is_focusable = false, + .predicted_username = 0}, + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .is_focusable = true}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .is_focusable = true}, + }, }, }); } @@ -1418,64 +1507,73 @@ TEST(FormParserTest, UsernamePredictions) { CheckTestData({ { - "Username prediction overrides structure", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .predicted_username = 0}, - {.form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = "Username prediction overrides structure", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .predicted_username = 0}, + {.form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, }, { - "Username prediction does not override structure if empty and mode " - "is SAVING", - { - {.role_filling = ElementRole::USERNAME, - .form_control_type = "text", - .predicted_username = 2, - .value = ""}, - {.role_saving = ElementRole::USERNAME, - .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = "Username prediction does not override " + "structure if empty and mode " + "is SAVING", + .fields = + { + {.role_filling = ElementRole::USERNAME, + .form_control_type = "text", + .predicted_username = 2, + .value = ""}, + {.role_saving = ElementRole::USERNAME, + .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, }, { - "Username prediction does not override autocomplete analysis", - { - {.form_control_type = "text", .predicted_username = 0}, - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .autocomplete_attribute = "username"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .autocomplete_attribute = "current-password"}, - }, + .description_for_logging = + "Username prediction does not override autocomplete analysis", + .fields = + { + {.form_control_type = "text", .predicted_username = 0}, + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .autocomplete_attribute = "username"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .autocomplete_attribute = "current-password"}, + }, }, { - "Username prediction does not override server hints", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME_AND_EMAIL_ADDRESS}}, - {.form_control_type = "text", .predicted_username = 0}, - {.role = ElementRole::CURRENT_PASSWORD, - .prediction = {.type = autofill::PASSWORD}, - .form_control_type = "password"}, - }, + .description_for_logging = + "Username prediction does not override server hints", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = + autofill::USERNAME_AND_EMAIL_ADDRESS}}, + {.form_control_type = "text", .predicted_username = 0}, + {.role = ElementRole::CURRENT_PASSWORD, + .prediction = {.type = autofill::PASSWORD}, + .form_control_type = "password"}, + }, }, { - "Username prediction order matters", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .predicted_username = 1}, - {.form_control_type = "text", .predicted_username = 4}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = "Username prediction order matters", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .predicted_username = 1}, + {.form_control_type = "text", .predicted_username = 4}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, }, }); } @@ -1491,41 +1589,47 @@ TEST(FormParserTest, ComplementingResults) { CheckTestData({ { - "Current password from autocomplete analysis, username from basic " - "heuristics", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .autocomplete_attribute = "current-password"}, - }, + .description_for_logging = "Current password from autocomplete " + "analysis, username from basic " + "heuristics", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .autocomplete_attribute = "current-password"}, + }, }, { - "New and confirmation passwords from server, username from basic " - "heuristics", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role_filling = ElementRole::CONFIRMATION_PASSWORD, - .role_saving = ElementRole::CURRENT_PASSWORD, - .prediction = {.type = autofill::CONFIRMATION_PASSWORD}, - .form_control_type = "password"}, - {.role = ElementRole::NEW_PASSWORD, - .prediction = {.type = autofill::NEW_PASSWORD}, - .form_control_type = "password"}, - }, + .description_for_logging = + "New and confirmation passwords from server, username from basic " + "heuristics", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role_filling = ElementRole::CONFIRMATION_PASSWORD, + .role_saving = ElementRole::CURRENT_PASSWORD, + .prediction = {.type = autofill::CONFIRMATION_PASSWORD}, + .form_control_type = "password"}, + {.role = ElementRole::NEW_PASSWORD, + .prediction = {.type = autofill::NEW_PASSWORD}, + .form_control_type = "password"}, + }, .is_new_password_reliable = true, }, { - "No password from server still means. Username hint from server is " - "used.", - { - {.role = ElementRole::USERNAME, - .prediction = {.type = autofill::USERNAME_AND_EMAIL_ADDRESS}, - .form_control_type = "text"}, - {.form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = "No password from server still means. " + "Username hint from server is " + "used.", + .fields = + { + {.role = ElementRole::USERNAME, + .prediction = {.type = autofill::USERNAME_AND_EMAIL_ADDRESS}, + .form_control_type = "text"}, + {.form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, }, }); } @@ -1534,49 +1638,60 @@ TEST(FormParserTest, CVC) { CheckTestData({ { - "Server hints: CREDIT_CARD_VERIFICATION_CODE.", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.form_control_type = "password", - .prediction = {.type = autofill::CREDIT_CARD_VERIFICATION_CODE}}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = + "Server hints: CREDIT_CARD_VERIFICATION_CODE.", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.form_control_type = "password", + .prediction = {.type = + autofill::CREDIT_CARD_VERIFICATION_CODE}}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, // The result should be trusted for more than just fallback, because // the chosen password was not a suspected CVC. .fallback_only = false, }, { - "Server hints: CREDIT_CARD_VERIFICATION_CODE on only password.", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .prediction = {.type = autofill::CREDIT_CARD_VERIFICATION_CODE}, - .form_control_type = "password"}, - }, + .description_for_logging = + "Server hints: CREDIT_CARD_VERIFICATION_CODE on only password.", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .prediction = {.type = + autofill::CREDIT_CARD_VERIFICATION_CODE}, + .form_control_type = "password"}, + }, .fallback_only = true, }, { - "Name of 'verification_type' matches the CVC pattern, ignore that " - "one.", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.form_control_type = "password", .name = "verification_type"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = "Name of 'verification_type' matches the " + "CVC pattern, ignore that " + "one.", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.form_control_type = "password", + .name = "verification_type"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, // The result should be trusted for more than just fallback, because // the chosen password was not a suspected CVC. .fallback_only = false, }, { - "Create a fallback for the only password being a CVC field.", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .name = "verification_type"}, - }, + .description_for_logging = + "Create a fallback for the only password being a CVC field.", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .name = "verification_type"}, + }, .fallback_only = true, }, }); @@ -1586,24 +1701,27 @@ TEST(FormParserTest, NotPasswordField) { CheckTestData({ { - "Server hints: NOT_PASSWORD.", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.form_control_type = "password", - .prediction = {.type = autofill::NOT_PASSWORD}}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = "Server hints: NOT_PASSWORD.", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.form_control_type = "password", + .prediction = {.type = autofill::NOT_PASSWORD}}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, .fallback_only = false, }, { - "Server hints: NOT_PASSWORD on only password.", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .prediction = {.type = autofill::NOT_PASSWORD}, - .form_control_type = "password"}, - }, + .description_for_logging = + "Server hints: NOT_PASSWORD on only password.", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .prediction = {.type = autofill::NOT_PASSWORD}, + .form_control_type = "password"}, + }, .fallback_only = true, }, }); @@ -1613,23 +1731,25 @@ TEST(FormParserTest, NotUsernameField) { CheckTestData({ { - "Server hints: NOT_USERNAME.", - {{.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::NONE, - .form_control_type = "text", - .prediction = {.type = autofill::NOT_USERNAME}}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::PASSWORD}}}, + .description_for_logging = "Server hints: NOT_USERNAME.", + .fields = {{.role = ElementRole::USERNAME, + .form_control_type = "text"}, + {.role = ElementRole::NONE, + .form_control_type = "text", + .prediction = {.type = autofill::NOT_USERNAME}}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::PASSWORD}}}, .fallback_only = false, }, { - "Server hints: NOT_USERNAME on only username.", - {{.role = ElementRole::NONE, - .form_control_type = "text", - .prediction = {.type = autofill::NOT_USERNAME}}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}}, + .description_for_logging = + "Server hints: NOT_USERNAME on only username.", + .fields = {{.role = ElementRole::NONE, + .form_control_type = "text", + .prediction = {.type = autofill::NOT_USERNAME}}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}}, .fallback_only = false, }, }); @@ -1640,26 +1760,29 @@ TEST(FormParserTest, NotUsernameFieldDespiteAutocompelteAtrribute) { CheckTestData({ { - "Server hints: NOT_USERNAME.", - {{.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.form_control_type = "text", - .autocomplete_attribute = "username", - .prediction = {.type = autofill::NOT_USERNAME}}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::PASSWORD}}}, + .description_for_logging = "Server hints: NOT_USERNAME.", + .fields = {{.role = ElementRole::USERNAME, + .form_control_type = "text"}, + {.form_control_type = "text", + .autocomplete_attribute = "username", + .prediction = {.type = autofill::NOT_USERNAME}}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::PASSWORD}}}, .fallback_only = false, }, { - "Server hints: NOT_USERNAME on only username.", - { - {.role = ElementRole::NONE, - .form_control_type = "text", - .autocomplete_attribute = "username", - .prediction = {.type = autofill::NOT_USERNAME}}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = + "Server hints: NOT_USERNAME on only username.", + .fields = + { + {.role = ElementRole::NONE, + .form_control_type = "text", + .autocomplete_attribute = "username", + .prediction = {.type = autofill::NOT_USERNAME}}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, .fallback_only = false, }, }); @@ -1669,31 +1792,34 @@ TEST(FormParserTest, NotPasswordFieldDespiteAutocompleteAttribute) { CheckTestData({ { - "Server hints: NOT_PASSWORD.", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.form_control_type = "password", - .prediction = {.type = autofill::NOT_PASSWORD}, - .autocomplete_attribute = "current-password"}, - {.form_control_type = "password", - .prediction = {.type = autofill::NOT_PASSWORD}, - .autocomplete_attribute = "new-password"}, - {.form_control_type = "password", - .prediction = {.type = autofill::NOT_PASSWORD}, - .autocomplete_attribute = "password"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = "Server hints: NOT_PASSWORD.", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.form_control_type = "password", + .prediction = {.type = autofill::NOT_PASSWORD}, + .autocomplete_attribute = "current-password"}, + {.form_control_type = "password", + .prediction = {.type = autofill::NOT_PASSWORD}, + .autocomplete_attribute = "new-password"}, + {.form_control_type = "password", + .prediction = {.type = autofill::NOT_PASSWORD}, + .autocomplete_attribute = "password"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, .fallback_only = false, }, { - "Server hints: NOT_PASSWORD on only password.", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .prediction = {.type = autofill::NOT_PASSWORD}, - .form_control_type = "password"}, - }, + .description_for_logging = + "Server hints: NOT_PASSWORD on only password.", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .prediction = {.type = autofill::NOT_PASSWORD}, + .form_control_type = "password"}, + }, .fallback_only = true, }, }); @@ -1703,14 +1829,16 @@ TEST(FormParserTest, ReadonlyStatus) { CheckTestData({ { - "Server predictions are ignored in saving mode", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .prediction = {.type = autofill::PASSWORD}, - .is_readonly = true, - .form_control_type = "password"}, - }, + .description_for_logging = + "Server predictions are ignored in saving mode", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .prediction = {.type = autofill::PASSWORD}, + .is_readonly = true, + .form_control_type = "password"}, + }, .readonly_status_for_filling = FormDataParser::ReadonlyPasswordFields::kNoHeuristics, .readonly_status_for_saving = @@ -1718,55 +1846,62 @@ .fallback_only = true, }, { - "Autocomplete attributes prevent heuristics from using readonly.", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .autocomplete_attribute = "current-password", - .is_readonly = true, - .form_control_type = "password"}, - }, + .description_for_logging = + "Autocomplete attributes prevent heuristics from using readonly.", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .autocomplete_attribute = "current-password", + .is_readonly = true, + .form_control_type = "password"}, + }, .readonly_status = FormDataParser::ReadonlyPasswordFields::kNoHeuristics, }, { - "No password fields are a special case of not going through local " - "heuristics.", - { - {.form_control_type = "text"}, - }, + .description_for_logging = "No password fields are a special case of " + "not going through local " + "heuristics.", + .fields = + { + {.form_control_type = "text"}, + }, .readonly_status = FormDataParser::ReadonlyPasswordFields::kNoHeuristics, }, { - "No readonly passwords ignored.", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role_filling = ElementRole::CURRENT_PASSWORD, - .role_saving = ElementRole::CURRENT_PASSWORD, - // While readonly, this field is not ignored because it was - // autofilled before. - .is_readonly = true, - .properties_mask = FieldPropertiesFlags::AUTOFILLED_ON_PAGELOAD, - .form_control_type = "password"}, - {.role_filling = ElementRole::NEW_PASSWORD, - .role_saving = ElementRole::NEW_PASSWORD, - .is_readonly = false, - .form_control_type = "password"}, - }, + .description_for_logging = "No readonly passwords ignored.", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role_filling = ElementRole::CURRENT_PASSWORD, + .role_saving = ElementRole::CURRENT_PASSWORD, + // While readonly, this field is not ignored because it was + // autofilled before. + .is_readonly = true, + .properties_mask = + FieldPropertiesFlags::AUTOFILLED_ON_PAGELOAD, + .form_control_type = "password"}, + {.role_filling = ElementRole::NEW_PASSWORD, + .role_saving = ElementRole::NEW_PASSWORD, + .is_readonly = false, + .form_control_type = "password"}, + }, .readonly_status = FormDataParser::ReadonlyPasswordFields::kNoneIgnored, .form_has_autofilled_value = true, }, { - "Some readonly passwords ignored.", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.is_readonly = true, .form_control_type = "password"}, - {.role = ElementRole::CURRENT_PASSWORD, - .is_readonly = false, - .form_control_type = "password"}, - }, + .description_for_logging = "Some readonly passwords ignored.", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.is_readonly = true, .form_control_type = "password"}, + {.role = ElementRole::CURRENT_PASSWORD, + .is_readonly = false, + .form_control_type = "password"}, + }, .readonly_status = FormDataParser::ReadonlyPasswordFields::kSomeIgnored, // The result should be trusted for more than just fallback, because @@ -1774,13 +1909,15 @@ .fallback_only = false, }, { - "All readonly passwords ignored, only returned as a fallback.", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .is_readonly = true}, - }, + .description_for_logging = + "All readonly passwords ignored, only returned as a fallback.", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .is_readonly = true}, + }, .readonly_status = FormDataParser::ReadonlyPasswordFields::kAllIgnored, .fallback_only = true, @@ -1792,56 +1929,62 @@ TEST(FormParserTest, NoEmptyValues) { CheckTestData({ { - "Server hints overridden for non-empty values.", - { - {.role_filling = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME}, - .value = ""}, - {.role_saving = ElementRole::USERNAME, - .form_control_type = "text"}, - {.role_saving = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - {.role_filling = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}, - .value = ""}, - }, + .description_for_logging = + "Server hints overridden for non-empty values.", + .fields = + { + {.role_filling = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::USERNAME}, + .value = ""}, + {.role_saving = ElementRole::USERNAME, + .form_control_type = "text"}, + {.role_saving = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + {.role_filling = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}, + .value = ""}, + }, .is_new_password_reliable = true, }, { - "Autocomplete attributes overridden for non-empty values.", - { - {.role_filling = ElementRole::USERNAME, - .form_control_type = "text", - .autocomplete_attribute = "username", - .value = ""}, - {.role_saving = ElementRole::USERNAME, - .form_control_type = "text"}, - {.role_filling = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .autocomplete_attribute = "current-password", - .value = ""}, - {.role = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .autocomplete_attribute = "new-password"}, - }, + .description_for_logging = + "Autocomplete attributes overridden for non-empty values.", + .fields = + { + {.role_filling = ElementRole::USERNAME, + .form_control_type = "text", + .autocomplete_attribute = "username", + .value = ""}, + {.role_saving = ElementRole::USERNAME, + .form_control_type = "text"}, + {.role_filling = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .autocomplete_attribute = "current-password", + .value = ""}, + {.role = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .autocomplete_attribute = "new-password"}, + }, .is_new_password_reliable = true, }, { - "Structure heuristics overridden for non-empty values.", - { - {.role_saving = ElementRole::USERNAME, - .form_control_type = "text"}, - {.role_filling = ElementRole::USERNAME, - .form_control_type = "text", - .value = ""}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - {.role_filling = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .value = ""}, - }, + .description_for_logging = + "Structure heuristics overridden for non-empty values.", + .fields = + { + {.role_saving = ElementRole::USERNAME, + .form_control_type = "text"}, + {.role_filling = ElementRole::USERNAME, + .form_control_type = "text", + .value = ""}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + {.role_filling = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .value = ""}, + }, }, }); } @@ -1850,120 +1993,132 @@ TEST(FormParserTest, MultipleUsernames) { CheckTestData({ { - "More than two usernames are ignored.", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::PASSWORD}}, - {.role = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, - }, + .description_for_logging = "More than two usernames are ignored.", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::PASSWORD}}, + {.role = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, + }, .is_new_password_reliable = true, }, { - "No current password -> ignore additional usernames.", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.role_filling = ElementRole::NEW_PASSWORD, - .role_saving = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, - }, + .description_for_logging = + "No current password -> ignore additional usernames.", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.role_filling = ElementRole::NEW_PASSWORD, + .role_saving = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, + }, }, { - "2 current passwods -> ignore additional usernames.", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::PASSWORD}}, - {.role_saving = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::PASSWORD}}, - }, + .description_for_logging = + "2 current passwods -> ignore additional usernames.", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::PASSWORD}}, + {.role_saving = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::PASSWORD}}, + }, }, { - "No new password -> ignore additional usernames.", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::PASSWORD}}, - }, + .description_for_logging = + "No new password -> ignore additional usernames.", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::PASSWORD}}, + }, }, { - "Two usernames in sign-in, sign-up order.", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::PASSWORD}}, - {.role = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, - }, + .description_for_logging = "Two usernames in sign-in, sign-up order.", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::PASSWORD}}, + {.role = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, + }, .is_new_password_reliable = true, }, { - "Two usernames in sign-up, sign-in order.", - { - {.role_saving = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.role_filling = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.role_filling = ElementRole::NEW_PASSWORD, - .role_saving = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, - {.form_control_type = "password", - .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, - {.role_filling = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::PASSWORD}}, - }, + .description_for_logging = "Two usernames in sign-up, sign-in order.", + .fields = + { + {.role_saving = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.role_filling = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.role_filling = ElementRole::NEW_PASSWORD, + .role_saving = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, + {.form_control_type = "password", + .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, + {.role_filling = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::PASSWORD}}, + }, }, { - "Two usernames in sign-in, sign-up order; sign-in is pre-filled.", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .properties_mask = FieldPropertiesFlags::AUTOFILLED_ON_PAGELOAD, - .prediction = {.type = autofill::USERNAME}}, - {.form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::PASSWORD}}, - {.role = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, - }, + .description_for_logging = + "Two usernames in sign-in, sign-up order; sign-in is pre-filled.", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .properties_mask = + FieldPropertiesFlags::AUTOFILLED_ON_PAGELOAD, + .prediction = {.type = autofill::USERNAME}}, + {.form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::PASSWORD}}, + {.role = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, + }, }, }); } @@ -1976,36 +2131,39 @@ TEST(FormParserTest, MultipleNewPasswords) { CheckTestData({ { - "Only one new-password recognised.", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.role_filling = ElementRole::NEW_PASSWORD, - .role_saving = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, - {.role_saving = ElementRole::NEW_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, - }, + .description_for_logging = "Only one new-password recognised.", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.role_filling = ElementRole::NEW_PASSWORD, + .role_saving = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, + {.role_saving = ElementRole::NEW_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, + }, }, { - "Only one new-password recognised, confirmation unaffected.", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.role_filling = ElementRole::NEW_PASSWORD, - .role_saving = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, - {.form_control_type = "password", - .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, - {.role_filling = ElementRole::CONFIRMATION_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::CONFIRMATION_PASSWORD}}, - }, + .description_for_logging = + "Only one new-password recognised, confirmation unaffected.", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.role_filling = ElementRole::NEW_PASSWORD, + .role_saving = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, + {.form_control_type = "password", + .prediction = {.type = autofill::ACCOUNT_CREATION_PASSWORD}}, + {.role_filling = ElementRole::CONFIRMATION_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::CONFIRMATION_PASSWORD}}, + }, }, }); } @@ -2017,92 +2175,105 @@ } kHistogramTestCases[] = { { { - "No username", - { - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::PASSWORD}}, - }, + .description_for_logging = "No username", + .fields = + { + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::PASSWORD}}, + }, }, UsernameDetectionMethod::kNoUsernameDetected, }, { { - "Reporting server analysis", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .prediction = {.type = autofill::USERNAME}}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::PASSWORD}}, - }, + .description_for_logging = "Reporting server analysis", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .prediction = {.type = autofill::USERNAME}}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::PASSWORD}}, + }, }, UsernameDetectionMethod::kServerSidePrediction, }, { { - "Reporting autocomplete analysis", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .autocomplete_attribute = "username"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .autocomplete_attribute = "current-password"}, - }, + .description_for_logging = "Reporting autocomplete analysis", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .autocomplete_attribute = "username"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .autocomplete_attribute = "current-password"}, + }, }, UsernameDetectionMethod::kAutocompleteAttribute, }, { { - "Reporting HTML classifier", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .predicted_username = 0}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = "Reporting HTML classifier", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .predicted_username = 0}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, }, UsernameDetectionMethod::kHtmlBasedClassifier, }, { { - "Reporting basic heuristics", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + .description_for_logging = "Reporting basic heuristics", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, }, UsernameDetectionMethod::kBaseHeuristic, }, { { - "Mixing server analysis on password and HTML classifier on " - "username is reported as HTML classifier", - { - {.role = ElementRole::USERNAME, - .form_control_type = "text", - .predicted_username = 0}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .prediction = {.type = autofill::PASSWORD}}, - }, + .description_for_logging = + "Mixing server analysis on password and HTML classifier " + "on " + "username is reported as HTML classifier", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text", + .predicted_username = 0}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .prediction = {.type = autofill::PASSWORD}}, + }, }, UsernameDetectionMethod::kHtmlBasedClassifier, }, { { - "Mixing autocomplete analysis on password and basic heuristics " - "on username is reported as basic heuristics", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password", - .autocomplete_attribute = "current-password"}, - }, + .description_for_logging = + "Mixing autocomplete analysis on password and basic " + "heuristics " + "on username is reported as basic heuristics", + .fields = + { + {.role = ElementRole::USERNAME, + .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password", + .autocomplete_attribute = "current-password"}, + }, }, UsernameDetectionMethod::kBaseHeuristic, }, @@ -2120,12 +2291,13 @@ TEST(FormParserTest, SubmissionEvent) { CheckTestData({ - {"Sign-in form, submission event is not None", - { - {.role = ElementRole::USERNAME, .form_control_type = "text"}, - {.role = ElementRole::CURRENT_PASSWORD, - .form_control_type = "password"}, - }, + {.description_for_logging = "Sign-in form, submission event is not None", + .fields = + { + {.role = ElementRole::USERNAME, .form_control_type = "text"}, + {.role = ElementRole::CURRENT_PASSWORD, + .form_control_type = "password"}, + }, .submission_event = SubmissionIndicatorEvent::XHR_SUCCEEDED}, }); }
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc index 38adbff1..a5cdbfee 100644 --- a/components/password_manager/core/browser/password_form_manager.cc +++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -126,6 +126,41 @@ return differences_bitmask; } +bool URLsEqualUpToScheme(const GURL& a, const GURL& b) { + return (a.GetContent() == b.GetContent()); +} + +bool URLsEqualUpToHttpHttpsSubstitution(const GURL& a, const GURL& b) { + if (a == b) + return true; + + // The first-time and retry login forms action URLs sometimes differ in + // switching from HTTP to HTTPS, see http://crbug.com/400769. + if (a.SchemeIsHTTPOrHTTPS() && b.SchemeIsHTTPOrHTTPS()) + return URLsEqualUpToScheme(a, b); + + return false; +} + +// Since empty or unspecified form's action is automatically set to the page +// origin, this function checks if a form's action is empty by comparing it to +// its origin. +bool HasNonEmptyAction(const FormData& form) { + // TODO(crbug.com/1008798): The logic isn't accurate and should be fixed. + return form.action != form.url; +} + +bool FormContainsFieldWithName(const FormData& form, + const base::string16& element) { + if (element.empty()) + return false; + for (const auto& field : form.fields) { + if (base::EqualsCaseInsensitiveASCII(field.name, element)) + return true; + } + return false; +} + } // namespace PasswordFormManager::PasswordFormManager( @@ -212,10 +247,29 @@ return false; if (IsHttpAuth()) return false; - if (form.action == submitted_form_.action) + + if (form.action.is_valid() && HasNonEmptyAction(form) && + HasNonEmptyAction(submitted_form_) && + URLsEqualUpToHttpHttpsSubstitution(submitted_form_.action, form.action)) { return true; - // TODO(https://crbug.com/831123): Implement other checks from a function - // IsPasswordFormReappeared from password_manager.cc. + } + + // Match the form if username and password fields are same. + if (FormContainsFieldWithName(form, + parsed_submitted_form_->username_element) && + FormContainsFieldWithName(form, + parsed_submitted_form_->password_element)) { + return true; + } + + // Match the form if the observed username field has the same value as in + // the submitted form. + if (!parsed_submitted_form_->username_value.empty()) { + for (const auto& field : form.fields) { + if (field.value == parsed_submitted_form_->username_value) + return true; + } + } return false; }
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.cc b/components/password_manager/core/browser/password_form_metrics_recorder.cc index 9390846..76e2c45 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder.cc +++ b/components/password_manager/core/browser/password_form_metrics_recorder.cc
@@ -16,7 +16,6 @@ #include "components/password_manager/core/browser/password_bubble_experiment.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h" #include "components/password_manager/core/browser/statistics_table.h" -#include "password_form_metrics_recorder.h" using autofill::FieldPropertiesFlags; using autofill::FormData; @@ -234,10 +233,6 @@ ukm_entry_builder_.SetGeneration_PopupShown( static_cast<int64_t>(password_generation_popup_shown_)); } - if (spec_priority_of_generated_password_) { - ukm_entry_builder_.SetGeneration_SpecPriority( - spec_priority_of_generated_password_.value()); - } if (showed_manual_fallback_for_saving_) { ukm_entry_builder_.SetSaving_ShowedManualFallbackForSaving( @@ -294,11 +289,6 @@ generated_password_status_ = status; } -void PasswordFormMetricsRecorder::ReportSpecPriorityForGeneratedPassword( - uint32_t spec_priority) { - spec_priority_of_generated_password_ = spec_priority; -} - void PasswordFormMetricsRecorder::SetManagerAction( ManagerAction manager_action) { manager_action_ = manager_action;
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.h b/components/password_manager/core/browser/password_form_metrics_recorder.h index f61927f2..dc7f09b5a 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder.h +++ b/components/password_manager/core/browser/password_form_metrics_recorder.h
@@ -304,13 +304,6 @@ // Stores the user action associated with a generated password. void SetGeneratedPasswordStatus(GeneratedPasswordStatus status); - // Reports the priority of a PasswordGenerationRequirementsSpec for a - // generated password. This can be used for debugging as a 0 means that - // no spec was used, a 10 means that the spec came from autofill and was crowd - // sourced, a 20 means that it was overrideen per domain and a 30 means that - // is was overridden for the form. - void ReportSpecPriorityForGeneratedPassword(uint32_t spec_priority); - // Stores the password manager action. During destruction the last // set value will be logged. void SetManagerAction(ManagerAction manager_action); @@ -458,8 +451,6 @@ // action. base::Optional<GeneratedPasswordStatus> generated_password_status_; - base::Optional<uint32_t> spec_priority_of_generated_password_; - // Tracks which bubble is currently being displayed to the user. CurrentBubbleOfInterest current_bubble_ = CurrentBubbleOfInterest::kNone;
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc index 729ae8a8..74f52f40 100644 --- a/components/password_manager/core/browser/password_manager.cc +++ b/components/password_manager/core/browser/password_manager.cc
@@ -21,7 +21,6 @@ #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/browser/logging/log_manager.h" #include "components/autofill/core/common/form_data_predictions.h" -#include "components/autofill/core/common/password_form_field_prediction_map.h" #include "components/autofill/core/common/save_password_progress_logger.h" #include "components/password_manager/core/browser/browser_save_password_progress_logger.h" #include "components/password_manager/core/browser/form_saver_impl.h" @@ -60,58 +59,6 @@ // already. using Logger = autofill::SavePasswordProgressLogger; -bool URLsEqualUpToScheme(const GURL& a, const GURL& b) { - return (a.GetContent() == b.GetContent()); -} - -bool URLsEqualUpToHttpHttpsSubstitution(const GURL& a, const GURL& b) { - if (a == b) - return true; - - // The first-time and retry login forms action URLs sometimes differ in - // switching from HTTP to HTTPS, see http://crbug.com/400769. - if (a.SchemeIsHTTPOrHTTPS() && b.SchemeIsHTTPOrHTTPS()) - return URLsEqualUpToScheme(a, b); - - return false; -} - -// Since empty or unspecified form's action is automatically set to the page -// origin, this function checks if a form's action is empty by comparing it to -// its origin. -bool HasNonEmptyAction(const PasswordForm& form) { - return form.action != form.origin; -} - -// Checks if the observed form looks like the submitted one to handle "Invalid -// password entered" case so we don't offer a password save when we shouldn't. -bool IsPasswordFormReappeared(const PasswordForm& observed_form, - const PasswordForm& submitted_form) { - if (observed_form.action.is_valid() && HasNonEmptyAction(observed_form) && - HasNonEmptyAction(submitted_form) && - URLsEqualUpToHttpHttpsSubstitution(submitted_form.action, - observed_form.action)) { - return true; - } - - // Match the form if username and password fields are same. - if (base::EqualsCaseInsensitiveASCII(observed_form.username_element, - submitted_form.username_element) && - base::EqualsCaseInsensitiveASCII(observed_form.password_element, - submitted_form.password_element)) { - return true; - } - - // Match the form if the observed username field has the same value as in - // the submitted form. - if (!submitted_form.username_value.empty() && - observed_form.username_value == submitted_form.username_value) { - return true; - } - - return false; -} - bool AreAllFieldsEmpty(const PasswordForm& form) { return form.username_value.empty() && form.password_value.empty() && form.new_password_value.empty(); @@ -804,8 +751,7 @@ if (submitted_manager->GetPendingCredentials().scheme == PasswordForm::Scheme::kHtml) { for (const PasswordForm& form : all_visible_forms_) { - if (IsPasswordFormReappeared( - form, submitted_manager->GetPendingCredentials())) { + if (submitted_manager->IsEqualToSubmittedForm(form.form_data)) { if (submitted_manager->IsPossibleChangePasswordFormWithoutUsername() && AreAllFieldsEmpty(form)) { continue;
diff --git a/components/password_manager/core/browser/password_manager_driver.h b/components/password_manager/core/browser/password_manager_driver.h index 8c81c21e..81914bb 100644 --- a/components/password_manager/core/browser/password_manager_driver.h +++ b/components/password_manager/core/browser/password_manager_driver.h
@@ -13,7 +13,6 @@ #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" #include "components/autofill/core/common/mojom/autofill_types.mojom.h" -#include "components/autofill/core/common/password_form_field_prediction_map.h" namespace autofill { class AutofillDriver;
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc index 29235fe..1a3c2d9 100644 --- a/components/password_manager/core/browser/password_manager_unittest.cc +++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -1481,7 +1481,9 @@ // Tests whether two submissions to the same origin but different schemes // result in only saving the first submission, which has a secure scheme. -TEST_F(PasswordManagerTest, AttemptedSavePasswordSameOriginInsecureScheme) { +// TODO(crbug.com/1008818): reenable this test after addressing the linked bug. +TEST_F(PasswordManagerTest, + DISABLED_AttemptedSavePasswordSameOriginInsecureScheme) { PasswordForm secure_form(MakeSimpleForm()); secure_form.origin = GURL("https://example.com/login"); secure_form.action = GURL("https://example.com/login");
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc b/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc index 4d60261..2aedcda1 100644 --- a/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc +++ b/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
@@ -12,7 +12,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/bind_test_util.h" #include "components/password_manager/core/browser/password_store_sync.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/model/data_batch.h" #include "components/sync/model/entity_change.h" #include "components/sync/model/metadata_batch.h" @@ -262,7 +262,7 @@ const sync_pb::PasswordSpecifics& specifics) { auto data = std::make_unique<syncer::EntityData>(); *data->specifics.mutable_password() = specifics; - data->client_tag_hash = syncer::GenerateSyncableHash( + data->client_tag_hash = syncer::ClientTagHash::FromUnhashed( syncer::PASSWORDS, bridge()->GetClientTag(*data)); return data; }
diff --git a/components/policy/core/common/cloud/component_cloud_policy_service.cc b/components/policy/core/common/cloud/component_cloud_policy_service.cc index ec8b27e2..8d3389ba 100644 --- a/components/policy/core/common/cloud/component_cloud_policy_service.cc +++ b/components/policy/core/common/cloud/component_cloud_policy_service.cc
@@ -285,14 +285,11 @@ policy_type == dm_protocol::kChromeSigninExtensionPolicyType); CHECK(!core_->client()); - external_policy_data_fetcher_backend_.reset( - new ExternalPolicyDataFetcherBackend(client->GetURLLoaderFactory())); - backend_.reset( new Backend(weak_ptr_factory_.GetWeakPtr(), backend_task_runner_, base::ThreadTaskRunnerHandle::Get(), std::move(cache), - external_policy_data_fetcher_backend_->CreateFrontend( - backend_task_runner_), + std::make_unique<ExternalPolicyDataFetcher>( + client->GetURLLoaderFactory(), backend_task_runner_), policy_type, policy_source)); // Observe the schema registry for keeping |current_schema_map_| up to date.
diff --git a/components/policy/core/common/cloud/component_cloud_policy_service.h b/components/policy/core/common/cloud/component_cloud_policy_service.h index 8777889e..e92e72b 100644 --- a/components/policy/core/common/cloud/component_cloud_policy_service.h +++ b/components/policy/core/common/cloud/component_cloud_policy_service.h
@@ -29,7 +29,6 @@ namespace policy { -class ExternalPolicyDataFetcherBackend; class ResourceCache; class SchemaMap; @@ -154,12 +153,6 @@ CloudPolicyCore* core_; scoped_refptr<base::SequencedTaskRunner> backend_task_runner_; - // The |external_policy_data_fetcher_backend_| handles network I/O for the - // |backend_| because the system SharedURLLoaderFactory cannot be referenced - // from background threads. It is owned by the thread |this| runs on. - std::unique_ptr<ExternalPolicyDataFetcherBackend> - external_policy_data_fetcher_backend_; - // The |backend_| handles all download scheduling, validation and caching of // policies. It is instantiated on the thread |this| runs on but after that, // must only be accessed and eventually destroyed via the
diff --git a/components/policy/core/common/cloud/component_cloud_policy_updater_unittest.cc b/components/policy/core/common/cloud/component_cloud_policy_updater_unittest.cc index 6d065f05c..42b2bc4 100644 --- a/components/policy/core/common/cloud/component_cloud_policy_updater_unittest.cc +++ b/components/policy/core/common/cloud/component_cloud_policy_updater_unittest.cc
@@ -91,7 +91,6 @@ private: base::ScopedTempDir temp_dir_; std::unique_ptr<ResourceCache> cache_; - std::unique_ptr<ExternalPolicyDataFetcherBackend> fetcher_backend_; std::string public_key_; }; @@ -130,11 +129,10 @@ auto url_loader_factory = base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &loader_factory_); - fetcher_backend_ = std::make_unique<ExternalPolicyDataFetcherBackend>( - std::move(url_loader_factory)); updater_ = std::make_unique<ComponentCloudPolicyUpdater>( task_env_.GetMainThreadTaskRunner(), - fetcher_backend_->CreateFrontend(task_env_.GetMainThreadTaskRunner()), + std::make_unique<ExternalPolicyDataFetcher>( + std::move(url_loader_factory), task_env_.GetMainThreadTaskRunner()), store_.get()); ASSERT_EQ(store_->policy().end(), store_->policy().begin()); }
diff --git a/components/policy/core/common/cloud/external_policy_data_fetcher.cc b/components/policy/core/common/cloud/external_policy_data_fetcher.cc index 27658cac..42823fd 100644 --- a/components/policy/core/common/cloud/external_policy_data_fetcher.cc +++ b/components/policy/core/common/cloud/external_policy_data_fetcher.cc
@@ -22,28 +22,16 @@ namespace policy { -namespace { - -// Helper that forwards a job cancelation confirmation from the thread that the -// ExternalPolicyDataFetcherBackend runs on to the thread that the -// ExternalPolicyDataFetcher which canceled the job runs on. -void ForwardJobCanceled(scoped_refptr<base::SequencedTaskRunner> task_runner, - base::OnceClosure callback) { - task_runner->PostTask(FROM_HERE, std::move(callback)); -} - -} // namespace - class ExternalPolicyDataFetcher::Job : public network::SimpleURLLoaderStreamConsumer { public: - Job(base::WeakPtr<ExternalPolicyDataFetcher> fetcher, - scoped_refptr<base::SequencedTaskRunner> frontend_task_runner, + Job(std::unique_ptr<network::SharedURLLoaderFactoryInfo> + url_loader_factory_info, + base::WeakPtr<ExternalPolicyDataFetcher> fetcher, + scoped_refptr<base::SequencedTaskRunner> fetcher_task_runner, ExternalPolicyDataFetcher::FetchCallback callback); - void Start(network::mojom::URLLoaderFactory* url_loader_factory, - const GURL& url, - int64_t max_size); + void Start(const GURL& url, int64_t max_size); void Cancel(); void OnResponseStarted(const GURL& final_url, const network::mojom::URLResponseHead& response_head); @@ -59,8 +47,9 @@ SEQUENCE_CHECKER(sequence_checker_); + std::unique_ptr<network::SharedURLLoaderFactoryInfo> url_loader_factory_info_; base::WeakPtr<ExternalPolicyDataFetcher> fetcher_; - scoped_refptr<base::SequencedTaskRunner> frontend_task_runner_; + scoped_refptr<base::SequencedTaskRunner> fetcher_task_runner_; ExternalPolicyDataFetcher::FetchCallback callback_; std::unique_ptr<network::SimpleURLLoader> url_loader_; std::string response_body_; @@ -70,21 +59,25 @@ }; ExternalPolicyDataFetcher::Job::Job( + std::unique_ptr<network::SharedURLLoaderFactoryInfo> + url_loader_factory_info, base::WeakPtr<ExternalPolicyDataFetcher> fetcher, - scoped_refptr<base::SequencedTaskRunner> frontend_task_runner, + scoped_refptr<base::SequencedTaskRunner> fetcher_task_runner, ExternalPolicyDataFetcher::FetchCallback callback) - : fetcher_(std::move(fetcher)), - frontend_task_runner_(std::move(frontend_task_runner)), + : url_loader_factory_info_(std::move(url_loader_factory_info)), + fetcher_(std::move(fetcher)), + fetcher_task_runner_(std::move(fetcher_task_runner)), callback_(std::move(callback)) { - // A job is created on the frontend thread but receives callbacks on the - // backend's sequence. + // A job is created on the fetcher sequence but it then lives on the separate + // job sequence. DETACH_FROM_SEQUENCE(sequence_checker_); } void ExternalPolicyDataFetcher::Job::Start( - network::mojom::URLLoaderFactory* url_loader_factory, const GURL& url, int64_t max_size) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK_GE(max_size, 0); max_size_ = max_size; @@ -125,16 +118,23 @@ url_loader_->SetOnResponseStartedCallback( base::BindOnce(&ExternalPolicyDataFetcher::Job::OnResponseStarted, base::Unretained(this))); - url_loader_->DownloadAsStream(url_loader_factory, this); + url_loader_->DownloadAsStream(network::SharedURLLoaderFactory::Create( + std::move(url_loader_factory_info_)) + .get(), + this); } void ExternalPolicyDataFetcher::Job::Cancel() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + url_loader_.reset(); } void ExternalPolicyDataFetcher::Job::OnResponseStarted( const GURL& /* final_url */, const network::mojom::URLResponseHead& response_head) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (response_head.content_length != -1 && response_head.content_length > max_size_) { url_loader_.reset(); @@ -146,6 +146,8 @@ void ExternalPolicyDataFetcher::Job::OnDataReceived( base::StringPiece string_piece, base::OnceClosure resume) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (response_body_.length() + string_piece.length() > static_cast<uint64_t>(max_size_)) { url_loader_.reset(); @@ -199,6 +201,8 @@ } void ExternalPolicyDataFetcher::Job::OnRetry(base::OnceClosure start_retry) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + response_body_.clear(); std::move(start_retry).Run(); } @@ -206,18 +210,21 @@ void ExternalPolicyDataFetcher::Job::ReportFinished( Result result, std::unique_ptr<std::string> data) { - frontend_task_runner_->PostTask( + fetcher_task_runner_->PostTask( FROM_HERE, base::BindOnce(&ExternalPolicyDataFetcher::OnJobFinished, fetcher_, std::move(callback_), this, result, std::move(data))); } ExternalPolicyDataFetcher::ExternalPolicyDataFetcher( - scoped_refptr<base::SequencedTaskRunner> task_runner, - const base::WeakPtr<ExternalPolicyDataFetcherBackend>& backend) + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + scoped_refptr<base::SequencedTaskRunner> task_runner) : task_runner_(std::move(task_runner)), - backend_task_runner_(base::ThreadTaskRunnerHandle::Get()), - backend_(backend) {} + job_task_runner_(base::ThreadTaskRunnerHandle::Get()) { + // |url_loader_factory| is null in some tests. + if (url_loader_factory) + url_loader_factory_info_ = url_loader_factory->Clone(); +} ExternalPolicyDataFetcher::~ExternalPolicyDataFetcher() { // No RunsTasksInCurrentSequence() check to avoid unit tests failures. @@ -237,12 +244,17 @@ int64_t max_size, FetchCallback callback) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); + if (!cloned_url_loader_factory_) { + cloned_url_loader_factory_ = network::SharedURLLoaderFactory::Create( + std::move(url_loader_factory_info_)); + } Job* job = - new Job(weak_factory_.GetWeakPtr(), task_runner_, std::move(callback)); + new Job(cloned_url_loader_factory_->Clone(), weak_factory_.GetWeakPtr(), + task_runner_, std::move(callback)); jobs_.insert(job); - backend_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&ExternalPolicyDataFetcherBackend::StartJob, - backend_, url, max_size, job)); + job_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&Job::Start, base::Unretained(job), url, max_size)); return job; } @@ -250,19 +262,15 @@ DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(jobs_.find(job) != jobs_.end()); jobs_.erase(job); - // Post a task that will cancel the |job| in the |backend_|. The |job| is - // removed from |jobs_| immediately to indicate that it has been canceled but - // is not actually deleted until the cancelation has reached the |backend_| - // and a confirmation has been posted back. This ensures that no new job can - // be allocated at the same address while an OnJobFinished() callback may - // still be pending for the canceled |job|. - backend_task_runner_->PostTask( - FROM_HERE, - base::BindOnce( - &ExternalPolicyDataFetcherBackend::CancelJob, backend_, job, - base::BindOnce(&ForwardJobCanceled, task_runner_, - base::BindOnce(base::DoNothing::Once<Job*>(), - base::Owned(job))))); + // Post a task that will cancel the |job| in the |job_task_runner_|. The |job| + // is removed from |jobs_| immediately to indicate that it has been canceled + // but is not actually deleted until the cancellation has reached the + // |job_task_runner_| and a confirmation has been posted back. This ensures + // that no new job can be allocated at the same address while an + // OnJobFinished() callback may still be pending for the canceled |job|. + job_task_runner_->PostTaskAndReply( + FROM_HERE, base::BindOnce(&Job::Cancel, base::Unretained(job)), + base::BindOnce(base::DoNothing::Once<Job*>(), base::Owned(job))); } void ExternalPolicyDataFetcher::OnJobFinished( @@ -274,8 +282,8 @@ auto it = jobs_.find(job); if (it == jobs_.end()) { // The |job| has been canceled and removed from |jobs_| already. This can - // happen because the |backend_| runs on a different thread and a |job| may - // finish before the cancellation has reached that thread. + // happen because the jobs run on a different sequence and a |job| may + // finish before the cancellation has reached that sequence. return; } std::move(callback).Run(result, std::move(data)); @@ -283,35 +291,4 @@ delete job; } -ExternalPolicyDataFetcherBackend::ExternalPolicyDataFetcherBackend( - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) - : url_loader_factory_(std::move(url_loader_factory)) {} - -ExternalPolicyDataFetcherBackend::~ExternalPolicyDataFetcherBackend() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -} - -std::unique_ptr<ExternalPolicyDataFetcher> -ExternalPolicyDataFetcherBackend::CreateFrontend( - scoped_refptr<base::SequencedTaskRunner> frontend_task_runner) { - return std::make_unique<ExternalPolicyDataFetcher>( - std::move(frontend_task_runner), weak_factory_.GetWeakPtr()); -} - -void ExternalPolicyDataFetcherBackend::StartJob( - const GURL& url, - int64_t max_size, - ExternalPolicyDataFetcher::Job* job) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - job->Start(url_loader_factory_.get(), url, max_size); -} - -void ExternalPolicyDataFetcherBackend::CancelJob( - ExternalPolicyDataFetcher::Job* job, - base::OnceClosure callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - job->Cancel(); - std::move(callback).Run(); -} - } // namespace policy
diff --git a/components/policy/core/common/cloud/external_policy_data_fetcher.h b/components/policy/core/common/cloud/external_policy_data_fetcher.h index acc8aec2..ae3d12a 100644 --- a/components/policy/core/common/cloud/external_policy_data_fetcher.h +++ b/components/policy/core/common/cloud/external_policy_data_fetcher.h
@@ -26,17 +26,14 @@ } namespace network { +class SharedURLLoaderFactoryInfo; class SharedURLLoaderFactory; } namespace policy { -class ExternalPolicyDataFetcherBackend; - // This class handles network fetch jobs for the ExternalPolicyDataUpdater by -// forwarding them to an ExternalPolicyDataFetcherBackend running on a different -// thread. This is necessary because the ExternalPolicyDataUpdater runs on a -// background thread where network I/O is not allowed. +// forwarding them to a job running on a different thread. // The class can be instantiated on any thread but from then on, it must be // accessed and destroyed on the background thread that the // ExternalPolicyDataUpdater runs on only. @@ -71,11 +68,9 @@ base::OnceCallback<void(Result, std::unique_ptr<std::string>)>; // |task_runner| represents the background thread that |this| runs on. - // |backend| is used to perform network I/O. It must be dereferenced and - // accessed via |task_runner| only. ExternalPolicyDataFetcher( - scoped_refptr<base::SequencedTaskRunner> task_runner, - const base::WeakPtr<ExternalPolicyDataFetcherBackend>& backend); + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + scoped_refptr<base::SequencedTaskRunner> task_runner); ~ExternalPolicyDataFetcher(); // Fetch data from |url| and invoke |callback| with the result. See the @@ -98,13 +93,15 @@ // Task runner representing the thread that |this| runs on. const scoped_refptr<base::SequencedTaskRunner> task_runner_; + // Task runner for running the fetch jobs. It's the task runner on which this + // instance was created. + const scoped_refptr<base::SequencedTaskRunner> job_task_runner_; - // Task runner representing the thread on which the |backend_| runs. - const scoped_refptr<base::SequencedTaskRunner> backend_task_runner_; - - // The |backend_| is used to perform network I/O. It may be dereferenced and - // accessed via |backend_task_runner_| only. - base::WeakPtr<ExternalPolicyDataFetcherBackend> backend_; + // The information for the lazy creation of |cloned_url_loader_factory_|. + std::unique_ptr<network::SharedURLLoaderFactoryInfo> url_loader_factory_info_; + // The cloned factory that can be used from |task_runner_|. It's created + // lazily, as our constructor runs on a difference sequence. + scoped_refptr<network::SharedURLLoaderFactory> cloned_url_loader_factory_; // Set that owns all currently running Jobs. typedef std::set<Job*> JobSet; @@ -115,44 +112,6 @@ DISALLOW_COPY_AND_ASSIGN(ExternalPolicyDataFetcher); }; -// This class handles network I/O for one or more ExternalPolicyDataFetchers. It -// can be instantiated on any thread that is allowed to reference -// SharedURLLoaderFactories (in Chrome, these are the UI and IO threads) and -// CreateFrontend() may be called from the same thread after instantiation. From -// then on, it must be accessed and destroyed on the thread that handles network -// I/O only (in Chrome, this is the IO thread). -class POLICY_EXPORT ExternalPolicyDataFetcherBackend { - public: - explicit ExternalPolicyDataFetcherBackend( - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); - ~ExternalPolicyDataFetcherBackend(); - - // Create an ExternalPolicyDataFetcher that allows fetch jobs to be started - // from |frontend_task_runner|. - std::unique_ptr<ExternalPolicyDataFetcher> CreateFrontend( - scoped_refptr<base::SequencedTaskRunner> frontend_task_runner); - - // Start a fetch job defined by |job|. The caller retains ownership of |job| - // and must ensure that it remains valid until the job ends, CancelJob() is - // called or |this| is destroyed. - void StartJob(const GURL& url, - int64_t max_size, - ExternalPolicyDataFetcher::Job* job); - - // Cancel the fetch job defined by |job| and invoke |callback| to confirm. - void CancelJob(ExternalPolicyDataFetcher::Job* job, - base::OnceClosure callback); - - private: - SEQUENCE_CHECKER(sequence_checker_); - - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; - base::WeakPtrFactory<ExternalPolicyDataFetcherBackend> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(ExternalPolicyDataFetcherBackend); -}; - - } // namespace policy #endif // COMPONENTS_POLICY_CORE_COMMON_CLOUD_EXTERNAL_POLICY_DATA_FETCHER_H_
diff --git a/components/policy/core/common/cloud/external_policy_data_fetcher_unittest.cc b/components/policy/core/common/cloud/external_policy_data_fetcher_unittest.cc index e3cfe139..e839482 100644 --- a/components/policy/core/common/cloud/external_policy_data_fetcher_unittest.cc +++ b/components/policy/core/common/cloud/external_policy_data_fetcher_unittest.cc
@@ -55,7 +55,6 @@ base::test::TaskEnvironment task_environment_; scoped_refptr<base::TestSimpleTaskRunner> owner_task_runner_; network::TestURLLoaderFactory test_url_loader_factory_; - std::unique_ptr<ExternalPolicyDataFetcherBackend> fetcher_backend_; std::unique_ptr<ExternalPolicyDataFetcher> fetcher_; std::map<int, ExternalPolicyDataFetcher::Job*> jobs_; // Not owned. @@ -79,10 +78,9 @@ auto url_loader_factory = base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory_); - fetcher_backend_ = std::make_unique<ExternalPolicyDataFetcherBackend>( - std::move(url_loader_factory)); owner_task_runner_ = base::MakeRefCounted<base::TestSimpleTaskRunner>(); - fetcher_ = fetcher_backend_->CreateFrontend(owner_task_runner_); + fetcher_ = std::make_unique<ExternalPolicyDataFetcher>( + std::move(url_loader_factory), owner_task_runner_); } void ExternalPolicyDataFetcherTest::StartJob(int index) { @@ -313,7 +311,7 @@ EXPECT_EQ(0, test_url_loader_factory_.NumPending()); // Cancel the fetch job before the successful fetch result has arrived from - // the backend. + // the job. CancelJob(0); // Verify that the callback is not invoked.
diff --git a/components/policy/core/common/cloud/external_policy_data_updater_unittest.cc b/components/policy/core/common/cloud/external_policy_data_updater_unittest.cc index 8fed109..ff036ea7 100644 --- a/components/policy/core/common/cloud/external_policy_data_updater_unittest.cc +++ b/components/policy/core/common/cloud/external_policy_data_updater_unittest.cc
@@ -77,7 +77,6 @@ network::TestURLLoaderFactory test_url_loader_factory_; MockFetchSuccessCallbackListener callback_listener_; scoped_refptr<base::TestSimpleTaskRunner> backend_task_runner_; - std::unique_ptr<ExternalPolicyDataFetcherBackend> fetcher_backend_; std::unique_ptr<ExternalPolicyDataUpdater> updater_; }; @@ -89,11 +88,10 @@ auto url_loader_factory = base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory_); - fetcher_backend_ = std::make_unique<ExternalPolicyDataFetcherBackend>( - std::move(url_loader_factory)); updater_ = std::make_unique<ExternalPolicyDataUpdater>( backend_task_runner_, - fetcher_backend_->CreateFrontend(backend_task_runner_), + std::make_unique<ExternalPolicyDataFetcher>(std::move(url_loader_factory), + backend_task_runner_), max_parallel_fetches); }
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto index c5c25b72..e96148c8 100644 --- a/components/policy/proto/chrome_device_policy.proto +++ b/components/policy/proto/chrome_device_policy.proto
@@ -692,6 +692,38 @@ // status on the login screen is persisted between users. optional bool login_screen_cursor_highlight_enabled = 18; optional PolicyOptions login_screen_cursor_highlight_enabled_options = 19; + + // Sets the state of the caret highlight accessibility feature on the login + // screen. If this policy is set to true, the caret highlight will be enabled + // when the login screen is shown. If this policy is set to false, the spoken + // feedback will be disabled when the caret highlight is shown. If the + // PolicyOptions mode was being mandatory then the user won't be able to + // change these settings. Only if PolicyOptions was being set as recommended + // users can temporarily override this setting by enabling or disabling the + // caret highlight. However, the user's choice is not persistent and the + // default is restored whenever the login screen is shown anew or the user + // remains idle on the login screen for a minute. If this policy is left + // unset, the caret highlight is disabled when the login screen is first + // shown. Users can enable or disable the caret highlight anytime and its + // status on the login screen is persisted between users. + optional bool login_screen_caret_highlight_enabled = 20; + optional PolicyOptions login_screen_caret_highlight_enabled_options = 21; + + // Sets the state of the mono audio accessibility feature on the login + // screen. If this policy is set to true, the mono audio will be enabled + // when the login screen is shown. If this policy is set to false, the mono + // audio will be disabled when the mono audio is shown. If the PolicyOptions + // mode was being mandatory then the user won't be able to change these + // settings. Only if PolicyOptions was being set as recommended users can + // temporarily override this setting by enabling or disabling the mono audio. + // However, the user's choice is not persistent and the default is restored + // whenever the login screen is shown anew or the user remains idle on the + // login screen for a minute. If this policy is left unset, the mono audio is + // disabled when the login screen is first shown. Users can enable or disable + // the mono audio anytime and its status on the login screen is persisted + // between users. + optional bool login_screen_mono_audio_enabled = 22; + optional PolicyOptions login_screen_mono_audio_enabled_options = 23; } message SupervisedUsersSettingsProto {
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index fee5798..0244913 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -648,6 +648,8 @@ 'DeviceLoginScreenDictationEnabled', 'DeviceLoginScreenSelectToSpeakEnabled', 'DeviceLoginScreenCursorHighlightEnabled', + 'DeviceLoginScreenCaretHighlightEnabled', + 'DeviceLoginScreenMonoAudioEnabled', ], }, { @@ -10454,6 +10456,58 @@ If this policy is left unset, the cursor highlight is disabled on the login screen initially but can be enabled by the user anytime.''', }, { + 'name': 'DeviceLoginScreenCaretHighlightEnabled', + 'owners': ['amraboelkher@chromium.org', 'emaxx@chromium.org'], + 'type': 'main', + 'schema': { 'type': 'boolean' }, + 'supported_on': ['chrome_os:79-'], + 'device_only': True, + 'features': { + 'can_be_recommended': True, + 'dynamic_refresh': True, + }, + 'example_value': True, + 'id': 614, + 'caption': '''Enable the caret highlight on the login screen''', + 'tags': [], + 'desc': '''Enable the caret highlight accessibility feature on the login screen. + + If this policy is set to true, the caret highlight will always be enabled on the login screen. + + If this policy is set to false, the caret highlight will always be disabled on the login screen. + + If you set this policy, users cannot change or override it. + + If this policy is left unset, the caret highlight is disabled on the login screen initially but can be enabled by the user anytime.''', + }, + { + 'name': 'DeviceLoginScreenMonoAudioEnabled', + 'owners': ['amraboelkher@chromium.org', 'emaxx@chromium.org'], + 'type': 'main', + 'schema': { 'type': 'boolean' }, + 'supported_on': ['chrome_os:79-'], + 'device_only': True, + 'features': { + 'can_be_recommended': True, + 'dynamic_refresh': True, + }, + 'example_value': True, + 'id': 615, + 'caption': '''Enable the mono audio on the login screen''', + 'tags': [], + 'desc': '''Enable the mono audio accessibility feature on the login screen. + + This feature allows to switch the device mode from the default stereo audio to the mono audio. + + If this policy is set to true, the mono audio will always be enabled on the login screen. + + If this policy is set to false, the mono audio will always be disabled on the login screen. + + If you set this policy, users cannot change or override it. + + If this policy is left unset, the mono audio is disabled on the login screen initially but can be enabled by the user anytime.''', + }, + { 'name': 'HideWebStoreIcon', 'owners': ['file://components/policy/resources/OWNERS'], 'type': 'main', @@ -18245,6 +18299,8 @@ 'DeviceLoginScreenDictationEnabled': 'accessibility_settings.login_screen_dictation_enabled', 'DeviceLoginScreenSelectToSpeakEnabled': 'accessibility_settings.login_screen_select_to_speak_enabled', 'DeviceLoginScreenCursorHighlightEnabled': 'accessibility_settings.login_screen_cursor_highlight_enabled', + 'DeviceLoginScreenCaretHighlightEnabled': 'accessibility_settings.login_screen_caret_highlight_enabled', + 'DeviceLoginScreenMonoAudioEnabled': 'accessibility_settings.login_screen_mono_audio_enabled', 'AttestationEnabledForDevice': 'attestation_settings.attestation_enabled', 'AttestationForContentProtectionEnabled': 'attestation_settings.content_protection_enabled', 'SystemTimezone': 'system_timezone.timezone', @@ -18745,6 +18801,6 @@ ], 'placeholders': [], 'deleted_policy_ids': [412, 546, 562, 569], - 'highest_id_currently_used': 613, + 'highest_id_currently_used': 615, 'highest_atomic_group_id_currently_used': 37 }
diff --git a/components/signin/ios/browser/BUILD.gn b/components/signin/ios/browser/BUILD.gn index 095aa04f..dd87e0b6 100644 --- a/components/signin/ios/browser/BUILD.gn +++ b/components/signin/ios/browser/BUILD.gn
@@ -7,6 +7,8 @@ sources = [ "account_consistency_service.h", "account_consistency_service.mm", + "features.cc", + "features.h", "manage_accounts_delegate.h", "wait_for_network_callback_helper.cc", "wait_for_network_callback_helper.h",
diff --git a/components/signin/ios/browser/features.cc b/components/signin/ios/browser/features.cc new file mode 100644 index 0000000..9419512 --- /dev/null +++ b/components/signin/ios/browser/features.cc
@@ -0,0 +1,16 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/signin/ios/browser/features.h" + +namespace signin { + +const base::Feature kForceStartupSigninPromo{"ForceStartupSigninPromo", + base::FEATURE_DISABLED_BY_DEFAULT}; + +bool ForceStartupSigninPromo() { + return base::FeatureList::IsEnabled(kForceStartupSigninPromo); +} + +} // namespace signin
diff --git a/components/signin/ios/browser/features.h b/components/signin/ios/browser/features.h new file mode 100644 index 0000000..5cdf203 --- /dev/null +++ b/components/signin/ios/browser/features.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 COMPONENTS_SIGNIN_IOS_BROWSER_FEATURES_H_ +#define COMPONENTS_SIGNIN_IOS_BROWSER_FEATURES_H_ + +#include "base/feature_list.h" + +namespace signin { + +// Features to trigger the startup sign-in promo at boot. +extern const base::Feature kForceStartupSigninPromo; + +// Returns true if the startup sign-in promo should be displayed at boot. +bool ForceStartupSigninPromo(); + +} // namespace signin + +#endif // COMPONENTS_SIGNIN_IOS_BROWSER_FEATURES_H_
diff --git a/components/ssl_errors_strings.grdp b/components/ssl_errors_strings.grdp index d39cd09..5026b76 100644 --- a/components/ssl_errors_strings.grdp +++ b/components/ssl_errors_strings.grdp
@@ -13,7 +13,7 @@ <message name="IDS_CERT_ERROR_EXPIRED_DETAILS" desc="Details for an expired X509 certificate [ICU Syntax]"> {1, plural, - =1 {This server could not prove that it is <ph name="DOMAIN"><strong>{0}<ex>paypal.com</ex></strong></ph>; its security certificate expired yesterday. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE">{2, date, full}<ex>Monday, July 16, 2012</ex></ph>. Does that look right? If not, you should correct your system's clock and then refresh this page.} + =1 {This server could not prove that it is <ph name="DOMAIN"><strong>{0}<ex>paypal.com</ex></strong></ph>; its security certificate expired in the last day. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE">{2, date, full}<ex>Monday, July 16, 2012</ex></ph>. Does that look right? If not, you should correct your system's clock and then refresh this page.} other {This server could not prove that it is <ph name="DOMAIN"><strong>{0}<ex>paypal.com</ex></strong></ph>; its security certificate expired # days ago. This may be caused by a misconfiguration or an attacker intercepting your connection. Your computer's clock is currently set to <ph name="CURRENT_DATE">{2, date, full}<ex>Monday, July 16, 2012</ex></ph>. Does that look right? If not, you should correct your system's clock and then refresh this page.}} </message> <message name="IDS_CERT_ERROR_EXPIRED_DESCRIPTION" desc="Description for an expired X509 certificate">
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index 6905a3bb..382d2c6e39 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -210,7 +210,6 @@ "engine_impl/non_blocking_type_commit_contribution.h", "engine_impl/nudge_handler.cc", "engine_impl/nudge_handler.h", - "engine_impl/nudge_source.cc", "engine_impl/nudge_source.h", "engine_impl/process_updates_util.cc", "engine_impl/process_updates_util.h", @@ -429,6 +428,7 @@ "//base:i18n", "//build:branding_buildflags", "//components/keyed_service/core", + "//components/variations/net", "//services/network/public/cpp", "//sql", "//third_party/cacheinvalidation", @@ -562,9 +562,9 @@ sources = [ "base/bind_to_task_runner_unittest.cc", "base/cancelation_signal_unittest.cc", + "base/client_tag_hash_unittest.cc", "base/data_type_histogram_unittest.cc", "base/enum_set_unittest.cc", - "base/hash_util_unittest.cc", "base/immutable_unittest.cc", "base/model_type_unittest.cc", "base/node_ordinal_unittest.cc",
diff --git a/components/sync/PRESUBMIT.py b/components/sync/PRESUBMIT.py index 08f919e92..062e29ea 100644 --- a/components/sync/PRESUBMIT.py +++ b/components/sync/PRESUBMIT.py
@@ -27,13 +27,6 @@ 'SUPERVISED_USER_WHITELISTS', # See previous. # Deprecated types: - 'DEPRECATED_APP_NOTIFICATIONS', - 'DEPRECATED_ARTICLES', - 'DEPRECATED_SUPERVISED_USERS', - 'DEPRECATED_SUPERVISED_USER_SHARED_SETTINGS', - 'DEPRECATED_SYNCED_NOTIFICATIONS', - 'DEPRECATED_SYNCED_NOTIFICATION_APP_INFO', - 'DEPRECATED_WIFI_CREDENTIALS', 'DEPRECATED_EXPERIMENTS'] # Root tags are used as prefixes when creating storage keys, so certain strings @@ -176,8 +169,8 @@ for line in file_contents.splitlines(): current_line_number += 1 if line.strip().startswith('//'): - # Ignore comments. - continue + # Ignore comments. + continue if start_pattern.match(line): inside_enum = True continue @@ -376,8 +369,7 @@ => 'AppSpecifics' """ return field_number.replace(FIELD_NUMBER_PREFIX, '').replace( - 'FieldNumber', 'Specifics').replace( - 'AppNotificationSpecifics', 'AppNotification') + 'FieldNumber', 'Specifics') def CheckChangeLintsClean(input_api, output_api): source_filter = lambda x: input_api.FilterSourceFile(
diff --git a/components/sync/PRESUBMIT_test.py b/components/sync/PRESUBMIT_test.py index f717bcbf..4a84129 100755 --- a/components/sync/PRESUBMIT_test.py +++ b/components/sync/PRESUBMIT_test.py
@@ -77,8 +77,7 @@ ' AppSpecifics app = 456;\n' ' AppSettingSpecifics app_setting = 789;\n' ' ExtensionSettingSpecifics extension_setting = 910;\n' - ' ManagedUserSharedSettingSpecifics managed_user_shared_setting' - ' = 915;\n' + ' ExperimentsSpecifics experiments = 161496;\n' ' //comment\n' ' }\n' '}\n' @@ -114,10 +113,9 @@ self.assertEqual(0, len(results)) def testValidChangeDeprecatedEntry(self): - results = self._testChange('{DEPRECATED_SUPERVISED_USER_SHARED_SETTINGS,' - '"MANAGED_USER_SHARED_SETTING", "managed_user_shared_settings",' - '"Managed User Shared Settings",' - 'sync_pb::EntitySpecifics::kManagedUserSharedSettingFieldNumber, 30},') + results = self._testChange('{DEPRECATED_EXPERIMENTS, "EXPERIMENTS",' + '"experiments", "Experiments",' + 'sync_pb::EntitySpecifics::kExperimentsFieldNumber, 19},') self.assertEqual(0, len(results)) def testInvalidChangeMismatchedNotificationType(self):
diff --git a/components/sync/base/BUILD.gn b/components/sync/base/BUILD.gn index 5146d93..2986bd5 100644 --- a/components/sync/base/BUILD.gn +++ b/components/sync/base/BUILD.gn
@@ -12,6 +12,8 @@ "cancelation_observer.h", "cancelation_signal.cc", "cancelation_signal.h", + "client_tag_hash.cc", + "client_tag_hash.h", "data_type_histogram.cc", "data_type_histogram.h", "encryptor.h",
diff --git a/components/sync/base/client_tag_hash.cc b/components/sync/base/client_tag_hash.cc new file mode 100644 index 0000000..04fdbe4 --- /dev/null +++ b/components/sync/base/client_tag_hash.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 "components/sync/base/client_tag_hash.h" + +#include <utility> + +#include "base/base64.h" +#include "base/hash/sha1.h" +#include "base/trace_event/memory_usage_estimator.h" +#include "components/sync/protocol/sync.pb.h" + +namespace syncer { + +// static +ClientTagHash ClientTagHash::FromUnhashed(ModelType model_type, + const std::string& client_tag) { + // Blank PB with just the field in it has termination symbol, + // handy for delimiter. + sync_pb::EntitySpecifics serialized_type; + AddDefaultFieldValue(model_type, &serialized_type); + std::string hash_input; + serialized_type.AppendToString(&hash_input); + hash_input.append(client_tag); + + std::string encode_output; + base::Base64Encode(base::SHA1HashString(hash_input), &encode_output); + return FromHashed(encode_output); +} + +// static +ClientTagHash ClientTagHash::FromHashed(std::string hash_value) { + return ClientTagHash(std::move(hash_value)); +} + +ClientTagHash::ClientTagHash() = default; + +ClientTagHash::ClientTagHash(std::string value) : value_(std::move(value)) {} + +ClientTagHash::ClientTagHash(const ClientTagHash& other) = default; + +ClientTagHash::ClientTagHash(ClientTagHash&& other) = default; + +ClientTagHash::~ClientTagHash() = default; + +ClientTagHash& ClientTagHash::operator=(const ClientTagHash& other) = default; + +ClientTagHash& ClientTagHash::operator=(ClientTagHash&& other) = default; + +size_t ClientTagHash::EstimateMemoryUsage() const { + return base::trace_event::EstimateMemoryUsage(value_); +} + +bool operator<(const ClientTagHash& lhs, const ClientTagHash& rhs) { + return lhs.value() < rhs.value(); +} + +bool operator==(const ClientTagHash& lhs, const ClientTagHash& rhs) { + return lhs.value() == rhs.value(); +} + +bool operator!=(const ClientTagHash& lhs, const ClientTagHash& rhs) { + return lhs.value() != rhs.value(); +} + +std::ostream& operator<<(std::ostream& os, + const ClientTagHash& client_tag_hash) { + return os << client_tag_hash.value(); +} + +} // namespace syncer
diff --git a/components/sync/base/client_tag_hash.h b/components/sync/base/client_tag_hash.h new file mode 100644 index 0000000..21c7d18 --- /dev/null +++ b/components/sync/base/client_tag_hash.h
@@ -0,0 +1,53 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SYNC_BASE_CLIENT_TAG_HASH_H_ +#define COMPONENTS_SYNC_BASE_CLIENT_TAG_HASH_H_ + +#include <iosfwd> +#include <string> + +#include "components/sync/base/model_type.h" + +namespace syncer { + +// Represents a client defined unique hash for sync entities. Hash is derived +// from client tag, and should be used as |client_defined_unique_tag| for +// SyncEntity at least for CommitMessages. For convenience it supports storing +// in ordered stl containers, logging and equality comparisons. +class ClientTagHash { + public: + // Creates ClientTagHash based on |client_tag|. + static ClientTagHash FromUnhashed(ModelType type, + const std::string& client_tag); + + // Creates ClientTagHash from already hashed client tag. + static ClientTagHash FromHashed(std::string hash_value); + + ClientTagHash(); + ClientTagHash(const ClientTagHash& other); + ClientTagHash(ClientTagHash&& other); + ~ClientTagHash(); + + ClientTagHash& operator=(const ClientTagHash& other); + ClientTagHash& operator=(ClientTagHash&& other); + + const std::string& value() const { return value_; } + + size_t EstimateMemoryUsage() const; + + private: + explicit ClientTagHash(std::string value); + std::string value_; +}; + +bool operator<(const ClientTagHash& lhs, const ClientTagHash& rhs); +bool operator==(const ClientTagHash& lhs, const ClientTagHash& rhs); +bool operator!=(const ClientTagHash& lhs, const ClientTagHash& rhs); +std::ostream& operator<<(std::ostream& os, + const ClientTagHash& client_tag_hash); + +} // namespace syncer + +#endif // COMPONENTS_SYNC_BASE_CLIENT_TAG_HASH_H_
diff --git a/components/sync/base/client_tag_hash_unittest.cc b/components/sync/base/client_tag_hash_unittest.cc new file mode 100644 index 0000000..35dfc17 --- /dev/null +++ b/components/sync/base/client_tag_hash_unittest.cc
@@ -0,0 +1,24 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/sync/base/client_tag_hash.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace syncer { + +// Tests that the hashing algorithm has not changed. +TEST(ClientTagHashTest, ShouldGenerateFromUnhashed) { + EXPECT_EQ("iNFQtRFQb+IZcn1kKUJEZDDkLs4=", + ClientTagHash::FromUnhashed(PREFERENCES, "tag1").value()); + EXPECT_EQ("gO1cPZQXaM73sHOvSA+tKCKFs58=", + ClientTagHash::FromUnhashed(AUTOFILL, "tag1").value()); + + EXPECT_EQ("XYxkF7bhS4eItStFgiOIAU23swI=", + ClientTagHash::FromUnhashed(PREFERENCES, "tag2").value()); + EXPECT_EQ("GFiWzo5NGhjLlN+OyCfhy28DJTQ=", + ClientTagHash::FromUnhashed(AUTOFILL, "tag2").value()); +} + +} // namespace syncer
diff --git a/components/sync/base/data_type_histogram.h b/components/sync/base/data_type_histogram.h index 4c5131b..c9b7674 100644 --- a/components/sync/base/data_type_histogram.h +++ b/components/sync/base/data_type_histogram.h
@@ -89,18 +89,9 @@ case ::syncer::EXTENSION_SETTINGS: \ PER_DATA_TYPE_MACRO("ExtensionSettings"); \ break; \ - case ::syncer::DEPRECATED_APP_NOTIFICATIONS: \ - PER_DATA_TYPE_MACRO("AppNotifications"); \ - break; \ case ::syncer::HISTORY_DELETE_DIRECTIVES: \ PER_DATA_TYPE_MACRO("HistoryDeleteDirectives"); \ break; \ - case ::syncer::DEPRECATED_SYNCED_NOTIFICATIONS: \ - PER_DATA_TYPE_MACRO("SyncedNotifications"); \ - break; \ - case ::syncer::DEPRECATED_SYNCED_NOTIFICATION_APP_INFO: \ - PER_DATA_TYPE_MACRO("SyncedNotificationAppInfo"); \ - break; \ case ::syncer::DICTIONARY: \ PER_DATA_TYPE_MACRO("Dictionary"); \ break; \ @@ -119,21 +110,9 @@ case ::syncer::SUPERVISED_USER_SETTINGS: \ PER_DATA_TYPE_MACRO("ManagedUserSetting"); \ break; \ - case ::syncer::DEPRECATED_SUPERVISED_USERS: \ - PER_DATA_TYPE_MACRO("ManagedUser"); \ - break; \ - case ::syncer::DEPRECATED_SUPERVISED_USER_SHARED_SETTINGS: \ - PER_DATA_TYPE_MACRO("ManagedUserSharedSetting"); \ - break; \ - case ::syncer::DEPRECATED_ARTICLES: \ - PER_DATA_TYPE_MACRO("Article"); \ - break; \ case ::syncer::APP_LIST: \ PER_DATA_TYPE_MACRO("AppList"); \ break; \ - case ::syncer::DEPRECATED_WIFI_CREDENTIALS: \ - PER_DATA_TYPE_MACRO("WifiCredentials"); \ - break; \ case ::syncer::SUPERVISED_USER_WHITELISTS: \ PER_DATA_TYPE_MACRO("ManagedUserWhitelist"); \ break; \
diff --git a/components/sync/base/hash_util.cc b/components/sync/base/hash_util.cc index e5e7a0f1..38251821 100644 --- a/components/sync/base/hash_util.cc +++ b/components/sync/base/hash_util.cc
@@ -6,30 +6,25 @@ #include "base/base64.h" #include "base/hash/sha1.h" +#include "components/sync/base/model_type.h" #include "components/sync/protocol/sync.pb.h" namespace syncer { -std::string GenerateSyncableHash(ModelType model_type, - const std::string& client_tag) { +std::string GenerateSyncableBookmarkHash( + const std::string& originator_cache_guid, + const std::string& originator_client_item_id) { // Blank PB with just the field in it has termination symbol, // handy for delimiter. sync_pb::EntitySpecifics serialized_type; - AddDefaultFieldValue(model_type, &serialized_type); + AddDefaultFieldValue(BOOKMARKS, &serialized_type); std::string hash_input; serialized_type.AppendToString(&hash_input); - hash_input.append(client_tag); + hash_input.append(originator_cache_guid + originator_client_item_id); std::string encode_output; base::Base64Encode(base::SHA1HashString(hash_input), &encode_output); return encode_output; } -std::string GenerateSyncableBookmarkHash( - const std::string& originator_cache_guid, - const std::string& originator_client_item_id) { - return GenerateSyncableHash( - BOOKMARKS, originator_cache_guid + originator_client_item_id); -} - } // namespace syncer
diff --git a/components/sync/base/hash_util.h b/components/sync/base/hash_util.h index efde407f..8f8de24c 100644 --- a/components/sync/base/hash_util.h +++ b/components/sync/base/hash_util.h
@@ -7,14 +7,8 @@ #include <string> -#include "components/sync/base/model_type.h" - namespace syncer { -// Generates a fixed-length tag for the given string under the given model_type. -std::string GenerateSyncableHash(ModelType model_type, - const std::string& client_tag); - // A helper for generating the bookmark type's tag. This is required in more // than one place, so we define the algorithm here to make sure the // implementation is consistent.
diff --git a/components/sync/base/hash_util_unittest.cc b/components/sync/base/hash_util_unittest.cc deleted file mode 100644 index c0925e89..0000000 --- a/components/sync/base/hash_util_unittest.cc +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 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. - -#include "components/sync/base/hash_util.h" - -#include "testing/gtest/include/gtest/gtest.h" - -namespace syncer { - -// Tests that the hashing algorithm has not changed. -TEST(SyncHashUtilTest, GenerateSyncableHash) { - EXPECT_EQ("OyaXV5mEzrPS4wbogmtKvRfekAI=", - GenerateSyncableHash(BOOKMARKS, "tag1")); - EXPECT_EQ("iNFQtRFQb+IZcn1kKUJEZDDkLs4=", - GenerateSyncableHash(PREFERENCES, "tag1")); - EXPECT_EQ("gO1cPZQXaM73sHOvSA+tKCKFs58=", - GenerateSyncableHash(AUTOFILL, "tag1")); - - EXPECT_EQ("A0eYIHXM1/jVwKDDp12Up20IkKY=", - GenerateSyncableHash(BOOKMARKS, "tag2")); - EXPECT_EQ("XYxkF7bhS4eItStFgiOIAU23swI=", - GenerateSyncableHash(PREFERENCES, "tag2")); - EXPECT_EQ("GFiWzo5NGhjLlN+OyCfhy28DJTQ=", - GenerateSyncableHash(AUTOFILL, "tag2")); -} - -} // namespace syncer
diff --git a/components/sync/base/model_type.cc b/components/sync/base/model_type.cc index f8cd9d7..7fdb224 100644 --- a/components/sync/base/model_type.cc +++ b/components/sync/base/model_type.cc
@@ -9,7 +9,6 @@ #include "base/stl_util.h" #include "base/strings/string_split.h" #include "base/values.h" -#include "components/sync/protocol/app_notification_specifics.pb.h" #include "components/sync/protocol/app_setting_specifics.pb.h" #include "components/sync/protocol/app_specifics.pb.h" #include "components/sync/protocol/autofill_specifics.pb.h" @@ -107,21 +106,10 @@ "Extension settings", sync_pb::EntitySpecifics::kExtensionSettingFieldNumber, ModelTypeForHistograms::kExtensionSettings}, - {DEPRECATED_APP_NOTIFICATIONS, "APP_NOTIFICATION", "app_notifications", - "App Notifications", sync_pb::EntitySpecifics::kAppNotificationFieldNumber, - ModelTypeForHistograms::kDeprecatedAppNotifications}, {HISTORY_DELETE_DIRECTIVES, "HISTORY_DELETE_DIRECTIVE", "history_delete_directives", "History Delete Directives", sync_pb::EntitySpecifics::kHistoryDeleteDirectiveFieldNumber, ModelTypeForHistograms::kHistoryDeleteDirectices}, - {DEPRECATED_SYNCED_NOTIFICATIONS, "SYNCED_NOTIFICATION", - "synced_notifications", "Synced Notifications", - sync_pb::EntitySpecifics::kSyncedNotificationFieldNumber, - ModelTypeForHistograms::kDeprecatedSyncedNotifications}, - {DEPRECATED_SYNCED_NOTIFICATION_APP_INFO, "SYNCED_NOTIFICATION_APP_INFO", - "synced_notification_app_info", "Synced Notification App Info", - sync_pb::EntitySpecifics::kSyncedNotificationAppInfoFieldNumber, - ModelTypeForHistograms::kDeprecatedSyncedNotificationAppInfo}, {DICTIONARY, "DICTIONARY", "dictionary", "Dictionary", sync_pb::EntitySpecifics::kDictionaryFieldNumber, ModelTypeForHistograms::kDictionary}, @@ -142,22 +130,9 @@ "Managed User Settings", sync_pb::EntitySpecifics::kManagedUserSettingFieldNumber, ModelTypeForHistograms::kSupervisedUserSettings}, - {DEPRECATED_SUPERVISED_USERS, "MANAGED_USER", "managed_users", - "Managed Users", sync_pb::EntitySpecifics::kManagedUserFieldNumber, - ModelTypeForHistograms::kDeprecatedSupervisedUsers}, - {DEPRECATED_SUPERVISED_USER_SHARED_SETTINGS, "MANAGED_USER_SHARED_SETTING", - "managed_user_shared_settings", "Managed User Shared Settings", - sync_pb::EntitySpecifics::kManagedUserSharedSettingFieldNumber, - ModelTypeForHistograms::kDeprecatedSupervisedUserSharedSettings}, - {DEPRECATED_ARTICLES, "ARTICLE", "articles", "Articles", - sync_pb::EntitySpecifics::kArticleFieldNumber, - ModelTypeForHistograms::kDeprecatedArticles}, {APP_LIST, "APP_LIST", "app_list", "App List", sync_pb::EntitySpecifics::kAppListFieldNumber, ModelTypeForHistograms::kAppList}, - {DEPRECATED_WIFI_CREDENTIALS, "WIFI_CREDENTIAL", "wifi_credentials", - "WiFi Credentials", sync_pb::EntitySpecifics::kWifiCredentialFieldNumber, - ModelTypeForHistograms::kDeprecatedWifiCredentials}, {SUPERVISED_USER_WHITELISTS, "MANAGED_USER_WHITELIST", "managed_user_whitelists", "Managed User Whitelists", sync_pb::EntitySpecifics::kManagedUserWhitelistFieldNumber, @@ -207,11 +182,11 @@ static_assert(base::size(kModelTypeInfoMap) == ModelType::NUM_ENTRIES, "kModelTypeInfoMap should have ModelType::NUM_ENTRIES elements"); -static_assert(46 == syncer::ModelType::NUM_ENTRIES, +static_assert(39 == syncer::ModelType::NUM_ENTRIES, "When adding a new type, update enum SyncModelTypes in enums.xml " "and suffix SyncModelType in histograms.xml."); -static_assert(46 == syncer::ModelType::NUM_ENTRIES, +static_assert(39 == syncer::ModelType::NUM_ENTRIES, "When adding a new type, update kAllocatorDumpNameWhitelist in " "base/trace_event/memory_infra_background_whitelist.cc."); @@ -266,18 +241,9 @@ case EXTENSION_SETTINGS: specifics->mutable_extension_setting(); break; - case DEPRECATED_APP_NOTIFICATIONS: - specifics->mutable_app_notification(); - break; case HISTORY_DELETE_DIRECTIVES: specifics->mutable_history_delete_directive(); break; - case DEPRECATED_SYNCED_NOTIFICATIONS: - specifics->mutable_synced_notification(); - break; - case DEPRECATED_SYNCED_NOTIFICATION_APP_INFO: - specifics->mutable_synced_notification_app_info(); - break; case DICTIONARY: specifics->mutable_dictionary(); break; @@ -296,21 +262,9 @@ case SUPERVISED_USER_SETTINGS: specifics->mutable_managed_user_setting(); break; - case DEPRECATED_SUPERVISED_USERS: - specifics->mutable_managed_user(); - break; - case DEPRECATED_SUPERVISED_USER_SHARED_SETTINGS: - specifics->mutable_managed_user_shared_setting(); - break; - case DEPRECATED_ARTICLES: - specifics->mutable_article(); - break; case APP_LIST: specifics->mutable_app_list(); break; - case DEPRECATED_WIFI_CREDENTIALS: - specifics->mutable_wifi_credential(); - break; case SUPERVISED_USER_WHITELISTS: specifics->mutable_managed_user_whitelist(); break; @@ -395,7 +349,7 @@ } ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics) { - static_assert(46 == ModelType::NUM_ENTRIES, + static_assert(39 == ModelType::NUM_ENTRIES, "When adding new protocol types, the following type lookup " "logic must be updated."); if (specifics.has_bookmark()) @@ -428,14 +382,8 @@ return APP_SETTINGS; if (specifics.has_extension_setting()) return EXTENSION_SETTINGS; - if (specifics.has_app_notification()) - return DEPRECATED_APP_NOTIFICATIONS; if (specifics.has_history_delete_directive()) return HISTORY_DELETE_DIRECTIVES; - if (specifics.has_synced_notification()) - return DEPRECATED_SYNCED_NOTIFICATIONS; - if (specifics.has_synced_notification_app_info()) - return DEPRECATED_SYNCED_NOTIFICATION_APP_INFO; if (specifics.has_dictionary()) return DICTIONARY; if (specifics.has_favicon_image()) @@ -448,16 +396,8 @@ return PRIORITY_PREFERENCES; if (specifics.has_managed_user_setting()) return SUPERVISED_USER_SETTINGS; - if (specifics.has_managed_user()) - return DEPRECATED_SUPERVISED_USERS; - if (specifics.has_managed_user_shared_setting()) - return DEPRECATED_SUPERVISED_USER_SHARED_SETTINGS; - if (specifics.has_article()) - return DEPRECATED_ARTICLES; if (specifics.has_app_list()) return APP_LIST; - if (specifics.has_wifi_credential()) - return DEPRECATED_WIFI_CREDENTIALS; if (specifics.has_managed_user_whitelist()) return SUPERVISED_USER_WHITELISTS; if (specifics.has_arc_package()) @@ -489,7 +429,7 @@ } ModelTypeSet EncryptableUserTypes() { - static_assert(46 == ModelType::NUM_ENTRIES, + static_assert(39 == ModelType::NUM_ENTRIES, "If adding an unencryptable type, remove from " "encryptable_user_types below."); ModelTypeSet encryptable_user_types = UserTypes(); @@ -497,11 +437,6 @@ encryptable_user_types.Remove(AUTOFILL_WALLET_DATA); // We never encrypt history delete directives. encryptable_user_types.Remove(HISTORY_DELETE_DIRECTIVES); - // Synced notifications are not encrypted since the server must see changes. - encryptable_user_types.Remove(DEPRECATED_SYNCED_NOTIFICATIONS); - // Synced Notification App Info does not have private data, so it is not - // encrypted. - encryptable_user_types.Remove(DEPRECATED_SYNCED_NOTIFICATION_APP_INFO); // Device info data is not encrypted because it might be synced before // encryption is ready. encryptable_user_types.Remove(DEVICE_INFO); @@ -510,11 +445,6 @@ encryptable_user_types.Remove(PRIORITY_PREFERENCES); // Supervised user settings are not encrypted since they are set server-side. encryptable_user_types.Remove(SUPERVISED_USER_SETTINGS); - // Supervised users are not encrypted since they are managed server-side. - encryptable_user_types.Remove(DEPRECATED_SUPERVISED_USERS); - // Supervised user shared settings are not encrypted since they are managed - // server-side and shared between manager and supervised user. - encryptable_user_types.Remove(DEPRECATED_SUPERVISED_USER_SHARED_SETTINGS); // Supervised user whitelists are not encrypted since they are managed // server-side. encryptable_user_types.Remove(SUPERVISED_USER_WHITELISTS); @@ -549,19 +479,6 @@ return kModelTypeInfoMap[model_type].notification_type; } -// The normal rules about histograms apply here. Always append to the bottom of -// the list, and be careful to not reuse integer values that have already been -// assigned. -// -// Don't forget to update the "SyncModelTypes" enum in enums.xml when you make -// changes to this list. -int ModelTypeToHistogramInt(ModelType model_type) { - DCHECK_GE(model_type, UNSPECIFIED); - DCHECK_LT(model_type, ModelType::NUM_ENTRIES); - return static_cast<int>( - kModelTypeInfoMap[model_type].model_type_histogram_val); -} - ModelTypeForHistograms ModelTypeHistogramValue(ModelType model_type) { DCHECK_GE(model_type, UNSPECIFIED); DCHECK_LT(model_type, ModelType::NUM_ENTRIES); @@ -572,7 +489,7 @@ DCHECK_GE(model_type, UNSPECIFIED); DCHECK_LT(model_type, ModelType::NUM_ENTRIES); // Make sure the value is stable and positive. - return ModelTypeToHistogramInt(model_type) + 1; + return static_cast<int>(ModelTypeHistogramValue(model_type)) + 1; } std::unique_ptr<base::Value> ModelTypeToValue(ModelType model_type) {
diff --git a/components/sync/base/model_type.h b/components/sync/base/model_type.h index d78f394..1ee889c7 100644 --- a/components/sync/base/model_type.h +++ b/components/sync/base/model_type.h
@@ -92,13 +92,9 @@ APP_SETTINGS, // An extension setting from the extension settings API. EXTENSION_SETTINGS, - // Deprecated. - DEPRECATED_APP_NOTIFICATIONS, // History delete directives, used to propagate history deletions (e.g. based // on a time range). HISTORY_DELETE_DIRECTIVES, - DEPRECATED_SYNCED_NOTIFICATIONS, - DEPRECATED_SYNCED_NOTIFICATION_APP_INFO, // Custom spelling dictionary entries. DICTIONARY, // Favicon images, including both the image URL and the actual pixels. @@ -114,12 +110,8 @@ PRIORITY_PREFERENCES, // Supervised user settings. Cannot be encrypted. SUPERVISED_USER_SETTINGS, - DEPRECATED_SUPERVISED_USERS, - DEPRECATED_SUPERVISED_USER_SHARED_SETTINGS, - DEPRECATED_ARTICLES, // App List items, used by the ChromeOS app launcher. APP_LIST, - DEPRECATED_WIFI_CREDENTIALS, // Supervised user whitelists. Each item contains a CRX ID (like an extension // ID) and a name. SUPERVISED_USER_WHITELISTS, @@ -256,16 +248,12 @@ BOOKMARKS, PREFERENCES, PASSWORDS, AUTOFILL_PROFILE, AUTOFILL, AUTOFILL_WALLET_DATA, AUTOFILL_WALLET_METADATA, THEMES, TYPED_URLS, EXTENSIONS, SEARCH_ENGINES, SESSIONS, APPS, APP_SETTINGS, - EXTENSION_SETTINGS, DEPRECATED_APP_NOTIFICATIONS, - HISTORY_DELETE_DIRECTIVES, DEPRECATED_SYNCED_NOTIFICATIONS, - DEPRECATED_SYNCED_NOTIFICATION_APP_INFO, DICTIONARY, FAVICON_IMAGES, + EXTENSION_SETTINGS, HISTORY_DELETE_DIRECTIVES, DICTIONARY, FAVICON_IMAGES, FAVICON_TRACKING, DEVICE_INFO, PRIORITY_PREFERENCES, - SUPERVISED_USER_SETTINGS, DEPRECATED_SUPERVISED_USERS, - DEPRECATED_SUPERVISED_USER_SHARED_SETTINGS, DEPRECATED_ARTICLES, APP_LIST, - DEPRECATED_WIFI_CREDENTIALS, SUPERVISED_USER_WHITELISTS, ARC_PACKAGE, - PRINTERS, READING_LIST, USER_EVENTS, NIGORI, DEPRECATED_EXPERIMENTS, - MOUNTAIN_SHARES, USER_CONSENTS, SEND_TAB_TO_SELF, SECURITY_EVENTS, - WEB_APPS, WIFI_CONFIGURATIONS); + SUPERVISED_USER_SETTINGS, APP_LIST, SUPERVISED_USER_WHITELISTS, + ARC_PACKAGE, PRINTERS, READING_LIST, USER_EVENTS, NIGORI, + DEPRECATED_EXPERIMENTS, MOUNTAIN_SHARES, USER_CONSENTS, SEND_TAB_TO_SELF, + SECURITY_EVENTS, WEB_APPS, WIFI_CONFIGURATIONS); } // These are the normal user-controlled types. This is to distinguish from @@ -364,9 +352,6 @@ // The mapping from ModelType to integer is defined here. It defines a // completely different order than the ModelType enum itself. The mapping should // match the SyncModelTypes mapping from integer to labels defined in enums.xml. -// TODO(crbug.com/1007293): Update all histogram recording sites to use -// ModelTypeHistogramValue() and remove ModelTypeToHistogramInt(); -int ModelTypeToHistogramInt(ModelType model_type); ModelTypeForHistograms ModelTypeHistogramValue(ModelType model_type); // Returns for every model_type a positive unique integer that is stable over
diff --git a/components/sync/base/user_selectable_type.cc b/components/sync/base/user_selectable_type.cc index df12e4d..b792ec5 100644 --- a/components/sync/base/user_selectable_type.cc +++ b/components/sync/base/user_selectable_type.cc
@@ -79,7 +79,10 @@ } int UserSelectableTypeToHistogramInt(UserSelectableType type) { - return ModelTypeToHistogramInt(UserSelectableTypeToCanonicalModelType(type)); + // TODO(crbug.com/1007293): Use ModelTypeHistogramValue instead of casting to + // int. + return static_cast<int>( + ModelTypeHistogramValue(UserSelectableTypeToCanonicalModelType(type))); } } // namespace syncer
diff --git a/components/sync/driver/about_sync_util.cc b/components/sync/driver/about_sync_util.cc index 2536557..4336e2e0 100644 --- a/components/sync/driver/about_sync_util.cc +++ b/components/sync/driver/about_sync_util.cc
@@ -428,15 +428,6 @@ section_that_cycle->AddIntStat("Committed Count"); Stat<int>* entries = section_that_cycle->AddIntStat("Entries"); - Section* section_nudge_info = - section_list.AddSection("Nudge Source Counters"); - Stat<int>* nudge_source_notification = - section_nudge_info->AddIntStat("Server Invalidations"); - Stat<int>* nudge_source_local = - section_nudge_info->AddIntStat("Local Changes"); - Stat<int>* nudge_source_local_refresh = - section_nudge_info->AddIntStat("Local Refreshes"); - // Populate all the fields we declared above. client_version->Set(GetVersionString(channel)); @@ -566,13 +557,6 @@ entries->Set(static_cast<int>(snapshot.num_entries())); } - // Nudge Source Counters. - if (is_status_valid) { - nudge_source_notification->Set(full_status.nudge_source_notification); - nudge_source_local->Set(full_status.nudge_source_local); - nudge_source_local_refresh->Set(full_status.nudge_source_local_refresh); - } - // This list of sections belongs in the 'details' field of the returned // message. about_info->SetKey(kDetailsKey, section_list.ToValue());
diff --git a/components/sync/driver/async_directory_type_controller.cc b/components/sync/driver/async_directory_type_controller.cc index 34c8c55..971301a1 100644 --- a/components/sync/driver/async_directory_type_controller.cc +++ b/components/sync/driver/async_directory_type_controller.cc
@@ -211,8 +211,7 @@ DCHECK(CalledOnValidThread()); // TODO(wychen): enum uma should be strongly typed. crbug.com/661401 UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures2", - ModelTypeToHistogramInt(type()), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(type())); #define PER_DATA_TYPE_MACRO(type_str) \ UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ MAX_CONFIGURE_RESULT);
diff --git a/components/sync/driver/data_type_manager_impl.cc b/components/sync/driver/data_type_manager_impl.cc index 1e15945f..0f18f383 100644 --- a/components/sync/driver/data_type_manager_impl.cc +++ b/components/sync/driver/data_type_manager_impl.cc
@@ -297,8 +297,7 @@ for (ModelType type : last_requested_types_) { // TODO(wychen): enum uma should be strongly typed. crbug.com/661401 UMA_HISTOGRAM_ENUMERATION("Sync.ConfigureDataTypes", - ModelTypeToHistogramInt(type), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(type)); } }
diff --git a/components/sync/driver/frontend_data_type_controller.cc b/components/sync/driver/frontend_data_type_controller.cc index 5ab8d202..48f789f66 100644 --- a/components/sync/driver/frontend_data_type_controller.cc +++ b/components/sync/driver/frontend_data_type_controller.cc
@@ -235,10 +235,8 @@ void FrontendDataTypeController::RecordStartFailure(ConfigureResult result) { DCHECK(CalledOnValidThread()); - // TODO(wychen): enum uma should be strongly typed. crbug.com/661401 UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures2", - ModelTypeToHistogramInt(type()), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(type())); #define PER_DATA_TYPE_MACRO(type_str) \ UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ MAX_CONFIGURE_RESULT);
diff --git a/components/sync/driver/generic_change_processor_unittest.cc b/components/sync/driver/generic_change_processor_unittest.cc index fc397ea..492d79c 100644 --- a/components/sync/driver/generic_change_processor_unittest.cc +++ b/components/sync/driver/generic_change_processor_unittest.cc
@@ -11,6 +11,7 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/test/task_environment.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/model_type.h" #include "components/sync/driver/data_type_manager.h" #include "components/sync/driver/sync_api_component_factory_mock.h" @@ -295,7 +296,7 @@ ASSERT_EQ(sync_data.size(), 1U); ASSERT_EQ("session tag 2", sync_data[0].GetSpecifics().session().session_tag()); - EXPECT_FALSE(SyncDataRemote(sync_data[0]).GetClientTagHash().empty()); + EXPECT_FALSE(SyncDataRemote(sync_data[0]).GetClientTagHash().value().empty()); } } // namespace
diff --git a/components/sync/driver/glue/sync_engine_backend.cc b/components/sync/driver/glue/sync_engine_backend.cc index 4507524..4953d03 100644 --- a/components/sync/driver/glue/sync_engine_backend.cc +++ b/components/sync/driver/glue/sync_engine_backend.cc
@@ -61,15 +61,14 @@ const base::FilePath::CharType kNigoriStorageFilename[] = FILE_PATH_LITERAL("Nigori.bin"); -void RecordPerModelTypeInvalidation(int model_type, bool is_grouped) { - UMA_HISTOGRAM_ENUMERATION("Sync.InvalidationPerModelType", model_type, - static_cast<int>(syncer::ModelType::NUM_ENTRIES)); +void RecordPerModelTypeInvalidation(ModelTypeForHistograms value, + bool is_grouped) { + UMA_HISTOGRAM_ENUMERATION("Sync.InvalidationPerModelType", value); if (!is_grouped) { // When recording metrics it's important to distinguish between // many/one case, since "many" aka grouped case is only common in // the deprecated implementation. - UMA_HISTOGRAM_ENUMERATION("Sync.NonGroupedInvalidation", model_type, - static_cast<int>(syncer::ModelType::NUM_ENTRIES)); + UMA_HISTOGRAM_ENUMERATION("Sync.NonGroupedInvalidation", value); } } @@ -293,7 +292,7 @@ << ObjectIdToString(object_id); } else { bool is_grouped = (ids.size() != 1); - RecordPerModelTypeInvalidation(ModelTypeToHistogramInt(type), is_grouped); + RecordPerModelTypeInvalidation(ModelTypeHistogramValue(type), is_grouped); SingleObjectInvalidationSet invalidation_set = invalidation_map.ForObject(object_id); for (Invalidation invalidation : invalidation_set) { @@ -303,8 +302,7 @@ if (!is_grouped && !invalidation.is_unknown_version()) { UMA_HISTOGRAM_ENUMERATION("Sync.NonGroupedInvalidationKnownVersion", - ModelTypeToHistogramInt(type), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(type)); } std::unique_ptr<InvalidationInterface> inv_adapter( new InvalidationAdapter(invalidation));
diff --git a/components/sync/driver/model_association_manager.cc b/components/sync/driver/model_association_manager.cc index 895f4762..8d2bec1 100644 --- a/components/sync/driver/model_association_manager.cc +++ b/components/sync/driver/model_association_manager.cc
@@ -36,17 +36,13 @@ // in parallel with the UI types. PASSWORDS, AUTOFILL, AUTOFILL_PROFILE, AUTOFILL_WALLET_DATA, AUTOFILL_WALLET_METADATA, EXTENSION_SETTINGS, APP_SETTINGS, TYPED_URLS, - HISTORY_DELETE_DIRECTIVES, DEPRECATED_SYNCED_NOTIFICATIONS, - DEPRECATED_SYNCED_NOTIFICATION_APP_INFO, + HISTORY_DELETE_DIRECTIVES, // UI thread data types. BOOKMARKS, PREFERENCES, PRIORITY_PREFERENCES, EXTENSIONS, APPS, APP_LIST, - ARC_PACKAGE, READING_LIST, THEMES, SEARCH_ENGINES, SESSIONS, - DEPRECATED_APP_NOTIFICATIONS, DICTIONARY, FAVICON_IMAGES, FAVICON_TRACKING, - PRINTERS, USER_CONSENTS, USER_EVENTS, SUPERVISED_USER_SETTINGS, - SUPERVISED_USER_WHITELISTS, DEPRECATED_WIFI_CREDENTIALS, - DEPRECATED_SUPERVISED_USERS, MOUNTAIN_SHARES, - DEPRECATED_SUPERVISED_USER_SHARED_SETTINGS, DEPRECATED_ARTICLES, + ARC_PACKAGE, READING_LIST, THEMES, SEARCH_ENGINES, SESSIONS, DICTIONARY, + FAVICON_IMAGES, FAVICON_TRACKING, PRINTERS, USER_CONSENTS, USER_EVENTS, + SUPERVISED_USER_SETTINGS, SUPERVISED_USER_WHITELISTS, MOUNTAIN_SHARES, SEND_TAB_TO_SELF, SECURITY_EVENTS, WEB_APPS, WIFI_CONFIGURATIONS}; static_assert(base::size(kStartOrder) == @@ -451,8 +447,7 @@ dtc->state() != DataTypeController::STOPPING) { // TODO(wychen): enum uma should be strongly typed. crbug.com/661401 UMA_HISTOGRAM_ENUMERATION("Sync.ConfigureFailed", - ModelTypeToHistogramInt(dtc->type()), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(dtc->type())); StopDatatypeImpl(SyncError(FROM_HERE, SyncError::DATATYPE_ERROR, "Association timed out.", dtc->type()), STOP_SYNC, dtc, base::DoNothing());
diff --git a/components/sync/driver/model_type_controller.cc b/components/sync/driver/model_type_controller.cc index 1fbf4f15..8133aad 100644 --- a/components/sync/driver/model_type_controller.cc +++ b/components/sync/driver/model_type_controller.cc
@@ -299,22 +299,14 @@ void ModelTypeController::RecordStartFailure() const { DCHECK(CalledOnValidThread()); - // TODO(wychen): enum uma should be strongly typed. crbug.com/661401 - // This is not strongly typed because historically, ModelTypeToHistogramInt() - // defines quite a different order from the type() enum. UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures2", - ModelTypeToHistogramInt(type()), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(type())); } void ModelTypeController::RecordRunFailure() const { DCHECK(CalledOnValidThread()); - // TODO(wychen): enum uma should be strongly typed. crbug.com/661401 - // This is not strongly typed because historically, ModelTypeToHistogramInt() - // defines quite a different order from the type() enum. UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures2", - ModelTypeToHistogramInt(type()), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(type())); } void ModelTypeController::OnDelegateStarted(
diff --git a/components/sync/driver/model_type_controller_unittest.cc b/components/sync/driver/model_type_controller_unittest.cc index d4c99d69..32f69fa 100644 --- a/components/sync/driver/model_type_controller_unittest.cc +++ b/components/sync/driver/model_type_controller_unittest.cc
@@ -301,7 +301,7 @@ base::RunLoop().RunUntilIdle(); EXPECT_EQ(DataTypeController::FAILED, controller()->state()); histogram_tester.ExpectBucketCount( - kStartFailuresHistogram, ModelTypeToHistogramInt(kTestModelType), 1); + kStartFailuresHistogram, ModelTypeHistogramValue(kTestModelType), 1); histogram_tester.ExpectTotalCount(kRunFailuresHistogram, 0); } @@ -444,7 +444,7 @@ base::RunLoop().RunUntilIdle(); EXPECT_EQ(DataTypeController::FAILED, controller()->state()); histogram_tester.ExpectBucketCount(kStartFailuresHistogram, - ModelTypeToHistogramInt(kTestModelType), + ModelTypeHistogramValue(kTestModelType), /*count=*/1); histogram_tester.ExpectTotalCount(kRunFailuresHistogram, 0); } @@ -654,7 +654,7 @@ EXPECT_EQ(DataTypeController::FAILED, controller()->state()); histogram_tester.ExpectTotalCount(kStartFailuresHistogram, 0); histogram_tester.ExpectBucketCount(kRunFailuresHistogram, - ModelTypeToHistogramInt(kTestModelType), + ModelTypeHistogramValue(kTestModelType), /*count=*/1); }
diff --git a/components/sync/driver/startup_controller.cc b/components/sync/driver/startup_controller.cc index 233162a..5ddbe0a4 100644 --- a/components/sync/driver/startup_controller.cc +++ b/components/sync/driver/startup_controller.cc
@@ -162,10 +162,8 @@ // Measure the time spent waiting for init and the type that triggered it. // We could measure the time spent deferred on a per-datatype basis, but // for now this is probably sufficient. - // TODO(wychen): enum uma should be strongly typed. crbug.com/661401 UMA_HISTOGRAM_ENUMERATION("Sync.Startup.TypeTriggeringInit", - ModelTypeToHistogramInt(type), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(type)); if (!start_up_time_.is_null()) { RecordTimeDeferred(); UMA_HISTOGRAM_ENUMERATION("Sync.Startup.DeferredInitTrigger",
diff --git a/components/sync/driver/sync_user_settings_impl.cc b/components/sync/driver/sync_user_settings_impl.cc index a4faac8..30c1ea9 100644 --- a/components/sync/driver/sync_user_settings_impl.cc +++ b/components/sync/driver/sync_user_settings_impl.cc
@@ -186,7 +186,7 @@ types.RetainAll(registered_model_types_); } - static_assert(46 == ModelType::NUM_ENTRIES, + static_assert(39 == ModelType::NUM_ENTRIES, "If adding a new sync data type, update the list below below if" " you want to disable the new data type for local sync."); types.PutAll(ControlTypes());
diff --git a/components/sync/engine/net/DEPS b/components/sync/engine/net/DEPS index 5d6c237..2fb0451 100644 --- a/components/sync/engine/net/DEPS +++ b/components/sync/engine/net/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/variations", "+net", "+services/network/public/cpp", "+services/network/test",
diff --git a/components/sync/engine/net/http_bridge.cc b/components/sync/engine/net/http_bridge.cc index e0dab5a..84ce13c7 100644 --- a/components/sync/engine/net/http_bridge.cc +++ b/components/sync/engine/net/http_bridge.cc
@@ -19,6 +19,7 @@ #include "base/strings/stringprintf.h" #include "base/task/post_task.h" #include "components/sync/base/cancelation_signal.h" +#include "components/variations/net/variations_http_headers.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/http/http_cache.h" @@ -277,6 +278,10 @@ resource_request->headers.SetHeader(net::HttpRequestHeaders::kUserAgent, user_agent_); + variations::AppendVariationsHeader( + url_for_request_, variations::InIncognito::kNo, + variations::SignedIn::kYes, resource_request.get()); + fetch_state_.url_loader = network::SimpleURLLoader::Create( std::move(resource_request), traffic_annotation); network::SimpleURLLoader* url_loader = fetch_state_.url_loader.get();
diff --git a/components/sync/engine/non_blocking_sync_common.h b/components/sync/engine/non_blocking_sync_common.h index f4264b8c..82044a01 100644 --- a/components/sync/engine/non_blocking_sync_common.h +++ b/components/sync/engine/non_blocking_sync_common.h
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/time/time.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/model/entity_data.h" #include "components/sync/protocol/sync.pb.h" @@ -52,7 +53,7 @@ // |id|. It could be different because the server can change the sync id // (e.g. for newly created bookmarks), std::string id_in_request; - std::string client_tag_hash; + ClientTagHash client_tag_hash; int64_t sequence_number = 0; int64_t response_version = 0; std::string specifics_hash;
diff --git a/components/sync/engine/sync_encryption_handler.cc b/components/sync/engine/sync_encryption_handler.cc index a53e6c0e8..f716dcc 100644 --- a/components/sync/engine/sync_encryption_handler.cc +++ b/components/sync/engine/sync_encryption_handler.cc
@@ -18,7 +18,6 @@ types.Put(PASSWORDS); // Has its own encryption, but include it anyway. types.Put( WIFI_CONFIGURATIONS); // Has its own encryption, but include it anyway. - types.Put(DEPRECATED_WIFI_CREDENTIALS); return types; }
diff --git a/components/sync/engine/sync_status.cc b/components/sync/engine/sync_status.cc index 48b579d1..f488301 100644 --- a/components/sync/engine/sync_status.cc +++ b/components/sync/engine/sync_status.cc
@@ -20,9 +20,6 @@ num_commits_total(0), num_local_overwrites_total(0), num_server_overwrites_total(0), - nudge_source_notification(0), - nudge_source_local(0), - nudge_source_local_refresh(0), cryptographer_can_encrypt(false), crypto_has_pending_keys(false), has_keystore_key(false),
diff --git a/components/sync/engine/sync_status.h b/components/sync/engine/sync_status.h index c493155..da54f38 100644 --- a/components/sync/engine/sync_status.h +++ b/components/sync/engine/sync_status.h
@@ -66,12 +66,6 @@ int num_local_overwrites_total; int num_server_overwrites_total; - // Nudge counts for each possible source - // TODO(crbug.com/1007969): Remove these; they're always 0. - int nudge_source_notification; - int nudge_source_local; - int nudge_source_local_refresh; - // Encryption related. ModelTypeSet encrypted_types; bool cryptographer_can_encrypt;
diff --git a/components/sync/engine_impl/commit.cc b/components/sync/engine_impl/commit.cc index 703f0f43..ed5abe9 100644 --- a/components/sync/engine_impl/commit.cc +++ b/components/sync/engine_impl/commit.cc
@@ -115,8 +115,7 @@ ModelType request_type = it->first; request_types.Put(request_type); UMA_HISTOGRAM_ENUMERATION("Sync.PostedDataTypeCommitRequest", - ModelTypeToHistogramInt(request_type), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(request_type)); } if (cycle->context()->debug_info_getter()) {
diff --git a/components/sync/engine_impl/directory_update_handler_unittest.cc b/components/sync/engine_impl/directory_update_handler_unittest.cc index 0340b0e..70b17ad 100644 --- a/components/sync/engine_impl/directory_update_handler_unittest.cc +++ b/components/sync/engine_impl/directory_update_handler_unittest.cc
@@ -251,31 +251,25 @@ } TEST_F(DirectoryUpdateHandlerProcessUpdateTest, GarbageCollectionByVersion) { - DirectoryTypeDebugInfoEmitter emitter(DEPRECATED_SYNCED_NOTIFICATIONS, - &type_observers_); - DirectoryUpdateHandler handler(dir(), DEPRECATED_SYNCED_NOTIFICATIONS, - ui_worker(), &emitter); + DirectoryTypeDebugInfoEmitter emitter(PREFERENCES, &type_observers_); + DirectoryUpdateHandler handler(dir(), PREFERENCES, ui_worker(), &emitter); StatusController status; sync_pb::DataTypeProgressMarker progress; - progress.set_data_type_id( - GetSpecificsFieldNumberFromModelType(DEPRECATED_SYNCED_NOTIFICATIONS)); + progress.set_data_type_id(GetSpecificsFieldNumberFromModelType(PREFERENCES)); progress.set_token("token"); progress.mutable_gc_directive()->set_version_watermark(kDefaultVersion + 10); sync_pb::DataTypeContext context; - context.set_data_type_id( - GetSpecificsFieldNumberFromModelType(DEPRECATED_SYNCED_NOTIFICATIONS)); + context.set_data_type_id(GetSpecificsFieldNumberFromModelType(PREFERENCES)); context.set_context("context"); context.set_version(1); - std::unique_ptr<sync_pb::SyncEntity> e1 = - CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e1")), "", - DEPRECATED_SYNCED_NOTIFICATIONS); + std::unique_ptr<sync_pb::SyncEntity> e1 = CreateUpdate( + SyncableIdToProto(Id::CreateFromServerId("e1")), "", PREFERENCES); - std::unique_ptr<sync_pb::SyncEntity> e2 = - CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e2")), "", - DEPRECATED_SYNCED_NOTIFICATIONS); + std::unique_ptr<sync_pb::SyncEntity> e2 = CreateUpdate( + SyncableIdToProto(Id::CreateFromServerId("e2")), "", PREFERENCES); e2->set_version(kDefaultVersion + 100); // Add to the applicable updates list. @@ -291,7 +285,7 @@ handler.ApplyUpdates(&status); // Verify none is deleted because they are unapplied during GC. - EXPECT_TRUE(TypeRootExists(DEPRECATED_SYNCED_NOTIFICATIONS)); + EXPECT_TRUE(TypeRootExists(PREFERENCES)); EXPECT_TRUE(EntryExists(e1->id_string())); EXPECT_TRUE(EntryExists(e2->id_string())); @@ -310,33 +304,27 @@ // Create 2 entries, one is 15-days-old, another is 5-days-old. Check if sync // will delete 15-days-old entry when server set expired age is 10 days. TEST_F(DirectoryUpdateHandlerProcessUpdateTest, GarbageCollectionByAge) { - DirectoryTypeDebugInfoEmitter emitter(DEPRECATED_SYNCED_NOTIFICATIONS, - &type_observers_); - DirectoryUpdateHandler handler(dir(), DEPRECATED_SYNCED_NOTIFICATIONS, - ui_worker(), &emitter); + DirectoryTypeDebugInfoEmitter emitter(PREFERENCES, &type_observers_); + DirectoryUpdateHandler handler(dir(), PREFERENCES, ui_worker(), &emitter); StatusController status; sync_pb::DataTypeProgressMarker progress; - progress.set_data_type_id( - GetSpecificsFieldNumberFromModelType(DEPRECATED_SYNCED_NOTIFICATIONS)); + progress.set_data_type_id(GetSpecificsFieldNumberFromModelType(PREFERENCES)); progress.set_token("token"); progress.mutable_gc_directive()->set_age_watermark_in_days(20); sync_pb::DataTypeContext context; - context.set_data_type_id( - GetSpecificsFieldNumberFromModelType(DEPRECATED_SYNCED_NOTIFICATIONS)); + context.set_data_type_id(GetSpecificsFieldNumberFromModelType(PREFERENCES)); context.set_context("context"); context.set_version(1); - std::unique_ptr<sync_pb::SyncEntity> e1 = - CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e1")), "", - DEPRECATED_SYNCED_NOTIFICATIONS); + std::unique_ptr<sync_pb::SyncEntity> e1 = CreateUpdate( + SyncableIdToProto(Id::CreateFromServerId("e1")), "", PREFERENCES); e1->set_mtime( TimeToProtoTime(base::Time::Now() - base::TimeDelta::FromDays(15))); - std::unique_ptr<sync_pb::SyncEntity> e2 = - CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e2")), "", - DEPRECATED_SYNCED_NOTIFICATIONS); + std::unique_ptr<sync_pb::SyncEntity> e2 = CreateUpdate( + SyncableIdToProto(Id::CreateFromServerId("e2")), "", PREFERENCES); e2->set_mtime( TimeToProtoTime(base::Time::Now() - base::TimeDelta::FromDays(5))); @@ -353,7 +341,7 @@ handler.ApplyUpdates(&status); // Verify none is deleted because they are unapplied during GC. - EXPECT_TRUE(TypeRootExists(DEPRECATED_SYNCED_NOTIFICATIONS)); + EXPECT_TRUE(TypeRootExists(PREFERENCES)); EXPECT_TRUE(EntryExists(e1->id_string())); EXPECT_TRUE(EntryExists(e2->id_string())); @@ -371,17 +359,13 @@ } TEST_F(DirectoryUpdateHandlerProcessUpdateTest, ContextVersion) { - DirectoryTypeDebugInfoEmitter emitter(DEPRECATED_SYNCED_NOTIFICATIONS, - &type_observers_); - DirectoryUpdateHandler handler(dir(), DEPRECATED_SYNCED_NOTIFICATIONS, - ui_worker(), &emitter); + DirectoryTypeDebugInfoEmitter emitter(PREFERENCES, &type_observers_); + DirectoryUpdateHandler handler(dir(), PREFERENCES, ui_worker(), &emitter); StatusController status; - int field_number = - GetSpecificsFieldNumberFromModelType(DEPRECATED_SYNCED_NOTIFICATIONS); + int field_number = GetSpecificsFieldNumberFromModelType(PREFERENCES); sync_pb::DataTypeProgressMarker progress; - progress.set_data_type_id( - GetSpecificsFieldNumberFromModelType(DEPRECATED_SYNCED_NOTIFICATIONS)); + progress.set_data_type_id(GetSpecificsFieldNumberFromModelType(PREFERENCES)); progress.set_token("token"); sync_pb::DataTypeContext old_context; @@ -389,9 +373,8 @@ old_context.set_context("data"); old_context.set_data_type_id(field_number); - std::unique_ptr<sync_pb::SyncEntity> e1 = - CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e1")), "", - DEPRECATED_SYNCED_NOTIFICATIONS); + std::unique_ptr<sync_pb::SyncEntity> e1 = CreateUpdate( + SyncableIdToProto(Id::CreateFromServerId("e1")), "", PREFERENCES); SyncEntityList updates; updates.push_back(e1.get()); @@ -404,15 +387,14 @@ handler.ApplyUpdates(&status); // The PREFERENCES root should be auto-created. - EXPECT_TRUE(TypeRootExists(DEPRECATED_SYNCED_NOTIFICATIONS)); + EXPECT_TRUE(TypeRootExists(PREFERENCES)); EXPECT_TRUE(EntryExists(e1->id_string())); { sync_pb::DataTypeContext dir_context; syncable::ReadTransaction trans(FROM_HERE, dir()); - trans.directory()->GetDataTypeContext( - &trans, DEPRECATED_SYNCED_NOTIFICATIONS, &dir_context); + trans.directory()->GetDataTypeContext(&trans, PREFERENCES, &dir_context); EXPECT_EQ(old_context.SerializeAsString(), dir_context.SerializeAsString()); } @@ -421,9 +403,8 @@ new_context.set_context("old"); new_context.set_data_type_id(field_number); - std::unique_ptr<sync_pb::SyncEntity> e2 = - CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e2")), "", - DEPRECATED_SYNCED_NOTIFICATIONS); + std::unique_ptr<sync_pb::SyncEntity> e2 = CreateUpdate( + SyncableIdToProto(Id::CreateFromServerId("e2")), "", PREFERENCES); updates.clear(); updates.push_back(e2.get()); @@ -440,8 +421,7 @@ { sync_pb::DataTypeContext dir_context; syncable::ReadTransaction trans(FROM_HERE, dir()); - trans.directory()->GetDataTypeContext( - &trans, DEPRECATED_SYNCED_NOTIFICATIONS, &dir_context); + trans.directory()->GetDataTypeContext(&trans, PREFERENCES, &dir_context); EXPECT_EQ(old_context.SerializeAsString(), dir_context.SerializeAsString()); } } @@ -497,8 +477,7 @@ password_worker_(new FakeModelWorker(GROUP_PASSWORD)), passive_worker_(new FakeModelWorker(GROUP_PASSIVE)), bookmarks_emitter_(BOOKMARKS, &type_observers_), - passwords_emitter_(PASSWORDS, &type_observers_), - articles_emitter_(DEPRECATED_ARTICLES, &type_observers_) {} + passwords_emitter_(PASSWORDS, &type_observers_) {} void SetUp() override { dir_maker_.SetUp(); @@ -524,10 +503,6 @@ return passwords_emitter_.GetUpdateCounters(); } - const UpdateCounters& GetArticlesUpdateCounters() { - return articles_emitter_.GetUpdateCounters(); - } - DirectoryCryptographer* GetCryptographer( const syncable::BaseTransaction* trans) { return dir_maker_.GetCryptographer(trans); @@ -559,7 +534,6 @@ base::ObserverList<TypeDebugInfoObserver>::Unchecked type_observers_; DirectoryTypeDebugInfoEmitter bookmarks_emitter_; DirectoryTypeDebugInfoEmitter passwords_emitter_; - DirectoryTypeDebugInfoEmitter articles_emitter_; std::map<ModelType, std::unique_ptr<UpdateHandler>> update_handler_map_; };
diff --git a/components/sync/engine_impl/loopback_server/persistent_unique_client_entity.cc b/components/sync/engine_impl/loopback_server/persistent_unique_client_entity.cc index c98d214..fc15fc63 100644 --- a/components/sync/engine_impl/loopback_server/persistent_unique_client_entity.cc +++ b/components/sync/engine_impl/loopback_server/persistent_unique_client_entity.cc
@@ -7,7 +7,7 @@ #include "base/guid.h" #include "base/rand_util.h" #include "base/strings/string_number_conversions.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/engine_impl/loopback_server/persistent_permanent_entity.h" #include "components/sync/protocol/sync.pb.h" @@ -65,7 +65,8 @@ int64_t creation_time, int64_t last_modified_time) { ModelType model_type = GetModelTypeFromSpecifics(entity_specifics); - std::string client_tag_hash = GenerateSyncableHash(model_type, client_tag); + std::string client_tag_hash = + ClientTagHash::FromUnhashed(model_type, client_tag).value(); std::string id = LoopbackServerEntity::CreateId(model_type, client_tag_hash); return std::make_unique<PersistentUniqueClientEntity>( id, model_type, 0, non_unique_name, client_tag_hash, entity_specifics,
diff --git a/components/sync/engine_impl/loopback_server/persistent_unique_client_entity_unittest.cc b/components/sync/engine_impl/loopback_server/persistent_unique_client_entity_unittest.cc index f00c6aa..306ab12 100644 --- a/components/sync/engine_impl/loopback_server/persistent_unique_client_entity_unittest.cc +++ b/components/sync/engine_impl/loopback_server/persistent_unique_client_entity_unittest.cc
@@ -4,7 +4,7 @@ #include "components/sync/engine_impl/loopback_server/persistent_unique_client_entity.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/engine_impl/loopback_server/loopback_server_entity.h" #include "components/sync/protocol/sync.pb.h" #include "testing/gtest/include/gtest/gtest.h" @@ -45,10 +45,11 @@ ASSERT_TRUE(entity); EXPECT_EQ(kNonUniqueName, entity->GetName()); EXPECT_EQ(syncer::PREFERENCES, entity->GetModelType()); - EXPECT_EQ(LoopbackServerEntity::CreateId( - syncer::PREFERENCES, - GenerateSyncableHash(syncer::PREFERENCES, kClientTag)), - entity->GetId()); + EXPECT_EQ( + LoopbackServerEntity::CreateId( + syncer::PREFERENCES, + ClientTagHash::FromUnhashed(syncer::PREFERENCES, kClientTag).value()), + entity->GetId()); } } // namespace
diff --git a/components/sync/engine_impl/model_type_registry.cc b/components/sync/engine_impl/model_type_registry.cc index 54140413..eb6ba28 100644 --- a/components/sync/engine_impl/model_type_registry.cc +++ b/components/sync/engine_impl/model_type_registry.cc
@@ -135,19 +135,15 @@ int migrated_entity_count = 0; if (uss_migrator_.Run(type, user_share_, worker_ptr, &migrated_entity_count)) { - // TODO(wychen): enum uma should be strongly typed. crbug.com/661401 UMA_HISTOGRAM_ENUMERATION("Sync.USSMigrationSuccess", - ModelTypeToHistogramInt(type), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(type)); // If we succesfully migrated, purge the directory of data for the type. // Purging removes the directory's local copy of the data only. directory()->PurgeEntriesWithTypeIn(ModelTypeSet(type), ModelTypeSet(), ModelTypeSet()); } else { - // TODO(wychen): enum uma should be strongly typed. crbug.com/661401 UMA_HISTOGRAM_ENUMERATION("Sync.USSMigrationFailure", - ModelTypeToHistogramInt(type), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(type)); } // Note that a partial failure may still contribute to the counts histogram.
diff --git a/components/sync/engine_impl/model_type_worker.cc b/components/sync/engine_impl/model_type_worker.cc index fba61da..df14223 100644 --- a/components/sync/engine_impl/model_type_worker.cc +++ b/components/sync/engine_impl/model_type_worker.cc
@@ -20,6 +20,7 @@ #include "base/strings/stringprintf.h" #include "base/trace_event/memory_usage_estimator.h" #include "components/sync/base/cancelation_signal.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/hash_util.h" #include "components/sync/base/model_type.h" #include "components/sync/base/time.h" @@ -40,14 +41,14 @@ } bool ContainsDuplicateClientTagHash(const UpdateResponseDataList& updates) { - std::vector<std::string> client_tag_hashes; + std::vector<std::string> raw_client_tag_hashes; for (const std::unique_ptr<UpdateResponseData>& update : updates) { DCHECK(update); - if (!update->entity->client_tag_hash.empty()) { - client_tag_hashes.push_back(update->entity->client_tag_hash); + if (!update->entity->client_tag_hash.value().empty()) { + raw_client_tag_hashes.push_back(update->entity->client_tag_hash.value()); } } - return ContainsDuplicate(std::move(client_tag_hashes)); + return ContainsDuplicate(std::move(raw_client_tag_hashes)); } bool ContainsDuplicateServerID(const UpdateResponseDataList& updates) { @@ -90,6 +91,104 @@ base::UmaHistogramEnumeration("Sync.BookmarkGUIDSource", source); } +void AdaptUniquePositionForBookmarks(const sync_pb::SyncEntity& update_entity, + syncer::EntityData* data) { + DCHECK(data); + bool has_position_scheme = false; + SyncPositioningScheme sync_positioning_scheme; + if (update_entity.has_unique_position()) { + data->unique_position = update_entity.unique_position(); + has_position_scheme = true; + sync_positioning_scheme = SyncPositioningScheme::UNIQUE_POSITION; + } else if (update_entity.has_position_in_parent() || + update_entity.has_insert_after_item_id()) { + bool missing_originator_fields = false; + if (!update_entity.has_originator_cache_guid() || + !update_entity.has_originator_client_item_id()) { + DLOG(ERROR) << "Update is missing requirements for bookmark position."; + missing_originator_fields = true; + } + + std::string suffix = missing_originator_fields + ? UniquePosition::RandomSuffix() + : GenerateSyncableBookmarkHash( + update_entity.originator_cache_guid(), + update_entity.originator_client_item_id()); + + if (update_entity.has_position_in_parent()) { + data->unique_position = + UniquePosition::FromInt64(update_entity.position_in_parent(), suffix) + .ToProto(); + has_position_scheme = true; + sync_positioning_scheme = SyncPositioningScheme::POSITION_IN_PARENT; + } else { + // If update_entity has insert_after_item_id, use 0 index. + DCHECK(update_entity.has_insert_after_item_id()); + data->unique_position = UniquePosition::FromInt64(0, suffix).ToProto(); + has_position_scheme = true; + sync_positioning_scheme = SyncPositioningScheme::INSERT_AFTER_ITEM_ID; + } + } else if (SyncerProtoUtil::ShouldMaintainPosition(update_entity) && + !update_entity.deleted()) { + DLOG(ERROR) << "Missing required position information in update."; + has_position_scheme = true; + sync_positioning_scheme = SyncPositioningScheme::MISSING; + } + if (has_position_scheme) { + UMA_HISTOGRAM_ENUMERATION("Sync.Entities.PositioningScheme", + sync_positioning_scheme); + } +} + +void AdaptTitleForBookmarks(const sync_pb::SyncEntity& update_entity, + sync_pb::EntitySpecifics* specifics, + bool specifics_were_encrypted) { + DCHECK(specifics); + if (specifics_were_encrypted || update_entity.deleted()) { + // If encrypted, the name field is never populated (unencrypted) for privacy + // reasons. Encryption was also introduced after moving the name out of + // SyncEntity so this hack is not needed at all. + return; + } + // Legacy clients populate the name field in the SyncEntity instead of the + // title field in the BookmarkSpecifics. + if (!specifics->bookmark().has_title() && !update_entity.name().empty()) { + specifics->mutable_bookmark()->set_title(update_entity.name()); + } +} + +void AdaptGuidForBookmarks(const sync_pb::SyncEntity& update_entity, + sync_pb::EntitySpecifics* specifics) { + DCHECK(specifics); + if (update_entity.deleted()) { + return; + } + // Legacy clients don't populate the guid field in the BookmarkSpecifics, so + // we use the originator_client_item_id instead, if it is a valid GUID. + // Otherwise, we leave the field empty. + if (specifics->bookmark().has_guid()) { + LogGUIDSource(BookmarkGUIDSource::kSpecifics); + } else if (base::IsValidGUID(update_entity.originator_client_item_id())) { + specifics->mutable_bookmark()->set_guid( + update_entity.originator_client_item_id()); + LogGUIDSource(BookmarkGUIDSource::kValidOCII); + } else { + LogGUIDSource(BookmarkGUIDSource::kLeftEmpty); + } +} + +void AdaptUpdateForCompatibilityAfterDecryption( + ModelType model_type, + const sync_pb::SyncEntity& update_entity, + sync_pb::EntitySpecifics* specifics, + bool specifics_were_encrypted) { + DCHECK(specifics); + if (model_type == BOOKMARKS) { + AdaptTitleForBookmarks(update_entity, specifics, specifics_were_encrypted); + AdaptGuidForBookmarks(update_entity, specifics); + } +} + } // namespace ModelTypeWorker::ModelTypeWorker( @@ -257,7 +356,8 @@ auto data = std::make_unique<syncer::EntityData>(); // Prepare the message for the model thread. data->id = update_entity.id_string(); - data->client_tag_hash = update_entity.client_defined_unique_tag(); + data->client_tag_hash = + ClientTagHash::FromHashed(update_entity.client_defined_unique_tag()); data->creation_time = ProtoTimeToTime(update_entity.ctime()); data->modification_time = ProtoTimeToTime(update_entity.mtime()); data->name = update_entity.name(); @@ -270,55 +370,12 @@ data->originator_cache_guid = update_entity.originator_cache_guid(); data->originator_client_item_id = update_entity.originator_client_item_id(); - // Handle deprecated positioning fields. Relevant only for bookmarks. - if (model_type == syncer::BOOKMARKS) { - bool has_position_scheme = false; - SyncPositioningScheme sync_positioning_scheme; - if (update_entity.has_unique_position()) { - data->unique_position = update_entity.unique_position(); - has_position_scheme = true; - sync_positioning_scheme = SyncPositioningScheme::UNIQUE_POSITION; - } else if (update_entity.has_position_in_parent() || - update_entity.has_insert_after_item_id()) { - bool missing_originator_fields = false; - if (!update_entity.has_originator_cache_guid() || - !update_entity.has_originator_client_item_id()) { - DLOG(ERROR) << "Update is missing requirements for bookmark position."; - missing_originator_fields = true; - } - - std::string suffix = - missing_originator_fields - ? UniquePosition::RandomSuffix() - : GenerateSyncableHash( - syncer::GetModelType(update_entity), - /*client_tag=*/update_entity.originator_cache_guid() + - update_entity.originator_client_item_id()); - - if (update_entity.has_position_in_parent()) { - data->unique_position = UniquePosition::FromInt64( - update_entity.position_in_parent(), suffix) - .ToProto(); - has_position_scheme = true; - sync_positioning_scheme = SyncPositioningScheme::POSITION_IN_PARENT; - } else { - // If update_entity has insert_after_item_id, use 0 index. - DCHECK(update_entity.has_insert_after_item_id()); - data->unique_position = UniquePosition::FromInt64(0, suffix).ToProto(); - has_position_scheme = true; - sync_positioning_scheme = SyncPositioningScheme::INSERT_AFTER_ITEM_ID; - } - } else if (SyncerProtoUtil::ShouldMaintainPosition(update_entity) && - !update_entity.deleted()) { - DLOG(ERROR) << "Missing required position information in update."; - has_position_scheme = true; - sync_positioning_scheme = SyncPositioningScheme::MISSING; - } - if (has_position_scheme) { - UMA_HISTOGRAM_ENUMERATION("Sync.Entities.PositioningScheme", - sync_positioning_scheme); - } + // Adapt the update for compatibility (all except specifics that may need + // encryption). + if (model_type == BOOKMARKS) { + AdaptUniquePositionForBookmarks(update_entity, data.get()); } + // TODO(crbug.com/881289): Generate client tag hash for wallet data. // Deleted entities must use the default instance of EntitySpecifics in // order for EntityData to correctly reflect that they are deleted. @@ -346,6 +403,9 @@ &data->specifics)) { return FAILED_TO_DECRYPT; } + AdaptUpdateForCompatibilityAfterDecryption( + model_type, update_entity, &data->specifics, + /*specifics_were_encrypted=*/true); response_data->entity = std::move(data); return SUCCESS; } @@ -354,26 +414,9 @@ if (!specifics.has_encrypted()) { // No encryption. data->specifics = specifics; - // Legacy clients populates the name field in the SyncEntity instead of the - // title field in the BookmarkSpecifics. - if (model_type == BOOKMARKS && !update_entity.deleted() && - !specifics.bookmark().has_title() && !update_entity.name().empty()) { - data->specifics.mutable_bookmark()->set_title(update_entity.name()); - } - // Legacy clients don't populate the guid field in the BookmarkSpecifics, so - // we use the originator_client_item_id instead, if it is a valid GUID. - // Otherwise, we leave the field empty. - if (model_type == BOOKMARKS && !update_entity.deleted()) { - if (specifics.bookmark().has_guid()) { - LogGUIDSource(BookmarkGUIDSource::kSpecifics); - } else if (base::IsValidGUID(update_entity.originator_client_item_id())) { - data->specifics.mutable_bookmark()->set_guid( - update_entity.originator_client_item_id()); - LogGUIDSource(BookmarkGUIDSource::kValidOCII); - } else { - LogGUIDSource(BookmarkGUIDSource::kLeftEmpty); - } - } + AdaptUpdateForCompatibilityAfterDecryption( + model_type, update_entity, &data->specifics, + /*specifics_were_encrypted=*/false); response_data->entity = std::move(data); return SUCCESS; } @@ -384,21 +427,9 @@ if (!DecryptSpecifics(*cryptographer, specifics, &data->specifics)) { return FAILED_TO_DECRYPT; } - - // Legacy clients don't populate the guid field in the BookmarkSpecifics, so - // we use the originator_client_item_id instead, if it is a valid GUID. - // Otherwise, we leave the field empty. - if (model_type == BOOKMARKS) { - if (data->specifics.bookmark().has_guid()) { - LogGUIDSource(BookmarkGUIDSource::kSpecifics); - } else if (base::IsValidGUID(update_entity.originator_client_item_id())) { - data->specifics.mutable_bookmark()->set_guid( - update_entity.originator_client_item_id()); - LogGUIDSource(BookmarkGUIDSource::kValidOCII); - } else { - LogGUIDSource(BookmarkGUIDSource::kLeftEmpty); - } - } + AdaptUpdateForCompatibilityAfterDecryption( + model_type, update_entity, &data->specifics, + /*specifics_were_encrypted=*/true); response_data->entity = std::move(data); response_data->encryption_key_name = specifics.encrypted().key_name(); return SUCCESS; @@ -637,12 +668,18 @@ decrypted_update->encryption_key_name = encryption_key_name; decrypted_update->entity = std::move(it->second->entity); decrypted_update->entity->specifics = std::move(specifics); - if (decrypted_update->entity->specifics.has_bookmark() && - !decrypted_update->entity->specifics.bookmark().has_guid() && - base::IsValidGUID( - decrypted_update->entity->originator_client_item_id)) { - decrypted_update->entity->specifics.mutable_bookmark()->set_guid( - decrypted_update->entity->originator_client_item_id); + // TODO(crbug.com/1007199): Reconcile with AdaptGuidForBookmarks(). + if (decrypted_update->entity->specifics.has_bookmark()) { + if (decrypted_update->entity->specifics.bookmark().has_guid()) { + LogGUIDSource(BookmarkGUIDSource::kSpecifics); + } else if (base::IsValidGUID( + decrypted_update->entity->originator_client_item_id)) { + decrypted_update->entity->specifics.mutable_bookmark()->set_guid( + decrypted_update->entity->originator_client_item_id); + LogGUIDSource(BookmarkGUIDSource::kValidOCII); + } else { + LogGUIDSource(BookmarkGUIDSource::kLeftEmpty); + } } pending_updates_.push_back(std::move(decrypted_update)); it = entries_pending_decryption_.erase(it); @@ -679,11 +716,11 @@ UpdateResponseDataList candidates; pending_updates_.swap(candidates); - std::map<std::string, size_t> tag_to_index; + std::map<ClientTagHash, size_t> tag_to_index; for (std::unique_ptr<UpdateResponseData>& candidate : candidates) { DCHECK(candidate); // Items with empty client tag hash just get passed through. - if (candidate->entity->client_tag_hash.empty()) { + if (candidate->entity->client_tag_hash.value().empty()) { pending_updates_.push_back(std::move(candidate)); continue; }
diff --git a/components/sync/engine_impl/model_type_worker_unittest.cc b/components/sync/engine_impl/model_type_worker_unittest.cc index c0679f5..44be2fbf 100644 --- a/components/sync/engine_impl/model_type_worker_unittest.cc +++ b/components/sync/engine_impl/model_type_worker_unittest.cc
@@ -15,7 +15,7 @@ #include "base/test/metrics/histogram_tester.h" #include "base/threading/thread.h" #include "components/sync/base/cancelation_signal.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/unique_position.h" #include "components/sync/engine/model_type_processor.h" #include "components/sync/engine_impl/commit_contribution.h" @@ -141,16 +141,16 @@ // convenience functions so we can emulate server behavior. class ModelTypeWorkerTest : public ::testing::Test { protected: - static std::string GenerateTagHash(const std::string& tag) { + static ClientTagHash GenerateTagHash(const std::string& tag) { if (tag.empty()) { - return std::string(); + return ClientTagHash(); } - return GenerateSyncableHash(PREFERENCES, tag); + return ClientTagHash::FromUnhashed(PREFERENCES, tag); } - const std::string kHash1 = GenerateTagHash(kTag1); - const std::string kHash2 = GenerateTagHash(kTag2); - const std::string kHash3 = GenerateTagHash(kTag3); + const ClientTagHash kHash1 = GenerateTagHash(kTag1); + const ClientTagHash kHash2 = GenerateTagHash(kTag2); + const ClientTagHash kHash3 = GenerateTagHash(kTag3); explicit ModelTypeWorkerTest(ModelType model_type = PREFERENCES) : model_type_(model_type), @@ -323,7 +323,7 @@ } CommitRequestDataList GenerateCommitRequest( - const std::string& tag_hash, + const ClientTagHash& tag_hash, const EntitySpecifics& specifics) { CommitRequestDataList commit_request; commit_request.push_back(processor()->CommitRequest(tag_hash, specifics)); @@ -332,7 +332,7 @@ CommitRequestDataList GenerateDeleteRequest(const std::string& tag) { CommitRequestDataList request; - const std::string tag_hash = GenerateTagHash(tag); + const ClientTagHash tag_hash = GenerateTagHash(tag); request.push_back(processor()->DeleteRequest(tag_hash)); return request; } @@ -562,7 +562,7 @@ processor()->SetCommitRequest(GenerateCommitRequest(kTag1, kValue1)); DoSuccessfulCommit(); - const std::string& client_tag_hash = GenerateTagHash(kTag1); + const ClientTagHash client_tag_hash = GenerateTagHash(kTag1); // Exhaustively verify the SyncEntity sent in the commit message. ASSERT_EQ(1U, server()->GetNumCommitMessages()); @@ -574,7 +574,7 @@ EXPECT_NE(0, entity.mtime()); EXPECT_NE(0, entity.ctime()); EXPECT_FALSE(entity.name().empty()); - EXPECT_EQ(client_tag_hash, entity.client_defined_unique_tag()); + EXPECT_EQ(client_tag_hash.value(), entity.client_defined_unique_tag()); EXPECT_EQ(kTag1, entity.specifics().preference().name()); EXPECT_FALSE(entity.deleted()); EXPECT_EQ(kValue1, entity.specifics().preference().value()); @@ -630,7 +630,7 @@ ASSERT_TRUE(server()->HasCommitEntity(kHash1)); const SyncEntity& entity = server()->GetLastCommittedEntity(kHash1); EXPECT_FALSE(entity.id_string().empty()); - EXPECT_EQ(GenerateTagHash(kTag1), entity.client_defined_unique_tag()); + EXPECT_EQ(GenerateTagHash(kTag1).value(), entity.client_defined_unique_tag()); EXPECT_EQ(base_version, entity.version()); EXPECT_TRUE(entity.deleted()); @@ -647,7 +647,7 @@ EXPECT_EQ(entity.id_string(), commit_response.id); EXPECT_EQ(entity.client_defined_unique_tag(), - commit_response.client_tag_hash); + commit_response.client_tag_hash.value()); EXPECT_EQ(entity.version(), commit_response.response_version); } @@ -716,7 +716,7 @@ EXPECT_EQ(0, emitter()->GetUpdateCounters().num_non_initial_updates_received); EXPECT_EQ(0, emitter()->GetUpdateCounters().num_updates_applied); - const std::string& tag_hash = GenerateTagHash(kTag1); + const ClientTagHash tag_hash = GenerateTagHash(kTag1); TriggerUpdateFromServer(10, kTag1, kValue1); @@ -881,7 +881,7 @@ GenerateSpecifics("key2", "value2")); // Mimic a bug on the server by modifying the second entity to have the same // tag as the first one. - entity2.set_client_defined_unique_tag(GenerateTagHash(kTag1)); + entity2.set_client_defined_unique_tag(GenerateTagHash(kTag1).value()); worker()->ProcessGetUpdatesResponse( server()->GetProgress(), server()->GetContext(), {&entity1, &entity2}, status_controller()); @@ -1226,7 +1226,7 @@ // Manually create an update. SyncEntity entity; - entity.set_client_defined_unique_tag(GenerateTagHash(kTag1)); + entity.set_client_defined_unique_tag(GenerateTagHash(kTag1).value()); entity.set_id_string("SomeID"); entity.set_version(1); entity.set_ctime(1000); @@ -1350,7 +1350,7 @@ EXPECT_FALSE(data.id.empty()); EXPECT_FALSE(data.parent_id.empty()); EXPECT_FALSE(data.is_folder); - EXPECT_EQ("CLIENT_TAG", data.client_tag_hash); + EXPECT_EQ("CLIENT_TAG", data.client_tag_hash.value()); EXPECT_EQ("SERVER_TAG", data.server_defined_unique_tag); EXPECT_FALSE(data.is_deleted()); EXPECT_EQ(kTag1, data.specifics.preference().name());
diff --git a/components/sync/engine_impl/net/server_connection_manager.cc b/components/sync/engine_impl/net/server_connection_manager.cc index 57d3799..61a94376 100644 --- a/components/sync/engine_impl/net/server_connection_manager.cc +++ b/components/sync/engine_impl/net/server_connection_manager.cc
@@ -119,21 +119,6 @@ return true; } -bool ServerConnectionManager::Connection::ReadDownloadResponse( - HttpResponse* response, - string* buffer_out) { - const int64_t bytes_read = - ReadResponse(buffer_out, static_cast<int>(response->content_length)); - - if (bytes_read != response->content_length) { - LOG(ERROR) << "Mismatched content lengths, server claimed " - << response->content_length << ", but sent " << bytes_read; - response->server_status = HttpResponse::IO_ERROR; - return false; - } - return true; -} - namespace { string StripTrailingSlash(const string& s) {
diff --git a/components/sync/engine_impl/net/server_connection_manager.h b/components/sync/engine_impl/net/server_connection_manager.h index da79f0f..b10c1242 100644 --- a/components/sync/engine_impl/net/server_connection_manager.h +++ b/components/sync/engine_impl/net/server_connection_manager.h
@@ -123,7 +123,6 @@ bool ReadBufferResponse(std::string* buffer_out, HttpResponse* response, bool require_response); - bool ReadDownloadResponse(HttpResponse* response, std::string* buffer_out); protected: std::string MakeConnectionURL(const std::string& sync_server,
diff --git a/components/sync/engine_impl/non_blocking_type_commit_contribution.cc b/components/sync/engine_impl/non_blocking_type_commit_contribution.cc index 116afbd..49900af 100644 --- a/components/sync/engine_impl/non_blocking_type_commit_contribution.cc +++ b/components/sync/engine_impl/non_blocking_type_commit_contribution.cc
@@ -186,7 +186,8 @@ // Populate client_defined_unique_tag only for non-bookmark and non-Nigori // data types. if (type != BOOKMARKS && type != NIGORI) { - commit_proto->set_client_defined_unique_tag(entity_data.client_tag_hash); + commit_proto->set_client_defined_unique_tag( + entity_data.client_tag_hash.value()); } commit_proto->set_version(commit_entity.base_version); commit_proto->set_deleted(entity_data.is_deleted());
diff --git a/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc b/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc index 9c6dee7..4f333d94 100644 --- a/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc +++ b/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc
@@ -10,7 +10,7 @@ #include "base/base64.h" #include "base/hash/sha1.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/model_type.h" #include "components/sync/base/unique_position.h" #include "components/sync/syncable/directory_cryptographer.h" @@ -23,15 +23,15 @@ using sync_pb::EntitySpecifics; using sync_pb::SyncEntity; -const char kTag[] = "tag"; +const ClientTagHash kTag = ClientTagHash::FromHashed("tag"); const char kValue[] = "value"; const char kURL[] = "url"; const char kTitle[] = "title"; -EntitySpecifics GeneratePreferenceSpecifics(const std::string& tag, +EntitySpecifics GeneratePreferenceSpecifics(const ClientTagHash& tag, const std::string& value) { EntitySpecifics specifics; - specifics.mutable_preference()->set_name(tag); + specifics.mutable_preference()->set_name(tag.value()); specifics.mutable_preference()->set_value(value); return specifics; } @@ -80,7 +80,7 @@ EXPECT_EQ(creation_time.ToJsTime(), entity.ctime()); EXPECT_FALSE(entity.name().empty()); EXPECT_FALSE(entity.client_defined_unique_tag().empty()); - EXPECT_EQ(kTag, entity.specifics().preference().name()); + EXPECT_EQ(kTag.value(), entity.specifics().preference().name()); EXPECT_FALSE(entity.deleted()); EXPECT_EQ(kValue, entity.specifics().preference().value()); EXPECT_TRUE(entity.parent_id_string().empty()); @@ -187,7 +187,7 @@ EXPECT_TRUE(entity.id_string().empty()); EXPECT_EQ(7, entity.version()); EXPECT_EQ("encrypted", entity.name()); - EXPECT_EQ(kTag, entity.client_defined_unique_tag()); + EXPECT_EQ(kTag.value(), entity.client_defined_unique_tag()); EXPECT_FALSE(entity.deleted()); EXPECT_FALSE(entity.specifics().has_encrypted()); EXPECT_TRUE(entity.specifics().has_password()); @@ -248,7 +248,7 @@ EXPECT_TRUE(entity.id_string().empty()); EXPECT_EQ(7, entity.version()); EXPECT_EQ("encrypted", entity.name()); - EXPECT_EQ(kTag, entity.client_defined_unique_tag()); + EXPECT_EQ(kTag.value(), entity.client_defined_unique_tag()); EXPECT_FALSE(entity.deleted()); EXPECT_FALSE(entity.specifics().has_encrypted()); EXPECT_TRUE(entity.specifics().has_password());
diff --git a/components/sync/engine_impl/nudge_source.cc b/components/sync/engine_impl/nudge_source.cc deleted file mode 100644 index 615370c..0000000 --- a/components/sync/engine_impl/nudge_source.cc +++ /dev/null
@@ -1,29 +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. - -#include "components/sync/engine_impl/nudge_source.h" - -#include "base/logging.h" - -namespace syncer { - -#define ENUM_CASE(x) \ - case x: \ - return #x; \ - break - -const char* GetNudgeSourceString(NudgeSource nudge_source) { - switch (nudge_source) { - ENUM_CASE(NUDGE_SOURCE_UNKNOWN); - ENUM_CASE(NUDGE_SOURCE_NOTIFICATION); - ENUM_CASE(NUDGE_SOURCE_LOCAL); - ENUM_CASE(NUDGE_SOURCE_LOCAL_REFRESH); - } - NOTREACHED(); - return ""; -} - -#undef ENUM_CASE - -} // namespace syncer
diff --git a/components/sync/engine_impl/nudge_source.h b/components/sync/engine_impl/nudge_source.h index 0c95c769..9dd181e3 100644 --- a/components/sync/engine_impl/nudge_source.h +++ b/components/sync/engine_impl/nudge_source.h
@@ -17,8 +17,6 @@ NUDGE_SOURCE_LOCAL_REFRESH, }; -const char* GetNudgeSourceString(NudgeSource nudge_source); - } // namespace syncer #endif // COMPONENTS_SYNC_ENGINE_IMPL_NUDGE_SOURCE_H_
diff --git a/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc b/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc index a0f09ca..80c17edc 100644 --- a/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc +++ b/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc
@@ -664,9 +664,7 @@ EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); ModelTypeSet encrypted_types = encryption_handler()->GetEncryptedTypesUnsafe(); - EXPECT_EQ( - ModelTypeSet(PASSWORDS, DEPRECATED_WIFI_CREDENTIALS, WIFI_CONFIGURATIONS), - encrypted_types); + EXPECT_EQ(ModelTypeSet(PASSWORDS, WIFI_CONFIGURATIONS), encrypted_types); { WriteTransaction trans(FROM_HERE, user_share()); @@ -699,9 +697,7 @@ EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); ModelTypeSet encrypted_types = encryption_handler()->GetEncryptedTypesUnsafe(); - EXPECT_EQ( - ModelTypeSet(PASSWORDS, DEPRECATED_WIFI_CREDENTIALS, WIFI_CONFIGURATIONS), - encrypted_types); + EXPECT_EQ(ModelTypeSet(PASSWORDS, WIFI_CONFIGURATIONS), encrypted_types); { WriteTransaction trans(FROM_HERE, user_share()); @@ -742,9 +738,7 @@ EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); ModelTypeSet encrypted_types = encryption_handler()->GetEncryptedTypesUnsafe(); - EXPECT_EQ( - ModelTypeSet(PASSWORDS, DEPRECATED_WIFI_CREDENTIALS, WIFI_CONFIGURATIONS), - encrypted_types); + EXPECT_EQ(ModelTypeSet(PASSWORDS, WIFI_CONFIGURATIONS), encrypted_types); { WriteTransaction trans(FROM_HERE, user_share()); @@ -754,8 +748,7 @@ EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); encrypted_types = encryption_handler()->GetEncryptedTypesUnsafe(); - EXPECT_EQ(ModelTypeSet(BOOKMARKS, PASSWORDS, DEPRECATED_WIFI_CREDENTIALS, - WIFI_CONFIGURATIONS), + EXPECT_EQ(ModelTypeSet(BOOKMARKS, PASSWORDS, WIFI_CONFIGURATIONS), encrypted_types); }
diff --git a/components/sync/engine_impl/sync_manager_impl.cc b/components/sync/engine_impl/sync_manager_impl.cc index 18ba58e5..3aa864ce 100644 --- a/components/sync/engine_impl/sync_manager_impl.cc +++ b/components/sync/engine_impl/sync_manager_impl.cc
@@ -479,10 +479,6 @@ return share_->directory.get(); } -const SyncScheduler* SyncManagerImpl::scheduler() const { - return scheduler_.get(); -} - // static std::string SyncManagerImpl::GenerateCacheGUIDForTest() { return GenerateCacheGUID();
diff --git a/components/sync/engine_impl/sync_manager_impl.h b/components/sync/engine_impl/sync_manager_impl.h index 82e8b79..150b3173 100644 --- a/components/sync/engine_impl/sync_manager_impl.h +++ b/components/sync/engine_impl/sync_manager_impl.h
@@ -171,8 +171,6 @@ void NudgeForInitialDownload(ModelType type) override; void NudgeForCommit(ModelType type) override; - const SyncScheduler* scheduler() const; - static std::string GenerateCacheGUIDForTest(); protected: @@ -197,8 +195,6 @@ base::DictionaryValue* ToValue() const; }; - base::TimeDelta GetNudgeDelayTimeDelta(const ModelType& model_type); - using NotificationInfoMap = std::map<ModelType, NotificationInfo>; // Determine if the parents or predecessors differ between the old and new
diff --git a/components/sync/engine_impl/sync_manager_impl_unittest.cc b/components/sync/engine_impl/sync_manager_impl_unittest.cc index 4923aab..c1fd8ba 100644 --- a/components/sync/engine_impl/sync_manager_impl_unittest.cc +++ b/components/sync/engine_impl/sync_manager_impl_unittest.cc
@@ -22,9 +22,9 @@ #include "base/test/values_test_util.h" #include "base/values.h" #include "components/sync/base/cancelation_signal.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/extensions_activity.h" #include "components/sync/base/fake_encryptor.h" -#include "components/sync/base/hash_util.h" #include "components/sync/base/mock_unrecoverable_error_handler.h" #include "components/sync/base/model_type_test_util.h" #include "components/sync/engine/engine_util.h" @@ -91,6 +91,13 @@ namespace { +// Tests in this file covers directory behavior, so we did't migrate them to +// use ClientTagHash. +std::string GenerateSyncableHash(ModelType type, + const std::string& client_tag) { + return ClientTagHash::FromUnhashed(type, client_tag).value(); +} + // Makes a child node under the type root folder. Returns the id of the // newly-created node. int64_t MakeNode(UserShare* share,
diff --git a/components/sync/engine_impl/syncer_proto_util.cc b/components/sync/engine_impl/syncer_proto_util.cc index 956f28d..8e6646a 100644 --- a/components/sync/engine_impl/syncer_proto_util.cc +++ b/components/sync/engine_impl/syncer_proto_util.cc
@@ -346,9 +346,8 @@ progress_marker.token(); UMA_HISTOGRAM_ENUMERATION( "Sync.PostedDataTypeGetUpdatesRequest", - ModelTypeToHistogramInt(GetModelTypeFromSpecificsFieldNumber( - progress_marker.data_type_id())), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(GetModelTypeFromSpecificsFieldNumber( + progress_marker.data_type_id()))); } }
diff --git a/components/sync/engine_impl/syncer_proto_util.h b/components/sync/engine_impl/syncer_proto_util.h index 3b75acc..a48fdea 100644 --- a/components/sync/engine_impl/syncer_proto_util.h +++ b/components/sync/engine_impl/syncer_proto_util.h
@@ -19,7 +19,6 @@ class ClientToServerResponse; class ClientToServerResponse_Error; class CommitResponse_EntryResponse; -class EntitySpecifics; class SyncEntity; } @@ -70,13 +69,6 @@ static const std::string& NameFromCommitEntryResponse( const sync_pb::CommitResponse_EntryResponse& entry); - // EntitySpecifics is used as a filter for the GetUpdates message to tell - // the server which datatypes to send back. This adds a datatype so that - // it's included in the filter. - static void AddToEntitySpecificDatatypesFilter( - ModelType datatype, - sync_pb::EntitySpecifics* filter); - // Get a debug string representation of the client to server response. static std::string ClientToServerResponseDebugString( const sync_pb::ClientToServerResponse& response);
diff --git a/components/sync/engine_impl/test_entry_factory.cc b/components/sync/engine_impl/test_entry_factory.cc index abbba1a..06dc2f9 100644 --- a/components/sync/engine_impl/test_entry_factory.cc +++ b/components/sync/engine_impl/test_entry_factory.cc
@@ -4,7 +4,7 @@ #include "components/sync/engine_impl/test_entry_factory.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/syncable/directory.h" #include "components/sync/syncable/entry.h" #include "components/sync/syncable/model_neutral_mutable_entry.h" @@ -311,7 +311,8 @@ entry->PutId(item_id); entry->PutCtime(now); entry->PutMtime(now); - entry->PutUniqueClientTag(GenerateSyncableHash(model_type, name)); + entry->PutUniqueClientTag( + ClientTagHash::FromUnhashed(model_type, name).value()); entry->PutBaseVersion(version); entry->PutIsUnsynced(false); entry->PutNonUniqueName(name);
diff --git a/components/sync/engine_impl/update_applicator.h b/components/sync/engine_impl/update_applicator.h index df01804..dd9e234 100644 --- a/components/sync/engine_impl/update_applicator.h +++ b/components/sync/engine_impl/update_applicator.h
@@ -20,7 +20,6 @@ namespace syncable { class WriteTransaction; -class Entry; } // An UpdateApplicator is used to iterate over a number of unapplied updates, @@ -48,9 +47,6 @@ } private: - // If true, AttemptOneApplication will skip over |entry| and return true. - bool SkipUpdate(const syncable::Entry& entry); - // Used to decrypt sensitive sync nodes. const Cryptographer* cryptographer_;
diff --git a/components/sync/engine_impl/uss_migrator_unittest.cc b/components/sync/engine_impl/uss_migrator_unittest.cc index c22a177..70d0561 100644 --- a/components/sync/engine_impl/uss_migrator_unittest.cc +++ b/components/sync/engine_impl/uss_migrator_unittest.cc
@@ -12,7 +12,7 @@ #include "base/test/task_environment.h" #include "base/time/time.h" #include "components/sync/base/cancelation_signal.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/engine_impl/cycle/non_blocking_type_debug_info_emitter.h" #include "components/sync/engine_impl/model_type_worker.h" #include "components/sync/engine_impl/test_entry_factory.h" @@ -30,11 +30,6 @@ namespace { const ModelType kModelType = PREFERENCES; - -std::string GenerateTagHash(const std::string& tag) { - return GenerateSyncableHash(kModelType, tag); -} - const char kToken1[] = "token1"; const char kTag1[] = "tag1"; const char kTag2[] = "tag2"; @@ -42,7 +37,10 @@ const char kValue1[] = "value1"; const char kValue2[] = "value2"; const char kValue3[] = "value3"; -const std::string kHash1(GenerateTagHash(kTag1)); + +ClientTagHash GenerateTagHash(const std::string& tag) { + return ClientTagHash::FromUnhashed(kModelType, tag); +} sync_pb::EntitySpecifics GenerateSpecifics(const std::string& tag, const std::string& value) { @@ -140,7 +138,7 @@ const EntityData& entity = *update->entity; EXPECT_FALSE(entity.id.empty()); - EXPECT_EQ(kHash1, entity.client_tag_hash); + EXPECT_EQ(GenerateTagHash(kTag1), entity.client_tag_hash); EXPECT_EQ(1, update->response_version); EXPECT_EQ(ctime, entity.creation_time); EXPECT_EQ(ctime, entity.modification_time);
diff --git a/components/sync/model/data_type_error_handler_impl.cc b/components/sync/model/data_type_error_handler_impl.cc index b05e98f..090edea 100644 --- a/components/sync/model/data_type_error_handler_impl.cc +++ b/components/sync/model/data_type_error_handler_impl.cc
@@ -22,10 +22,8 @@ void DataTypeErrorHandlerImpl::OnUnrecoverableError(const SyncError& error) { if (!dump_stack_.is_null()) dump_stack_.Run(); - // TODO(wychen): enum uma should be strongly typed. crbug.com/661401 UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures2", - ModelTypeToHistogramInt(error.model_type()), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(error.model_type())); ui_thread_->PostTask(error.location(), base::BindOnce(sync_callback_, error)); }
diff --git a/components/sync/model/entity_data.cc b/components/sync/model/entity_data.cc index 16ba2cd..19cdbf71 100644 --- a/components/sync/model/entity_data.cc +++ b/components/sync/model/entity_data.cc
@@ -80,7 +80,7 @@ std::make_unique<base::DictionaryValue>(); dict->Set("SPECIFICS", EntitySpecificsToValue(specifics)); ADD_TO_DICT(dict, id); - ADD_TO_DICT(dict, client_tag_hash); + ADD_TO_DICT(dict, client_tag_hash.value()); ADD_TO_DICT(dict, originator_cache_guid); ADD_TO_DICT(dict, originator_client_item_id); ADD_TO_DICT(dict, server_defined_unique_tag);
diff --git a/components/sync/model/entity_data.h b/components/sync/model/entity_data.h index 80b01b1..330f54c6 100644 --- a/components/sync/model/entity_data.h +++ b/components/sync/model/entity_data.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/time/time.h" #include "base/values.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/protocol/sync.pb.h" namespace syncer { @@ -36,7 +37,7 @@ // Used for various map lookups. Should always be available for all data types // except bookmarks. Sent to the server as // SyncEntity::client_defined_unique_tag. - std::string client_tag_hash; + ClientTagHash client_tag_hash; // A GUID that identifies the the sync client who initially committed this // entity. It's relevant only for bookmarks. See the definition in sync.proto
diff --git a/components/sync/model/fake_model_type_change_processor.cc b/components/sync/model/fake_model_type_change_processor.cc index d585da0b..f8b18fc2 100644 --- a/components/sync/model/fake_model_type_change_processor.cc +++ b/components/sync/model/fake_model_type_change_processor.cc
@@ -41,7 +41,7 @@ const std::string& storage_key) {} void FakeModelTypeChangeProcessor::UntrackEntityForClientTagHash( - const std::string& client_tag_hash) {} + const ClientTagHash& client_tag_hash) {} bool FakeModelTypeChangeProcessor::IsEntityUnsynced( const std::string& storage_key) {
diff --git a/components/sync/model/fake_model_type_change_processor.h b/components/sync/model/fake_model_type_change_processor.h index 6c2f4a3..347a72d9 100644 --- a/components/sync/model/fake_model_type_change_processor.h +++ b/components/sync/model/fake_model_type_change_processor.h
@@ -37,7 +37,7 @@ MetadataChangeList* metadata_change_list) override; void UntrackEntityForStorageKey(const std::string& storage_key) override; void UntrackEntityForClientTagHash( - const std::string& client_tag_hash) override; + const ClientTagHash& client_tag_hash) override; bool IsEntityUnsynced(const std::string& storage_key) override; base::Time GetEntityCreationTime( const std::string& storage_key) const override;
diff --git a/components/sync/model/fake_model_type_sync_bridge.cc b/components/sync/model/fake_model_type_sync_bridge.cc index 86fa9ce2..0c309c3 100644 --- a/components/sync/model/fake_model_type_sync_bridge.cc +++ b/components/sync/model/fake_model_type_sync_bridge.cc
@@ -10,7 +10,7 @@ #include "base/bind.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/model/conflict_resolution.h" #include "components/sync/model/model_type_store.h" #include "components/sync/model/mutable_data_batch.h" @@ -65,9 +65,9 @@ } // static -std::string FakeModelTypeSyncBridge::TagHashFromKey(const std::string& key) { - return GenerateSyncableHash(PREFERENCES, - FakeModelTypeSyncBridge::ClientTagFromKey(key)); +ClientTagHash FakeModelTypeSyncBridge::TagHashFromKey(const std::string& key) { + return ClientTagHash::FromUnhashed( + PREFERENCES, FakeModelTypeSyncBridge::ClientTagFromKey(key)); } // static
diff --git a/components/sync/model/fake_model_type_sync_bridge.h b/components/sync/model/fake_model_type_sync_bridge.h index f1c959a..e7ef5353 100644 --- a/components/sync/model/fake_model_type_sync_bridge.h +++ b/components/sync/model/fake_model_type_sync_bridge.h
@@ -22,6 +22,8 @@ namespace syncer { +class ClientTagHash; + // A basic, functional implementation of ModelTypeSyncBridge for testing // purposes. It uses the PREFERENCES type to provide a simple key/value // interface, and uses its own simple in-memory Store class. @@ -31,7 +33,7 @@ static std::string ClientTagFromKey(const std::string& key); // Generates the tag hash for a given key. - static std::string TagHashFromKey(const std::string& key); + static ClientTagHash TagHashFromKey(const std::string& key); // Generates entity specifics for the given key and value. static sync_pb::EntitySpecifics GenerateSpecifics(const std::string& key,
diff --git a/components/sync/model/mock_model_type_change_processor.cc b/components/sync/model/mock_model_type_change_processor.cc index 0aa016d..cb437936d 100644 --- a/components/sync/model/mock_model_type_change_processor.cc +++ b/components/sync/model/mock_model_type_change_processor.cc
@@ -45,7 +45,7 @@ } void UntrackEntityForClientTagHash( - const std::string& client_tag_hash) override { + const ClientTagHash& client_tag_hash) override { other_->UntrackEntityForClientTagHash(client_tag_hash); }
diff --git a/components/sync/model/mock_model_type_change_processor.h b/components/sync/model/mock_model_type_change_processor.h index 6594d33..f029094 100644 --- a/components/sync/model/mock_model_type_change_processor.h +++ b/components/sync/model/mock_model_type_change_processor.h
@@ -33,7 +33,7 @@ MOCK_METHOD1(UntrackEntityForStorageKey, void(const std::string& storage_key)); MOCK_METHOD1(UntrackEntityForClientTagHash, - void(const std::string& client_tag_hash)); + void(const ClientTagHash& client_tag_hash)); MOCK_METHOD1(IsEntityUnsynced, bool(const std::string& storage_key)); MOCK_CONST_METHOD1(GetEntityCreationTime, base::Time(const std::string& storage_key));
diff --git a/components/sync/model/model_type_change_processor.h b/components/sync/model/model_type_change_processor.h index bfc55b2..d9078d2 100644 --- a/components/sync/model/model_type_change_processor.h +++ b/components/sync/model/model_type_change_processor.h
@@ -19,6 +19,7 @@ namespace syncer { +class ClientTagHash; class MetadataBatch; class MetadataChangeList; class ModelTypeSyncBridge; @@ -65,7 +66,7 @@ // datatypes that can't generate storage keys. The call is ignored if // |client_tag_hash| is unknown. virtual void UntrackEntityForClientTagHash( - const std::string& client_tag_hash) = 0; + const ClientTagHash& client_tag_hash) = 0; // Returns true if a tracked entity has local changes. A commit may or may not // be in progress at this time.
diff --git a/components/sync/model/model_type_store_service.h b/components/sync/model/model_type_store_service.h index 0663f43..1203307 100644 --- a/components/sync/model/model_type_store_service.h +++ b/components/sync/model/model_type_store_service.h
@@ -15,8 +15,6 @@ namespace syncer { -class BlockingModelTypeStore; - // Handles the shared resources for ModelTypeStore and related classes, // including a shared background sequence runner. class ModelTypeStoreService : public KeyedService { @@ -31,12 +29,6 @@ virtual RepeatingModelTypeStoreFactory GetStoreFactory() = 0; virtual scoped_refptr<base::SequencedTaskRunner> GetBackendTaskRunner() = 0; - - // Creates a BlockingModelTypeStore. Must be called from the backend - // sequence as returned in GetBackendTaskRunner(). Can return null if there - // was an error. - virtual std::unique_ptr<BlockingModelTypeStore> - CreateBlockingStoreFromBackendSequence(ModelType type) = 0; }; } // namespace syncer
diff --git a/components/sync/model/recording_model_type_change_processor.cc b/components/sync/model/recording_model_type_change_processor.cc index 8e54c6fa..0be034b8 100644 --- a/components/sync/model/recording_model_type_change_processor.cc +++ b/components/sync/model/recording_model_type_change_processor.cc
@@ -44,7 +44,7 @@ } void RecordingModelTypeChangeProcessor::UntrackEntityForClientTagHash( - const std::string& client_tag_hash) { + const ClientTagHash& client_tag_hash) { untrack_for_client_tag_hash_set_.insert(client_tag_hash); } @@ -54,18 +54,13 @@ } bool RecordingModelTypeChangeProcessor::IsTrackingMetadata() { - return is_tracking_metadata_; + return true; } std::string RecordingModelTypeChangeProcessor::TrackedAccountId() { return ""; } -void RecordingModelTypeChangeProcessor::SetIsTrackingMetadata( - bool is_tracking) { - is_tracking_metadata_ = is_tracking; -} - // static std::unique_ptr<ModelTypeChangeProcessor> RecordingModelTypeChangeProcessor::CreateProcessorAndAssignRawPointer(
diff --git a/components/sync/model/recording_model_type_change_processor.h b/components/sync/model/recording_model_type_change_processor.h index a3aa2f7..e66f46d 100644 --- a/components/sync/model/recording_model_type_change_processor.h +++ b/components/sync/model/recording_model_type_change_processor.h
@@ -10,6 +10,7 @@ #include <set> #include <string> +#include "components/sync/base/client_tag_hash.h" #include "components/sync/model/fake_model_type_change_processor.h" #include "components/sync/model/model_type_sync_bridge.h" @@ -33,13 +34,11 @@ MetadataChangeList* metadata_change_list) override; void UntrackEntityForStorageKey(const std::string& storage_key) override; void UntrackEntityForClientTagHash( - const std::string& client_tag_hash) override; + const ClientTagHash& client_tag_hash) override; void ModelReadyToSync(std::unique_ptr<MetadataBatch> batch) override; bool IsTrackingMetadata() override; std::string TrackedAccountId() override; - void SetIsTrackingMetadata(bool is_tracking); - const std::multimap<std::string, std::unique_ptr<EntityData>>& put_multimap() const { return put_multimap_; @@ -56,7 +55,7 @@ return untrack_for_storage_key_set_; } - const std::set<std::string>& untrack_for_client_tag_hash_set() const { + const std::set<ClientTagHash>& untrack_for_client_tag_hash_set() const { return untrack_for_client_tag_hash_set_; } @@ -74,9 +73,8 @@ std::multimap<std::string, std::unique_ptr<EntityData>> update_multimap_; std::set<std::string> delete_set_; std::set<std::string> untrack_for_storage_key_set_; - std::set<std::string> untrack_for_client_tag_hash_set_; + std::set<ClientTagHash> untrack_for_client_tag_hash_set_; std::unique_ptr<MetadataBatch> metadata_; - bool is_tracking_metadata_ = true; }; } // namespace syncer
diff --git a/components/sync/model/sync_change.cc b/components/sync/model/sync_change.cc index a405d40..e182e4ef 100644 --- a/components/sync/model/sync_change.cc +++ b/components/sync/model/sync_change.cc
@@ -6,6 +6,8 @@ #include <ostream> +#include "components/sync/protocol/sync.pb.h" + namespace syncer { SyncChange::SyncChange() : change_type_(ACTION_INVALID) {} @@ -28,8 +30,14 @@ return IsRealDataType(sync_data_.GetDataType()); // Local changes must always have a tag and specify a valid datatype. - if (SyncDataLocal(sync_data_).GetTag().empty() || - !IsRealDataType(sync_data_.GetDataType())) { + if (SyncDataLocal(sync_data_).GetTag().empty()) + return false; + // TODO(crbug.com/1007942): The ARTICLES data type has been removed and so is + // not considered a "real" data type anymore, but dom_distiller code still + // uses it for its local storage, and will DCHECK-fail if we don't consider + // article data as valid here. + if (!IsRealDataType(sync_data_.GetDataType()) && + !sync_data_.GetSpecifics().has_article()) { return false; }
diff --git a/components/sync/model/sync_data.cc b/components/sync/model/sync_data.cc index 865f19d..aa9a61c2 100644 --- a/components/sync/model/sync_data.cc +++ b/components/sync/model/sync_data.cc
@@ -11,6 +11,7 @@ #include "base/json/json_writer.h" #include "base/strings/string_number_conversions.h" #include "base/values.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/protocol/proto_value_conversions.h" #include "components/sync/protocol/sync.pb.h" #include "components/sync/syncable/base_node.h" @@ -153,7 +154,7 @@ return id_; } -const std::string& SyncDataRemote::GetClientTagHash() const { +ClientTagHash SyncDataRemote::GetClientTagHash() const { // It seems that client_defined_unique_tag has a bit of an overloaded use, // holding onto the un-hashed tag while local, and then the hashed value when // communicating with the server. This usage is copying the latter of these @@ -161,7 +162,8 @@ // the server so we wouldn't be able to set this value anyways. The only way // to recreate an un-hashed tag is for the service to do so with a specifics. DCHECK(!immutable_entity_.Get().client_defined_unique_tag().empty()); - return immutable_entity_.Get().client_defined_unique_tag(); + return ClientTagHash::FromHashed( + immutable_entity_.Get().client_defined_unique_tag()); } } // namespace syncer
diff --git a/components/sync/model/sync_data.h b/components/sync/model/sync_data.h index e0b5d4c4..f269774a 100644 --- a/components/sync/model/sync_data.h +++ b/components/sync/model/sync_data.h
@@ -26,6 +26,7 @@ namespace syncer { +class ClientTagHash; class SyncDataLocal; class SyncDataRemote; @@ -149,7 +150,7 @@ // Returns the tag hash value. May not always be present, in which case an // empty string will be returned. - const std::string& GetClientTagHash() const; + ClientTagHash GetClientTagHash() const; // Deprecated: might not be populated in SyncableService API. // TODO(crbug.com/870624): Remove when directory is removed.
diff --git a/components/sync/model/sync_error.cc b/components/sync/model/sync_error.cc index 44ef6e7..dbe35e93 100644 --- a/components/sync/model/sync_error.cc +++ b/components/sync/model/sync_error.cc
@@ -154,8 +154,4 @@ << message_; } -void PrintTo(const SyncError& sync_error, std::ostream* os) { - *os << sync_error.ToString(); -} - } // namespace syncer
diff --git a/components/sync/model/sync_error.h b/components/sync/model/sync_error.h index d07af6f..eaf1943 100644 --- a/components/sync/model/sync_error.h +++ b/components/sync/model/sync_error.h
@@ -120,9 +120,6 @@ ErrorType error_type_; }; -// gmock printer helper. -void PrintTo(const SyncError& sync_error, std::ostream* os); - } // namespace syncer #endif // COMPONENTS_SYNC_MODEL_SYNC_ERROR_H_
diff --git a/components/sync/model/test_model_type_store_service.cc b/components/sync/model/test_model_type_store_service.cc index b75eb6a..277deef6 100644 --- a/components/sync/model/test_model_type_store_service.cc +++ b/components/sync/model/test_model_type_store_service.cc
@@ -31,11 +31,4 @@ return base::SequencedTaskRunnerHandle::Get(); } -std::unique_ptr<BlockingModelTypeStore> -TestModelTypeStoreService::CreateBlockingStoreFromBackendSequence( - ModelType type) { - return std::make_unique<BlockingModelTypeStoreImpl>(type, - store_backend_.get()); -} - } // namespace syncer
diff --git a/components/sync/model/test_model_type_store_service.h b/components/sync/model/test_model_type_store_service.h index 977ac144..6d71a4b 100644 --- a/components/sync/model/test_model_type_store_service.h +++ b/components/sync/model/test_model_type_store_service.h
@@ -28,8 +28,6 @@ const base::FilePath& GetSyncDataPath() const override; RepeatingModelTypeStoreFactory GetStoreFactory() override; scoped_refptr<base::SequencedTaskRunner> GetBackendTaskRunner() override; - std::unique_ptr<BlockingModelTypeStore> - CreateBlockingStoreFromBackendSequence(ModelType type) override; private: const scoped_refptr<ModelTypeStoreBackend> store_backend_;
diff --git a/components/sync/model_impl/blocking_model_type_store_impl.cc b/components/sync/model_impl/blocking_model_type_store_impl.cc index 32ddbd78..71889f89 100644 --- a/components/sync/model_impl/blocking_model_type_store_impl.cc +++ b/components/sync/model_impl/blocking_model_type_store_impl.cc
@@ -241,8 +241,7 @@ static_cast<LevelDbWriteBatch*>(write_batch.release())); DCHECK_EQ(write_batch_impl->GetModelType(), type_); UMA_HISTOGRAM_ENUMERATION("Sync.ModelTypeStoreCommitCount", - ModelTypeToHistogramInt(type_), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(type_)); return backend_->WriteModifications( LevelDbWriteBatch::ToLevelDbWriteBatch(std::move(write_batch_impl))); }
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor.cc b/components/sync/model_impl/client_tag_based_model_type_processor.cc index 0c24ca9..beefb109 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor.cc +++ b/components/sync/model_impl/client_tag_based_model_type_processor.cc
@@ -15,7 +15,6 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "base/trace_event/memory_usage_estimator.h" #include "components/sync/base/data_type_histogram.h" -#include "components/sync/base/hash_util.h" #include "components/sync/base/model_type.h" #include "components/sync/base/time.h" #include "components/sync/engine/commit_queue.h" @@ -30,7 +29,7 @@ namespace { int CountNonTombstoneEntries( - const std::map<std::string, std::unique_ptr<ProcessorEntity>>& entities) { + const std::map<ClientTagHash, std::unique_ptr<ProcessorEntity>>& entities) { int count = 0; for (const auto& kv : entities) { if (!kv.second->metadata().is_deleted()) { @@ -130,9 +129,10 @@ // to avoid copying. std::unique_ptr<ProcessorEntity> entity = ProcessorEntity::CreateFromMetadata(it->first, std::move(*metadata)); - storage_key_to_tag_hash_[entity->storage_key()] = - entity->metadata().client_tag_hash(); - entities_[entity->metadata().client_tag_hash()] = std::move(entity); + ClientTagHash client_tag_hash = + ClientTagHash::FromHashed(entity->metadata().client_tag_hash()); + storage_key_to_tag_hash_[entity->storage_key()] = client_tag_hash; + entities_[client_tag_hash] = std::move(entity); } model_type_state_ = batch->GetModelTypeState(); } else { @@ -184,12 +184,8 @@ // belong to the current syncing client. if (model_type_state_.progress_marker().data_type_id() != GetSpecificsFieldNumberFromModelType(type_)) { - // This is not strongly typed because historically, - // ModelTypeToHistogramInt() defines quite a different order from the - // type_ enum. UMA_HISTOGRAM_ENUMERATION("Sync.PersistedModelTypeIdMismatch", - ModelTypeToHistogramInt(type_), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(type_)); } ClearMetadataAndResetState(); @@ -391,14 +387,15 @@ if (entity == nullptr) { // The bridge is creating a new entity. The bridge may or may not populate // |data->client_tag_hash|, so let's ask for the client tag if needed. - if (data->client_tag_hash.empty()) { + if (data->client_tag_hash.value().empty()) { data->client_tag_hash = GetClientTagHash(storage_key, *data); } else if (bridge_->SupportsGetClientTag()) { // If the Put() call already included the client tag, let's verify that // it's consistent with the bridge's regular GetClientTag() function (if // supported by the bridge). - DCHECK_EQ(data->client_tag_hash, - GenerateSyncableHash(type_, bridge_->GetClientTag(*data))); + DCHECK_EQ( + data->client_tag_hash, + ClientTagHash::FromUnhashed(type_, bridge_->GetClientTag(*data))); } // If another entity exists for the same client_tag_hash, it could be the // case that the bridge has deleted this entity but the tombstone hasn't @@ -427,8 +424,7 @@ } else if (entity->MatchesData(*data)) { // Ignore changes that don't actually change anything. UMA_HISTOGRAM_ENUMERATION("Sync.ModelTypeRedundantPut", - ModelTypeToHistogramInt(type_), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(type_)); return; } @@ -467,8 +463,8 @@ const EntityData& entity_data, const std::string& storage_key, MetadataChangeList* metadata_change_list) { - const std::string& client_tag_hash = entity_data.client_tag_hash; - DCHECK(!client_tag_hash.empty()); + const ClientTagHash& client_tag_hash = entity_data.client_tag_hash; + DCHECK(!client_tag_hash.value().empty()); DCHECK(!storage_key.empty()); DCHECK(!bridge_->SupportsGetStorageKey()); DCHECK(model_type_state_.initial_sync_done()); @@ -501,9 +497,9 @@ } void ClientTagBasedModelTypeProcessor::UntrackEntityForClientTagHash( - const std::string& client_tag_hash) { + const ClientTagHash& client_tag_hash) { DCHECK(model_type_state_.initial_sync_done()); - DCHECK(!client_tag_hash.empty()); + DCHECK(!client_tag_hash.value().empty()); // Is a no-op if no entity for |client_tag_hash| is tracked. DCHECK(GetEntityForTagHash(client_tag_hash) == nullptr || GetEntityForTagHash(client_tag_hash)->storage_key().empty()); @@ -675,8 +671,8 @@ // wallet_data entity has a client tag. continue; } - update->entity->client_tag_hash = - GenerateSyncableHash(type, bridge->GetClientTag(*update->entity)); + update->entity->client_tag_hash = ClientTagHash::FromUnhashed( + type, bridge->GetClientTag(*update->entity)); } } @@ -759,18 +755,18 @@ EntityChangeList* entity_changes, std::string* storage_key_to_clear) { const EntityData& data = *update->entity; - const std::string& client_tag_hash = data.client_tag_hash; + const ClientTagHash& client_tag_hash = data.client_tag_hash; // Filter out updates without a client tag hash (including permanent nodes, // which have server tags instead). - if (client_tag_hash.empty()) { + if (client_tag_hash.value().empty()) { return nullptr; } // Filter out unexpected client tag hashes. if (!data.is_deleted() && bridge_->SupportsGetClientTag() && client_tag_hash != - GenerateSyncableHash(type_, bridge_->GetClientTag(data))) { + ClientTagHash::FromUnhashed(type_, bridge_->GetClientTag(data))) { DLOG(WARNING) << "Received unexpected client tag hash: " << client_tag_hash << " for " << ModelTypeToString(type_); return nullptr; @@ -1022,8 +1018,8 @@ for (const std::unique_ptr<syncer::UpdateResponseData>& update : updates) { DCHECK(update); - const std::string& client_tag_hash = update->entity->client_tag_hash; - if (client_tag_hash.empty()) { + const ClientTagHash& client_tag_hash = update->entity->client_tag_hash; + if (client_tag_hash.value().empty()) { // Ignore updates missing a client tag hash (e.g. permanent nodes). continue; } @@ -1034,7 +1030,7 @@ continue; } if (bridge_->SupportsGetClientTag() && - client_tag_hash != GenerateSyncableHash( + client_tag_hash != ClientTagHash::FromUnhashed( type_, bridge_->GetClientTag(*update->entity))) { DLOG(WARNING) << "Received unexpected client tag hash: " << client_tag_hash << " for " << ModelTypeToString(type_); @@ -1126,7 +1122,8 @@ if (entity->CanClearMetadata()) { metadata_changes->ClearMetadata(entity->storage_key()); storage_key_to_tag_hash_.erase(entity->storage_key()); - entities_.erase(entity->metadata().client_tag_hash()); + entities_.erase( + ClientTagHash::FromHashed(entity->metadata().client_tag_hash())); } else { metadata_changes->UpdateMetadata(entity->storage_key(), entity->metadata()); @@ -1198,8 +1195,7 @@ // had been called. storage_keys_to_untrack.push_back(storage_key); UMA_HISTOGRAM_ENUMERATION("Sync.ModelTypeOrphanMetadata", - ModelTypeToHistogramInt(type_), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(type_)); } if (storage_keys_to_untrack.empty()) { @@ -1240,13 +1236,13 @@ std::move(callback).Run(std::move(commit_requests)); } -std::string ClientTagBasedModelTypeProcessor::GetClientTagHash( +ClientTagHash ClientTagBasedModelTypeProcessor::GetClientTagHash( const std::string& storage_key, const EntityData& data) const { auto iter = storage_key_to_tag_hash_.find(storage_key); DCHECK(bridge_->SupportsGetClientTag()); return iter == storage_key_to_tag_hash_.end() - ? GenerateSyncableHash(type_, bridge_->GetClientTag(data)) + ? ClientTagHash::FromUnhashed(type_, bridge_->GetClientTag(data)) : iter->second; } @@ -1267,13 +1263,13 @@ } ProcessorEntity* ClientTagBasedModelTypeProcessor::GetEntityForTagHash( - const std::string& tag_hash) { + const ClientTagHash& tag_hash) { auto it = entities_.find(tag_hash); return it != entities_.end() ? it->second.get() : nullptr; } const ProcessorEntity* ClientTagBasedModelTypeProcessor::GetEntityForTagHash( - const std::string& tag_hash) const { + const ClientTagHash& tag_hash) const { auto it = entities_.find(tag_hash); return it != entities_.end() ? it->second.get() : nullptr; } @@ -1281,7 +1277,7 @@ ProcessorEntity* ClientTagBasedModelTypeProcessor::CreateEntity( const std::string& storage_key, const EntityData& data) { - DCHECK(!data.client_tag_hash.empty()); + DCHECK(!data.client_tag_hash.value().empty()); DCHECK(entities_.find(data.client_tag_hash) == entities_.end()); DCHECK(!bridge_->SupportsGetStorageKey() || !storage_key.empty()); DCHECK(storage_key.empty() || storage_key_to_tag_hash_.find(storage_key) == @@ -1299,7 +1295,7 @@ const EntityData& data) { if (bridge_->SupportsGetClientTag()) { DCHECK_EQ(data.client_tag_hash, - GenerateSyncableHash(type_, bridge_->GetClientTag(data))); + ClientTagHash::FromUnhashed(type_, bridge_->GetClientTag(data))); } std::string storage_key; if (bridge_->SupportsGetStorageKey()) @@ -1368,7 +1364,8 @@ MetadataChangeList* metadata_change_list) { metadata_change_list->ClearMetadata(entity->storage_key()); storage_key_to_tag_hash_.erase(entity->storage_key()); - entities_.erase(entity->metadata().client_tag_hash()); + entities_.erase( + ClientTagHash::FromHashed(entity->metadata().client_tag_hash())); } void ClientTagBasedModelTypeProcessor::ResetState( @@ -1424,7 +1421,8 @@ data->id = "s" + metadata.server_id(); data->creation_time = ProtoTimeToTime(metadata.creation_time()); data->modification_time = ProtoTimeToTime(metadata.modification_time()); - data->client_tag_hash = metadata.client_tag_hash(); + data->client_tag_hash = + ClientTagHash::FromHashed(metadata.client_tag_hash()); } std::unique_ptr<base::DictionaryValue> node = data->ToDictionaryValue();
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor.h b/components/sync/model_impl/client_tag_based_model_type_processor.h index 67842cf..88ebbc3 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor.h +++ b/components/sync/model_impl/client_tag_based_model_type_processor.h
@@ -14,6 +14,7 @@ #include "base/memory/weak_ptr.h" #include "base/optional.h" #include "base/sequence_checker.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/model_type.h" #include "components/sync/base/sync_stop_metadata_fate.h" #include "components/sync/engine/cycle/status_counters.h" @@ -68,7 +69,7 @@ MetadataChangeList* metadata_change_list) override; void UntrackEntityForStorageKey(const std::string& storage_key) override; void UntrackEntityForClientTagHash( - const std::string& client_tag_hash) override; + const ClientTagHash& client_tag_hash) override; bool IsEntityUnsynced(const std::string& storage_key) override; base::Time GetEntityCreationTime( const std::string& storage_key) const override; @@ -191,8 +192,8 @@ // Looks up the client tag hash for the given |storage_key|, and regenerates // with |data| if the lookup finds nothing. Does not update the storage key to // client tag hash mapping. - std::string GetClientTagHash(const std::string& storage_key, - const EntityData& data) const; + ClientTagHash GetClientTagHash(const std::string& storage_key, + const EntityData& data) const; // Gets the entity for the given storage key, or null if there isn't one. ProcessorEntity* GetEntityForStorageKey(const std::string& storage_key); @@ -200,8 +201,9 @@ const std::string& storage_key) const; // Gets the entity for the given tag hash, or null if there isn't one. - ProcessorEntity* GetEntityForTagHash(const std::string& tag_hash); - const ProcessorEntity* GetEntityForTagHash(const std::string& tag_hash) const; + ProcessorEntity* GetEntityForTagHash(const ClientTagHash& tag_hash); + const ProcessorEntity* GetEntityForTagHash( + const ClientTagHash& tag_hash) const; // Create an entity in the entity map for |storage_key| and return a pointer // to it. @@ -291,7 +293,7 @@ // A map of client tag hash to sync entities known to this processor. This // should contain entries and metadata for most everything, although the // entities may not always contain model type data/specifics. - std::map<std::string, std::unique_ptr<ProcessorEntity>> entities_; + std::map<ClientTagHash, std::unique_ptr<ProcessorEntity>> entities_; // The bridge wants to communicate entirely via storage keys that it is free // to define and can understand more easily. All of the sync machinery wants @@ -302,7 +304,7 @@ // GetStorageKey(). In this case the bridge is responsible for updating // storage key with UpdateStorageKey() call from within // MergeSyncData/ApplySyncChanges. - std::map<std::string, std::string> storage_key_to_tag_hash_; + std::map<std::string, ClientTagHash> storage_key_to_tag_hash_; // If the processor should behave as if |type_| is one of the commit only // model types. For this processor, being commit only means that on commit
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc b/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc index 9399271..071abf06 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc +++ b/components/sync/model_impl/client_tag_based_model_type_processor_unittest.cc
@@ -16,6 +16,7 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "base/threading/platform_thread.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/model_type.h" #include "components/sync/base/sync_mode.h" #include "components/sync/base/time.h" @@ -42,11 +43,10 @@ const char kValue1[] = "value1"; const char kValue2[] = "value2"; const char kValue3[] = "value3"; -const std::string kHash1(FakeModelTypeSyncBridge::TagHashFromKey(kKey1)); -const std::string kHash2(FakeModelTypeSyncBridge::TagHashFromKey(kKey2)); -const std::string kHash3(FakeModelTypeSyncBridge::TagHashFromKey(kKey3)); -const std::string kHash4(FakeModelTypeSyncBridge::TagHashFromKey(kKey4)); -const std::string kHash5(FakeModelTypeSyncBridge::TagHashFromKey(kKey5)); + +ClientTagHash GetHash(const std::string& key) { + return FakeModelTypeSyncBridge::TagHashFromKey(key); +} // Typically used for verification after a delete. The specifics given to the // worker/processor will not have been initialized and thus empty. @@ -454,7 +454,7 @@ EXPECT_EQ(0, bridge()->merge_call_count()); // Initial sync with one server item. - worker()->UpdateFromServer(kHash2, GenerateSpecifics(kKey2, kValue2)); + worker()->UpdateFromServer(GetHash(kKey2), GenerateSpecifics(kKey2, kValue2)); EXPECT_EQ(1, bridge()->merge_call_count()); // Now have data and metadata for both items, as well as a commit request for @@ -464,7 +464,7 @@ EXPECT_EQ(2U, ProcessorEntityCount()); EXPECT_EQ(1, db()->GetMetadata(kKey1).sequence_number()); EXPECT_EQ(0, db()->GetMetadata(kKey2).sequence_number()); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); } // Test that an initial sync filters out tombstones in the processor. @@ -475,7 +475,7 @@ EXPECT_EQ(0, bridge()->merge_call_count()); // Initial sync with a tombstone. The fake bridge checks that it doesn't get // any tombstones in its MergeSyncData function. - worker()->TombstoneFromServer(kHash1); + worker()->TombstoneFromServer(GetHash(kKey1)); EXPECT_EQ(1, bridge()->merge_call_count()); // Should still have no data, metadata, or commit requests. @@ -511,7 +511,7 @@ // Check that data coming from sync is treated as a normal GetUpdates. OnSyncStarting(); - worker()->UpdateFromServer(kHash2, GenerateSpecifics(kKey2, kValue2)); + worker()->UpdateFromServer(GetHash(kKey2), GenerateSpecifics(kKey2, kValue2)); EXPECT_EQ(0, bridge()->merge_call_count()); EXPECT_EQ(1, bridge()->apply_call_count()); EXPECT_EQ(2U, db()->data_count()); @@ -579,7 +579,7 @@ OnSyncStarting(); OnCommitDataLoaded(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {specifics2}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {specifics2}); // Connect, data, put. EntitySpecifics specifics6 = ResetStateWriteItem(kKey1, kValue1); @@ -588,8 +588,8 @@ OnCommitDataLoaded(); EntitySpecifics specifics7 = bridge()->WriteItem(kKey1, kValue2); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {specifics6}); - worker()->VerifyNthPendingCommit(1, {kHash1}, {specifics7}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {specifics6}); + worker()->VerifyNthPendingCommit(1, {GetHash(kKey1)}, {specifics7}); // Connect, put, data. EntitySpecifics specifics100 = ResetStateWriteItem(kKey1, kValue1); @@ -598,7 +598,7 @@ EntitySpecifics specifics8 = bridge()->WriteItem(kKey1, kValue2); OnCommitDataLoaded(); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {specifics8}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {specifics8}); // GetData was launched as a result of GetLocalChanges call(). Since all data // are in memory, the 2nd pending commit should be empty. worker()->VerifyNthPendingCommit(1, {}, {}); @@ -610,7 +610,7 @@ OnSyncStarting(); EXPECT_FALSE(bridge()->GetDataCallback()); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {specifics10}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {specifics10}); // Connect, data, delete. EntitySpecifics specifics12 = ResetStateWriteItem(kKey1, kValue1); @@ -619,8 +619,8 @@ OnCommitDataLoaded(); bridge()->DeleteItem(kKey1); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {specifics12}); - worker()->VerifyNthPendingCommit(1, {kHash1}, {kEmptySpecifics}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {specifics12}); + worker()->VerifyNthPendingCommit(1, {GetHash(kKey1)}, {kEmptySpecifics}); // Connect, delete, data. ResetStateWriteItem(kKey1, kValue1); @@ -629,7 +629,7 @@ bridge()->DeleteItem(kKey1); OnCommitDataLoaded(); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {kEmptySpecifics}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {kEmptySpecifics}); // GetData was launched as a result of GetLocalChanges call(). Since all data // are in memory, the 2nd pending commit should be empty. worker()->VerifyNthPendingCommit(1, {}, {}); @@ -641,7 +641,7 @@ OnSyncStarting(); EXPECT_FALSE(bridge()->GetDataCallback()); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {kEmptySpecifics}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {kEmptySpecifics}); } // Tests cases where pending data loads synchronously. @@ -652,7 +652,7 @@ InitializeToMetadataLoaded(); OnSyncStarting(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {specifics1}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {specifics1}); // Sync, model. EntitySpecifics specifics2 = ResetStateWriteItem(kKey1, kValue1); @@ -660,7 +660,7 @@ bridge()->ExpectSynchronousDataCallback(); InitializeToMetadataLoaded(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {specifics2}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {specifics2}); } // This test covers race conditions during loading a pending delete. All cases @@ -679,7 +679,7 @@ InitializeToMetadataLoaded(); OnSyncStarting(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {kEmptySpecifics}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {kEmptySpecifics}); // Connect, put. ResetStateDeleteItem(kKey1, kValue1); @@ -688,8 +688,8 @@ EXPECT_EQ(1U, worker()->GetNumPendingCommits()); EntitySpecifics specifics1 = bridge()->WriteItem(kKey1, kValue2); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {kEmptySpecifics}); - worker()->VerifyNthPendingCommit(1, {kHash1}, {specifics1}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {kEmptySpecifics}); + worker()->VerifyNthPendingCommit(1, {GetHash(kKey1)}, {specifics1}); // Put, connect. ResetStateDeleteItem(kKey1, kValue1); @@ -697,7 +697,7 @@ EntitySpecifics specifics2 = bridge()->WriteItem(kKey1, kValue2); OnSyncStarting(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {specifics2}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {specifics2}); // Connect, delete. ResetStateDeleteItem(kKey1, kValue1); @@ -706,8 +706,8 @@ EXPECT_EQ(1U, worker()->GetNumPendingCommits()); bridge()->DeleteItem(kKey1); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {kEmptySpecifics}); - worker()->VerifyNthPendingCommit(1, {kHash1}, {kEmptySpecifics}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {kEmptySpecifics}); + worker()->VerifyNthPendingCommit(1, {GetHash(kKey1)}, {kEmptySpecifics}); // Delete, connect. ResetStateDeleteItem(kKey1, kValue1); @@ -715,7 +715,7 @@ bridge()->DeleteItem(kKey1); OnSyncStarting(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {kEmptySpecifics}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {kEmptySpecifics}); } // Test that loading a committed item does not queue another commit. @@ -746,9 +746,9 @@ type_processor()->GetEntityModificationTime(kKey1)); // Verify the commit request this operation has triggered. - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); const CommitRequestData* tag1_request_data = - worker()->GetLatestPendingCommitForHash(kHash1); + worker()->GetLatestPendingCommitForHash(GetHash(kKey1)); ASSERT_TRUE(tag1_request_data); const EntityData& tag1_data = *tag1_request_data->entity; @@ -808,24 +808,24 @@ entity_data->specifics.mutable_preference()->set_value(kValue1); entity_data->name = kKey1; - entity_data->client_tag_hash = kHash1; + entity_data->client_tag_hash = GetHash(kKey1); entity_data->id = kId1; bridge()->WriteItem(kKey1, std::move(entity_data)); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - ASSERT_FALSE(worker()->HasPendingCommitForHash(kHash3)); - ASSERT_TRUE(worker()->HasPendingCommitForHash(kHash1)); + ASSERT_FALSE(worker()->HasPendingCommitForHash(GetHash(kKey3))); + ASSERT_TRUE(worker()->HasPendingCommitForHash(GetHash(kKey1))); EXPECT_EQ(1U, db()->metadata_count()); - ASSERT_TRUE(worker()->GetLatestPendingCommitForHash(kHash1)); + ASSERT_TRUE(worker()->GetLatestPendingCommitForHash(GetHash(kKey1))); const EntityData& out_entity1 = - *worker()->GetLatestPendingCommitForHash(kHash1)->entity; + *worker()->GetLatestPendingCommitForHash(GetHash(kKey1))->entity; const EntityMetadata metadata_v1 = db()->GetMetadata(kKey1); EXPECT_EQ(kId1, out_entity1.id); - EXPECT_NE(kHash3, out_entity1.client_tag_hash); + EXPECT_NE(GetHash(kKey3), out_entity1.client_tag_hash); EXPECT_EQ(kValue1, out_entity1.specifics.preference().value()); EXPECT_EQ(kId1, metadata_v1.server_id()); - EXPECT_EQ(metadata_v1.client_tag_hash(), out_entity1.client_tag_hash); + EXPECT_EQ(metadata_v1.client_tag_hash(), out_entity1.client_tag_hash.value()); entity_data = std::make_unique<EntityData>(); // This is a sketchy move here, changing the name will change the generated @@ -833,25 +833,25 @@ entity_data->specifics.mutable_preference()->set_name(kKey2); entity_data->specifics.mutable_preference()->set_value(kValue2); entity_data->name = kKey2; - entity_data->client_tag_hash = kHash3; + entity_data->client_tag_hash = GetHash(kKey3); // Make sure ID isn't overwritten either. entity_data->id = kId2; bridge()->WriteItem(kKey1, std::move(entity_data)); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - ASSERT_FALSE(worker()->HasPendingCommitForHash(kHash3)); - ASSERT_TRUE(worker()->HasPendingCommitForHash(kHash1)); + ASSERT_FALSE(worker()->HasPendingCommitForHash(GetHash(kKey3))); + ASSERT_TRUE(worker()->HasPendingCommitForHash(GetHash(kKey1))); EXPECT_EQ(1U, db()->metadata_count()); - ASSERT_TRUE(worker()->GetLatestPendingCommitForHash(kHash1)); + ASSERT_TRUE(worker()->GetLatestPendingCommitForHash(GetHash(kKey1))); const EntityData& out_entity2 = - *worker()->GetLatestPendingCommitForHash(kHash1)->entity; + *worker()->GetLatestPendingCommitForHash(GetHash(kKey1))->entity; const EntityMetadata metadata_v2 = db()->GetMetadata(kKey1); EXPECT_EQ(kValue2, out_entity2.specifics.preference().value()); // Should still see old cid1 value, override is not respected on update. EXPECT_EQ(kId1, out_entity2.id); EXPECT_EQ(kId1, metadata_v2.server_id()); - EXPECT_EQ(metadata_v2.client_tag_hash(), out_entity2.client_tag_hash); + EXPECT_EQ(metadata_v2.client_tag_hash(), out_entity2.client_tag_hash.value()); // Specifics have changed so the hashes should not match. EXPECT_NE(metadata_v1.specifics_hash(), metadata_v2.specifics_hash()); @@ -864,14 +864,14 @@ bridge()->WriteItem(kKey1, kValue1); ASSERT_EQ(1U, db()->metadata_count()); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); const EntityMetadata metadata_v1 = db()->GetMetadata(kKey1); int64_t request_data_v1_sequence_number; { // request_data_v1 is valid only while the commit is still pending. const CommitRequestData* request_data_v1 = - worker()->GetLatestPendingCommitForHash(kHash1); + worker()->GetLatestPendingCommitForHash(GetHash(kKey1)); ASSERT_TRUE(request_data_v1); const EntityData& data_v1 = *request_data_v1->entity; EXPECT_EQ(data_v1.specifics.preference().value(), kValue1); @@ -890,7 +890,7 @@ bridge()->WriteItem(kKey1, kValue2); EXPECT_EQ(1U, db()->metadata_count()); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); EXPECT_TRUE(type_processor()->IsEntityUnsynced(kKey1)); EXPECT_EQ(ctime, type_processor()->GetEntityCreationTime(kKey1)); @@ -898,7 +898,7 @@ EXPECT_NE(ctime, mtime); const CommitRequestData* request_data_v2 = - worker()->GetLatestPendingCommitForHash(kHash1); + worker()->GetLatestPendingCommitForHash(GetHash(kKey1)); ASSERT_TRUE(request_data_v2); const EntityData& data_v2 = *request_data_v2->entity; const EntityMetadata metadata_v2 = db()->GetMetadata(kKey1); @@ -942,10 +942,10 @@ bridge()->WriteItem(kKey1, kValue1); ASSERT_EQ(1U, db()->metadata_count()); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); const CommitRequestData* request_data_v1 = - worker()->GetLatestPendingCommitForHash(kHash1); + worker()->GetLatestPendingCommitForHash(GetHash(kKey1)); ASSERT_TRUE(request_data_v1); const EntityData& data_v1 = *request_data_v1->entity; const EntityMetadata metadata_v1 = db()->GetMetadata(kKey1); @@ -961,7 +961,7 @@ bridge()->WriteItem(kKey1, kValue2); EXPECT_EQ(1U, db()->metadata_count()); - worker()->VerifyPendingCommits({{kHash1}, {kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}, {GetHash(kKey1)}}); EXPECT_TRUE(type_processor()->IsEntityUnsynced(kKey1)); EXPECT_EQ(ctime, type_processor()->GetEntityCreationTime(kKey1)); @@ -969,7 +969,7 @@ EXPECT_NE(mtime, ctime); const CommitRequestData* request_data_v2 = - worker()->GetLatestPendingCommitForHash(kHash1); + worker()->GetLatestPendingCommitForHash(GetHash(kKey1)); ASSERT_TRUE(request_data_v2); const EntityData& data_v2 = *request_data_v2->entity; const EntityMetadata metadata_v2 = db()->GetMetadata(kKey1); @@ -1011,7 +1011,7 @@ InitializeToReadyState(); bridge()->WriteItem(kKey1, kValue1); ASSERT_EQ(1U, db()->metadata_count()); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); const base::Time ctime = type_processor()->GetEntityCreationTime(kKey1); const base::Time mtime = type_processor()->GetEntityModificationTime(kKey1); @@ -1019,7 +1019,7 @@ ASSERT_FALSE(mtime.is_null()); bridge()->WriteItem(kKey1, kValue1); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); EXPECT_EQ(ctime, type_processor()->GetEntityCreationTime(kKey1)); EXPECT_EQ(mtime, type_processor()->GetEntityModificationTime(kKey1)); @@ -1028,7 +1028,7 @@ // Thoroughly tests the data generated by a server item creation. TEST_F(ClientTagBasedModelTypeProcessorTest, ShouldProcessRemoteCreation) { InitializeToReadyState(); - worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue1)); + worker()->UpdateFromServer(GetHash(kKey1), GenerateSpecifics(kKey1, kValue1)); EXPECT_EQ(1U, db()->data_count()); EXPECT_EQ(1U, db()->metadata_count()); EXPECT_EQ(1U, ProcessorEntityCount()); @@ -1069,7 +1069,7 @@ TEST_F(ClientTagBasedModelTypeProcessorTest, ShouldIgnoreRemoteUpdatesWithUnexpectedClientTagHash) { InitializeToReadyState(); - worker()->UpdateFromServer(kHash2, GenerateSpecifics(kKey1, kValue1)); + worker()->UpdateFromServer(GetHash(kKey2), GenerateSpecifics(kKey1, kValue1)); EXPECT_EQ(0U, db()->data_count()); EXPECT_EQ(0U, db()->metadata_count()); EXPECT_EQ(0U, ProcessorEntityCount()); @@ -1081,7 +1081,7 @@ InitializeToReadyState(); bridge()->ErrorOnNextCall(); ExpectError(); - worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue1)); + worker()->UpdateFromServer(GetHash(kKey1), GenerateSpecifics(kKey1, kValue1)); } // Thoroughly tests the data generated by a server item creation. @@ -1094,12 +1094,12 @@ EXPECT_EQ(2U, db()->metadata_change_count()); // Redundant update from server doesn't write data but updates metadata. - worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue1)); + worker()->UpdateFromServer(GetHash(kKey1), GenerateSpecifics(kKey1, kValue1)); EXPECT_EQ(1U, db()->data_change_count()); EXPECT_EQ(3U, db()->metadata_change_count()); // A reflection (update already received) is ignored completely. - worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue1), + worker()->UpdateFromServer(GetHash(kKey1), GenerateSpecifics(kKey1, kValue1), 0 /* version_offset */); EXPECT_EQ(1U, db()->data_change_count()); EXPECT_EQ(3U, db()->metadata_change_count()); @@ -1122,7 +1122,7 @@ // Metadata is not removed until the commit response comes back. EXPECT_EQ(1U, db()->metadata_count()); EXPECT_EQ(1U, ProcessorEntityCount()); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); const EntityMetadata metadata_v2 = db()->GetMetadata(kKey1); EXPECT_TRUE(metadata_v2.is_deleted()); @@ -1161,9 +1161,9 @@ ShouldHandleLocalDeletionDuringLocalCreationCommit) { InitializeToReadyState(); bridge()->WriteItem(kKey1, kValue1); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); const CommitRequestData* data_v1 = - worker()->GetLatestPendingCommitForHash(kHash1); + worker()->GetLatestPendingCommitForHash(GetHash(kKey1)); ASSERT_TRUE(data_v1); const EntityMetadata metadata_v1 = db()->GetMetadata(kKey1); @@ -1176,10 +1176,10 @@ EXPECT_EQ(0U, db()->data_count()); EXPECT_EQ(1U, db()->metadata_count()); EXPECT_EQ(1U, ProcessorEntityCount()); - worker()->VerifyPendingCommits({{kHash1}, {kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}, {GetHash(kKey1)}}); const CommitRequestData* data_v2 = - worker()->GetLatestPendingCommitForHash(kHash1); + worker()->GetLatestPendingCommitForHash(GetHash(kKey1)); ASSERT_TRUE(data_v2); EXPECT_GT(data_v2->sequence_number, data_v1->sequence_number); EXPECT_TRUE(data_v2->entity->id.empty()); @@ -1218,7 +1218,7 @@ EXPECT_EQ(1U, db()->data_count()); EXPECT_EQ(0U, worker()->GetNumPendingCommits()); - worker()->TombstoneFromServer(kHash1); + worker()->TombstoneFromServer(GetHash(kKey1)); // Delete from server should clear the data and all the metadata. EXPECT_EQ(0U, db()->data_count()); EXPECT_EQ(0U, db()->metadata_count()); @@ -1251,7 +1251,7 @@ TEST_F(ClientTagBasedModelTypeProcessorTest, ShouldIgnoreRemoteDeletionOfUnknownEntity) { InitializeToReadyState(); - worker()->TombstoneFromServer(kHash1); + worker()->TombstoneFromServer(GetHash(kKey1)); EXPECT_EQ(0U, db()->data_count()); EXPECT_EQ(0U, db()->metadata_count()); EXPECT_EQ(0U, ProcessorEntityCount()); @@ -1264,7 +1264,7 @@ ShouldRetryCommitAfterServerError) { InitializeToReadyState(); bridge()->WriteItem(kKey1, kValue1); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); // Entity is sent to server. Processor shouldn't include it in local changes. CommitRequestDataList commit_request; @@ -1279,7 +1279,7 @@ INT_MAX, base::BindOnce(&CaptureCommitRequest, &commit_request)); OnCommitDataLoaded(); EXPECT_EQ(1U, commit_request.size()); - EXPECT_EQ(kHash1, commit_request[0]->entity->client_tag_hash); + EXPECT_EQ(GetHash(kKey1), commit_request[0]->entity->client_tag_hash); } // Tests that GetLocalChanges honors max_entries parameter. @@ -1308,7 +1308,7 @@ const EntityMetadata metadata1 = db()->GetMetadata(kKey1); // There should be one commit request for this item only. - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); bridge()->WriteItem(kKey2, kValue2); EXPECT_EQ(2U, db()->data_count()); @@ -1316,7 +1316,7 @@ const EntityMetadata metadata2 = db()->GetMetadata(kKey2); // The second write should trigger another single-item commit request. - worker()->VerifyPendingCommits({{kHash1}, {kHash2}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}, {GetHash(kKey2)}}); EXPECT_FALSE(metadata1.is_deleted()); EXPECT_EQ(1, metadata1.sequence_number()); @@ -1337,16 +1337,16 @@ EXPECT_EQ(kValue1, db()->GetValue(kKey1)); EXPECT_EQ(1U, db()->metadata_change_count()); EXPECT_EQ(kUncommittedVersion, db()->GetMetadata(kKey1).server_version()); - worker()->VerifyPendingCommits({{kHash1}}); - worker()->VerifyNthPendingCommit(0, {kHash1}, {specifics}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {specifics}); // Changes match doesn't call ResolveConflict. - worker()->UpdateFromServer(kHash1, specifics); + worker()->UpdateFromServer(GetHash(kKey1), specifics); // Updated metadata but not data; no new commit request. EXPECT_EQ(1U, db()->data_change_count()); EXPECT_EQ(1, db()->GetMetadata(kKey1).server_version()); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); } TEST_F(ClientTagBasedModelTypeProcessorTest, @@ -1359,15 +1359,15 @@ // Change value locally and at the same time simulate conflicting update from // server. EntitySpecifics specifics2 = bridge()->WriteItem(kKey1, kValue2); - worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue3)); + worker()->UpdateFromServer(GetHash(kKey1), GenerateSpecifics(kKey1, kValue3)); OnCommitDataLoaded(); // Updated metadata but not data; new commit request. EXPECT_EQ(2U, db()->data_change_count()); EXPECT_EQ(4U, db()->metadata_change_count()); EXPECT_EQ(2, db()->GetMetadata(kKey1).server_version()); - worker()->VerifyPendingCommits({{kHash1}, {kHash1}}); - worker()->VerifyNthPendingCommit(1, {kHash1}, {specifics2}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}, {GetHash(kKey1)}}); + worker()->VerifyNthPendingCommit(1, {GetHash(kKey1)}, {specifics2}); } TEST_F(ClientTagBasedModelTypeProcessorTest, @@ -1377,14 +1377,15 @@ bridge()->WriteItem(kKey1, kValue1); ASSERT_EQ(1U, worker()->GetNumPendingCommits()); - ASSERT_TRUE(worker()->GetLatestPendingCommitForHash(kHash1)); - ASSERT_TRUE( - worker()->GetLatestPendingCommitForHash(kHash1)->entity->id.empty()); + ASSERT_TRUE(worker()->GetLatestPendingCommitForHash(GetHash(kKey1))); + ASSERT_TRUE(worker() + ->GetLatestPendingCommitForHash(GetHash(kKey1)) + ->entity->id.empty()); // The update from the server should be mostly ignored because local wins, but // the server ID should be updated. bridge()->SetConflictResolution(ConflictResolution::kUseLocal); - worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue3)); + worker()->UpdateFromServer(GetHash(kKey1), GenerateSpecifics(kKey1, kValue3)); OnCommitDataLoaded(); // In this test setup, the processor's nudge for commit immediately pulls // updates from the processor and list them as pending commits, so we should @@ -1393,7 +1394,7 @@ // Verify the commit request this operation has triggered. const CommitRequestData* tag1_request_data = - worker()->GetLatestPendingCommitForHash(kHash1); + worker()->GetLatestPendingCommitForHash(GetHash(kKey1)); ASSERT_TRUE(tag1_request_data); const EntityData& tag1_data = *tag1_request_data->entity; @@ -1427,15 +1428,16 @@ bridge()->DeleteItem(kKey1); ASSERT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->VerifyPendingCommits({{kHash1}}); - ASSERT_TRUE(worker()->GetLatestPendingCommitForHash(kHash1)); - ASSERT_TRUE( - worker()->GetLatestPendingCommitForHash(kHash1)->entity->is_deleted()); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); + ASSERT_TRUE(worker()->GetLatestPendingCommitForHash(GetHash(kKey1))); + ASSERT_TRUE(worker() + ->GetLatestPendingCommitForHash(GetHash(kKey1)) + ->entity->is_deleted()); ASSERT_EQ(2U, db()->data_change_count()); ASSERT_EQ(3U, db()->metadata_change_count()); ASSERT_TRUE(type_processor()->IsTrackingEntityForTest(kKey1)); - worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue2)); + worker()->UpdateFromServer(GetHash(kKey1), GenerateSpecifics(kKey1, kValue2)); // Updated client data and metadata; no new commit request. EXPECT_TRUE(type_processor()->IsTrackingEntityForTest(kKey1)); @@ -1443,7 +1445,7 @@ EXPECT_EQ(kValue2, db()->GetValue(kKey1)); EXPECT_EQ(4U, db()->metadata_change_count()); EXPECT_EQ(2, db()->GetMetadata(kKey1).server_version()); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); } TEST_F(ClientTagBasedModelTypeProcessorTest, @@ -1455,15 +1457,16 @@ bridge()->DeleteItem(kKey1); ASSERT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->VerifyPendingCommits({{kHash1}}); - ASSERT_TRUE(worker()->GetLatestPendingCommitForHash(kHash1)); - ASSERT_TRUE( - worker()->GetLatestPendingCommitForHash(kHash1)->entity->is_deleted()); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); + ASSERT_TRUE(worker()->GetLatestPendingCommitForHash(GetHash(kKey1))); + ASSERT_TRUE(worker() + ->GetLatestPendingCommitForHash(GetHash(kKey1)) + ->entity->is_deleted()); ASSERT_EQ(2U, db()->data_change_count()); ASSERT_EQ(3U, db()->metadata_change_count()); ASSERT_TRUE(type_processor()->IsTrackingEntityForTest(kKey1)); - worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue2)); + worker()->UpdateFromServer(GetHash(kKey1), GenerateSpecifics(kKey1, kValue2)); // A new storage key should have been generated, which should replace the // previous when it comes to storing data and metadata. @@ -1481,7 +1484,7 @@ EXPECT_EQ(kValue2, db()->GetValue(new_storage_key)); EXPECT_EQ(5U, db()->metadata_change_count()); EXPECT_EQ(2, db()->GetMetadata(new_storage_key).server_version()); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); } TEST_F(ClientTagBasedModelTypeProcessorTest, @@ -1489,14 +1492,14 @@ InitializeToReadyState(); bridge()->WriteItem(kKey1, kValue1); bridge()->SetConflictResolution(ConflictResolution::kUseRemote); - worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue2)); + worker()->UpdateFromServer(GetHash(kKey1), GenerateSpecifics(kKey1, kValue2)); // Updated client data and metadata; no new commit request. EXPECT_EQ(2U, db()->data_change_count()); EXPECT_EQ(kValue2, db()->GetValue(kKey1)); EXPECT_EQ(2U, db()->metadata_change_count()); EXPECT_EQ(1, db()->GetMetadata(kKey1).server_version()); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); } TEST_F(ClientTagBasedModelTypeProcessorTest, @@ -1504,7 +1507,7 @@ InitializeToReadyState(); bridge()->WriteItem(kKey1, kValue1); bridge()->SetConflictResolution(ConflictResolution::kUseRemote); - worker()->TombstoneFromServer(kHash1); + worker()->TombstoneFromServer(GetHash(kKey1)); // Updated client data and metadata; no new commit request. EXPECT_EQ(0U, db()->data_count()); @@ -1525,7 +1528,7 @@ // The second item has a commit request in progress. bridge()->WriteItem(kKey2, kValue2); - EXPECT_TRUE(worker()->HasPendingCommitForHash(kHash2)); + EXPECT_TRUE(worker()->HasPendingCommitForHash(GetHash(kKey2))); DisconnectSync(); @@ -1539,13 +1542,13 @@ EXPECT_EQ(2U, worker()->GetNthPendingCommit(0).size()); // The first item was already in sync. - EXPECT_FALSE(worker()->HasPendingCommitForHash(kHash1)); + EXPECT_FALSE(worker()->HasPendingCommitForHash(GetHash(kKey1))); // The second item's commit was interrupted and should be retried. - EXPECT_TRUE(worker()->HasPendingCommitForHash(kHash2)); + EXPECT_TRUE(worker()->HasPendingCommitForHash(GetHash(kKey2))); // The third item's commit was not started until the reconnect. - EXPECT_TRUE(worker()->HasPendingCommitForHash(kHash3)); + EXPECT_TRUE(worker()->HasPendingCommitForHash(GetHash(kKey3))); } // Test proper handling of stop (without disabling sync) and re-enable. @@ -1560,7 +1563,7 @@ // The second item has a commit request in progress. bridge()->WriteItem(kKey2, kValue2); - EXPECT_TRUE(worker()->HasPendingCommitForHash(kHash2)); + EXPECT_TRUE(worker()->HasPendingCommitForHash(GetHash(kKey2))); type_processor()->OnSyncStopping(KEEP_METADATA); EXPECT_TRUE(type_processor()->IsTrackingMetadata()); @@ -1573,7 +1576,7 @@ worker()->UpdateFromServer(); // Once we're ready to commit, only the newest items should be committed. - worker()->VerifyPendingCommits({{kHash3}}); + worker()->VerifyPendingCommits({{GetHash(kKey3)}}); } // Test proper handling of disable and re-enable. @@ -1588,7 +1591,7 @@ // The second item has a commit request in progress. bridge()->WriteItem(kKey2, kValue2); - EXPECT_TRUE(worker()->HasPendingCommitForHash(kHash2)); + EXPECT_TRUE(worker()->HasPendingCommitForHash(GetHash(kKey2))); type_processor()->OnSyncStopping(CLEAR_METADATA); EXPECT_FALSE(type_processor()->IsTrackingMetadata()); @@ -1603,7 +1606,8 @@ // Once we're ready to commit, all three local items should consider // themselves uncommitted and pending for commit. - worker()->VerifyPendingCommits({{kHash1}, {kHash2}, {kHash3}}); + worker()->VerifyPendingCommits( + {{GetHash(kKey1)}, {GetHash(kKey2)}, {GetHash(kKey3)}}); } // Test proper handling of disable-sync before initial sync done. @@ -1634,7 +1638,7 @@ EntitySpecifics specifics1 = WriteItemAndAck(kKey1, kValue1); // Create another item and don't wait for its commit response. EntitySpecifics specifics2 = bridge()->WriteItem(kKey2, kValue2); - worker()->VerifyPendingCommits({{kHash2}}); + worker()->VerifyPendingCommits({{GetHash(kKey2)}}); EXPECT_EQ(1U, db()->GetMetadata(kKey1).sequence_number()); EXPECT_EQ(1U, db()->GetMetadata(kKey2).sequence_number()); @@ -1646,7 +1650,7 @@ OnCommitDataLoaded(); // All data are in memory now. ASSERT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(1, {kHash1, kHash2}, + worker()->VerifyNthPendingCommit(1, {GetHash(kKey1), GetHash(kKey2)}, {specifics1, specifics2}); // Sequence numbers in the store are updated. EXPECT_EQ(2U, db()->GetMetadata(kKey1).sequence_number()); @@ -1669,36 +1673,38 @@ InitializeToReadyState(); // Receive an unencrypted update. - worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue1)); + worker()->UpdateFromServer(GetHash(kKey1), GenerateSpecifics(kKey1, kValue1)); ASSERT_EQ(0U, worker()->GetNumPendingCommits()); UpdateResponseDataList update; // Receive an entity with old encryption as part of the update. update.push_back(worker()->GenerateUpdateData( - kHash2, GenerateSpecifics(kKey2, kValue2), 1, "k1")); + GetHash(kKey2), GenerateSpecifics(kKey2, kValue2), 1, "k1")); // Receive an entity with up-to-date encryption as part of the update. update.push_back(worker()->GenerateUpdateData( - kHash3, GenerateSpecifics(kKey3, kValue3), 1, "k2")); + GetHash(kKey3), GenerateSpecifics(kKey3, kValue3), 1, "k2")); // Set desired encryption key to k2 to force updates to some items. worker()->UpdateWithEncryptionKey("k2", std::move(update)); OnCommitDataLoaded(); // kKey1 needed data so once that's loaded, kKey1 and kKey2 are queued for // commit. - worker()->VerifyPendingCommits({{kHash1, kHash2}}); + worker()->VerifyPendingCommits({{GetHash(kKey1), GetHash(kKey2)}}); // Receive a separate update that was encrypted with key k1. - worker()->UpdateFromServer(kHash4, GenerateSpecifics(kKey4, kValue1), 1, - "k1"); + worker()->UpdateFromServer(GetHash(kKey4), GenerateSpecifics(kKey4, kValue1), + 1, "k1"); OnCommitDataLoaded(); // Receipt of updates encrypted with old key also forces a re-encrypt commit. - worker()->VerifyPendingCommits({{kHash1, kHash2}, {kHash4}}); + worker()->VerifyPendingCommits( + {{GetHash(kKey1), GetHash(kKey2)}, {GetHash(kKey4)}}); // Receive an update that was encrypted with key k2. - worker()->UpdateFromServer(kHash5, GenerateSpecifics(kKey5, kValue1), 1, - "k2"); + worker()->UpdateFromServer(GetHash(kKey5), GenerateSpecifics(kKey5, kValue1), + 1, "k2"); // That was the correct key, so no re-encryption is required. - worker()->VerifyPendingCommits({{kHash1, kHash2}, {kHash4}}); + worker()->VerifyPendingCommits( + {{GetHash(kKey1), GetHash(kKey2)}, {GetHash(kKey4)}}); } // Test that re-encrypting enqueues the right data for kUseLocal conflicts. @@ -1711,16 +1717,17 @@ OnCommitDataLoaded(); EntitySpecifics specifics = bridge()->WriteItem(kKey1, kValue2); - worker()->VerifyPendingCommits({{kHash1}, {kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}, {GetHash(kKey1)}}); bridge()->SetConflictResolution(ConflictResolution::kUseLocal); // Unencrypted update needs to be re-commited with key k1. - worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue3), 1, ""); + worker()->UpdateFromServer(GetHash(kKey1), GenerateSpecifics(kKey1, kValue3), + 1, ""); OnCommitDataLoaded(); // Ensure the re-commit has the correct value. EXPECT_EQ(3U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(2, {kHash1}, {specifics}); + worker()->VerifyNthPendingCommit(2, {GetHash(kKey1)}, {specifics}); EXPECT_EQ(kValue2, db()->GetValue(kKey1)); } @@ -1734,12 +1741,12 @@ bridge()->SetConflictResolution(ConflictResolution::kUseRemote); // Unencrypted update needs to be re-commited with key k1. EntitySpecifics specifics = GenerateSpecifics(kKey1, kValue2); - worker()->UpdateFromServer(kHash1, specifics, 1, ""); + worker()->UpdateFromServer(GetHash(kKey1), specifics, 1, ""); OnCommitDataLoaded(); // Ensure the re-commit has the correct value. EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(1, {kHash1}, {specifics}); + worker()->VerifyNthPendingCommit(1, {GetHash(kKey1)}, {specifics}); EXPECT_EQ(kValue2, db()->GetValue(kKey1)); } @@ -1755,12 +1762,12 @@ // Unencrypted update needs to be re-commited with key k1. EntitySpecifics specifics = GenerateSpecifics(kKey1, kValue2); - worker()->UpdateFromServer(kHash1, specifics, 1, ""); + worker()->UpdateFromServer(GetHash(kKey1), specifics, 1, ""); OnCommitDataLoaded(); // Ensure the re-commit has the correct value. EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(1, {kHash1}, {specifics}); + worker()->VerifyNthPendingCommit(1, {GetHash(kKey1)}, {specifics}); EXPECT_EQ(kValue2, db()->GetValue(kKey1)); } @@ -1772,9 +1779,9 @@ worker()->UpdateWithEncryptionKey("k1"); OnCommitDataLoaded(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {specifics}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {specifics}); - worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue2)); + worker()->UpdateFromServer(GetHash(kKey1), GenerateSpecifics(kKey1, kValue2)); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); } @@ -1784,7 +1791,7 @@ InitializeToReadyState(); UpdateResponseDataList updates; updates.push_back(worker()->GenerateUpdateData( - /*tag_hash=*/"", GenerateSpecifics(kKey1, kValue1), 1, "k1")); + ClientTagHash(), GenerateSpecifics(kKey1, kValue1), 1, "k1")); worker()->UpdateFromServer(std::move(updates)); @@ -1804,7 +1811,7 @@ UpdateResponseDataList updates; updates.push_back(worker()->GenerateUpdateData( - /*tag_hash=*/"", GenerateSpecifics(kKey1, kValue1), 1, "k1")); + ClientTagHash(), GenerateSpecifics(kKey1, kValue1), 1, "k1")); worker()->UpdateFromServer(std::move(updates)); ASSERT_EQ(1, bridge()->merge_call_count()); @@ -1828,7 +1835,7 @@ UpdateResponseDataList updates; updates.push_back(worker()->GenerateUpdateData( - /*tag_hash=*/"", GenerateSpecifics(kKey1, kValue1), 1, "k1")); + ClientTagHash(), GenerateSpecifics(kKey1, kValue1), 1, "k1")); worker()->UpdateFromServer(std::move(updates)); ASSERT_EQ(1, bridge()->merge_call_count()); @@ -1856,9 +1863,9 @@ InitializeToReadyState(); UpdateResponseDataList updates; updates.push_back(worker()->GenerateUpdateData( - /*tag_hash=*/"", GenerateSpecifics(kKey1, kValue1), 1, "k1")); + ClientTagHash(), GenerateSpecifics(kKey1, kValue1), 1, "k1")); updates.push_back(worker()->GenerateUpdateData( - /*tag_hash=*/"", GenerateSpecifics(kKey2, kValue2), 2, "k2")); + ClientTagHash(), GenerateSpecifics(kKey2, kValue2), 2, "k2")); // Create 2 entries, one is version 3, another is version 1. sync_pb::GarbageCollectionDirective garbage_collection_directive; @@ -1895,7 +1902,7 @@ UpdateResponseDataList updates1; updates1.push_back(worker()->GenerateUpdateData( - /*tag_hash=*/"", GenerateSpecifics(kKey1, kValue1), 1, "k1")); + ClientTagHash(), GenerateSpecifics(kKey1, kValue1), 1, "k1")); sync_pb::GarbageCollectionDirective garbage_collection_directive; garbage_collection_directive.set_version_watermark(1); @@ -1914,7 +1921,7 @@ { UpdateResponseDataList updates2; updates2.push_back(worker()->GenerateUpdateData( - /*tag_hash=*/"", GenerateSpecifics(kKey1, kValue1), 1, "k1")); + ClientTagHash(), GenerateSpecifics(kKey1, kValue1), 1, "k1")); base::HistogramTester histogram_tester; // Send one more update with the same data. worker()->UpdateWithGarbageCollection(std::move(updates2), @@ -1935,7 +1942,7 @@ InitializeToReadyState(); ExpectError(); - worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue1)); + worker()->UpdateFromServer(GetHash(kKey1), GenerateSpecifics(kKey1, kValue1)); } // Tests that empty updates without a version GC are processed for types that @@ -1972,7 +1979,7 @@ ModelReadyToSync(); OnSyncStarting(); - worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue1)); + worker()->UpdateFromServer(GetHash(kKey1), GenerateSpecifics(kKey1, kValue1)); } class WalletDataClientTagBasedModelTypeProcessorTest @@ -1992,7 +1999,7 @@ // Commit an item. UpdateResponseDataList updates; updates.push_back(worker()->GenerateUpdateData( - /*tag_hash=*/"", GenerateSpecifics(kKey1, kValue1), 1, "k1")); + ClientTagHash(), GenerateSpecifics(kKey1, kValue1), 1, "k1")); sync_pb::GarbageCollectionDirective garbage_collection_directive; garbage_collection_directive.set_version_watermark(1); worker()->UpdateWithGarbageCollection(std::move(updates), @@ -2011,13 +2018,14 @@ EntitySpecifics specifics2 = bridge()->WriteItem(kKey1, kValue2); UpdateResponseDataList update; - update.push_back(worker()->GenerateUpdateData(kHash1, specifics1, 1, "k1")); + update.push_back( + worker()->GenerateUpdateData(GetHash(kKey1), specifics1, 1, "k1")); worker()->UpdateWithEncryptionKey("k1", std::move(update)); OnCommitDataLoaded(); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(1, {kHash1}, {specifics2}); + worker()->VerifyNthPendingCommit(1, {GetHash(kKey1)}, {specifics2}); } // Same as above but with two commit requests before one ack. @@ -2031,16 +2039,17 @@ worker()->AckOnePendingCommit(); // kValue2 is now the base value. EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(0, {kHash1}, {specifics2}); + worker()->VerifyNthPendingCommit(0, {GetHash(kKey1)}, {specifics2}); UpdateResponseDataList update; - update.push_back(worker()->GenerateUpdateData(kHash1, specifics1, 1, "k1")); + update.push_back( + worker()->GenerateUpdateData(GetHash(kKey1), specifics1, 1, "k1")); worker()->UpdateWithEncryptionKey("k1", std::move(update)); OnCommitDataLoaded(); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->VerifyNthPendingCommit(1, {kHash1}, {specifics2}); + worker()->VerifyNthPendingCommit(1, {GetHash(kKey1)}, {specifics2}); } // Tests that UpdateStorageKey propagates storage key to ProcessorEntity @@ -2057,11 +2066,11 @@ // Initial update from server should be handled by MergeSyncData. UpdateResponseDataList updates; - updates.push_back( - worker()->GenerateUpdateData(kHash1, GenerateSpecifics(kKey1, kValue1))); + updates.push_back(worker()->GenerateUpdateData( + GetHash(kKey1), GenerateSpecifics(kKey1, kValue1))); // Create update which will be ignored by bridge. - updates.push_back( - worker()->GenerateUpdateData(kHash3, GenerateSpecifics(kKey3, kValue3))); + updates.push_back(worker()->GenerateUpdateData( + GetHash(kKey3), GenerateSpecifics(kKey3, kValue3))); bridge()->AddValueToIgnore(kValue3); worker()->UpdateFromServer(std::move(updates)); EXPECT_EQ(1, bridge()->merge_call_count()); @@ -2082,7 +2091,7 @@ // Second update from server should be handled by ApplySyncChanges. Similarly // It should call UpdateStorageKey, not GetStorageKey. - worker()->UpdateFromServer(kHash2, GenerateSpecifics(kKey2, kValue2)); + worker()->UpdateFromServer(GetHash(kKey2), GenerateSpecifics(kKey2, kValue2)); EXPECT_EQ(1, bridge()->apply_call_count()); const std::string storage_key2 = bridge()->GetLastGeneratedStorageKey(); EXPECT_NE(storage_key1, storage_key2); @@ -2102,10 +2111,10 @@ UpdateResponseDataList update; update.push_back(worker()->GenerateUpdateData( - kHash1, GenerateSpecifics(kKey1, kValue1), 1, "ek1")); + GetHash(kKey1), GenerateSpecifics(kKey1, kValue1), 1, "ek1")); worker()->UpdateWithEncryptionKey("ek2", std::move(update)); OnCommitDataLoaded(); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); } // Tests that UntrackEntity won't propagate storage key to @@ -2121,7 +2130,7 @@ OnSyncStarting(); // Initial update from server should be handled by MergeSyncData. - worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue1)); + worker()->UpdateFromServer(GetHash(kKey1), GenerateSpecifics(kKey1, kValue1)); EXPECT_EQ(1, bridge()->merge_call_count()); EXPECT_EQ(0U, ProcessorEntityCount()); // Metadata should not be written under kUntrackKey1. This means that @@ -2138,7 +2147,7 @@ TEST_F(ClientTagBasedModelTypeProcessorTest, ShouldUntrackEntityForStorageKey) { InitializeToReadyState(); bridge()->WriteItem(kKey1, kValue1); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); worker()->AckOnePendingCommit(); // Check the processor tracks the entity. @@ -2248,7 +2257,7 @@ OnSyncStarting(); histogram_tester.ExpectBucketCount( "Sync.PersistedModelTypeIdMismatch", - /*bucket=*/ModelTypeToHistogramInt(GetModelType()), /*count=*/1); + /*bucket=*/ModelTypeHistogramValue(GetModelType()), /*count=*/1); // Model should still be ready to sync. ASSERT_TRUE(type_processor()->IsModelReadyToSyncForTest()); @@ -2282,7 +2291,7 @@ histogram_tester.ExpectBucketCount( "Sync.ModelTypeOrphanMetadata", - /*bucket=*/ModelTypeToHistogramInt(GetModelType()), /*count=*/1); + /*bucket=*/ModelTypeHistogramValue(GetModelType()), /*count=*/1); } // Orphan metadata should have been deleted. @@ -2303,7 +2312,7 @@ // The processor should not report orphan again in UMA. histogram_tester.ExpectBucketCount( "Sync.ModelTypeOrphanMetadata", - /*bucket=*/ModelTypeToHistogramInt(GetModelType()), /*count=*/0); + /*bucket=*/ModelTypeHistogramValue(GetModelType()), /*count=*/0); } TEST_F( @@ -2510,7 +2519,7 @@ EXPECT_TRUE(db()->model_type_state().initial_sync_done()); bridge()->WriteItem(kKey1, kValue1); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); EXPECT_EQ(1U, db()->data_count()); EXPECT_EQ(1U, db()->metadata_count()); @@ -2526,17 +2535,17 @@ InitializeToReadyState(); bridge()->WriteItem(kKey1, kValue1); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); EXPECT_EQ(1U, db()->data_count()); EXPECT_EQ(1U, db()->metadata_count()); bridge()->WriteItem(kKey1, kValue2); - worker()->VerifyPendingCommits({{kHash1}, {kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}, {GetHash(kKey1)}}); EXPECT_EQ(1U, db()->data_count()); EXPECT_EQ(1U, db()->metadata_count()); worker()->AckOnePendingCommit(); - worker()->VerifyPendingCommits({{kHash1}}); + worker()->VerifyPendingCommits({{GetHash(kKey1)}}); EXPECT_EQ(1U, db()->data_count()); EXPECT_EQ(1U, db()->metadata_count());
diff --git a/components/sync/model_impl/model_type_store_service_impl.cc b/components/sync/model_impl/model_type_store_service_impl.cc index c0039537..504c0262 100644 --- a/components/sync/model_impl/model_type_store_service_impl.cc +++ b/components/sync/model_impl/model_type_store_service_impl.cc
@@ -124,15 +124,4 @@ return backend_task_runner_; } -std::unique_ptr<BlockingModelTypeStore> -ModelTypeStoreServiceImpl::CreateBlockingStoreFromBackendSequence( - ModelType type) { - DCHECK(backend_task_runner_->RunsTasksInCurrentSequence()); - if (!store_backend_) { - return nullptr; - } - return std::make_unique<BlockingModelTypeStoreImpl>(type, - store_backend_.get()); -} - } // namespace syncer
diff --git a/components/sync/model_impl/model_type_store_service_impl.h b/components/sync/model_impl/model_type_store_service_impl.h index 9daf0c0..6ef2371 100644 --- a/components/sync/model_impl/model_type_store_service_impl.h +++ b/components/sync/model_impl/model_type_store_service_impl.h
@@ -32,13 +32,8 @@ const base::FilePath& GetSyncDataPath() const override; RepeatingModelTypeStoreFactory GetStoreFactory() override; scoped_refptr<base::SequencedTaskRunner> GetBackendTaskRunner() override; - std::unique_ptr<BlockingModelTypeStore> - CreateBlockingStoreFromBackendSequence(ModelType type) override; private: - void CreateModelTypeStore(ModelType type, - ModelTypeStore::InitCallback callback); - // The path to the base directory under which sync should store its // information. const base::FilePath sync_path_;
diff --git a/components/sync/model_impl/processor_entity.cc b/components/sync/model_impl/processor_entity.cc index a85ff9b..dd36b8e 100644 --- a/components/sync/model_impl/processor_entity.cc +++ b/components/sync/model_impl/processor_entity.cc
@@ -13,6 +13,7 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" #include "base/trace_event/memory_usage_estimator.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/sync_base_switches.h" #include "components/sync/base/time.h" #include "components/sync/engine/non_blocking_sync_common.h" @@ -38,12 +39,12 @@ std::unique_ptr<ProcessorEntity> ProcessorEntity::CreateNew( const std::string& storage_key, - const std::string& client_tag_hash, + const ClientTagHash& client_tag_hash, const std::string& id, base::Time creation_time) { // Initialize metadata sync_pb::EntityMetadata metadata; - metadata.set_client_tag_hash(client_tag_hash); + metadata.set_client_tag_hash(client_tag_hash.value()); if (!id.empty()) metadata.set_server_id(id); metadata.set_sequence_number(0); @@ -88,7 +89,8 @@ void ProcessorEntity::SetCommitData(std::unique_ptr<EntityData> data) { DCHECK(data); // Update data's fields from metadata. - data->client_tag_hash = metadata_.client_tag_hash(); + data->client_tag_hash = + ClientTagHash::FromHashed(metadata_.client_tag_hash()); if (!metadata_.server_id().empty()) data->id = metadata_.server_id(); data->creation_time = ProtoTimeToTime(metadata_.creation_time()); @@ -105,7 +107,7 @@ } bool ProcessorEntity::HasCommitData() const { - return commit_data_ && !commit_data_->client_tag_hash.empty(); + return commit_data_ && !commit_data_->client_tag_hash.value().empty(); } bool ProcessorEntity::MatchesData(const EntityData& data) const { @@ -255,14 +257,16 @@ void ProcessorEntity::InitializeCommitRequestData(CommitRequestData* request) { if (!metadata_.is_deleted()) { DCHECK(HasCommitData()); - DCHECK_EQ(commit_data_->client_tag_hash, metadata_.client_tag_hash()); + DCHECK_EQ(commit_data_->client_tag_hash.value(), + metadata_.client_tag_hash()); DCHECK_EQ(commit_data_->id, metadata_.server_id()); request->entity = std::move(commit_data_); } else { // Make an EntityData with empty specifics to indicate deletion. This is // done lazily here to simplify loading a pending deletion on startup. auto data = std::make_unique<syncer::EntityData>(); - data->client_tag_hash = metadata_.client_tag_hash(); + data->client_tag_hash = + ClientTagHash::FromHashed(metadata_.client_tag_hash()); data->id = metadata_.server_id(); data->creation_time = ProtoTimeToTime(metadata_.creation_time()); data->modification_time = ProtoTimeToTime(metadata_.modification_time()); @@ -279,7 +283,7 @@ void ProcessorEntity::ReceiveCommitResponse(const CommitResponseData& data, bool commit_only, ModelType type_for_uma) { - DCHECK_EQ(metadata_.client_tag_hash(), data.client_tag_hash); + DCHECK_EQ(metadata_.client_tag_hash(), data.client_tag_hash.value()); DCHECK_GT(data.sequence_number, metadata_.acked_sequence_number()); // Version is not valid for commit only types, as it's stripped before being // sent to the server, so it cannot behave correctly.
diff --git a/components/sync/model_impl/processor_entity.h b/components/sync/model_impl/processor_entity.h index 2951d8bd..f3d24fe 100644 --- a/components/sync/model_impl/processor_entity.h +++ b/components/sync/model_impl/processor_entity.h
@@ -18,6 +18,8 @@ #include "components/sync/protocol/entity_metadata.pb.h" namespace syncer { + +class ClientTagHash; struct CommitRequestData; struct CommitResponseData; struct UpdateResponseData; @@ -31,7 +33,7 @@ // Construct an instance representing a new locally-created item. static std::unique_ptr<ProcessorEntity> CreateNew( const std::string& storage_key, - const std::string& client_tag_hash, + const ClientTagHash& client_tag_hash, const std::string& id, base::Time creation_time); @@ -45,7 +47,6 @@ const std::string& storage_key() const { return storage_key_; } const sync_pb::EntityMetadata& metadata() const { return metadata_; } const EntityData& commit_data() { return *commit_data_; } - base::Time unsynced_time() const { return unsynced_time_; } // Returns true if this data is out of sync with the server. // A commit may or may not be in progress at this time.
diff --git a/components/sync/model_impl/processor_entity_unittest.cc b/components/sync/model_impl/processor_entity_unittest.cc index b56f33a6..810dae10 100644 --- a/components/sync/model_impl/processor_entity_unittest.cc +++ b/components/sync/model_impl/processor_entity_unittest.cc
@@ -8,6 +8,7 @@ #include <vector> #include "base/test/metrics/histogram_tester.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/model_type.h" #include "components/sync/base/time.h" #include "components/sync/engine/non_blocking_sync_common.h" @@ -20,7 +21,7 @@ namespace { const char kKey[] = "key"; -const char kHash[] = "hash"; +const ClientTagHash kHash = ClientTagHash::FromHashed("hash"); const char kId[] = "id"; const char kName[] = "name"; const char kValue1[] = "value1"; @@ -36,7 +37,7 @@ return specifics; } -std::unique_ptr<EntityData> GenerateEntityData(const std::string& hash, +std::unique_ptr<EntityData> GenerateEntityData(const ClientTagHash& hash, const std::string& name, const std::string& value) { std::unique_ptr<EntityData> entity_data(new EntityData()); @@ -48,7 +49,7 @@ std::unique_ptr<UpdateResponseData> GenerateUpdate( const ProcessorEntity& entity, - const std::string& hash, + const ClientTagHash& hash, const std::string& id, const std::string& name, const std::string& value, @@ -65,7 +66,7 @@ std::unique_ptr<UpdateResponseData> GenerateTombstone( const ProcessorEntity& entity, - const std::string& hash, + const ClientTagHash& hash, const std::string& id, const std::string& name, const base::Time& mtime, @@ -141,7 +142,7 @@ std::unique_ptr<ProcessorEntity> entity = CreateNew(); EXPECT_EQ(kKey, entity->storage_key()); - EXPECT_EQ(kHash, entity->metadata().client_tag_hash()); + EXPECT_EQ(kHash.value(), entity->metadata().client_tag_hash()); EXPECT_EQ("", entity->metadata().server_id()); EXPECT_FALSE(entity->metadata().is_deleted()); EXPECT_EQ(0, entity->metadata().sequence_number());
diff --git a/components/sync/model_impl/syncable_service_based_bridge.cc b/components/sync/model_impl/syncable_service_based_bridge.cc index eb7f418a..24c1e946 100644 --- a/components/sync/model_impl/syncable_service_based_bridge.cc +++ b/components/sync/model_impl/syncable_service_based_bridge.cc
@@ -11,8 +11,8 @@ #include "base/bind_helpers.h" #include "base/location.h" #include "base/trace_event/memory_usage_estimator.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/data_type_histogram.h" -#include "components/sync/base/hash_util.h" #include "components/sync/model/mutable_data_batch.h" #include "components/sync/model/sync_change.h" #include "components/sync/model/sync_error_factory.h" @@ -28,9 +28,9 @@ constexpr int64_t kInvalidNodeId = 0; std::unique_ptr<EntityData> ConvertPersistedToEntityData( - const std::string& client_tag_hash, + const ClientTagHash& client_tag_hash, sync_pb::PersistedEntityData data) { - DCHECK(!client_tag_hash.empty()); + DCHECK(!client_tag_hash.value().empty()); auto entity_data = std::make_unique<EntityData>(); entity_data->name = std::move(*data.mutable_name()); @@ -156,8 +156,10 @@ SyncDataLocal sync_data(change.sync_data()); DCHECK(sync_data.IsValid()) << " from " << change.location().ToString(); - const std::string storage_key = - GenerateSyncableHash(type_, sync_data.GetTag()); + + const ClientTagHash client_tag_hash = + ClientTagHash::FromUnhashed(type_, sync_data.GetTag()); + const std::string storage_key = client_tag_hash.value(); DCHECK(!storage_key.empty()); (*in_memory_store_)[storage_key] = sync_data.GetSpecifics(); @@ -165,11 +167,11 @@ CreatePersistedFromSyncData(sync_data); batch->WriteData(storage_key, persisted_entity.SerializeAsString()); - other_->Put( - storage_key, - ConvertPersistedToEntityData( - /*client_tag_hash=*/storage_key, std::move(persisted_entity)), - batch->GetMetadataChangeList()); + other_->Put(storage_key, + ConvertPersistedToEntityData( + /*client_tag_hash=*/client_tag_hash, + std::move(persisted_entity)), + batch->GetMetadataChangeList()); break; } @@ -180,10 +182,11 @@ SyncDataLocal sync_data(change.sync_data()); DCHECK(sync_data.IsValid()) << " from " << change.location().ToString(); - storage_key = GenerateSyncableHash(type_, sync_data.GetTag()); + storage_key = + ClientTagHash::FromUnhashed(type_, sync_data.GetTag()).value(); } else { SyncDataRemote sync_data(change.sync_data()); - storage_key = sync_data.GetClientTagHash(); + storage_key = sync_data.GetClientTagHash().value(); } DCHECK(!storage_key.empty()) @@ -601,12 +604,13 @@ // Because we use the client tag hash as storage key, let the processor // know. change_processor()->UpdateStorageKey( - change->data(), /*storage_key=*/change->data().client_tag_hash, + change->data(), + /*storage_key=*/change->data().client_tag_hash.value(), batch->GetMetadataChangeList()); FALLTHROUGH; case EntityChange::ACTION_UPDATE: { - const std::string& storage_key = change->data().client_tag_hash; + const std::string& storage_key = change->data().client_tag_hash.value(); DVLOG(1) << ModelTypeToString(type_) << ": Processing add/update with key: " << storage_key; @@ -614,7 +618,7 @@ FROM_HERE, ConvertToSyncChangeType(change->type()), SyncData::CreateRemoteData( /*id=*/kInvalidNodeId, change->data().specifics, - change->data().client_tag_hash)); + change->data().client_tag_hash.value())); batch->WriteData( storage_key, @@ -662,9 +666,9 @@ } // Note that client tag hash is used as storage key too. - batch->Put(record.id, - ConvertPersistedToEntityData( - /*client_tag_hash=*/record.id, std::move(persisted_entity))); + batch->Put(record.id, ConvertPersistedToEntityData( + ClientTagHash::FromHashed(record.id), + std::move(persisted_entity))); } std::move(callback).Run(std::move(batch)); }
diff --git a/components/sync/model_impl/syncable_service_based_bridge_unittest.cc b/components/sync/model_impl/syncable_service_based_bridge_unittest.cc index 8f8b087..353d86f 100644 --- a/components/sync/model_impl/syncable_service_based_bridge_unittest.cc +++ b/components/sync/model_impl/syncable_service_based_bridge_unittest.cc
@@ -12,7 +12,7 @@ #include "base/test/bind_test_util.h" #include "base/test/mock_callback.h" #include "base/test/task_environment.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/model/mock_model_type_change_processor.h" #include "components/sync/model/model_error.h" #include "components/sync/model/model_type_store_test_util.h" @@ -156,8 +156,8 @@ } const std::string kClientTag = "clienttag"; - const std::string kClientTagHash = - GenerateSyncableHash(kModelType, kClientTag); + const ClientTagHash kClientTagHash = + ClientTagHash::FromUnhashed(kModelType, kClientTag); base::test::SingleThreadTaskEnvironment task_environment_; testing::NiceMock<MockSyncableService> syncable_service_; @@ -207,7 +207,7 @@ kModelType, ElementsAre(SyncDataRemoteMatches("name1")), NotNull(), NotNull())); worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name1")); - EXPECT_THAT(GetAllData(), ElementsAre(Pair(kClientTagHash, _))); + EXPECT_THAT(GetAllData(), ElementsAre(Pair(kClientTagHash.value(), _))); } TEST_F(SyncableServiceBasedBridgeTest, ShouldWaitUntilModelReadyToSync) { @@ -309,7 +309,7 @@ // SyncableService being stopped. EXPECT_CALL(syncable_service_, StopSyncing(_)).Times(0); real_processor_->OnSyncStopping(KEEP_METADATA); - EXPECT_THAT(GetAllData(), ElementsAre(Pair(kClientTagHash, _))); + EXPECT_THAT(GetAllData(), ElementsAre(Pair(kClientTagHash.value(), _))); // Since the SyncableService wasn't stopped, it shouldn't get restarted either // when Sync starts up again. @@ -375,9 +375,10 @@ InitializeBridge(); StartSyncing(); - EXPECT_CALL(mock_processor_, Put(kClientTagHash, NotNull(), NotNull())); + EXPECT_CALL(mock_processor_, + Put(kClientTagHash.value(), NotNull(), NotNull())); worker_->UpdateFromServer(); - EXPECT_THAT(GetAllData(), ElementsAre(Pair(kClientTagHash, _))); + EXPECT_THAT(GetAllData(), ElementsAre(Pair(kClientTagHash.value(), _))); } TEST_F(SyncableServiceBasedBridgeTest, ShouldPropagateLocalCreation) { @@ -387,7 +388,8 @@ ASSERT_THAT(start_syncing_sync_processor_, NotNull()); ASSERT_THAT(GetAllData(), IsEmpty()); - EXPECT_CALL(mock_processor_, Put(kClientTagHash, NotNull(), NotNull())); + EXPECT_CALL(mock_processor_, + Put(kClientTagHash.value(), NotNull(), NotNull())); SyncChangeList change_list; change_list.emplace_back( @@ -396,7 +398,7 @@ const SyncError error = start_syncing_sync_processor_->ProcessSyncChanges(FROM_HERE, change_list); EXPECT_FALSE(error.IsSet()); - EXPECT_THAT(GetAllData(), ElementsAre(Pair(kClientTagHash, _))); + EXPECT_THAT(GetAllData(), ElementsAre(Pair(kClientTagHash.value(), _))); } TEST_F(SyncableServiceBasedBridgeTest, ShouldPropagateLocalUpdate) { @@ -405,10 +407,10 @@ worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name1")); ASSERT_THAT(start_syncing_sync_processor_, NotNull()); ASSERT_THAT(GetAllData(), - ElementsAre(Pair(kClientTagHash, HasName("name1")))); + ElementsAre(Pair(kClientTagHash.value(), HasName("name1")))); - EXPECT_CALL(mock_processor_, Put(GenerateSyncableHash(kModelType, kClientTag), - NotNull(), NotNull())); + EXPECT_CALL(mock_processor_, + Put(kClientTagHash.value(), NotNull(), NotNull())); SyncChangeList change_list; change_list.emplace_back(FROM_HERE, SyncChange::ACTION_UPDATE, @@ -418,7 +420,7 @@ start_syncing_sync_processor_->ProcessSyncChanges(FROM_HERE, change_list); EXPECT_FALSE(error.IsSet()); EXPECT_THAT(GetAllData(), - ElementsAre(Pair(kClientTagHash, HasName("name2")))); + ElementsAre(Pair(kClientTagHash.value(), HasName("name2")))); } TEST_F(SyncableServiceBasedBridgeTest, ShouldPropagateLocalDeletion) { @@ -427,10 +429,9 @@ worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name1")); ASSERT_THAT(start_syncing_sync_processor_, NotNull()); ASSERT_THAT(GetAllData(), - ElementsAre(Pair(kClientTagHash, HasName("name1")))); + ElementsAre(Pair(kClientTagHash.value(), HasName("name1")))); - EXPECT_CALL(mock_processor_, - Delete(GenerateSyncableHash(kModelType, kClientTag), NotNull())); + EXPECT_CALL(mock_processor_, Delete(kClientTagHash.value(), NotNull())); SyncChangeList change_list; change_list.emplace_back(FROM_HERE, SyncChange::ACTION_DELETE, @@ -480,7 +481,7 @@ SyncChange::ACTION_ADD, "name1")))); worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name1")); EXPECT_THAT(GetAllData(), - ElementsAre(Pair(kClientTagHash, HasName("name1")))); + ElementsAre(Pair(kClientTagHash.value(), HasName("name1")))); } TEST_F(SyncableServiceBasedBridgeTest, ShouldPropagateRemoteUpdates) { @@ -489,14 +490,14 @@ worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name1")); ASSERT_THAT(start_syncing_sync_processor_, NotNull()); ASSERT_THAT(GetAllData(), - ElementsAre(Pair(kClientTagHash, HasName("name1")))); + ElementsAre(Pair(kClientTagHash.value(), HasName("name1")))); EXPECT_CALL(syncable_service_, ProcessSyncChanges(_, ElementsAre(SyncChangeMatches( SyncChange::ACTION_UPDATE, "name2")))); worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name2")); EXPECT_THAT(GetAllData(), - ElementsAre(Pair(kClientTagHash, HasName("name2")))); + ElementsAre(Pair(kClientTagHash.value(), HasName("name2")))); // A second update for the same entity. EXPECT_CALL(syncable_service_, @@ -504,7 +505,7 @@ SyncChange::ACTION_UPDATE, "name3")))); worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name3")); EXPECT_THAT(GetAllData(), - ElementsAre(Pair(kClientTagHash, HasName("name3")))); + ElementsAre(Pair(kClientTagHash.value(), HasName("name3")))); } TEST_F(SyncableServiceBasedBridgeTest, ShouldPropagateRemoteDeletion) { @@ -513,7 +514,7 @@ worker_->UpdateFromServer(kClientTagHash, GetTestSpecifics("name1")); ASSERT_THAT(start_syncing_sync_processor_, NotNull()); ASSERT_THAT(GetAllData(), - ElementsAre(Pair(kClientTagHash, HasName("name1")))); + ElementsAre(Pair(kClientTagHash.value(), HasName("name1")))); EXPECT_CALL(syncable_service_, ProcessSyncChanges(_, ElementsAre(SyncChangeMatches(
diff --git a/components/sync/nigori/nigori_model_type_processor.cc b/components/sync/nigori/nigori_model_type_processor.cc index 846c3be..d817d119 100644 --- a/components/sync/nigori/nigori_model_type_processor.cc +++ b/components/sync/nigori/nigori_model_type_processor.cc
@@ -5,6 +5,7 @@ #include "components/sync/nigori/nigori_model_type_processor.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/data_type_histogram.h" #include "components/sync/base/time.h" #include "components/sync/engine/commit_queue.h" @@ -21,7 +22,7 @@ // TODO(mamir): remove those and adjust the code accordingly. Similarly in // tests. const char kNigoriStorageKey[] = "NigoriStorageKey"; -const char kNigoriClientTagHash[] = "NigoriClientTagHash"; +const char kRawNigoriClientTagHash[] = "NigoriClientTagHash"; } // namespace @@ -131,8 +132,8 @@ } else { DCHECK(!updates[0]->entity->is_deleted()); entity_ = ProcessorEntity::CreateNew( - kNigoriStorageKey, kNigoriClientTagHash, updates[0]->entity->id, - updates[0]->entity->creation_time); + kNigoriStorageKey, ClientTagHash::FromHashed(kRawNigoriClientTagHash), + updates[0]->entity->id, updates[0]->entity->creation_time); entity_->RecordAcceptedUpdate(*updates[0]); error = bridge_->MergeSyncData(std::move(*updates[0]->entity)); } @@ -300,7 +301,7 @@ model_type_state_ = std::move(nigori_metadata.model_type_state); sync_pb::EntityMetadata metadata = std::move(*nigori_metadata.entity_metadata); - metadata.set_client_tag_hash(kNigoriClientTagHash); + metadata.set_client_tag_hash(kRawNigoriClientTagHash); entity_ = ProcessorEntity::CreateFromMetadata(kNigoriStorageKey, std::move(metadata)); } else {
diff --git a/components/sync/nigori/nigori_model_type_processor_unittest.cc b/components/sync/nigori/nigori_model_type_processor_unittest.cc index 27ba362..46a0995 100644 --- a/components/sync/nigori/nigori_model_type_processor_unittest.cc +++ b/components/sync/nigori/nigori_model_type_processor_unittest.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/test/mock_callback.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/time.h" #include "components/sync/engine/commit_queue.h" #include "components/sync/nigori/nigori_sync_bridge.h" @@ -26,7 +27,7 @@ using testing::NotNull; // TODO(mamir): remove those and adjust the code accordingly. -const char kNigoriClientTagHash[] = "NigoriClientTagHash"; +const char kRawNigoriClientTagHash[] = "NigoriClientTagHash"; const char kNigoriNonUniqueName[] = "nigori"; const char kNigoriServerId[] = "nigori_server_id"; @@ -75,7 +76,8 @@ int response_version) { CommitResponseData commit_response_data; commit_response_data.id = kNigoriServerId; - commit_response_data.client_tag_hash = kNigoriClientTagHash; + commit_response_data.client_tag_hash = + ClientTagHash::FromHashed(kRawNigoriClientTagHash); commit_response_data.sequence_number = commit_request_data.sequence_number; commit_response_data.response_version = response_version; commit_response_data.specifics_hash = commit_request_data.specifics_hash;
diff --git a/components/sync/nigori/nigori_sync_bridge_impl.cc b/components/sync/nigori/nigori_sync_bridge_impl.cc index d55b2343..9e11940 100644 --- a/components/sync/nigori/nigori_sync_bridge_impl.cc +++ b/components/sync/nigori/nigori_sync_bridge_impl.cc
@@ -395,7 +395,7 @@ void UpdateNigoriSpecificsFromEncryptedTypes( ModelTypeSet encrypted_types, sync_pb::NigoriSpecifics* specifics) { - static_assert(46 == ModelType::NUM_ENTRIES, + static_assert(39 == ModelType::NUM_ENTRIES, "If adding an encryptable type, update handling below."); specifics->set_encrypt_bookmarks(encrypted_types.Has(BOOKMARKS)); specifics->set_encrypt_preferences(encrypted_types.Has(PREFERENCES)); @@ -413,13 +413,10 @@ specifics->set_encrypt_app_settings(encrypted_types.Has(APP_SETTINGS)); specifics->set_encrypt_extension_settings( encrypted_types.Has(EXTENSION_SETTINGS)); - specifics->set_encrypt_app_notifications( - encrypted_types.Has(DEPRECATED_APP_NOTIFICATIONS)); specifics->set_encrypt_dictionary(encrypted_types.Has(DICTIONARY)); specifics->set_encrypt_favicon_images(encrypted_types.Has(FAVICON_IMAGES)); specifics->set_encrypt_favicon_tracking( encrypted_types.Has(FAVICON_TRACKING)); - specifics->set_encrypt_articles(encrypted_types.Has(DEPRECATED_ARTICLES)); specifics->set_encrypt_app_list(encrypted_types.Has(APP_LIST)); specifics->set_encrypt_arc_package(encrypted_types.Has(ARC_PACKAGE)); specifics->set_encrypt_printers(encrypted_types.Has(PRINTERS));
diff --git a/components/sync/protocol/app_notification_specifics.proto b/components/sync/protocol/app_notification_specifics.proto deleted file mode 100644 index a3280d11..0000000 --- a/components/sync/protocol/app_notification_specifics.proto +++ /dev/null
@@ -1,45 +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. -// -// Sync protocol datatype extension for app notifications. - -// If you change or add any fields in this file, update proto_visitors.h and -// potentially proto_enum_conversions.{h, cc}. - -syntax = "proto2"; - -option java_multiple_files = true; -option java_package = "org.chromium.components.sync.protocol"; - -option optimize_for = LITE_RUNTIME; - -package sync_pb; - -// Properties of an app notification. - -// An App Notification, to be delivered from Chrome Apps to the -// Chrome browser through the Notification API. -message AppNotification { - // Globally unique id. This is more robust for uniquely identifying each - // notification and hence gives us flexibility in the future. In absence - // of this, unique id would be (app_id, creation_timestamp_ms). But that - // relies on creation_timestamp_ms being high resolution and is not - // globally unique - only unique for a given user. - optional string guid = 1; - // Metadata, not shown directly to the user. - // The unique App Id, as created by the webstore and used to - // delegate messages to the applications. This is defined as 32 characters - optional string app_id = 2; - // Timestamp when the message was created in milliseconds. - // This is seperate from ctime as this is only set by the application. - optional int64 creation_timestamp_ms = 3; - - // Payload - these fields are visible to the user content is defined by the - // app. The fields are described in: - // chrome/browser/extensions/app_notification.h - optional string title = 4; - optional string body_text = 5; - optional string link_url = 6; - optional string link_text = 7; -}
diff --git a/components/sync/protocol/managed_user_shared_setting_specifics.proto b/components/sync/protocol/managed_user_shared_setting_specifics.proto deleted file mode 100644 index 82512ce..0000000 --- a/components/sync/protocol/managed_user_shared_setting_specifics.proto +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Sync protocol datatype extension for managed user shared settings. - -// If you change or add any fields in this file, update proto_visitors.h and -// potentially proto_enum_conversions.{h, cc}. - -syntax = "proto2"; - -option java_multiple_files = true; -option java_package = "org.chromium.components.sync.protocol"; - -option optimize_for = LITE_RUNTIME; - -package sync_pb; - -// Properties of managed user shared setting sync objects. -message ManagedUserSharedSettingSpecifics { - // The MU ID for the managed user to whom the setting applies. - optional string mu_id = 1; - // The key of the setting. - optional string key = 2; - // The setting value. The setting is a JSON encoding of an arbitrary - // Javascript value. - optional string value = 3; - // This flag is set by the server to acknowledge that it has committed a - // change to a setting. - optional bool acknowledged = 4 [default = false]; -}
diff --git a/components/sync/protocol/managed_user_specifics.proto b/components/sync/protocol/managed_user_specifics.proto deleted file mode 100644 index e36e8c66..0000000 --- a/components/sync/protocol/managed_user_specifics.proto +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Sync protocol datatype extension for managed user settings. - -// If you change or add any fields in this file, update proto_visitors.h and -// potentially proto_enum_conversions.{h, cc}. - -syntax = "proto2"; - -option java_multiple_files = true; -option java_package = "org.chromium.components.sync.protocol"; - -option optimize_for = LITE_RUNTIME; - -package sync_pb; - -// Properties of managed user sync objects. -message ManagedUserSpecifics { - // A randomly-generated identifier for the managed user. - optional string id = 1; - // The human-visible name of the managed user - optional string name = 2; - // This flag is set by the server to acknowledge that it has committed a - // newly created managed user. - optional bool acknowledged = 3 [default = false]; - // Master key for managed user cryptohome. - optional string master_key = 4; - // A string representing the index of the supervised user avatar on Chrome. - // It has the following format: - // "chrome-avatar-index:INDEX" where INDEX is an integer. - optional string chrome_avatar = 5; - // A string representing the index of the supervised user avatar on Chrome OS. - // It has the following format: - // "chromeos-avatar-index:INDEX" where INDEX is an integer. - optional string chromeos_avatar = 6; - // Key for signing supervised user's password. - optional string password_signature_key = 7; - // Key for encrypting supervised user's password. - optional string password_encryption_key = 8; -}
diff --git a/components/sync/protocol/nigori_specifics.proto b/components/sync/protocol/nigori_specifics.proto index e1e9085..5e294426 100644 --- a/components/sync/protocol/nigori_specifics.proto +++ b/components/sync/protocol/nigori_specifics.proto
@@ -75,7 +75,10 @@ optional bool encrypt_everything = 24; optional bool encrypt_extension_settings = 25; - optional bool encrypt_app_notifications = 26 [deprecated = true]; + + reserved 26; + reserved "encrypt_app_notifications"; + optional bool encrypt_app_settings = 27; // User device information. Contains information about each device that has a @@ -132,8 +135,8 @@ optional bool encrypt_favicon_images = 35; optional bool encrypt_favicon_tracking = 36; - // Boolean corresponding to whether articles should be encrypted. - optional bool encrypt_articles = 37; + reserved 37; + reserved "encrypt_articles"; // Boolean corresponding to whether app list items should be encrypted. optional bool encrypt_app_list = 38;
diff --git a/components/sync/protocol/proto_enum_conversions.cc b/components/sync/protocol/proto_enum_conversions.cc index f82837ca..2235a55 100644 --- a/components/sync/protocol/proto_enum_conversions.cc +++ b/components/sync/protocol/proto_enum_conversions.cc
@@ -633,20 +633,6 @@ return ""; } -const char* ProtoEnumToString( - sync_pb::WifiCredentialSpecifics::SecurityClass security_class) { - ASSERT_ENUM_BOUNDS(sync_pb::WifiCredentialSpecifics, SecurityClass, - SECURITY_CLASS_INVALID, SECURITY_CLASS_PSK); - switch (security_class) { - ENUM_CASE(sync_pb::WifiCredentialSpecifics, SECURITY_CLASS_INVALID); - ENUM_CASE(sync_pb::WifiCredentialSpecifics, SECURITY_CLASS_NONE); - ENUM_CASE(sync_pb::WifiCredentialSpecifics, SECURITY_CLASS_WEP); - ENUM_CASE(sync_pb::WifiCredentialSpecifics, SECURITY_CLASS_PSK); - } - NOTREACHED(); - return ""; -} - #undef ASSERT_ENUM_BOUNDS #undef ENUM_CASE
diff --git a/components/sync/protocol/proto_enum_conversions.h b/components/sync/protocol/proto_enum_conversions.h index 7ada191..a67e899 100644 --- a/components/sync/protocol/proto_enum_conversions.h +++ b/components/sync/protocol/proto_enum_conversions.h
@@ -131,9 +131,6 @@ sync_pb::WifiConfigurationSpecificsData::ProxyConfiguration::ProxyOption proxy_option); -const char* ProtoEnumToString( - sync_pb::WifiCredentialSpecifics::SecurityClass security_class); - } // namespace syncer #endif // COMPONENTS_SYNC_PROTOCOL_PROTO_ENUM_CONVERSIONS_H_
diff --git a/components/sync/protocol/proto_enum_conversions_unittest.cc b/components/sync/protocol/proto_enum_conversions_unittest.cc index 127a084..f38ef68c 100644 --- a/components/sync/protocol/proto_enum_conversions_unittest.cc +++ b/components/sync/protocol/proto_enum_conversions_unittest.cc
@@ -74,11 +74,6 @@ ProxyConfiguration::ProxyOption_MAX); } -TEST_F(ProtoEnumConversionsTest, GetWifiCredentialSecurityClassString) { - TestEnumStringFunction(sync_pb::WifiCredentialSpecifics::SecurityClass_MIN, - sync_pb::WifiCredentialSpecifics::SecurityClass_MAX); -} - TEST_F(ProtoEnumConversionsTest, GetUpdatesSourceString) { TestEnumStringFunction(sync_pb::GetUpdatesCallerInfo::GetUpdatesSource_MIN, sync_pb::GetUpdatesCallerInfo::PERIODIC);
diff --git a/components/sync/protocol/proto_value_conversions.cc b/components/sync/protocol/proto_value_conversions.cc index e0d1bb5..0e70dd51 100644 --- a/components/sync/protocol/proto_value_conversions.cc +++ b/components/sync/protocol/proto_value_conversions.cc
@@ -300,12 +300,10 @@ } IMPLEMENT_PROTO_TO_VALUE(AppListSpecifics) -IMPLEMENT_PROTO_TO_VALUE(AppNotification) IMPLEMENT_PROTO_TO_VALUE(AppNotificationSettings) IMPLEMENT_PROTO_TO_VALUE(AppSettingSpecifics) IMPLEMENT_PROTO_TO_VALUE(AppSpecifics) IMPLEMENT_PROTO_TO_VALUE(ArcPackageSpecifics) -IMPLEMENT_PROTO_TO_VALUE(ArticleSpecifics) IMPLEMENT_PROTO_TO_VALUE(AutofillProfileSpecifics) IMPLEMENT_PROTO_TO_VALUE(AutofillSpecifics) IMPLEMENT_PROTO_TO_VALUE(AutofillWalletSpecifics) @@ -328,8 +326,6 @@ IMPLEMENT_PROTO_TO_VALUE(HistoryDeleteDirectiveSpecifics) IMPLEMENT_PROTO_TO_VALUE(LinkedAppIconInfo) IMPLEMENT_PROTO_TO_VALUE(ManagedUserSettingSpecifics) -IMPLEMENT_PROTO_TO_VALUE(ManagedUserSharedSettingSpecifics) -IMPLEMENT_PROTO_TO_VALUE(ManagedUserSpecifics) IMPLEMENT_PROTO_TO_VALUE(ManagedUserWhitelistSpecifics) IMPLEMENT_PROTO_TO_VALUE(MountainShareSpecifics) IMPLEMENT_PROTO_TO_VALUE(NavigationRedirect) @@ -350,8 +346,6 @@ IMPLEMENT_PROTO_TO_VALUE(SessionTab) IMPLEMENT_PROTO_TO_VALUE(SessionWindow) IMPLEMENT_PROTO_TO_VALUE(SyncCycleCompletedEventInfo) -IMPLEMENT_PROTO_TO_VALUE(SyncedNotificationAppInfoSpecifics) -IMPLEMENT_PROTO_TO_VALUE(SyncedNotificationSpecifics) IMPLEMENT_PROTO_TO_VALUE(TabNavigation) IMPLEMENT_PROTO_TO_VALUE(ThemeSpecifics) IMPLEMENT_PROTO_TO_VALUE(TimeRangeDirective) @@ -364,7 +358,6 @@ IMPLEMENT_PROTO_TO_VALUE(WalletPostalAddress) IMPLEMENT_PROTO_TO_VALUE(WebAppSpecifics) IMPLEMENT_PROTO_TO_VALUE(WifiConfigurationSpecifics) -IMPLEMENT_PROTO_TO_VALUE(WifiCredentialSpecifics) IMPLEMENT_PROTO_TO_VALUE_INCLUDE_SPECIFICS(ClientToServerMessage) IMPLEMENT_PROTO_TO_VALUE_INCLUDE_SPECIFICS(ClientToServerResponse)
diff --git a/components/sync/protocol/proto_value_conversions.h b/components/sync/protocol/proto_value_conversions.h index c8ef6867..1b0b276 100644 --- a/components/sync/protocol/proto_value_conversions.h +++ b/components/sync/protocol/proto_value_conversions.h
@@ -13,12 +13,10 @@ namespace sync_pb { class AppListSpecifics; -class AppNotification; class AppNotificationSettings; class AppSettingSpecifics; class AppSpecifics; class ArcPackageSpecifics; -class ArticleSpecifics; class AutofillProfileSpecifics; class AutofillSpecifics; class AutofillWalletSpecifics; @@ -39,12 +37,9 @@ class ExtensionSpecifics; class FaviconImageSpecifics; class FaviconTrackingSpecifics; -class GlobalIdDirective; class HistoryDeleteDirectiveSpecifics; class LinkedAppIconInfo; class ManagedUserSettingSpecifics; -class ManagedUserSharedSettingSpecifics; -class ManagedUserSpecifics; class ManagedUserWhitelistSpecifics; class MountainShareSpecifics; class NavigationRedirect; @@ -66,8 +61,6 @@ class SessionWindow; class SyncCycleCompletedEventInfo; class SyncEntity; -class SyncedNotificationAppInfoSpecifics; -class SyncedNotificationSpecifics; class TabNavigation; class ThemeSpecifics; class TimeRangeDirective; @@ -80,7 +73,6 @@ class WalletPostalAddress; class WebAppSpecifics; class WifiConfigurationSpecifics; -class WifiCredentialSpecifics; } // namespace sync_pb // Keep this file in sync with the .proto files in this directory. @@ -95,9 +87,6 @@ std::unique_ptr<base::DictionaryValue> AppListSpecificsToValue( const sync_pb::AppListSpecifics& proto); -std::unique_ptr<base::DictionaryValue> AppNotificationToValue( - const sync_pb::AppNotification& app_notification_specifics); - std::unique_ptr<base::DictionaryValue> AppNotificationSettingsToValue( const sync_pb::AppNotificationSettings& app_notification_settings); @@ -110,9 +99,6 @@ std::unique_ptr<base::DictionaryValue> ArcPackageSpecificsToValue( const sync_pb::ArcPackageSpecifics& proto); -std::unique_ptr<base::DictionaryValue> ArticleSpecificsToValue( - const sync_pb::ArticleSpecifics& article_specifics); - std::unique_ptr<base::DictionaryValue> AutofillProfileSpecificsToValue( const sync_pb::AutofillProfileSpecifics& autofill_profile_specifics); @@ -167,9 +153,6 @@ std::unique_ptr<base::DictionaryValue> FaviconTrackingSpecificsToValue( const sync_pb::FaviconTrackingSpecifics& favicon_tracking_specifics); -std::unique_ptr<base::DictionaryValue> GlobalIdDirectiveToValue( - const sync_pb::GlobalIdDirective& global_id_directive); - std::unique_ptr<base::DictionaryValue> HistoryDeleteDirectiveSpecificsToValue( const sync_pb::HistoryDeleteDirectiveSpecifics& history_delete_directive_specifics); @@ -180,13 +163,6 @@ std::unique_ptr<base::DictionaryValue> ManagedUserSettingSpecificsToValue( const sync_pb::ManagedUserSettingSpecifics& managed_user_setting_specifics); -std::unique_ptr<base::DictionaryValue> ManagedUserSharedSettingSpecificsToValue( - const sync_pb::ManagedUserSharedSettingSpecifics& - managed_user_shared_setting_specifics); - -std::unique_ptr<base::DictionaryValue> ManagedUserSpecificsToValue( - const sync_pb::ManagedUserSpecifics& managed_user_specifics); - std::unique_ptr<base::DictionaryValue> ManagedUserWhitelistSpecificsToValue( const sync_pb::ManagedUserWhitelistSpecifics& managed_user_whitelist_specifics); @@ -248,14 +224,6 @@ std::unique_ptr<base::DictionaryValue> SyncCycleCompletedEventInfoToValue( const sync_pb::SyncCycleCompletedEventInfo& proto); -std::unique_ptr<base::DictionaryValue> -SyncedNotificationAppInfoSpecificsToValue( - const sync_pb::SyncedNotificationAppInfoSpecifics& - synced_notification_specifics); - -std::unique_ptr<base::DictionaryValue> SyncedNotificationSpecificsToValue( - const sync_pb::SyncedNotificationSpecifics& synced_notification_specifics); - std::unique_ptr<base::DictionaryValue> TabNavigationToValue( const sync_pb::TabNavigation& tab_navigation); @@ -292,9 +260,6 @@ std::unique_ptr<base::DictionaryValue> WifiConfigurationSpecificsToValue( const sync_pb::WifiConfigurationSpecifics& wifi_configuration_specifics); -std::unique_ptr<base::DictionaryValue> WifiCredentialSpecificsToValue( - const sync_pb::WifiCredentialSpecifics& wifi_credential_specifics); - // ToValue functions that allow omitting specifics. std::unique_ptr<base::DictionaryValue> ClientToServerMessageToValue(
diff --git a/components/sync/protocol/proto_value_conversions_unittest.cc b/components/sync/protocol/proto_value_conversions_unittest.cc index 72b3320..5ba9ca804 100644 --- a/components/sync/protocol/proto_value_conversions_unittest.cc +++ b/components/sync/protocol/proto_value_conversions_unittest.cc
@@ -11,7 +11,6 @@ #include "base/values.h" #include "components/sync/base/model_type.h" #include "components/sync/base/unique_position.h" -#include "components/sync/protocol/app_notification_specifics.pb.h" #include "components/sync/protocol/app_setting_specifics.pb.h" #include "components/sync/protocol/app_specifics.pb.h" #include "components/sync/protocol/autofill_specifics.pb.h" @@ -24,8 +23,6 @@ #include "components/sync/protocol/favicon_image_specifics.pb.h" #include "components/sync/protocol/favicon_tracking_specifics.pb.h" #include "components/sync/protocol/managed_user_setting_specifics.pb.h" -#include "components/sync/protocol/managed_user_shared_setting_specifics.pb.h" -#include "components/sync/protocol/managed_user_specifics.pb.h" #include "components/sync/protocol/managed_user_whitelist_specifics.pb.h" #include "components/sync/protocol/nigori_specifics.pb.h" #include "components/sync/protocol/password_specifics.pb.h" @@ -36,7 +33,6 @@ #include "components/sync/protocol/sync.pb.h" #include "components/sync/protocol/theme_specifics.pb.h" #include "components/sync/protocol/typed_url_specifics.pb.h" -#include "components/sync/protocol/wifi_credential_specifics.pb.h" #include "testing/gtest/include/gtest/gtest.h" namespace syncer { @@ -60,17 +56,15 @@ DEFINE_SPECIFICS_TO_VALUE_TEST(encrypted) -static_assert(46 == syncer::ModelType::NUM_ENTRIES, +static_assert(39 == syncer::ModelType::NUM_ENTRIES, "When adding a new field, add a DEFINE_SPECIFICS_TO_VALUE_TEST " "for your field below, and optionally a test for the specific " "conversions."); DEFINE_SPECIFICS_TO_VALUE_TEST(app) DEFINE_SPECIFICS_TO_VALUE_TEST(app_list) -DEFINE_SPECIFICS_TO_VALUE_TEST(app_notification) DEFINE_SPECIFICS_TO_VALUE_TEST(app_setting) DEFINE_SPECIFICS_TO_VALUE_TEST(arc_package) -DEFINE_SPECIFICS_TO_VALUE_TEST(article) DEFINE_SPECIFICS_TO_VALUE_TEST(autofill) DEFINE_SPECIFICS_TO_VALUE_TEST(autofill_profile) DEFINE_SPECIFICS_TO_VALUE_TEST(autofill_wallet) @@ -83,9 +77,7 @@ DEFINE_SPECIFICS_TO_VALUE_TEST(favicon_image) DEFINE_SPECIFICS_TO_VALUE_TEST(favicon_tracking) DEFINE_SPECIFICS_TO_VALUE_TEST(history_delete_directive) -DEFINE_SPECIFICS_TO_VALUE_TEST(managed_user) DEFINE_SPECIFICS_TO_VALUE_TEST(managed_user_setting) -DEFINE_SPECIFICS_TO_VALUE_TEST(managed_user_shared_setting) DEFINE_SPECIFICS_TO_VALUE_TEST(managed_user_whitelist) DEFINE_SPECIFICS_TO_VALUE_TEST(mountain_share) DEFINE_SPECIFICS_TO_VALUE_TEST(nigori) @@ -98,8 +90,6 @@ DEFINE_SPECIFICS_TO_VALUE_TEST(security_event) DEFINE_SPECIFICS_TO_VALUE_TEST(send_tab_to_self) DEFINE_SPECIFICS_TO_VALUE_TEST(session) -DEFINE_SPECIFICS_TO_VALUE_TEST(synced_notification) -DEFINE_SPECIFICS_TO_VALUE_TEST(synced_notification_app_info) DEFINE_SPECIFICS_TO_VALUE_TEST(theme) DEFINE_SPECIFICS_TO_VALUE_TEST(typed_url) DEFINE_SPECIFICS_TO_VALUE_TEST(user_consent) @@ -107,7 +97,6 @@ DEFINE_SPECIFICS_TO_VALUE_TEST(wallet_metadata) DEFINE_SPECIFICS_TO_VALUE_TEST(web_app) DEFINE_SPECIFICS_TO_VALUE_TEST(wifi_configuration) -DEFINE_SPECIFICS_TO_VALUE_TEST(wifi_credential) TEST(ProtoValueConversionsTest, PasswordSpecifics) { sync_pb::PasswordSpecifics specifics;
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h index b83e9de9..6ee25b2 100644 --- a/components/sync/protocol/proto_visitors.h +++ b/components/sync/protocol/proto_visitors.h
@@ -7,7 +7,6 @@ #include "components/sync/base/model_type.h" #include "components/sync/protocol/app_list_specifics.pb.h" -#include "components/sync/protocol/app_notification_specifics.pb.h" #include "components/sync/protocol/app_setting_specifics.pb.h" #include "components/sync/protocol/app_specifics.pb.h" #include "components/sync/protocol/arc_package_specifics.pb.h" @@ -101,16 +100,6 @@ VISIT(item_pin_ordinal); } -VISIT_PROTO_FIELDS(const sync_pb::AppNotification& proto) { - VISIT(guid); - VISIT(app_id); - VISIT(creation_timestamp_ms); - VISIT(title); - VISIT(body_text); - VISIT(link_url); - VISIT(link_text); -} - VISIT_PROTO_FIELDS(const sync_pb::AppNotificationSettings& proto) { VISIT(initial_setup_done); VISIT(disabled); @@ -142,16 +131,6 @@ VISIT(last_backup_time); } -VISIT_PROTO_FIELDS(const sync_pb::ArticlePage& proto) { - VISIT(url); -} - -VISIT_PROTO_FIELDS(const sync_pb::ArticleSpecifics& proto) { - VISIT(entry_id); - VISIT(title); - VISIT_REP(pages); -} - VISIT_PROTO_FIELDS(const sync_pb::AutofillCullingFlags& proto) { VISIT(enabled); } @@ -383,16 +362,14 @@ } VISIT_PROTO_FIELDS(const sync_pb::EntitySpecifics& proto) { - static_assert(46 == ModelType::NUM_ENTRIES, + static_assert(39 == ModelType::NUM_ENTRIES, "When adding a new protocol type, you will likely need to add " "it here as well."); VISIT(encrypted); VISIT(app); VISIT(app_list); - VISIT(app_notification); VISIT(app_setting); VISIT(arc_package); - VISIT(article); VISIT(autofill); VISIT(autofill_profile); VISIT(autofill_wallet); @@ -405,9 +382,7 @@ VISIT(favicon_image); VISIT(favicon_tracking); VISIT(history_delete_directive); - VISIT(managed_user); VISIT(managed_user_setting); - VISIT(managed_user_shared_setting); VISIT(managed_user_whitelist); VISIT(mountain_share); VISIT(nigori); @@ -420,8 +395,6 @@ VISIT(security_event); VISIT(send_tab_to_self); VISIT(session); - VISIT(synced_notification); - VISIT(synced_notification_app_info); VISIT(theme); VISIT(typed_url); VISIT(user_consent); @@ -429,7 +402,6 @@ VISIT(wallet_metadata); VISIT(web_app); VISIT(wifi_configuration); - VISIT(wifi_credential); } VISIT_PROTO_FIELDS(const sync_pb::ExperimentsSpecifics& proto) { @@ -576,24 +548,6 @@ VISIT(value); } -VISIT_PROTO_FIELDS(const sync_pb::ManagedUserSharedSettingSpecifics& proto) { - VISIT(mu_id); - VISIT(key); - VISIT(value); - VISIT(acknowledged); -} - -VISIT_PROTO_FIELDS(const sync_pb::ManagedUserSpecifics& proto) { - VISIT(id); - VISIT(name); - VISIT(acknowledged); - VISIT(master_key); - VISIT(chrome_avatar); - VISIT(chromeos_avatar); - VISIT(password_signature_key); - VISIT(password_encryption_key); -} - VISIT_PROTO_FIELDS(const sync_pb::ManagedUserWhitelistSpecifics& proto) { VISIT(id); VISIT(name); @@ -675,7 +629,6 @@ VISIT(encrypt_apps); VISIT(encrypt_search_engines); VISIT(encrypt_dictionary); - VISIT(encrypt_articles); VISIT(encrypt_app_list); VISIT(encrypt_arc_package); VISIT(encrypt_reading_list); @@ -864,10 +817,6 @@ VISIT_BYTES(ordinal_in_parent); } -VISIT_PROTO_FIELDS(const sync_pb::SyncedNotificationAppInfoSpecifics& proto) {} - -VISIT_PROTO_FIELDS(const sync_pb::SyncedNotificationSpecifics& proto) {} - VISIT_PROTO_FIELDS(const sync_pb::SecurityEventSpecifics& proto) { VISIT(gaia_password_reuse_event); VISIT(event_time_usec); @@ -1137,12 +1086,6 @@ VISIT(theme_color); } -VISIT_PROTO_FIELDS(const sync_pb::WifiCredentialSpecifics& proto) { - VISIT_BYTES(ssid); - VISIT_ENUM(security_class); - VISIT_BYTES(passphrase); -} - VISIT_PROTO_FIELDS(const sync_pb::WifiConfigurationSpecifics& proto) { VISIT(encrypted); VISIT(client_only_encrypted_data);
diff --git a/components/sync/protocol/protocol_sources.gni b/components/sync/protocol/protocol_sources.gni index 3f194ee..9735d55 100644 --- a/components/sync/protocol/protocol_sources.gni +++ b/components/sync/protocol/protocol_sources.gni
@@ -3,7 +3,6 @@ # found in the LICENSE file. sync_protocol_bases = [ - "app_notification_specifics", "app_setting_specifics", "app_specifics", "app_list_specifics", @@ -30,8 +29,6 @@ "history_status", "loopback_server", "managed_user_setting_specifics", - "managed_user_shared_setting_specifics", - "managed_user_specifics", "managed_user_whitelist_specifics", "model_type_state", "model_type_store_schema_descriptor", @@ -50,8 +47,6 @@ "session_specifics", "sync", "sync_enums", - "synced_notification_app_info_specifics", - "synced_notification_specifics", "test", "theme_specifics", "typed_url_specifics", @@ -61,7 +56,6 @@ "user_event_specifics", "web_app_specifics", "wifi_configuration_specifics", - "wifi_credential_specifics", ] sync_protocol_sources = []
diff --git a/components/sync/protocol/sync.proto b/components/sync/protocol/sync.proto index e213548..cbdd502 100644 --- a/components/sync/protocol/sync.proto +++ b/components/sync/protocol/sync.proto
@@ -18,7 +18,6 @@ package sync_pb; import "app_list_specifics.proto"; -import "app_notification_specifics.proto"; import "app_setting_specifics.proto"; import "app_specifics.proto"; import "arc_package_specifics.proto"; @@ -38,8 +37,6 @@ import "get_updates_caller_info.proto"; import "history_delete_directive_specifics.proto"; import "managed_user_setting_specifics.proto"; -import "managed_user_shared_setting_specifics.proto"; -import "managed_user_specifics.proto"; import "managed_user_whitelist_specifics.proto"; import "mountain_share_specifics.proto"; import "nigori_specifics.proto"; @@ -53,8 +50,6 @@ import "send_tab_to_self_specifics.proto"; import "session_specifics.proto"; import "sync_enums.proto"; -import "synced_notification_app_info_specifics.proto"; -import "synced_notification_specifics.proto"; import "theme_specifics.proto"; import "typed_url_specifics.proto"; import "unique_position.proto"; @@ -62,7 +57,6 @@ import "user_event_specifics.proto"; import "web_app_specifics.proto"; import "wifi_configuration_specifics.proto"; -import "wifi_credential_specifics.proto"; // Used for inspecting how long we spent performing operations in different // backends. All times must be in millis. @@ -118,7 +112,6 @@ PreferenceSpecifics preference = 37702; TypedUrlSpecifics typed_url = 40781; ThemeSpecifics theme = 41210; - AppNotification app_notification = 45184; PasswordSpecifics password = 45873; NigoriSpecifics nigori = 47745; ExtensionSpecifics extension = 48119; @@ -129,8 +122,6 @@ ExtensionSettingSpecifics extension_setting = 96159; AppSettingSpecifics app_setting = 103656; HistoryDeleteDirectiveSpecifics history_delete_directive = 150251; - SyncedNotificationSpecifics synced_notification = 153108; - SyncedNotificationAppInfoSpecifics synced_notification_app_info = 235816; DeviceInfoSpecifics device_info = 154522; ExperimentsSpecifics experiments = 161496; PriorityPreferenceSpecifics priority_preference = 163425; @@ -138,12 +129,11 @@ FaviconTrackingSpecifics favicon_tracking = 181534; FaviconImageSpecifics favicon_image = 182019; ManagedUserSettingSpecifics managed_user_setting = 186662; - ManagedUserSpecifics managed_user = 194582; - ManagedUserSharedSettingSpecifics managed_user_shared_setting = 202026; ManagedUserWhitelistSpecifics managed_user_whitelist = 306060; - ArticleSpecifics article = 223759; + // TODO(crbug.com/1007942): |article| isn't used by Sync anymore, but it + // can't be removed because dom_distiller code uses it for local storage. + ArticleSpecifics article = 223759 [deprecated = true]; AppListSpecifics app_list = 229170; - WifiCredentialSpecifics wifi_credential = 218175; AutofillWalletSpecifics autofill_wallet = 306270; WalletMetadataSpecifics wallet_metadata = 330441; ArcPackageSpecifics arc_package = 340906; @@ -157,6 +147,18 @@ WebAppSpecifics web_app = 673225; WifiConfigurationSpecifics wifi_configuration = 662827; } + reserved 45184; + reserved "app_notification"; + reserved 153108; + reserved "synced_notification"; + reserved 194582; + reserved "managed_user"; + reserved 202026; + reserved "managed_user_shared_setting"; + reserved 218175; + reserved "wifi_credential"; + reserved 235816; + reserved "synced_notification_app_info"; } message SyncEntity {
diff --git a/components/sync/protocol/synced_notification_app_info_specifics.proto b/components/sync/protocol/synced_notification_app_info_specifics.proto deleted file mode 100644 index f8dea52b..0000000 --- a/components/sync/protocol/synced_notification_app_info_specifics.proto +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2014 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. -// -// Sync protocol datatype extension for synced notification app info objects. -// DO NOT USE: This datatype is deprecated. - -syntax = "proto2"; - -option java_multiple_files = true; -option java_package = "org.chromium.components.sync.protocol"; - -option optimize_for = LITE_RUNTIME; - -package sync_pb; - -// This message is kept around for backwards compatibility sake. -message SyncedNotificationAppInfoSpecifics {}
diff --git a/components/sync/protocol/synced_notification_specifics.proto b/components/sync/protocol/synced_notification_specifics.proto deleted file mode 100644 index c649f342..0000000 --- a/components/sync/protocol/synced_notification_specifics.proto +++ /dev/null
@@ -1,18 +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. -// -// Sync protocol datatype extension for synced notifications. -// DO NOT USE: This datatype is deprecated. - -syntax = "proto2"; - -option java_multiple_files = true; -option java_package = "org.chromium.components.sync.protocol"; - -option optimize_for = LITE_RUNTIME; - -package sync_pb; - -// This message is kept around for backwards compatibility sake. -message SyncedNotificationSpecifics {}
diff --git a/components/sync/protocol/wifi_credential_specifics.proto b/components/sync/protocol/wifi_credential_specifics.proto deleted file mode 100644 index 25016f3..0000000 --- a/components/sync/protocol/wifi_credential_specifics.proto +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2014 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. -// -// Sync protocol datatype extension for WiFi credentials. - -// If you change or add any fields in this file, update proto_visitors.h and -// potentially proto_enum_conversions.{h, cc}. - -syntax = "proto2"; - -option java_multiple_files = true; -option java_package = "org.chromium.components.sync.protocol"; - -option optimize_for = LITE_RUNTIME; - -package sync_pb; - -// Properties of WiFi credential objects. -message WifiCredentialSpecifics { - optional bytes ssid = 1; // Not necessarily UTF-8. May contain NUL. - - enum SecurityClass { - SECURITY_CLASS_INVALID = 0; - SECURITY_CLASS_NONE = 1; - SECURITY_CLASS_WEP = 2; - SECURITY_CLASS_PSK = 3; // WPA-PSK or RSN-PSK - // 802.1X is omittted, as we do not support syncing 802.1X - // credentials. - } - optional SecurityClass security_class = 2; - - // Network passphrase. - // - // For SECURITY_CLASS_NONE, the passphrase should be ignored. - // - // For SECURITY_CLASS_WEP, the passphrase should have one of the - // following formats: - // - WEP-40: - // - 5 character ASCII string. Each character maps one byte of the key. - // - 10 character hex string. The string maps to the WEP key by simple - // hex decoding. - // - WEP-104: - // - 13 character ASCII string. Each character maps one byte of the key. - // - 26 character hex string. The string maps to the WEP key by simple - // hex decoding. - // - // For SECURITY_CLASS_PSK, the passphrase should have one of the - // following two formats: - // - An 8-63 character ASCII string. The string maps to the - // WPA/WPA-2 PSK as per IEEE 802.11i. - // - A 64 character hex string. The string maps to the PSK per - // simple hex decoding. - // - // Note that, although the passphrase "should" contain only ASCII - // characters, we represent |passphrase| as |bytes| rather than - // |string|. This is to accomodate networks that use non-ASCII - // passphrases. - optional bytes passphrase = 3; -}
diff --git a/components/sync/syncable/base_node.cc b/components/sync/syncable/base_node.cc index ef8a5042..5be7a39 100644 --- a/components/sync/syncable/base_node.cc +++ b/components/sync/syncable/base_node.cc
@@ -163,10 +163,6 @@ return GetEntry()->GetMetahandle(); } -base::Time BaseNode::GetModificationTime() const { - return GetEntry()->GetMtime(); -} - bool BaseNode::GetIsFolder() const { return GetEntry()->GetIsDir(); } @@ -266,11 +262,6 @@ return *wifi_configuration_data_; } -const sync_pb::TypedUrlSpecifics& BaseNode::GetTypedUrlSpecifics() const { - DCHECK_EQ(GetModelType(), TYPED_URLS); - return GetEntitySpecifics().typed_url(); -} - const sync_pb::EntitySpecifics& BaseNode::GetEntitySpecifics() const { return GetUnencryptedSpecifics(GetEntry()); }
diff --git a/components/sync/syncable/base_node.h b/components/sync/syncable/base_node.h index 82d8b71..2925b44 100644 --- a/components/sync/syncable/base_node.h +++ b/components/sync/syncable/base_node.h
@@ -30,7 +30,6 @@ class EntitySpecifics; class NigoriSpecifics; class PasswordSpecificsData; -class TypedUrlSpecifics; class WifiConfigurationSpecificsData; } // namespace sync_pb @@ -84,9 +83,6 @@ // different ID value. virtual int64_t GetId() const; - // Returns the modification time of the object. - base::Time GetModificationTime() const; - // Nodes are hierarchically arranged into a single-rooted tree. // InitByRootLookup on ReadNode allows access to the root. GetParentId is // how you find a node's parent. @@ -126,10 +122,6 @@ const sync_pb::WifiConfigurationSpecificsData& GetWifiConfigurationSpecifics() const; - // Getter specific to the TYPED_URLS datatype. Returns protobuf - // data. Can only be called if GetModelType() == TYPED_URLS. - const sync_pb::TypedUrlSpecifics& GetTypedUrlSpecifics() const; - const sync_pb::EntitySpecifics& GetEntitySpecifics() const; // Returns the local external ID associated with the node.
diff --git a/components/sync/syncable/nigori_util.cc b/components/sync/syncable/nigori_util.cc index 4d2fb24..a4d62e7 100644 --- a/components/sync/syncable/nigori_util.cc +++ b/components/sync/syncable/nigori_util.cc
@@ -229,8 +229,7 @@ DVLOG(2) << "Specifics of type " << ModelTypeToString(type) << " already match, dropping change."; UMA_HISTOGRAM_ENUMERATION("Sync.ModelTypeRedundantPut", - ModelTypeToHistogramInt(type), - static_cast<int>(ModelType::NUM_ENTRIES)); + ModelTypeHistogramValue(type)); return true; } @@ -266,7 +265,7 @@ bool encrypt_everything, sync_pb::NigoriSpecifics* nigori) { nigori->set_encrypt_everything(encrypt_everything); - static_assert(46 == ModelType::NUM_ENTRIES, + static_assert(39 == ModelType::NUM_ENTRIES, "If adding an encryptable type, update handling below."); nigori->set_encrypt_bookmarks(encrypted_types.Has(BOOKMARKS)); nigori->set_encrypt_preferences(encrypted_types.Has(PREFERENCES)); @@ -283,12 +282,9 @@ nigori->set_encrypt_app_settings(encrypted_types.Has(APP_SETTINGS)); nigori->set_encrypt_extension_settings( encrypted_types.Has(EXTENSION_SETTINGS)); - nigori->set_encrypt_app_notifications( - encrypted_types.Has(DEPRECATED_APP_NOTIFICATIONS)); nigori->set_encrypt_dictionary(encrypted_types.Has(DICTIONARY)); nigori->set_encrypt_favicon_images(encrypted_types.Has(FAVICON_IMAGES)); nigori->set_encrypt_favicon_tracking(encrypted_types.Has(FAVICON_TRACKING)); - nigori->set_encrypt_articles(encrypted_types.Has(DEPRECATED_ARTICLES)); nigori->set_encrypt_app_list(encrypted_types.Has(APP_LIST)); nigori->set_encrypt_arc_package(encrypted_types.Has(ARC_PACKAGE)); nigori->set_encrypt_printers(encrypted_types.Has(PRINTERS)); @@ -304,7 +300,7 @@ return ModelTypeSet::All(); ModelTypeSet encrypted_types; - static_assert(46 == ModelType::NUM_ENTRIES, + static_assert(39 == ModelType::NUM_ENTRIES, "If adding an encryptable type, update handling below."); if (nigori.encrypt_bookmarks()) encrypted_types.Put(BOOKMARKS); @@ -332,16 +328,12 @@ encrypted_types.Put(APP_SETTINGS); if (nigori.encrypt_extension_settings()) encrypted_types.Put(EXTENSION_SETTINGS); - if (nigori.encrypt_app_notifications()) - encrypted_types.Put(DEPRECATED_APP_NOTIFICATIONS); if (nigori.encrypt_dictionary()) encrypted_types.Put(DICTIONARY); if (nigori.encrypt_favicon_images()) encrypted_types.Put(FAVICON_IMAGES); if (nigori.encrypt_favicon_tracking()) encrypted_types.Put(FAVICON_TRACKING); - if (nigori.encrypt_articles()) - encrypted_types.Put(DEPRECATED_ARTICLES); if (nigori.encrypt_app_list()) encrypted_types.Put(APP_LIST); if (nigori.encrypt_arc_package())
diff --git a/components/sync/syncable/read_node.cc b/components/sync/syncable/read_node.cc index 6f220cb4..d651ed1 100644 --- a/components/sync/syncable/read_node.cc +++ b/components/sync/syncable/read_node.cc
@@ -5,7 +5,7 @@ #include "components/sync/syncable/read_node.h" #include "base/logging.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/syncable/base_transaction.h" #include "components/sync/syncable/entry.h" #include "components/sync/syncable/syncable_base_transaction.h" @@ -58,7 +58,7 @@ if (tag.empty()) return INIT_FAILED_PRECONDITION; - const std::string hash = GenerateSyncableHash(model_type, tag); + const std::string hash = ClientTagHash::FromUnhashed(model_type, tag).value(); entry_ = new syncable::Entry(transaction_->GetWrappedTrans(), syncable::GET_BY_CLIENT_TAG, hash);
diff --git a/components/sync/syncable/write_node.cc b/components/sync/syncable/write_node.cc index aa0a3608f..507166b 100644 --- a/components/sync/syncable/write_node.cc +++ b/components/sync/syncable/write_node.cc
@@ -9,7 +9,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/passphrase_enums.h" #include "components/sync/engine/engine_util.h" #include "components/sync/nigori/cryptographer.h" @@ -271,7 +271,7 @@ if (tag.empty()) return INIT_FAILED_PRECONDITION; - const std::string hash = GenerateSyncableHash(model_type, tag); + const std::string hash = ClientTagHash::FromUnhashed(model_type, tag).value(); entry_ = new syncable::MutableEntry(transaction_->GetWrappedWriteTrans(), syncable::GET_BY_CLIENT_TAG, hash); @@ -362,7 +362,7 @@ return INIT_FAILED_EMPTY_TAG; } - const std::string hash = GenerateSyncableHash(model_type, tag); + const std::string hash = ClientTagHash::FromUnhashed(model_type, tag).value(); // Start out with a dummy name. We expect // the caller to set a meaningful name after creation.
diff --git a/components/sync/test/engine/mock_model_type_processor.cc b/components/sync/test/engine/mock_model_type_processor.cc index 1c46ef0..ea3a06f 100644 --- a/components/sync/test/engine/mock_model_type_processor.cc +++ b/components/sync/test/engine/mock_model_type_processor.cc
@@ -9,6 +9,7 @@ #include "base/base64.h" #include "base/bind.h" #include "base/hash/sha1.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/engine/commit_queue.h" namespace syncer { @@ -68,7 +69,7 @@ } std::unique_ptr<CommitRequestData> MockModelTypeProcessor::CommitRequest( - const std::string& tag_hash, + const ClientTagHash& tag_hash, const sync_pb::EntitySpecifics& specifics) { const int64_t base_version = GetBaseVersion(tag_hash); @@ -86,7 +87,7 @@ data->creation_time = base::Time::UnixEpoch() + base::TimeDelta::FromDays(1); data->modification_time = data->creation_time + base::TimeDelta::FromSeconds(base_version); - data->name = "Name: " + tag_hash; + data->name = "Name: " + tag_hash.value(); auto request_data = std::make_unique<CommitRequestData>(); request_data->entity = std::move(data); @@ -99,7 +100,7 @@ } std::unique_ptr<CommitRequestData> MockModelTypeProcessor::DeleteRequest( - const std::string& tag_hash) { + const ClientTagHash& tag_hash) { const int64_t base_version = GetBaseVersion(tag_hash); auto data = std::make_unique<syncer::EntityData>(); @@ -166,26 +167,26 @@ } bool MockModelTypeProcessor::HasUpdateResponse( - const std::string& tag_hash) const { + const ClientTagHash& tag_hash) const { auto it = update_response_items_.find(tag_hash); return it != update_response_items_.end(); } const UpdateResponseData& MockModelTypeProcessor::GetUpdateResponse( - const std::string& tag_hash) const { + const ClientTagHash& tag_hash) const { DCHECK(HasUpdateResponse(tag_hash)); auto it = update_response_items_.find(tag_hash); return *it->second; } bool MockModelTypeProcessor::HasCommitResponse( - const std::string& tag_hash) const { + const ClientTagHash& tag_hash) const { auto it = commit_response_items_.find(tag_hash); return it != commit_response_items_.end(); } CommitResponseData MockModelTypeProcessor::GetCommitResponse( - const std::string& tag_hash) const { + const ClientTagHash& tag_hash) const { DCHECK(HasCommitResponse(tag_hash)); auto it = commit_response_items_.find(tag_hash); return it->second; @@ -211,7 +212,7 @@ received_commit_responses_.push_back(response_list); type_states_received_on_commit_.push_back(type_state); for (auto it = response_list.begin(); it != response_list.end(); ++it) { - const std::string tag_hash = it->client_tag_hash; + const ClientTagHash& tag_hash = it->client_tag_hash; commit_response_items_.insert(std::make_pair(tag_hash, *it)); if (pending_deleted_hashes_.find(tag_hash) != @@ -235,7 +236,7 @@ UpdateResponseDataList response_list) { type_states_received_on_update_.push_back(type_state); for (auto it = response_list.begin(); it != response_list.end(); ++it) { - const std::string client_tag_hash = (*it)->entity->client_tag_hash; + const ClientTagHash& client_tag_hash = (*it)->entity->client_tag_hash; // Server wins. Set the model's base version. SetBaseVersion(client_tag_hash, (*it)->response_version); SetServerAssignedId(client_tag_hash, (*it)->entity->id); @@ -247,7 +248,7 @@ // Fetches the sequence number as of the most recent update request. int64_t MockModelTypeProcessor::GetCurrentSequenceNumber( - const std::string& tag_hash) const { + const ClientTagHash& tag_hash) const { auto it = sequence_numbers_.find(tag_hash); if (it == sequence_numbers_.end()) { return 0; @@ -259,7 +260,7 @@ // The model thread should be sending us items with strictly increasing // sequence numbers. Here's where we emulate that behavior. int64_t MockModelTypeProcessor::GetNextSequenceNumber( - const std::string& tag_hash) { + const ClientTagHash& tag_hash) { int64_t sequence_number = GetCurrentSequenceNumber(tag_hash); sequence_number++; sequence_numbers_[tag_hash] = sequence_number; @@ -267,7 +268,7 @@ } int64_t MockModelTypeProcessor::GetBaseVersion( - const std::string& tag_hash) const { + const ClientTagHash& tag_hash) const { auto it = base_versions_.find(tag_hash); if (it == base_versions_.end()) { return kUncommittedVersion; @@ -276,23 +277,23 @@ } } -void MockModelTypeProcessor::SetBaseVersion(const std::string& tag_hash, +void MockModelTypeProcessor::SetBaseVersion(const ClientTagHash& tag_hash, int64_t version) { base_versions_[tag_hash] = version; } bool MockModelTypeProcessor::HasServerAssignedId( - const std::string& tag_hash) const { + const ClientTagHash& tag_hash) const { return assigned_ids_.find(tag_hash) != assigned_ids_.end(); } const std::string& MockModelTypeProcessor::GetServerAssignedId( - const std::string& tag_hash) const { + const ClientTagHash& tag_hash) const { DCHECK(HasServerAssignedId(tag_hash)); return assigned_ids_.find(tag_hash)->second; } -void MockModelTypeProcessor::SetServerAssignedId(const std::string& tag_hash, +void MockModelTypeProcessor::SetServerAssignedId(const ClientTagHash& tag_hash, const std::string& id) { assigned_ids_[tag_hash] = id; }
diff --git a/components/sync/test/engine/mock_model_type_processor.h b/components/sync/test/engine/mock_model_type_processor.h index dd9a755..d065cadb 100644 --- a/components/sync/test/engine/mock_model_type_processor.h +++ b/components/sync/test/engine/mock_model_type_processor.h
@@ -69,9 +69,10 @@ // return the value to the caller so the test framework can handle them as it // sees fit. std::unique_ptr<CommitRequestData> CommitRequest( - const std::string& tag_hash, + const ClientTagHash& tag_hash, const sync_pb::EntitySpecifics& specifics); - std::unique_ptr<CommitRequestData> DeleteRequest(const std::string& tag_hash); + std::unique_ptr<CommitRequestData> DeleteRequest( + const ClientTagHash& tag_hash); // Getters to access the log of received update responses. // @@ -88,13 +89,13 @@ sync_pb::ModelTypeState GetNthCommitState(size_t n) const; // Getters to access the lastest update response for a given tag_hash. - bool HasUpdateResponse(const std::string& tag_hash) const; + bool HasUpdateResponse(const ClientTagHash& tag_hash) const; const UpdateResponseData& GetUpdateResponse( - const std::string& tag_hash) const; + const ClientTagHash& tag_hash) const; // Getters to access the lastest commit response for a given tag_hash. - bool HasCommitResponse(const std::string& tag_hash) const; - CommitResponseData GetCommitResponse(const std::string& tag_hash) const; + bool HasCommitResponse(const ClientTagHash& tag_hash) const; + CommitResponseData GetCommitResponse(const ClientTagHash& tag_hash) const; void SetDisconnectCallback(const DisconnectCallback& callback); @@ -117,17 +118,18 @@ UpdateResponseDataList response_list); // Getter and setter for per-item sequence number tracking. - int64_t GetCurrentSequenceNumber(const std::string& tag_hash) const; - int64_t GetNextSequenceNumber(const std::string& tag_hash); + int64_t GetCurrentSequenceNumber(const ClientTagHash& tag_hash) const; + int64_t GetNextSequenceNumber(const ClientTagHash& tag_hash); // Getter and setter for per-item base version tracking. - int64_t GetBaseVersion(const std::string& tag_hash) const; - void SetBaseVersion(const std::string& tag_hash, int64_t version); + int64_t GetBaseVersion(const ClientTagHash& tag_hash) const; + void SetBaseVersion(const ClientTagHash& tag_hash, int64_t version); // Getters and setter for server-assigned ID values. - bool HasServerAssignedId(const std::string& tag_hash) const; - const std::string& GetServerAssignedId(const std::string& tag_hash) const; - void SetServerAssignedId(const std::string& tag_hash, const std::string& id); + bool HasServerAssignedId(const ClientTagHash& tag_hash) const; + const std::string& GetServerAssignedId(const ClientTagHash& tag_hash) const; + void SetServerAssignedId(const ClientTagHash& tag_hash, + const std::string& id); // State related to the implementation of deferred work. // See SetSynchronousExecution() for details. @@ -142,17 +144,17 @@ std::vector<sync_pb::ModelTypeState> type_states_received_on_commit_; // Latest responses received, indexed by tag_hash. - std::map<const std::string, CommitResponseData> commit_response_items_; - std::map<const std::string, const UpdateResponseData*> update_response_items_; + std::map<ClientTagHash, CommitResponseData> commit_response_items_; + std::map<ClientTagHash, const UpdateResponseData*> update_response_items_; // The per-item state maps. - std::map<const std::string, int64_t> sequence_numbers_; - std::map<const std::string, int64_t> base_versions_; - std::map<const std::string, std::string> assigned_ids_; + std::map<ClientTagHash, int64_t> sequence_numbers_; + std::map<ClientTagHash, int64_t> base_versions_; + std::map<ClientTagHash, std::string> assigned_ids_; // Set of tag hashes which were deleted with DeleteRequest but haven't yet // been confirmed by the server with OnCommitCompleted. - std::set<std::string> pending_deleted_hashes_; + std::set<ClientTagHash> pending_deleted_hashes_; // Callback which will be call during disconnection DisconnectCallback disconnect_callback_;
diff --git a/components/sync/test/engine/mock_model_type_worker.cc b/components/sync/test/engine/mock_model_type_worker.cc index 6121812..a36e332 100644 --- a/components/sync/test/engine/mock_model_type_worker.cc +++ b/components/sync/test/engine/mock_model_type_worker.cc
@@ -56,7 +56,7 @@ } bool MockModelTypeWorker::HasPendingCommitForHash( - const std::string& tag_hash) const { + const ClientTagHash& tag_hash) const { for (const CommitRequestDataList& commit : pending_commits_) { for (const std::unique_ptr<CommitRequestData>& data : commit) { if (data && data->entity->client_tag_hash == tag_hash) { @@ -68,7 +68,7 @@ } const CommitRequestData* MockModelTypeWorker::GetLatestPendingCommitForHash( - const std::string& tag_hash) const { + const ClientTagHash& tag_hash) const { // Iterate backward through the sets of commit requests to find the most // recent one that applies to the specified tag_hash. for (auto rev_it = pending_commits_.rbegin(); @@ -85,7 +85,7 @@ void MockModelTypeWorker::VerifyNthPendingCommit( size_t n, - const std::vector<std::string>& tag_hashes, + const std::vector<ClientTagHash>& tag_hashes, const std::vector<sync_pb::EntitySpecifics>& specifics_list) { ASSERT_EQ(tag_hashes.size(), specifics_list.size()); std::vector<const CommitRequestData*> list = GetNthPendingCommit(n); @@ -100,7 +100,7 @@ } void MockModelTypeWorker::VerifyPendingCommits( - const std::vector<std::vector<std::string>>& tag_hashes) { + const std::vector<std::vector<ClientTagHash>>& tag_hashes) { ASSERT_EQ(tag_hashes.size(), GetNumPendingCommits()); for (size_t i = 0; i < tag_hashes.size(); i++) { std::vector<const CommitRequestData*> commits = GetNthPendingCommit(i); @@ -123,13 +123,13 @@ } void MockModelTypeWorker::UpdateFromServer( - const std::string& tag_hash, + const ClientTagHash& tag_hash, const sync_pb::EntitySpecifics& specifics) { UpdateFromServer(tag_hash, specifics, 1); } void MockModelTypeWorker::UpdateFromServer( - const std::string& tag_hash, + const ClientTagHash& tag_hash, const sync_pb::EntitySpecifics& specifics, int64_t version_offset) { UpdateFromServer(tag_hash, specifics, version_offset, @@ -137,7 +137,7 @@ } void MockModelTypeWorker::UpdateFromServer( - const std::string& tag_hash, + const ClientTagHash& tag_hash, const sync_pb::EntitySpecifics& specifics, int64_t version_offset, const std::string& ekn) { @@ -153,7 +153,7 @@ std::unique_ptr<syncer::UpdateResponseData> MockModelTypeWorker::GenerateUpdateData( - const std::string& tag_hash, + const ClientTagHash& tag_hash, const sync_pb::EntitySpecifics& specifics, int64_t version_offset, const std::string& ekn) { @@ -187,7 +187,7 @@ std::unique_ptr<syncer::UpdateResponseData> MockModelTypeWorker::GenerateUpdateData( - const std::string& tag_hash, + const ClientTagHash& tag_hash, const sync_pb::EntitySpecifics& specifics) { return GenerateUpdateData(tag_hash, specifics, 1, model_type_state_.encryption_key_name()); @@ -212,7 +212,7 @@ return response_data; } -void MockModelTypeWorker::TombstoneFromServer(const std::string& tag_hash) { +void MockModelTypeWorker::TombstoneFromServer(const ClientTagHash& tag_hash) { int64_t old_version = GetServerVersion(tag_hash); int64_t version = old_version + 1; SetServerVersion(tag_hash, version); @@ -262,7 +262,7 @@ const CommitRequestData& request_data, int64_t version_offset) { const EntityData& entity = *request_data.entity; - const std::string& client_tag_hash = entity.client_tag_hash; + const ClientTagHash& client_tag_hash = entity.client_tag_hash; CommitResponseData response_data; @@ -313,13 +313,12 @@ processor_->OnUpdateReceived(model_type_state_, std::move(update)); } -std::string MockModelTypeWorker::GenerateId(const std::string& tag_hash) { - return "FakeId:" + tag_hash; +std::string MockModelTypeWorker::GenerateId(const ClientTagHash& tag_hash) { + return "FakeId:" + tag_hash.value(); } -int64_t MockModelTypeWorker::GetServerVersion(const std::string& tag_hash) { - std::map<const std::string, int64_t>::const_iterator it; - it = server_versions_.find(tag_hash); +int64_t MockModelTypeWorker::GetServerVersion(const ClientTagHash& tag_hash) { + auto it = server_versions_.find(tag_hash); if (it == server_versions_.end()) { return 0; } else { @@ -327,7 +326,7 @@ } } -void MockModelTypeWorker::SetServerVersion(const std::string& tag_hash, +void MockModelTypeWorker::SetServerVersion(const ClientTagHash& tag_hash, int64_t version) { server_versions_[tag_hash] = version; }
diff --git a/components/sync/test/engine/mock_model_type_worker.h b/components/sync/test/engine/mock_model_type_worker.h index 7325607e..bc3faff 100644 --- a/components/sync/test/engine/mock_model_type_worker.h +++ b/components/sync/test/engine/mock_model_type_worker.h
@@ -16,6 +16,7 @@ #include "base/containers/circular_deque.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/model_type.h" #include "components/sync/engine/commit_queue.h" #include "components/sync/engine/model_type_processor.h" @@ -45,21 +46,21 @@ // Getters to inspect the requests sent to this object. size_t GetNumPendingCommits() const; std::vector<const CommitRequestData*> GetNthPendingCommit(size_t n) const; - bool HasPendingCommitForHash(const std::string& tag_hash) const; + bool HasPendingCommitForHash(const ClientTagHash& tag_hash) const; const CommitRequestData* GetLatestPendingCommitForHash( - const std::string& tag_hash) const; + const ClientTagHash& tag_hash) const; // Verify that the |n|th commit request list has the corresponding commit // requests for |tag_hashes| with |value| set. void VerifyNthPendingCommit( size_t n, - const std::vector<std::string>& tag_hashes, + const std::vector<ClientTagHash>& tag_hashes, const std::vector<sync_pb::EntitySpecifics>& specificsList); // Verify the pending commits each contain a list of CommitRequestData and // they have the same hashes in the same order as |tag_hashes|. void VerifyPendingCommits( - const std::vector<std::vector<std::string>>& tag_hashes); + const std::vector<std::vector<ClientTagHash>>& tag_hashes); // Updates the model type state to be used in all future updates from server. void UpdateModelTypeState(const sync_pb::ModelTypeState& model_type_state); @@ -68,12 +69,12 @@ // descriptions. |version_offset| defaults to 1 and |ekn| defaults to the // current encryption key name the worker has. void UpdateFromServer(); - void UpdateFromServer(const std::string& tag_hash, + void UpdateFromServer(const ClientTagHash& tag_hash, const sync_pb::EntitySpecifics& specifics); - void UpdateFromServer(const std::string& tag_hash, + void UpdateFromServer(const ClientTagHash& tag_hash, const sync_pb::EntitySpecifics& specifics, int64_t version_offset); - void UpdateFromServer(const std::string& tag_hash, + void UpdateFromServer(const ClientTagHash& tag_hash, const sync_pb::EntitySpecifics& specifics, int64_t version_offset, const std::string& ekn); @@ -88,7 +89,7 @@ // // |ekn| is the encryption key name this item will fake having. std::unique_ptr<syncer::UpdateResponseData> GenerateUpdateData( - const std::string& tag_hash, + const ClientTagHash& tag_hash, const sync_pb::EntitySpecifics& specifics, int64_t version_offset, const std::string& ekn); @@ -96,7 +97,7 @@ // Mostly same as GenerateUpdateData above, but set 1 as |version_offset|, and // use model_type_state_.encryption_key_name() as |ekn|. std::unique_ptr<syncer::UpdateResponseData> GenerateUpdateData( - const std::string& tag_hash, + const ClientTagHash& tag_hash, const sync_pb::EntitySpecifics& specifics); // Returns an UpdateResponseData representing an update received from @@ -106,7 +107,7 @@ // Triggers a server-side deletion of the entity with |tag_hash|; updates // server state accordingly. - void TombstoneFromServer(const std::string& tag_hash); + void TombstoneFromServer(const ClientTagHash& tag_hash); // Pops one pending commit from the front of the queue and send a commit // response to the processor for it. @@ -132,7 +133,7 @@ private: // Generate an ID string. - static std::string GenerateId(const std::string& tag_hash); + static std::string GenerateId(const ClientTagHash& tag_hash); // Returns a commit response that indicates a successful commit of the // given |request_data|. Updates server state accordingly. @@ -141,8 +142,8 @@ int64_t version_offset); // Retrieve or set the server version. - int64_t GetServerVersion(const std::string& tag_hash); - void SetServerVersion(const std::string& tag_hash, int64_t version); + int64_t GetServerVersion(const ClientTagHash& tag_hash); + void SetServerVersion(const ClientTagHash& tag_hash, int64_t version); sync_pb::ModelTypeState model_type_state_; @@ -154,7 +155,7 @@ // Map of versions by client tag hash. // This is an essential part of the mocked server state. - std::map<const std::string, int64_t> server_versions_; + std::map<ClientTagHash, int64_t> server_versions_; // WeakPtrFactory for this worker which will be sent to sync thread. base::WeakPtrFactory<MockModelTypeWorker> weak_ptr_factory_{this};
diff --git a/components/sync/test/engine/single_type_mock_server.cc b/components/sync/test/engine/single_type_mock_server.cc index 72b4842..313f09a 100644 --- a/components/sync/test/engine/single_type_mock_server.cc +++ b/components/sync/test/engine/single_type_mock_server.cc
@@ -34,7 +34,7 @@ sync_pb::SyncEntity SingleTypeMockServer::UpdateFromServer( int64_t version_offset, - const std::string& tag_hash, + const ClientTagHash& tag_hash, const sync_pb::EntitySpecifics& specifics) { int64_t old_version = GetServerVersion(tag_hash); int64_t version = old_version + version_offset; @@ -47,7 +47,7 @@ entity.set_id_string(GenerateId(tag_hash)); entity.set_parent_id_string(type_root_id_); entity.set_version(version); - entity.set_client_defined_unique_tag(tag_hash); + entity.set_client_defined_unique_tag(tag_hash.value()); entity.set_deleted(false); entity.mutable_specifics()->CopyFrom(specifics); @@ -56,14 +56,14 @@ base::Time mtime = ctime + base::TimeDelta::FromSeconds(version); entity.set_ctime(TimeToProtoTime(ctime)); entity.set_mtime(TimeToProtoTime(mtime)); - entity.set_name("Name: " + tag_hash); + entity.set_name("Name: " + tag_hash.value()); return entity; } sync_pb::SyncEntity SingleTypeMockServer::TombstoneFromServer( int64_t version_offset, - const std::string& tag_hash) { + const ClientTagHash& tag_hash) { int64_t old_version = GetServerVersion(tag_hash); int64_t version = old_version + version_offset; if (version > old_version) { @@ -75,7 +75,7 @@ entity.set_id_string(GenerateId(tag_hash)); entity.set_parent_id_string(type_root_id_); entity.set_version(version); - entity.set_client_defined_unique_tag(tag_hash); + entity.set_client_defined_unique_tag(tag_hash.value()); entity.set_deleted(false); AddDefaultFieldValue(type_, entity.mutable_specifics()); @@ -99,7 +99,8 @@ const RepeatedPtrField<sync_pb::SyncEntity>& entries = message.commit().entries(); for (const auto& entry : entries) { - const std::string tag_hash = entry.client_defined_unique_tag(); + const ClientTagHash tag_hash = + ClientTagHash::FromHashed(entry.client_defined_unique_tag()); committed_items_[tag_hash] = entry; @@ -131,12 +132,13 @@ return commit_messages_[n]; } -bool SingleTypeMockServer::HasCommitEntity(const std::string& tag_hash) const { +bool SingleTypeMockServer::HasCommitEntity( + const ClientTagHash& tag_hash) const { return committed_items_.find(tag_hash) != committed_items_.end(); } sync_pb::SyncEntity SingleTypeMockServer::GetLastCommittedEntity( - const std::string& tag_hash) const { + const ClientTagHash& tag_hash) const { DCHECK(HasCommitEntity(tag_hash)); return committed_items_.find(tag_hash)->second; } @@ -156,14 +158,13 @@ progress_marker_token_ = token; } -std::string SingleTypeMockServer::GenerateId(const std::string& tag_hash) { - return "FakeId:" + tag_hash; +std::string SingleTypeMockServer::GenerateId(const ClientTagHash& tag_hash) { + return "FakeId:" + tag_hash.value(); } int64_t SingleTypeMockServer::GetServerVersion( - const std::string& tag_hash) const { - std::map<const std::string, int64_t>::const_iterator it; - it = server_versions_.find(tag_hash); + const ClientTagHash& tag_hash) const { + auto it = server_versions_.find(tag_hash); // Server versions do not necessarily start at 1 or 0. if (it == server_versions_.end()) { return 2048; @@ -172,7 +173,7 @@ } } -void SingleTypeMockServer::SetServerVersion(const std::string& tag_hash, +void SingleTypeMockServer::SetServerVersion(const ClientTagHash& tag_hash, int64_t version) { server_versions_[tag_hash] = version; }
diff --git a/components/sync/test/engine/single_type_mock_server.h b/components/sync/test/engine/single_type_mock_server.h index 72742fc9..2f06642 100644 --- a/components/sync/test/engine/single_type_mock_server.h +++ b/components/sync/test/engine/single_type_mock_server.h
@@ -13,6 +13,7 @@ #include <vector> #include "base/macros.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/model_type.h" #include "components/sync/engine/non_blocking_sync_common.h" @@ -40,13 +41,13 @@ // updates, redeliveries, and genuine updates. sync_pb::SyncEntity UpdateFromServer( int64_t version_offset, - const std::string& tag_hash, + const ClientTagHash& tag_hash, const sync_pb::EntitySpecifics& specifics); // Generates a SyncEntity representing a server-delivered update to delete // an item. sync_pb::SyncEntity TombstoneFromServer(int64_t version_offset, - const std::string& tag_hash); + const ClientTagHash& tag_hash); // Generates a response to the specified commit message. // @@ -66,8 +67,9 @@ // Getters to return the most recently committed entities for a given // unique_client_tag hash. - bool HasCommitEntity(const std::string& tag_hash) const; - sync_pb::SyncEntity GetLastCommittedEntity(const std::string& tag_hash) const; + bool HasCommitEntity(const ClientTagHash& tag_hash) const; + sync_pb::SyncEntity GetLastCommittedEntity( + const ClientTagHash& tag_hash) const; // Getters that create realistic-looking progress markers and data type // context. @@ -78,23 +80,23 @@ void SetProgressMarkerToken(const std::string& token); private: - static std::string GenerateId(const std::string& tag_hash); + static std::string GenerateId(const ClientTagHash& tag_hash); // Get and set our emulated server state. - int64_t GetServerVersion(const std::string& tag_hash) const; - void SetServerVersion(const std::string& tag_hash, int64_t version); + int64_t GetServerVersion(const ClientTagHash& tag_hash) const; + void SetServerVersion(const ClientTagHash& tag_hash, int64_t version); const ModelType type_; const std::string type_root_id_; // Server version state maps. - std::map<const std::string, int64_t> server_versions_; + std::map<ClientTagHash, int64_t> server_versions_; // Log of messages sent to the server. std::vector<sync_pb::ClientToServerMessage> commit_messages_; // Map of most recent commits by tag_hash. - std::map<const std::string, sync_pb::SyncEntity> committed_items_; + std::map<ClientTagHash, sync_pb::SyncEntity> committed_items_; // The token that is used to generate the current progress marker. std::string progress_marker_token_;
diff --git a/components/sync_device_info/BUILD.gn b/components/sync_device_info/BUILD.gn index e85e53e..be19364 100644 --- a/components/sync_device_info/BUILD.gn +++ b/components/sync_device_info/BUILD.gn
@@ -15,6 +15,8 @@ "device_info_prefs.h", "device_info_sync_bridge.cc", "device_info_sync_bridge.h", + "device_info_sync_client.cc", + "device_info_sync_client.h", "device_info_sync_service.cc", "device_info_sync_service.h", "device_info_sync_service_impl.cc",
diff --git a/components/sync_device_info/device_info_sync_client.cc b/components/sync_device_info/device_info_sync_client.cc new file mode 100644 index 0000000..75ae6db1 --- /dev/null +++ b/components/sync_device_info/device_info_sync_client.cc
@@ -0,0 +1,12 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/sync_device_info/device_info_sync_client.h" + +namespace syncer { + +DeviceInfoSyncClient::DeviceInfoSyncClient() = default; +DeviceInfoSyncClient::~DeviceInfoSyncClient() = default; + +} // namespace syncer
diff --git a/components/sync_device_info/device_info_sync_client.h b/components/sync_device_info/device_info_sync_client.h new file mode 100644 index 0000000..386038d1 --- /dev/null +++ b/components/sync_device_info/device_info_sync_client.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 COMPONENTS_SYNC_DEVICE_INFO_DEVICE_INFO_SYNC_CLIENT_H_ +#define COMPONENTS_SYNC_DEVICE_INFO_DEVICE_INFO_SYNC_CLIENT_H_ + +#include <string> + +#include "base/macros.h" + +namespace syncer { + +// Interface for clients of DeviceInfoSyncService. +class DeviceInfoSyncClient { + public: + DeviceInfoSyncClient(); + virtual ~DeviceInfoSyncClient(); + + virtual std::string GetSigninScopedDeviceId() const = 0; + virtual bool GetSendTabToSelfReceivingEnabled() const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(DeviceInfoSyncClient); +}; + +} // namespace syncer + +#endif // COMPONENTS_SYNC_DEVICE_INFO_DEVICE_INFO_SYNC_CLIENT_H_
diff --git a/components/sync_device_info/device_info_sync_service_impl.cc b/components/sync_device_info/device_info_sync_service_impl.cc index a2136a05..a4a5da0 100644 --- a/components/sync_device_info/device_info_sync_service_impl.cc +++ b/components/sync_device_info/device_info_sync_service_impl.cc
@@ -12,6 +12,7 @@ #include "components/sync_device_info/device_info.h" #include "components/sync_device_info/device_info_prefs.h" #include "components/sync_device_info/device_info_sync_bridge.h" +#include "components/sync_device_info/device_info_sync_client.h" #include "components/sync_device_info/device_info_tracker.h" #include "components/sync_device_info/local_device_info_provider.h" @@ -20,9 +21,12 @@ DeviceInfoSyncServiceImpl::DeviceInfoSyncServiceImpl( OnceModelTypeStoreFactory model_type_store_factory, std::unique_ptr<MutableLocalDeviceInfoProvider> local_device_info_provider, - std::unique_ptr<DeviceInfoPrefs> device_info_prefs) { + std::unique_ptr<DeviceInfoPrefs> device_info_prefs, + std::unique_ptr<DeviceInfoSyncClient> device_info_sync_client) + : device_info_sync_client_(std::move(device_info_sync_client)) { DCHECK(local_device_info_provider); DCHECK(device_info_prefs); + DCHECK(device_info_sync_client_); // Make a copy of the channel to avoid relying on argument evaluation order. const version_info::Channel channel =
diff --git a/components/sync_device_info/device_info_sync_service_impl.h b/components/sync_device_info/device_info_sync_service_impl.h index 65cca99..32a084a 100644 --- a/components/sync_device_info/device_info_sync_service_impl.h +++ b/components/sync_device_info/device_info_sync_service_impl.h
@@ -14,6 +14,7 @@ namespace syncer { class DeviceInfoPrefs; +class DeviceInfoSyncClient; class DeviceInfoSyncBridge; class MutableLocalDeviceInfoProvider; @@ -21,10 +22,13 @@ public: // |local_device_info_provider| must not be null. // |device_info_prefs| must not be null. - DeviceInfoSyncServiceImpl(OnceModelTypeStoreFactory model_type_store_factory, - std::unique_ptr<MutableLocalDeviceInfoProvider> - local_device_info_provider, - std::unique_ptr<DeviceInfoPrefs> device_info_prefs); + // |device_info_sync_client| must not be null and must outlive this object. + DeviceInfoSyncServiceImpl( + OnceModelTypeStoreFactory model_type_store_factory, + std::unique_ptr<MutableLocalDeviceInfoProvider> + local_device_info_provider, + std::unique_ptr<DeviceInfoPrefs> device_info_prefs, + std::unique_ptr<DeviceInfoSyncClient> device_info_sync_client); ~DeviceInfoSyncServiceImpl() override; // DeviceInfoSyncService implementation. @@ -33,6 +37,7 @@ base::WeakPtr<ModelTypeControllerDelegate> GetControllerDelegate() override; private: + std::unique_ptr<DeviceInfoSyncClient> device_info_sync_client_; std::unique_ptr<DeviceInfoSyncBridge> bridge_; DISALLOW_COPY_AND_ASSIGN(DeviceInfoSyncServiceImpl);
diff --git a/components/sync_device_info/local_device_info_provider_impl.cc b/components/sync_device_info/local_device_info_provider_impl.cc index de40505..aae8589 100644 --- a/components/sync_device_info/local_device_info_provider_impl.cc +++ b/components/sync_device_info/local_device_info_provider_impl.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "components/sync/base/sync_prefs.h" #include "components/sync/driver/sync_util.h" +#include "components/sync_device_info/device_info_sync_client.h" #include "components/sync_device_info/local_device_info_util.h" namespace syncer { @@ -14,16 +15,9 @@ LocalDeviceInfoProviderImpl::LocalDeviceInfoProviderImpl( version_info::Channel channel, const std::string& version, - const SigninScopedDeviceIdCallback& signin_scoped_device_id_callback, - const SendTabToSelfReceivingEnabledCallback& - send_tab_to_self_receiving_enabled_callback) - : channel_(channel), - version_(version), - signin_scoped_device_id_callback_(signin_scoped_device_id_callback), - send_tab_to_self_receiving_enabled_callback_( - send_tab_to_self_receiving_enabled_callback) { - DCHECK(signin_scoped_device_id_callback_); - DCHECK(send_tab_to_self_receiving_enabled_callback_); + const DeviceInfoSyncClient* sync_client) + : channel_(channel), version_(version), sync_client_(sync_client) { + DCHECK(sync_client); } LocalDeviceInfoProviderImpl::~LocalDeviceInfoProviderImpl() { @@ -38,12 +32,12 @@ const DeviceInfo* LocalDeviceInfoProviderImpl::GetLocalDeviceInfo() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - bool send_tab_to_self_receiving_enabled = - send_tab_to_self_receiving_enabled_callback_.Run(); - if (local_device_info_) { - local_device_info_->set_send_tab_to_self_receiving_enabled( - send_tab_to_self_receiving_enabled); + if (!local_device_info_) { + return nullptr; } + + local_device_info_->set_send_tab_to_self_receiving_enabled( + sync_client_->GetSendTabToSelfReceivingEnabled()); return local_device_info_.get(); } @@ -64,9 +58,9 @@ // the specifics when it will be synced up. local_device_info_ = std::make_unique<DeviceInfo>( cache_guid, session_name, version_, MakeUserAgentForSync(channel_), - GetLocalDeviceType(), signin_scoped_device_id_callback_.Run(), + GetLocalDeviceType(), sync_client_->GetSigninScopedDeviceId(), /*last_updated_timestamp=*/base::Time(), - send_tab_to_self_receiving_enabled_callback_.Run()); + sync_client_->GetSendTabToSelfReceivingEnabled()); // Notify observers. callback_list_.Notify();
diff --git a/components/sync_device_info/local_device_info_provider_impl.h b/components/sync_device_info/local_device_info_provider_impl.h index e214c89..259dad5 100644 --- a/components/sync_device_info/local_device_info_provider_impl.h +++ b/components/sync_device_info/local_device_info_provider_impl.h
@@ -18,17 +18,13 @@ namespace syncer { +class DeviceInfoSyncClient; + class LocalDeviceInfoProviderImpl : public MutableLocalDeviceInfoProvider { public: - using SigninScopedDeviceIdCallback = base::RepeatingCallback<std::string()>; - using SendTabToSelfReceivingEnabledCallback = base::RepeatingCallback<bool()>; - - LocalDeviceInfoProviderImpl( - version_info::Channel channel, - const std::string& version, - const SigninScopedDeviceIdCallback& signin_scoped_device_id_callback, - const SendTabToSelfReceivingEnabledCallback& - send_tab_to_self_receiving_enabled_callback); + LocalDeviceInfoProviderImpl(version_info::Channel channel, + const std::string& version, + const DeviceInfoSyncClient* sync_client); ~LocalDeviceInfoProviderImpl() override; // MutableLocalDeviceInfoProvider implementation. @@ -47,9 +43,7 @@ // The version string for the current client. const std::string version_; - const SigninScopedDeviceIdCallback signin_scoped_device_id_callback_; - const SendTabToSelfReceivingEnabledCallback - send_tab_to_self_receiving_enabled_callback_; + const DeviceInfoSyncClient* const sync_client_; std::unique_ptr<DeviceInfo> local_device_info_; base::CallbackList<void(void)> callback_list_;
diff --git a/components/sync_device_info/local_device_info_provider_impl_unittest.cc b/components/sync_device_info/local_device_info_provider_impl_unittest.cc index 6f0379e..aabd8f0 100644 --- a/components/sync_device_info/local_device_info_provider_impl_unittest.cc +++ b/components/sync_device_info/local_device_info_provider_impl_unittest.cc
@@ -4,8 +4,9 @@ #include "components/sync_device_info/local_device_info_provider_impl.h" -#include "base/test/mock_callback.h" +#include "base/memory/ptr_util.h" #include "components/sync/driver/sync_util.h" +#include "components/sync_device_info/device_info_sync_client.h" #include "components/version_info/version_string.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -19,6 +20,18 @@ using testing::NotNull; using testing::Return; +class MockDeviceInfoSyncClient : public DeviceInfoSyncClient { + public: + MockDeviceInfoSyncClient() = default; + ~MockDeviceInfoSyncClient() = default; + + MOCK_CONST_METHOD0(GetSigninScopedDeviceId, std::string()); + MOCK_CONST_METHOD0(GetSendTabToSelfReceivingEnabled, bool()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockDeviceInfoSyncClient); +}; + class LocalDeviceInfoProviderImplTest : public testing::Test { public: LocalDeviceInfoProviderImplTest() {} @@ -28,8 +41,7 @@ provider_ = std::make_unique<LocalDeviceInfoProviderImpl>( version_info::Channel::UNKNOWN, version_info::GetVersionStringWithModifier("UNKNOWN"), - signin_scoped_device_id_callback_.Get(), - send_tab_to_self_receiving_enabled_callback_.Get()); + &device_info_sync_client_); } void TearDown() override { provider_.reset(); } @@ -41,12 +53,7 @@ provider_->Initialize(guid, kLocalDeviceSessionName); } - testing::NiceMock<base::MockCallback< - LocalDeviceInfoProviderImpl::SigninScopedDeviceIdCallback>> - signin_scoped_device_id_callback_; - testing::NiceMock<base::MockCallback< - LocalDeviceInfoProviderImpl::SendTabToSelfReceivingEnabledCallback>> - send_tab_to_self_receiving_enabled_callback_; + testing::NiceMock<MockDeviceInfoSyncClient> device_info_sync_client_; std::unique_ptr<LocalDeviceInfoProviderImpl> provider_; }; @@ -69,7 +76,7 @@ TEST_F(LocalDeviceInfoProviderImplTest, GetSigninScopedDeviceId) { const std::string kSigninScopedDeviceId = "device_id"; - EXPECT_CALL(signin_scoped_device_id_callback_, Run()) + EXPECT_CALL(device_info_sync_client_, GetSigninScopedDeviceId()) .WillOnce(Return(kSigninScopedDeviceId)); InitializeProvider(); @@ -80,7 +87,7 @@ } TEST_F(LocalDeviceInfoProviderImplTest, SendTabToSelfReceivingEnabled) { - ON_CALL(send_tab_to_self_receiving_enabled_callback_, Run()) + ON_CALL(device_info_sync_client_, GetSendTabToSelfReceivingEnabled()) .WillByDefault(Return(true)); InitializeProvider(); @@ -89,7 +96,7 @@ EXPECT_TRUE( provider_->GetLocalDeviceInfo()->send_tab_to_self_receiving_enabled()); - ON_CALL(send_tab_to_self_receiving_enabled_callback_, Run()) + ON_CALL(device_info_sync_client_, GetSendTabToSelfReceivingEnabled()) .WillByDefault(Return(false)); ASSERT_THAT(provider_->GetLocalDeviceInfo(), NotNull());
diff --git a/components/sync_sessions/session_sync_bridge.cc b/components/sync_sessions/session_sync_bridge.cc index a91a3b8..12136d6 100644 --- a/components/sync_sessions/session_sync_bridge.cc +++ b/components/sync_sessions/session_sync_bridge.cc
@@ -17,7 +17,7 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" #include "components/history/core/browser/history_service.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/time.h" #include "components/sync/model/data_type_activation_request.h" #include "components/sync/model/entity_change.h" @@ -235,8 +235,8 @@ // Guaranteed by the processor. DCHECK_EQ(change->data().client_tag_hash, - GenerateSyncableHash(syncer::SESSIONS, - SessionStore::GetClientTag(specifics))); + syncer::ClientTagHash::FromUnhashed( + syncer::SESSIONS, SessionStore::GetClientTag(specifics))); batch->PutAndUpdateTracker(specifics, change->data().modification_time); // If a favicon or favicon urls are present, load the URLs and visit
diff --git a/components/sync_sessions/session_sync_bridge_unittest.cc b/components/sync_sessions/session_sync_bridge_unittest.cc index 5afc307..af019fd5 100644 --- a/components/sync_sessions/session_sync_bridge_unittest.cc +++ b/components/sync_sessions/session_sync_bridge_unittest.cc
@@ -17,7 +17,7 @@ #include "base/test/mock_callback.h" #include "base/test/task_environment.h" #include "components/prefs/testing_pref_service.h" -#include "components/sync/base/hash_util.h" +#include "components/sync/base/client_tag_hash.h" #include "components/sync/base/sync_prefs.h" #include "components/sync/model/data_batch.h" #include "components/sync/model/data_type_activation_request.h" @@ -82,7 +82,7 @@ const sync_pb::SessionSpecifics& specifics, base::Time mtime = base::Time::Now()) { auto data = std::make_unique<syncer::EntityData>(); - data->client_tag_hash = syncer::GenerateSyncableHash( + data->client_tag_hash = syncer::ClientTagHash::FromUnhashed( syncer::SESSIONS, SessionStore::GetClientTag(specifics)); *data->specifics.mutable_session() = specifics; data->modification_time = mtime; @@ -111,7 +111,7 @@ auto tombstone = std::make_unique<syncer::EntityData>(); tombstone->client_tag_hash = - syncer::GenerateSyncableHash(syncer::SESSIONS, client_tag); + syncer::ClientTagHash::FromUnhashed(syncer::SESSIONS, client_tag); auto data = std::make_unique<syncer::UpdateResponseData>(); data->entity = std::move(tombstone); @@ -123,7 +123,7 @@ const std::string& client_tag) { syncer::CommitResponseData response; response.client_tag_hash = - syncer::GenerateSyncableHash(syncer::SESSIONS, client_tag); + syncer::ClientTagHash::FromUnhashed(syncer::SESSIONS, client_tag); response.sequence_number = 1; return response; }
diff --git a/components/sync_sessions/synced_session_tracker.cc b/components/sync_sessions/synced_session_tracker.cc index 4e2224c5..ee269b3 100644 --- a/components/sync_sessions/synced_session_tracker.cc +++ b/components/sync_sessions/synced_session_tracker.cc
@@ -215,18 +215,6 @@ return session ? session->tab_node_pool.GetAllTabNodeIds() : std::set<int>(); } -std::vector<const sessions::SessionTab*> -SyncedSessionTracker::LookupUnmappedTabs(const std::string& session_tag) const { - const TrackedSession* session = LookupTrackedSession(session_tag); - std::vector<const sessions::SessionTab*> unmapped_tabs; - if (session) { - for (const auto& unmapped_tab_entry : session->unmapped_tabs) { - unmapped_tabs.push_back(unmapped_tab_entry.second.get()); - } - } - return unmapped_tabs; -} - const SyncedSession* SyncedSessionTracker::LookupLocalSession() const { return LookupSession(local_session_tag_); }
diff --git a/components/sync_sessions/synced_session_tracker.h b/components/sync_sessions/synced_session_tracker.h index e0585400..7422be7 100644 --- a/components/sync_sessions/synced_session_tracker.h +++ b/components/sync_sessions/synced_session_tracker.h
@@ -67,10 +67,6 @@ // session having tag |session_tag|. std::set<int> LookupTabNodeIds(const std::string& session_tag) const; - // Returns tabs that are unmapped for session with tag |session_tag|. - std::vector<const sessions::SessionTab*> LookupUnmappedTabs( - const std::string& session_tag) const; - // Attempts to look up the session windows associatd with the session given // by |session_tag|. Ownership of SessionWindows stays within the // SyncedSessionTracker.
diff --git a/components/sync_sessions/synced_session_tracker_unittest.cc b/components/sync_sessions/synced_session_tracker_unittest.cc index 98379746..ce62699 100644 --- a/components/sync_sessions/synced_session_tracker_unittest.cc +++ b/components/sync_sessions/synced_session_tracker_unittest.cc
@@ -397,20 +397,6 @@ EXPECT_THAT(tracker_.LookupTabNodeIds(kTag2), IsEmpty()); } -TEST_F(SyncedSessionTrackerTest, LookupUnmappedTabs) { - EXPECT_THAT(tracker_.LookupUnmappedTabs(kTag), IsEmpty()); - - sessions::SessionTab* tab = tracker_.GetTab(kTag, kTab1); - ASSERT_THAT(tab, NotNull()); - - EXPECT_THAT(tracker_.LookupUnmappedTabs(kTag), ElementsAre(tab)); - EXPECT_THAT(tracker_.LookupUnmappedTabs(kTag2), IsEmpty()); - - tracker_.PutWindowInSession(kTag, kWindow1); - tracker_.PutTabInWindow(kTag, kWindow1, kTab1); - EXPECT_THAT(tracker_.LookupUnmappedTabs(kTag), IsEmpty()); -} - TEST_F(SyncedSessionTrackerTest, SessionTracking) { ASSERT_TRUE(tracker_.Empty());
diff --git a/components/sync_sessions/synced_tab_delegate.h b/components/sync_sessions/synced_tab_delegate.h index e756fe06..bf48b062 100644 --- a/components/sync_sessions/synced_tab_delegate.h +++ b/components/sync_sessions/synced_tab_delegate.h
@@ -35,11 +35,6 @@ virtual SessionID GetSessionId() const = 0; virtual bool IsBeingDestroyed() const = 0; - // Get the tab id of the tab responsible for opening this tab, if applicable. - // Returns an invalid ID if no such tab relationship is known. - // TODO(mastiz): Rename to GetSourceTabSessionId(). - virtual SessionID GetSourceTabID() const = 0; - // Method derived from extensions TabHelper. virtual std::string GetExtensionAppId() const = 0;
diff --git a/components/sync_sessions/test_synced_window_delegates_getter.cc b/components/sync_sessions/test_synced_window_delegates_getter.cc index af19b3c8..5e9db84 100644 --- a/components/sync_sessions/test_synced_window_delegates_getter.cc +++ b/components/sync_sessions/test_synced_window_delegates_getter.cc
@@ -160,10 +160,6 @@ return http_count > 0; } -SessionID TestSyncedTabDelegate::GetSourceTabID() const { - return SessionID::InvalidValue(); -} - int64_t TestSyncedTabDelegate::GetTaskIdForNavigationId(int nav_id) const { // Task IDs are currently not used in the tests. -1 signals an unknown Task // ID. @@ -268,10 +264,6 @@ return false; } -SessionID PlaceholderTabDelegate::GetSourceTabID() const { - return SessionID::InvalidValue(); -} - int64_t PlaceholderTabDelegate::GetTaskIdForNavigationId(int nav_id) const { // Task IDs are currently not used in the tests. -1 signals an unknown Task // ID.
diff --git a/components/sync_sessions/test_synced_window_delegates_getter.h b/components/sync_sessions/test_synced_window_delegates_getter.h index 108df04..f373c00b 100644 --- a/components/sync_sessions/test_synced_window_delegates_getter.h +++ b/components/sync_sessions/test_synced_window_delegates_getter.h
@@ -62,7 +62,6 @@ GetBlockedNavigations() const override; bool IsPlaceholderTab() const override; bool ShouldSync(SyncSessionsClient* sessions_client) override; - SessionID GetSourceTabID() const override; int64_t GetTaskIdForNavigationId(int nav_id) const override; int64_t GetParentTaskIdForNavigationId(int nav_id) const override; int64_t GetRootTaskIdForNavigationId(int nav_id) const override; @@ -113,7 +112,6 @@ const std::vector<std::unique_ptr<const sessions::SerializedNavigationEntry>>* GetBlockedNavigations() const override; bool ShouldSync(SyncSessionsClient* sessions_client) override; - SessionID GetSourceTabID() const override; int64_t GetTaskIdForNavigationId(int nav_id) const override; int64_t GetParentTaskIdForNavigationId(int nav_id) const override; int64_t GetRootTaskIdForNavigationId(int nav_id) const override;
diff --git a/components/tracing/common/trace_startup_config.cc b/components/tracing/common/trace_startup_config.cc index a5d7eb86..8720fe0c 100644 --- a/components/tracing/common/trace_startup_config.cc +++ b/components/tracing/common/trace_startup_config.cc
@@ -79,14 +79,12 @@ TraceStartupConfig::TraceStartupConfig() { auto* command_line = base::CommandLine::ForCurrentProcess(); - if (!command_line->HasSwitch(switches::kDisablePerfetto)) { - const std::string value = - command_line->GetSwitchValueASCII(switches::kTraceStartupOwner); - if (value == "devtools") { - session_owner_ = SessionOwner::kDevToolsTracingHandler; - } else if (value == "system") { - session_owner_ = SessionOwner::kSystemTracing; - } + const std::string value = + command_line->GetSwitchValueASCII(switches::kTraceStartupOwner); + if (value == "devtools") { + session_owner_ = SessionOwner::kDevToolsTracingHandler; + } else if (value == "system") { + session_owner_ = SessionOwner::kSystemTracing; } if (EnableFromCommandLine()) {
diff --git a/components/tracing/common/tracing_switches.cc b/components/tracing/common/tracing_switches.cc index bdd8bd5..0428622f 100644 --- a/components/tracing/common/tracing_switches.cc +++ b/components/tracing/common/tracing_switches.cc
@@ -58,16 +58,6 @@ // through the normal methods for stopping system traces. const char kTraceStartupOwner[] = "trace-startup-owner"; -// Disables the perfetto tracing backend. We need a separate command line -// argument from the kTracingPerfettoBackend feature, because feature flags are -// parsed too late during startup for early startup tracing support. -const char kDisablePerfetto[] = "disable-perfetto"; - -// Enables the perfetto tracing backend. We need a separate command line -// argument from the kTracingPerfettoBackend feature, because feature flags are -// parsed too late during startup for early startup tracing support. -const char kEnablePerfetto[] = "enable-perfetto"; - // Repeat internable data for each TraceEvent in the perfetto proto format. const char kPerfettoDisableInterning[] = "perfetto-disable-interning";
diff --git a/components/tracing/common/tracing_switches.h b/components/tracing/common/tracing_switches.h index b06520d6..09b7a20 100644 --- a/components/tracing/common/tracing_switches.h +++ b/components/tracing/common/tracing_switches.h
@@ -16,8 +16,6 @@ TRACING_EXPORT extern const char kTraceStartupFile[]; TRACING_EXPORT extern const char kTraceStartupRecordMode[]; TRACING_EXPORT extern const char kTraceStartupOwner[]; -TRACING_EXPORT extern const char kDisablePerfetto[]; -TRACING_EXPORT extern const char kEnablePerfetto[]; TRACING_EXPORT extern const char kPerfettoDisableInterning[]; TRACING_EXPORT extern const char kPerfettoOutputFile[]; TRACING_EXPORT extern const char kTraceToConsole[];
diff --git a/components/ui_devtools/tracing_agent.cc b/components/ui_devtools/tracing_agent.cc index e4c0d3b..e3faab2 100644 --- a/components/ui_devtools/tracing_agent.cc +++ b/components/ui_devtools/tracing_agent.cc
@@ -380,14 +380,8 @@ void TracingAgent::StartTracing(std::unique_ptr<StartCallback> callback) { trace_config_.SetProcessFilterConfig(CreateProcessFilterConfig(gpu_pid_)); - if (tracing::TracingUsesPerfettoBackend()) { - perfetto_session_ = - std::make_unique<PerfettoTracingSession>(connector_.get()); - } else { - callback->sendFailure( - Response::Error("Could not start tracing by Perfetto.")); - return; - } + perfetto_session_ = + std::make_unique<PerfettoTracingSession>(connector_.get()); perfetto_session_->EnableTracing( trace_config_, base::BindOnce(&TracingAgent::OnRecordingEnabled,
diff --git a/components/viz/host/host_display_client.cc b/components/viz/host/host_display_client.cc index 76ed0dd..0108c892 100644 --- a/components/viz/host/host_display_client.cc +++ b/components/viz/host/host_display_client.cc
@@ -59,7 +59,7 @@ } #endif -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) void HostDisplayClient::DidCompleteSwapWithNewSize(const gfx::Size& size) { NOTIMPLEMENTED(); }
diff --git a/components/viz/host/host_display_client.h b/components/viz/host/host_display_client.h index 4619f19..af01fab0 100644 --- a/components/viz/host/host_display_client.h +++ b/components/viz/host/host_display_client.h
@@ -42,7 +42,7 @@ mojo::PendingReceiver<mojom::LayeredWindowUpdater> receiver) override; #endif -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) void DidCompleteSwapWithNewSize(const gfx::Size& size) override; #endif
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index c1a8f7ba..c87cdf65 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -930,7 +930,7 @@ void SkiaOutputSurfaceImplOnGpu::CopyOutput( RenderPassId id, - const copy_output::RenderPassGeometry& geometry, + copy_output::RenderPassGeometry geometry, const gfx::ColorSpace& color_space, std::unique_ptr<CopyOutputRequest> request, base::OnceCallback<bool()> deferred_framebuffer_draw_closure) { @@ -943,6 +943,40 @@ base::BindOnce([](std::vector<std::unique_ptr<SkDeferredDisplayList>>) {}, std::move(destroy_after_swap_))); + bool use_gl_renderer_copier = + !is_using_vulkan() && !features::IsUsingSkiaForGLReadback(); + // Lazy initialize GLRendererCopier before draw because + // DirectContextProvider ctor the backbuffer. + if (use_gl_renderer_copier && !copier_) { + if (!MakeCurrent(true /* need_fbo0 */)) + return; + auto client = std::make_unique<DirectContextProviderDelegateImpl>( + gpu_preferences_, dependency_->GetGpuDriverBugWorkarounds(), + dependency_->GetGpuFeatureInfo(), context_state_.get(), + dependency_->GetMailboxManager(), dependency_->GetSharedImageManager(), + CreateSyncPointClientState(dependency_, sequence_id_)); + context_provider_ = base::MakeRefCounted<DirectContextProvider>( + context_state_->context(), gl_surface_, supports_alpha_, + gpu_preferences_, feature_info_.get(), std::move(client)); + auto result = context_provider_->BindToCurrentThread(); + if (result != gpu::ContextResult::kSuccess) { + DLOG(ERROR) << "Couldn't initialize GLRendererCopier"; + context_provider_ = nullptr; + return; + } + context_current_task_runner_ = + base::MakeRefCounted<ContextCurrentTaskRunner>(this); + texture_deleter_ = + std::make_unique<TextureDeleter>(context_current_task_runner_); + copier_ = std::make_unique<GLRendererCopier>(context_provider_, + texture_deleter_.get()); + copier_->set_async_gl_task_runner(context_current_task_runner_); + + // DirectContextProvider changed GL state. Reset Skia state tracking + // for potential draw below. + gr_context()->resetContext(); + } + if (deferred_framebuffer_draw_closure) { // returns false if context not set to current, i.e lost if (!std::move(deferred_framebuffer_draw_closure).Run()) @@ -978,37 +1012,19 @@ surface->flush(); } - if (!is_using_vulkan() && !features::IsUsingSkiaForGLReadback()) { - // Lazy initialize GLRendererCopier. - if (!copier_) { - auto client = std::make_unique<DirectContextProviderDelegateImpl>( - gpu_preferences_, dependency_->GetGpuDriverBugWorkarounds(), - dependency_->GetGpuFeatureInfo(), context_state_.get(), - dependency_->GetMailboxManager(), - dependency_->GetSharedImageManager(), - CreateSyncPointClientState(dependency_, sequence_id_)); - context_provider_ = base::MakeRefCounted<DirectContextProvider>( - context_state_->context(), gl_surface_, supports_alpha_, - gpu_preferences_, feature_info_.get(), std::move(client)); - auto result = context_provider_->BindToCurrentThread(); - if (result != gpu::ContextResult::kSuccess) { - DLOG(ERROR) << "Couldn't initialize GLRendererCopier"; - context_provider_ = nullptr; - return; - } - context_current_task_runner_ = - base::MakeRefCounted<ContextCurrentTaskRunner>(this); - texture_deleter_ = - std::make_unique<TextureDeleter>(context_current_task_runner_); - copier_ = std::make_unique<GLRendererCopier>(context_provider_, - texture_deleter_.get()); - copier_->set_async_gl_task_runner(context_current_task_runner_); - } + if (use_gl_renderer_copier) { surface->flush(); GLuint gl_id = 0; GLenum internal_format = supports_alpha_ ? GL_RGBA : GL_RGB; bool flipped = from_fbo0 ? !capabilities().flipped_output_surface : false; + // readback_offset is in window co-ordinate space and must take into account + // flipping. + if (flipped) { + geometry.readback_offset.set_y( + size_.height() - + (geometry.readback_offset.y() + geometry.result_selection.height())); + } base::Optional<ScopedSurfaceToTexture> texture_mapper; if (!from_fbo0 || dependency_->IsOffscreen()) {
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index 59971434..eb9d790 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -141,7 +141,7 @@ void RemoveRenderPassResource( std::vector<std::unique_ptr<ImageContextImpl>> image_contexts); void CopyOutput(RenderPassId id, - const copy_output::RenderPassGeometry& geometry, + copy_output::RenderPassGeometry geometry, const gfx::ColorSpace& color_space, std::unique_ptr<CopyOutputRequest> request, base::OnceCallback<bool()> deferred_framebuffer_draw_closure);
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc b/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc index ce80e8b..103db80 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_unittest.cc
@@ -187,19 +187,8 @@ geometry.result_bounds = kSurfaceRect; geometry.result_selection = output_rect; geometry.sampling_bounds = kSurfaceRect; + geometry.readback_offset = gfx::Vector2d(0, 0); - if (gpu_service_holder_->is_vulkan_enabled()) { - // No flipping because Skia handles all co-ordinate transformation on the - // software readback path currently implemented for Vulkan. - geometry.readback_offset = geometry.readback_offset = gfx::Vector2d(0, 0); - } else { - // GLRendererCopier may need a vertical flip depending on output surface - // characteristics. - geometry.readback_offset = - output_surface_->capabilities().flipped_output_surface - ? geometry.readback_offset = gfx::Vector2d(0, 0) - : geometry.readback_offset = gfx::Vector2d(0, 90); - } output_surface_->CopyOutput(0, geometry, color_space, std::move(request)); BlockMainThread();
diff --git a/components/viz/service/display_embedder/software_output_surface.cc b/components/viz/service/display_embedder/software_output_surface.cc index 85a2040..65080f7 100644 --- a/components/viz/service/display_embedder/software_output_surface.cc +++ b/components/viz/service/display_embedder/software_output_surface.cc
@@ -119,7 +119,7 @@ base::TimeTicks now = base::TimeTicks::Now(); base::TimeDelta interval_to_next_refresh = now.SnappedToNextTick(refresh_timebase_, refresh_interval_) - now; -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) if (needs_swap_size_notifications_) client_->DidSwapWithSize(pixel_size); #endif @@ -148,7 +148,7 @@ return gfx::OVERLAY_TRANSFORM_NONE; } -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) void SoftwareOutputSurface::SetNeedsSwapSizeNotifications( bool needs_swap_size_notifications) { needs_swap_size_notifications_ = needs_swap_size_notifications;
diff --git a/components/viz/service/display_embedder/software_output_surface.h b/components/viz/service/display_embedder/software_output_surface.h index eb3ef42..c109013 100644 --- a/components/viz/service/display_embedder/software_output_surface.h +++ b/components/viz/service/display_embedder/software_output_surface.h
@@ -10,6 +10,7 @@ #include <vector> #include "base/memory/weak_ptr.h" +#include "build/build_config.h" #include "components/viz/common/display/update_vsync_parameters_callback.h" #include "components/viz/common/frame_sinks/begin_frame_args.h" #include "components/viz/service/display/output_surface.h" @@ -49,7 +50,7 @@ UpdateVSyncParametersCallback callback) override; void SetDisplayTransformHint(gfx::OverlayTransform transform) override {} gfx::OverlayTransform GetDisplayTransform() override; -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) void SetNeedsSwapSizeNotifications( bool needs_swap_size_notifications) override; #endif @@ -69,7 +70,7 @@ std::queue<std::vector<ui::LatencyInfo>> stored_latency_info_; ui::LatencyTracker latency_tracker_; -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) bool needs_swap_size_notifications_ = false; #endif
diff --git a/components/viz/service/display_embedder/viz_process_context_provider.cc b/components/viz/service/display_embedder/viz_process_context_provider.cc index 47e7214..41d744bd 100644 --- a/components/viz/service/display_embedder/viz_process_context_provider.cc +++ b/components/viz/service/display_embedder/viz_process_context_provider.cc
@@ -138,6 +138,7 @@ base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( this); } + cache_controller_->SetGrContext(nullptr); } void VizProcessContextProvider::AddRef() const {
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc index a20afa4..0807495 100644 --- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc +++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
@@ -49,7 +49,7 @@ output_surface->SetNeedsSwapSizeNotifications( params->send_swap_size_notifications); -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) // For X11, we need notify client about swap completion after resizing, so the // client can use it for synchronize with X11 WM. output_surface->SetNeedsSwapSizeNotifications(true); @@ -358,7 +358,7 @@ #if defined(OS_ANDROID) if (display_client_) display_client_->DidCompleteSwapWithSize(pixel_size); -#elif defined(USE_X11) +#elif defined(OS_LINUX) && !defined(OS_CHROMEOS) if (display_client_ && pixel_size != last_swap_pixel_size_) { last_swap_pixel_size_ = pixel_size; display_client_->DidCompleteSwapWithNewSize(last_swap_pixel_size_);
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h index 34e18572..1c9b6f5 100644 --- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h +++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.h
@@ -135,7 +135,7 @@ // to the BFS. std::unique_ptr<Display> display_; -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) gfx::Size last_swap_pixel_size_; #endif
diff --git a/components/viz/test/fake_output_surface.cc b/components/viz/test/fake_output_surface.cc index 09db4f660..b245b40 100644 --- a/components/viz/test/fake_output_surface.cc +++ b/components/viz/test/fake_output_surface.cc
@@ -107,7 +107,7 @@ return gfx::OVERLAY_TRANSFORM_NONE; } -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) void FakeOutputSurface::SetNeedsSwapSizeNotifications( bool needs_swap_size_notifications) {} #endif
diff --git a/components/viz/test/fake_output_surface.h b/components/viz/test/fake_output_surface.h index cb9a3b03..042a8d7 100644 --- a/components/viz/test/fake_output_surface.h +++ b/components/viz/test/fake_output_surface.h
@@ -11,6 +11,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/time/time.h" +#include "build/build_config.h" #include "components/viz/common/frame_sinks/begin_frame_args.h" #include "components/viz/service/display/output_surface.h" #include "components/viz/service/display/output_surface_frame.h" @@ -82,7 +83,7 @@ UpdateVSyncParametersCallback callback) override; void SetDisplayTransformHint(gfx::OverlayTransform transform) override {} gfx::OverlayTransform GetDisplayTransform() override; -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) void SetNeedsSwapSizeNotifications( bool needs_swap_size_notifications) override; #endif
diff --git a/components/webdata/common/web_database_migration_unittest.cc b/components/webdata/common/web_database_migration_unittest.cc index 1db9a9ec..278a3605 100644 --- a/components/webdata/common/web_database_migration_unittest.cc +++ b/components/webdata/common/web_database_migration_unittest.cc
@@ -1698,8 +1698,9 @@ ASSERT_TRUE(s1.Step()); // Note: This is the *wrong* ID for AUTOFILL, simulating the botched // migration in version 78. See crbug.com/895826. - ASSERT_EQ(syncer::ModelTypeToHistogramInt(syncer::AUTOFILL), - s1.ColumnInt(0)); + ASSERT_EQ( + static_cast<int>(syncer::ModelTypeHistogramValue(syncer::AUTOFILL)), + s1.ColumnInt(0)); ASSERT_EQ("storage_key1", s1.ColumnString(1)); ASSERT_EQ("blob1", s1.ColumnString(2)); @@ -1715,8 +1716,9 @@ "SELECT model_type, value FROM autofill_model_type_state")); ASSERT_TRUE(s2.Step()); // Like above: Bad value. - ASSERT_EQ(syncer::ModelTypeToHistogramInt(syncer::AUTOFILL), - s2.ColumnInt(0)); + ASSERT_EQ( + static_cast<int>(syncer::ModelTypeHistogramValue(syncer::AUTOFILL)), + s2.ColumnInt(0)); ASSERT_EQ("state1", s2.ColumnString(1)); ASSERT_TRUE(s2.Step()); // Good value.
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 53694424..e8d43be 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -826,8 +826,6 @@ "download/save_types.h", "field_trial_recorder.cc", "field_trial_recorder.h", - "file_url_loader_factory.cc", - "file_url_loader_factory.h", "fileapi/browser_file_system_helper.cc", "fileapi/browser_file_system_helper.h", "fileapi/file_system_manager_impl.cc", @@ -1087,6 +1085,8 @@ "loader/data_pipe_to_source_stream.h", "loader/download_utils_impl.cc", "loader/download_utils_impl.h", + "loader/file_url_loader_factory.cc", + "loader/file_url_loader_factory.h", "loader/merkle_integrity_source_stream.cc", "loader/merkle_integrity_source_stream.h", "loader/navigation_loader_interceptor.cc",
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc index 0b4ee87..b106731 100644 --- a/content/browser/browser_child_process_host_impl.cc +++ b/content/browser/browser_child_process_host_impl.cc
@@ -347,7 +347,6 @@ service_manager::switches::kDisableInProcessStackTraces, switches::kDisableBestEffortTasks, switches::kDisableLogging, - switches::kDisablePerfetto, switches::kEnableLogging, switches::kIPCConnectionTimeout, switches::kLogBestEffortTasks,
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index 0b77194..53cf5c2c 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc
@@ -21,6 +21,7 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/service_worker_context.h" #include "content/public/browser/shared_worker_instance.h" +#include "content/public/common/content_features.h" #include "device/gamepad/gamepad_monitor.h" #include "device/gamepad/public/mojom/gamepad.mojom.h" #include "media/capture/mojom/image_capture.mojom.h" @@ -37,9 +38,11 @@ #include "third_party/blink/public/mojom/idle/idle_manager.mojom.h" #include "third_party/blink/public/mojom/keyboard_lock/keyboard_lock.mojom.h" #include "third_party/blink/public/mojom/locks/lock_manager.mojom.h" +#include "third_party/blink/public/mojom/payments/payment_app.mojom.h" #include "third_party/blink/public/mojom/permissions/permission.mojom.h" #include "third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom.h" #include "third_party/blink/public/mojom/presentation/presentation.mojom.h" +#include "third_party/blink/public/mojom/sms/sms_receiver.mojom.h" #include "third_party/blink/public/mojom/speech/speech_synthesis.mojom.h" #include "third_party/blink/public/mojom/wake_lock/wake_lock.mojom.h" #include "third_party/blink/public/mojom/webaudio/audio_context_manager.mojom.h" @@ -53,7 +56,6 @@ #endif #if defined(OS_ANDROID) -#include "content/public/common/content_features.h" #include "services/device/public/mojom/nfc.mojom.h" #endif @@ -113,6 +115,11 @@ map->Add<blink::mojom::ScreenEnumeration>( base::BindRepeating(&ScreenEnumerationImpl::Create)); + if (base::FeatureList::IsEnabled(features::kSmsReceiver)) { + map->Add<blink::mojom::SmsReceiver>(base::BindRepeating( + &RenderFrameHostImpl::BindSmsReceiverReceiver, base::Unretained(host))); + } + map->Add<blink::mojom::LockManager>(base::BindRepeating( &RenderFrameHostImpl::CreateLockManager, base::Unretained(host))); @@ -139,6 +146,10 @@ map->Add<media::mojom::ImageCapture>( base::BindRepeating(&ImageCaptureImpl::Create)); + map->Add<payments::mojom::PaymentManager>( + base::BindRepeating(&RenderProcessHost::CreatePaymentManager, + base::Unretained(host->GetProcess()))); + map->Add<blink::mojom::WebBluetoothService>(base::BindRepeating( &RenderFrameHostImpl::CreateWebBluetoothService, base::Unretained(host))); @@ -196,14 +207,20 @@ &DedicatedWorkerHost::CreateIdleManager, base::Unretained(host))); map->Add<blink::mojom::ScreenEnumeration>( base::BindRepeating(&ScreenEnumerationImpl::Create)); + if (base::FeatureList::IsEnabled(features::kSmsReceiver)) { + map->Add<blink::mojom::SmsReceiver>(base::BindRepeating( + &DedicatedWorkerHost::BindSmsReceiverReceiver, base::Unretained(host))); + } + map->Add<payments::mojom::PaymentManager>(base::BindRepeating( + &DedicatedWorkerHost::CreatePaymentManager, base::Unretained(host))); } void PopulateBinderMapWithContext( DedicatedWorkerHost* host, service_manager::BinderMapWithContext<const url::Origin&>* map) { - map->Add<blink::mojom::LockManager>( - base::BindRepeating(&RenderProcessHost::CreateLockManager, - base::Unretained(host->GetProcessHost()))); + map->Add<blink::mojom::LockManager>(base::BindRepeating( + &RenderProcessHost::CreateLockManager, + base::Unretained(host->GetProcessHost()), MSG_ROUTING_NONE)); map->Add<blink::mojom::PermissionService>( base::BindRepeating(&RenderProcessHost::CreatePermissionService, base::Unretained(host->GetProcessHost()))); @@ -227,6 +244,8 @@ &SharedWorkerHost::CreateAppCacheBackend, base::Unretained(host))); map->Add<blink::mojom::ScreenEnumeration>( base::BindRepeating(&ScreenEnumerationImpl::Create)); + map->Add<payments::mojom::PaymentManager>(base::BindRepeating( + &SharedWorkerHost::CreatePaymentManager, base::Unretained(host))); } void PopulateBinderMapWithContext( @@ -236,9 +255,9 @@ map->Add<blink::mojom::FileSystemManager>( base::BindRepeating(&RenderProcessHost::BindFileSystemManager, base::Unretained(host->GetProcessHost()))); - map->Add<blink::mojom::LockManager>( - base::BindRepeating(&RenderProcessHost::CreateLockManager, - base::Unretained(host->GetProcessHost()))); + map->Add<blink::mojom::LockManager>(base::BindRepeating( + &RenderProcessHost::CreateLockManager, + base::Unretained(host->GetProcessHost()), MSG_ROUTING_NONE)); map->Add<blink::mojom::PermissionService>( base::BindRepeating(&RenderProcessHost::CreatePermissionService, base::Unretained(host->GetProcessHost()))); @@ -268,6 +287,9 @@ map->Add<blink::mojom::PermissionService>( base::BindRepeating(&ServiceWorkerProviderHost::CreatePermissionService, base::Unretained(host))); + map->Add<payments::mojom::PaymentManager>( + base::BindRepeating(&ServiceWorkerProviderHost::CreatePaymentManager, + base::Unretained(host))); } void PopulateBinderMapWithContext(
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index 4196b270..b25def1 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -114,7 +114,7 @@ return content::BrowserMainLoop::GetInstance()->GetFrameSinkManager(); } -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) class HostDisplayClient : public viz::HostDisplayClient { public: explicit HostDisplayClient(ui::Compositor* compositor)
diff --git a/content/browser/compositor/software_browser_compositor_output_surface.cc b/content/browser/compositor/software_browser_compositor_output_surface.cc index 31b6c038..b7938e45 100644 --- a/content/browser/compositor/software_browser_compositor_output_surface.cc +++ b/content/browser/compositor/software_browser_compositor_output_surface.cc
@@ -89,7 +89,7 @@ const gfx::Size& pixel_size) { latency_tracker_.OnGpuSwapBuffersCompleted(latency_info); client_->DidReceiveSwapBuffersAck({swap_time, swap_time}); -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) if (needs_swap_size_notifications_) client_->DidSwapWithSize(pixel_size); #endif @@ -129,7 +129,7 @@ return 0; } -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) void SoftwareBrowserCompositorOutputSurface::SetNeedsSwapSizeNotifications( bool needs_swap_size_notifications) { needs_swap_size_notifications_ = needs_swap_size_notifications;
diff --git a/content/browser/compositor/software_browser_compositor_output_surface.h b/content/browser/compositor/software_browser_compositor_output_surface.h index 45fed95..164289b 100644 --- a/content/browser/compositor/software_browser_compositor_output_surface.h +++ b/content/browser/compositor/software_browser_compositor_output_surface.h
@@ -39,7 +39,7 @@ gfx::BufferFormat GetOverlayBufferFormat() const override; uint32_t GetFramebufferCopyTextureFormat() override; unsigned UpdateGpuFence() override; -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) void SetNeedsSwapSizeNotifications( bool needs_swap_size_notifications) override; #endif @@ -55,7 +55,7 @@ base::TimeDelta refresh_interval_; ui::LatencyTracker latency_tracker_; -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) bool needs_swap_size_notifications_ = false; #endif
diff --git a/content/browser/devtools/protocol/tracing_handler.cc b/content/browser/devtools/protocol/tracing_handler.cc index 7730d55d..0cd0ca1 100644 --- a/content/browser/devtools/protocol/tracing_handler.cc +++ b/content/browser/devtools/protocol/tracing_handler.cc
@@ -249,46 +249,6 @@ DISALLOW_COPY_AND_ASSIGN(TracingSession); }; -class TracingHandler::LegacyTracingSession - : public TracingHandler::TracingSession { - public: - void EnableTracing(const base::trace_event::TraceConfig& chrome_config, - base::OnceClosure on_recording_enabled_callback) override { - DCHECK(!TracingController::GetInstance()->IsTracing()); - TracingController::GetInstance()->StartTracing( - chrome_config, std::move(on_recording_enabled_callback)); - } - - void AdoptStartupTracingSession() override { - // Nothing to do for legacy tracing here (tracing is already active). - DCHECK(TracingController::GetInstance()->IsTracing()); - } - - void ChangeTraceConfig( - const base::trace_event::TraceConfig& chrome_config) override { - TracingController::GetInstance()->StartTracing( - chrome_config, TracingController::StartTracingDoneCallback()); - } - - void DisableTracing(bool use_proto_format, - const std::string& agent_label, - const scoped_refptr<TracingController::TraceDataEndpoint>& - endpoint) override { - DCHECK(!use_proto_format); - TracingController::GetInstance()->StopTracing(endpoint, agent_label); - } - - void GetBufferUsage(base::OnceCallback<void(float percent_full, - size_t approximate_event_count)> - on_buffer_usage_callback) override { - TracingController::GetInstance()->GetTraceBufferUsage( - std::move(on_buffer_usage_callback)); - } - - bool HasTracingFailed() override { return false; } - bool HasDataLossOccurred() override { return false; } -}; - class TracingHandler::PerfettoTracingSession : public TracingHandler::TracingSession, public tracing::mojom::TracingSessionClient, @@ -586,7 +546,6 @@ return; } - DCHECK(tracing::TracingUsesPerfettoBackend()); session_ = std::make_unique<PerfettoTracingSession>(); session_->AdoptStartupTracingSession(); g_any_agent_tracing = true; @@ -743,12 +702,6 @@ bool proto_format = transfer_format.fromMaybe("") == Tracing::StreamFormatEnum::Proto; - if (proto_format && !tracing::TracingUsesPerfettoBackend()) { - callback->sendFailure(Response::Error( - "Proto format is only supported with the perfetto backend.")); - return; - } - if (proto_format && !return_as_stream) { callback->sendFailure(Response::Error( "Proto format is only supported when using stream transfer mode.")); @@ -821,11 +774,7 @@ SetupProcessFilter(gpu_pid, nullptr); - if (tracing::TracingUsesPerfettoBackend()) { - session_ = std::make_unique<PerfettoTracingSession>(); - } else { - session_ = std::make_unique<LegacyTracingSession>(); - } + session_ = std::make_unique<PerfettoTracingSession>(); session_->EnableTracing( trace_config_, base::BindOnce(&TracingHandler::OnRecordingEnabled, @@ -884,16 +833,6 @@ } Response TracingHandler::End() { - // Startup tracing triggered by --trace-config-file is a special case, where - // tracing is started automatically upon browser startup and can be stopped - // via DevTools. - // TODO(eseckler): Remove this when we remove the legacy tracing backend. - if (!tracing::TracingUsesPerfettoBackend() && IsStartupTracingActive()) { - DCHECK(!session_ && !did_initiate_recording_); - session_ = std::make_unique<LegacyTracingSession>(); - session_->AdoptStartupTracingSession(); - } - if (!session_) return Response::Error("Tracing is not started"); @@ -972,20 +911,25 @@ } void TracingHandler::RequestMemoryDump( + Maybe<bool> deterministic, std::unique_ptr<RequestMemoryDumpCallback> callback) { if (!IsTracing()) { callback->sendFailure(Response::Error("Tracing is not started")); return; } + auto determinism = deterministic.fromMaybe(false) + ? base::trace_event::MemoryDumpDeterminism::FORCE_GC + : base::trace_event::MemoryDumpDeterminism::NONE; + auto on_memory_dump_finished = base::BindOnce(&TracingHandler::OnMemoryDumpFinished, weak_factory_.GetWeakPtr(), std::move(callback)); + memory_instrumentation::MemoryInstrumentation::GetInstance() ->RequestGlobalDumpAndAppendToTrace( base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED, - base::trace_event::MemoryDumpLevelOfDetail::DETAILED, - base::trace_event::MemoryDumpDeterminism::NONE, + base::trace_event::MemoryDumpLevelOfDetail::DETAILED, determinism, std::move(on_memory_dump_finished)); }
diff --git a/content/browser/devtools/protocol/tracing_handler.h b/content/browser/devtools/protocol/tracing_handler.h index c83b585..5dcfe36 100644 --- a/content/browser/devtools/protocol/tracing_handler.h +++ b/content/browser/devtools/protocol/tracing_handler.h
@@ -73,6 +73,7 @@ Response End() override; void GetCategories(std::unique_ptr<GetCategoriesCallback> callback) override; void RequestMemoryDump( + Maybe<bool> deterministic, std::unique_ptr<RequestMemoryDumpCallback> callback) override; Response RecordClockSyncMarker(const std::string& sync_id) override;
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc index 15989dd..17c3898a 100644 --- a/content/browser/download/download_manager_impl.cc +++ b/content/browser/download/download_manager_impl.cc
@@ -40,8 +40,8 @@ #include "content/browser/data_url_loader_factory.h" #include "content/browser/devtools/devtools_instrumentation.h" #include "content/browser/download/network_download_url_loader_factory_info.h" -#include "content/browser/file_url_loader_factory.h" #include "content/browser/fileapi/file_system_url_loader_factory.h" +#include "content/browser/loader/file_url_loader_factory.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/storage_partition_impl.h" #include "content/browser/web_contents/web_contents_impl.h"
diff --git a/content/browser/download/save_file_manager.cc b/content/browser/download/save_file_manager.cc index 61dc065f..92c718d 100644 --- a/content/browser/download/save_file_manager.cc +++ b/content/browser/download/save_file_manager.cc
@@ -15,8 +15,8 @@ #include "content/browser/data_url_loader_factory.h" #include "content/browser/download/save_file.h" #include "content/browser/download/save_package.h" -#include "content/browser/file_url_loader_factory.h" #include "content/browser/fileapi/file_system_url_loader_factory.h" +#include "content/browser/loader/file_url_loader_factory.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/browser_context.h"
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 6764afb..d85525b 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -45,7 +45,6 @@ #include "content/browser/devtools/devtools_instrumentation.h" #include "content/browser/dom_storage/dom_storage_context_wrapper.h" #include "content/browser/download/mhtml_generation_manager.h" -#include "content/browser/file_url_loader_factory.h" #include "content/browser/fileapi/file_system_manager_impl.h" #include "content/browser/fileapi/file_system_url_loader_factory.h" #include "content/browser/frame_host/back_forward_cache_impl.h" @@ -66,6 +65,7 @@ #include "content/browser/generic_sensor/sensor_provider_proxy_impl.h" #include "content/browser/geolocation/geolocation_service_impl.h" #include "content/browser/interface_provider_filtering.h" +#include "content/browser/loader/file_url_loader_factory.h" #include "content/browser/loader/navigation_url_loader_impl.h" #include "content/browser/loader/prefetch_url_loader_service.h" #include "content/browser/log_console_message.h" @@ -1063,6 +1063,13 @@ if (owned_render_widget_host_) owned_render_widget_host_->ShutdownAndDestroyWidget(false); + // TODO(https://crbug.com/1005077): There is no known reason for removing the + // RenderViewHostImpl here instead of automatically at the end of the + // destructor. In practise, not doing it here will prevent android WebView to + // display a new page after a long sequence of WebView creation / deletion. + // The real reason why this is needed needs to be investigated. + render_view_host_.reset(); + // If another frame is waiting for a beforeunload ACK from this frame, // simulate it now. RenderFrameHostImpl* beforeunload_initiator = GetBeforeUnloadInitiator(); @@ -4471,11 +4478,6 @@ registry_->AddInterface(base::BindRepeating( &GetRestrictedCookieManager, base::Unretained(this), GetProcess()->GetID(), routing_id_, GetProcess()->GetStoragePartition())); - - if (base::FeatureList::IsEnabled(features::kSmsReceiver)) { - registry_->AddInterface(base::BindRepeating( - &RenderFrameHostImpl::BindSmsReceiverReceiver, base::Unretained(this))); - } } void RenderFrameHostImpl::ResetWaitingState() { @@ -6445,7 +6447,7 @@ void RenderFrameHostImpl::CreateLockManager( mojo::PendingReceiver<blink::mojom::LockManager> receiver) { - GetProcess()->CreateLockManager(GetLastCommittedOrigin(), + GetProcess()->CreateLockManager(GetRoutingID(), GetLastCommittedOrigin(), std::move(receiver)); }
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 06792b6..91251c4 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -1110,6 +1110,9 @@ void BindNFCReceiver(mojo::PendingReceiver<device::mojom::NFC> receiver); #endif + void BindSmsReceiverReceiver( + mojo::PendingReceiver<blink::mojom::SmsReceiver> receiver); + // https://mikewest.github.io/corpp/#initialize-embedder-policy-for-global network::mojom::CrossOriginEmbedderPolicy cross_origin_embedder_policy() const { @@ -1611,9 +1614,6 @@ mojo::PendingReceiver<blink::mojom::Authenticator> receiver); #endif - void BindSmsReceiverReceiver( - mojo::PendingReceiver<blink::mojom::SmsReceiver> receiver); - // service_manager::mojom::InterfaceProvider: void GetInterface(const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override; @@ -1892,7 +1892,7 @@ // // TODO(creis): RenderViewHost will eventually go away and be replaced with // some form of page context. - const scoped_refptr<RenderViewHostImpl> render_view_host_; + scoped_refptr<RenderViewHostImpl> render_view_host_; RenderFrameHostDelegate* const delegate_;
diff --git a/content/browser/file_url_loader_factory.cc b/content/browser/loader/file_url_loader_factory.cc similarity index 99% rename from content/browser/file_url_loader_factory.cc rename to content/browser/loader/file_url_loader_factory.cc index 4fedf44..d5c926c 100644 --- a/content/browser/file_url_loader_factory.cc +++ b/content/browser/loader/file_url_loader_factory.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 "content/browser/file_url_loader_factory.h" +#include "content/browser/loader/file_url_loader_factory.h" #include <memory> #include <string> @@ -491,6 +491,13 @@ return; } + if (file_access_policy == FileAccessPolicy::kRestricted && + !GetContentClient()->browser()->IsFileAccessAllowed( + path, base::MakeAbsoluteFilePath(path), profile_path)) { + OnClientComplete(net::ERR_ACCESS_DENIED, std::move(observer)); + return; + } + #if defined(OS_WIN) base::FilePath shortcut_target; if (link_following_policy == LinkFollowingPolicy::kFollow && @@ -529,13 +536,6 @@ } #endif // defined(OS_WIN) - if (file_access_policy == FileAccessPolicy::kRestricted && - !GetContentClient()->browser()->IsFileAccessAllowed( - path, base::MakeAbsoluteFilePath(path), profile_path)) { - OnClientComplete(net::ERR_ACCESS_DENIED, std::move(observer)); - return; - } - mojo::DataPipe pipe(kDefaultFileUrlPipeSize); if (!pipe.consumer_handle.is_valid()) { OnClientComplete(net::ERR_FAILED, std::move(observer));
diff --git a/content/browser/file_url_loader_factory.h b/content/browser/loader/file_url_loader_factory.h similarity index 93% rename from content/browser/file_url_loader_factory.h rename to content/browser/loader/file_url_loader_factory.h index 90a1dbb..fb6f236b 100644 --- a/content/browser/file_url_loader_factory.h +++ b/content/browser/loader/file_url_loader_factory.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 CONTENT_BROWSER_FILE_URL_LOADER_FACTORY_H_ -#define CONTENT_BROWSER_FILE_URL_LOADER_FACTORY_H_ +#ifndef CONTENT_BROWSER_LOADER_FILE_URL_LOADER_FACTORY_H_ +#define CONTENT_BROWSER_LOADER_FILE_URL_LOADER_FACTORY_H_ #include "base/files/file_path.h" #include "base/macros.h" @@ -67,4 +67,4 @@ } // namespace content -#endif // CONTENT_BROWSER_FILE_URL_LOADER_FACTORY_H_ +#endif // CONTENT_BROWSER_LOADER_FILE_URL_LOADER_FACTORY_H_
diff --git a/content/browser/loader/file_url_loader_factory_browsertest.cc b/content/browser/loader/file_url_loader_factory_browsertest.cc new file mode 100644 index 0000000..f1a303c --- /dev/null +++ b/content/browser/loader/file_url_loader_factory_browsertest.cc
@@ -0,0 +1,316 @@ +// 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. + +// This must be before Windows headers +#include "base/bind_helpers.h" +#include "build/build_config.h" + +#if defined(OS_WIN) +#include <objbase.h> +#include <shlobj.h> +#include <windows.h> +#include <wrl/client.h> +#endif + +#include <string> + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/macros.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_restrictions.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/site_instance.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/content_browser_test.h" +#include "content/public/test/content_browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" +#include "content/shell/browser/shell.h" +#include "content/test/test_content_browser_client.h" +#include "net/base/filename_util.h" +#include "net/base/net_errors.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/gtest_util.h" +#include "url/gurl.h" + +namespace content { +namespace { + +const char kSuccessTitle[] = "Title Of Awesomeness"; +const char kErrorTitle[] = "Error"; + +base::FilePath TestFilePath() { + base::ScopedAllowBlockingForTesting allow_blocking; + return GetTestFilePath("", "title2.html"); +} + +base::FilePath AbsoluteFilePath(const base::FilePath& file_path) { + base::ScopedAllowBlockingForTesting allow_blocking; + return base::MakeAbsoluteFilePath(file_path); +} + +class TestFileAccessContentBrowserClient : public TestContentBrowserClient { + public: + struct FileAccessAllowedArgs { + base::FilePath path; + base::FilePath absolute_path; + base::FilePath profile_path; + }; + + TestFileAccessContentBrowserClient() { + old_content_browser_client_ = SetBrowserClientForTesting(this); + } + + void set_blocked_path(const base::FilePath& blocked_path) { + blocked_path_ = AbsoluteFilePath(blocked_path); + } + + ~TestFileAccessContentBrowserClient() override { + EXPECT_EQ(this, SetBrowserClientForTesting(old_content_browser_client_)); + } + + bool IsFileAccessAllowed(const base::FilePath& path, + const base::FilePath& absolute_path, + const base::FilePath& profile_path) override { + access_allowed_args_.push_back( + FileAccessAllowedArgs{path, absolute_path, profile_path}); + return blocked_path_ != absolute_path; + } + + // Returns a vector of arguments passed to each invocation of + // IsFileAccessAllowed(). + const std::vector<FileAccessAllowedArgs>& access_allowed_args() const { + return access_allowed_args_; + } + + void ClearAccessAllowedArgs() { access_allowed_args_.clear(); } + + private: + ContentBrowserClient* old_content_browser_client_; + + base::FilePath blocked_path_; + + std::vector<FileAccessAllowedArgs> access_allowed_args_; + + DISALLOW_COPY_AND_ASSIGN(TestFileAccessContentBrowserClient); +}; + +// This class contains integration tests for file URLs. +class FileURLLoaderFactoryBrowserTest : public ContentBrowserTest { + public: + FileURLLoaderFactoryBrowserTest() { + EXPECT_TRUE(embedded_test_server()->Start()); + } + + base::FilePath ProfilePath() const { + return shell() + ->web_contents() + ->GetSiteInstance() + ->GetBrowserContext() + ->GetPath(); + } +}; + +IN_PROC_BROWSER_TEST_F(FileURLLoaderFactoryBrowserTest, Basic) { + TestFileAccessContentBrowserClient test_browser_client; + EXPECT_TRUE(NavigateToURL(shell(), net::FilePathToFileURL(TestFilePath()))); + EXPECT_EQ(base::ASCIIToUTF16(kSuccessTitle), + shell()->web_contents()->GetTitle()); + + ASSERT_EQ(1u, test_browser_client.access_allowed_args().size()); + EXPECT_EQ(TestFilePath(), test_browser_client.access_allowed_args()[0].path); + EXPECT_EQ(AbsoluteFilePath(TestFilePath()), + test_browser_client.access_allowed_args()[0].absolute_path); + EXPECT_EQ(ProfilePath(), + test_browser_client.access_allowed_args()[0].profile_path); +} + +IN_PROC_BROWSER_TEST_F(FileURLLoaderFactoryBrowserTest, FileAccessNotAllowed) { + TestFileAccessContentBrowserClient test_browser_client; + test_browser_client.set_blocked_path(TestFilePath()); + + TestNavigationObserver navigation_observer(shell()->web_contents()); + EXPECT_FALSE(NavigateToURL(shell(), net::FilePathToFileURL(TestFilePath()))); + EXPECT_FALSE(navigation_observer.last_navigation_succeeded()); + EXPECT_THAT(navigation_observer.last_net_error_code(), + net::test::IsError(net::ERR_ACCESS_DENIED)); + EXPECT_EQ(net::FilePathToFileURL(TestFilePath()), + shell()->web_contents()->GetURL()); + EXPECT_EQ(base::ASCIIToUTF16(kErrorTitle), + shell()->web_contents()->GetTitle()); + + ASSERT_EQ(1u, test_browser_client.access_allowed_args().size()); + EXPECT_EQ(TestFilePath(), test_browser_client.access_allowed_args()[0].path); + EXPECT_EQ(AbsoluteFilePath(TestFilePath()), + test_browser_client.access_allowed_args()[0].absolute_path); + EXPECT_EQ(ProfilePath(), + test_browser_client.access_allowed_args()[0].profile_path); +} + +#if defined(OS_POSIX) + +// Test symbolic links on POSIX platforms. These act like the contents of +// the symbolic link are the same as the contents of the file it links to. +IN_PROC_BROWSER_TEST_F(FileURLLoaderFactoryBrowserTest, SymlinksToFiles) { + TestFileAccessContentBrowserClient test_browser_client; + + base::ScopedAllowBlockingForTesting allow_blocking; + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + + // Get an absolute path since |temp_dir| can contain a symbolic link. + base::FilePath absolute_temp_dir = AbsoluteFilePath(temp_dir.GetPath()); + + // MIME sniffing uses the symbolic link's path, so this needs to end in + // ".html" for it to be sniffed as HTML. + base::FilePath sym_link = absolute_temp_dir.AppendASCII("link.html"); + ASSERT_TRUE( + base::CreateSymbolicLink(AbsoluteFilePath(TestFilePath()), sym_link)); + + EXPECT_TRUE(NavigateToURL(shell(), net::FilePathToFileURL(sym_link))); + EXPECT_EQ(base::ASCIIToUTF16(kSuccessTitle), + shell()->web_contents()->GetTitle()); + + ASSERT_EQ(1u, test_browser_client.access_allowed_args().size()); + EXPECT_EQ(sym_link, test_browser_client.access_allowed_args()[0].path); + EXPECT_EQ(AbsoluteFilePath(sym_link), + test_browser_client.access_allowed_args()[0].absolute_path); + EXPECT_EQ(ProfilePath(), + test_browser_client.access_allowed_args()[0].profile_path); + + // Test the case where access to the destination URL is blocked. Note that + // this is the same as blocking the symbolic link URL - the + // IsFileAccessAllowed() is passed both the symbolic link path and the + // absolute path, so rejecting on looks just like rejecting the other. + + test_browser_client.ClearAccessAllowedArgs(); + test_browser_client.set_blocked_path(TestFilePath()); + + TestNavigationObserver navigation_observer3(shell()->web_contents()); + EXPECT_FALSE(NavigateToURL(shell(), net::FilePathToFileURL(sym_link))); + EXPECT_FALSE(navigation_observer3.last_navigation_succeeded()); + EXPECT_THAT(navigation_observer3.last_net_error_code(), + net::test::IsError(net::ERR_ACCESS_DENIED)); + EXPECT_EQ(net::FilePathToFileURL(sym_link), + shell()->web_contents()->GetURL()); + EXPECT_EQ(base::ASCIIToUTF16(kErrorTitle), + shell()->web_contents()->GetTitle()); + + ASSERT_EQ(1u, test_browser_client.access_allowed_args().size()); + EXPECT_EQ(sym_link, test_browser_client.access_allowed_args()[0].path); + EXPECT_EQ(AbsoluteFilePath(sym_link), + test_browser_client.access_allowed_args()[0].absolute_path); + EXPECT_EQ(ProfilePath(), + test_browser_client.access_allowed_args()[0].profile_path); +} + +#elif defined(OS_WIN) + +// Test shortcuts on Windows. These are treated as redirects. +IN_PROC_BROWSER_TEST_F(FileURLLoaderFactoryBrowserTest, ResolveShortcutTest) { + TestFileAccessContentBrowserClient test_browser_client; + + // Create an empty temp directory, to be sure there's no file in it. + base::ScopedAllowBlockingForTesting allow_blocking; + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + + base::FilePath lnk_path = + temp_dir.GetPath().Append(FILE_PATH_LITERAL("foo.lnk")); + + base::FilePath test = TestFilePath(); + + // Create a shortcut for the test. + { + Microsoft::WRL::ComPtr<IShellLink> shell; + ASSERT_TRUE(SUCCEEDED(::CoCreateInstance( + CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shell)))); + Microsoft::WRL::ComPtr<IPersistFile> persist; + ASSERT_TRUE(SUCCEEDED(shell.As<IPersistFile>(&persist))); + EXPECT_TRUE( + SUCCEEDED(shell->SetPath(base::as_wcstr(TestFilePath().value())))); + EXPECT_TRUE(SUCCEEDED(shell->SetDescription(L"ResolveShortcutTest"))); + base::string16 lnk_string = lnk_path.value(); + EXPECT_TRUE(SUCCEEDED(persist->Save(base::as_wcstr(lnk_string), TRUE))); + } + + EXPECT_TRUE(NavigateToURL( + shell(), net::FilePathToFileURL(lnk_path), + net::FilePathToFileURL(TestFilePath()) /* expect_commit_url */)); + EXPECT_EQ(base::ASCIIToUTF16(kSuccessTitle), + shell()->web_contents()->GetTitle()); + + ASSERT_EQ(2u, test_browser_client.access_allowed_args().size()); + EXPECT_EQ(lnk_path, test_browser_client.access_allowed_args()[0].path); + EXPECT_EQ(AbsoluteFilePath(lnk_path), + test_browser_client.access_allowed_args()[0].absolute_path); + EXPECT_EQ(ProfilePath(), + test_browser_client.access_allowed_args()[0].profile_path); + + EXPECT_EQ(TestFilePath(), test_browser_client.access_allowed_args()[1].path); + EXPECT_EQ(AbsoluteFilePath(TestFilePath()), + test_browser_client.access_allowed_args()[1].absolute_path); + EXPECT_EQ(ProfilePath(), + test_browser_client.access_allowed_args()[1].profile_path); + + // Test the case where access to the shortcut URL is blocked. Should display + // an error page at the shortcut's file URL. + + test_browser_client.ClearAccessAllowedArgs(); + test_browser_client.set_blocked_path(lnk_path); + + TestNavigationObserver navigation_observer2(shell()->web_contents()); + EXPECT_FALSE(NavigateToURL(shell(), net::FilePathToFileURL(lnk_path))); + EXPECT_FALSE(navigation_observer2.last_navigation_succeeded()); + EXPECT_THAT(navigation_observer2.last_net_error_code(), + net::test::IsError(net::ERR_ACCESS_DENIED)); + EXPECT_EQ(net::FilePathToFileURL(lnk_path), + shell()->web_contents()->GetURL()); + EXPECT_EQ(base::ASCIIToUTF16(kErrorTitle), + shell()->web_contents()->GetTitle()); + + ASSERT_EQ(1u, test_browser_client.access_allowed_args().size()); + EXPECT_EQ(lnk_path, test_browser_client.access_allowed_args()[0].path); + EXPECT_EQ(AbsoluteFilePath(lnk_path), + test_browser_client.access_allowed_args()[0].absolute_path); + EXPECT_EQ(ProfilePath(), + test_browser_client.access_allowed_args()[0].profile_path); + + // Test the case where access to the destination URL is blocked. The redirect + // is followed, so this should end up at the shortcut destination, but + // displaying an error. + + test_browser_client.ClearAccessAllowedArgs(); + test_browser_client.set_blocked_path(TestFilePath()); + + TestNavigationObserver navigation_observer3(shell()->web_contents()); + EXPECT_FALSE(NavigateToURL(shell(), net::FilePathToFileURL(lnk_path))); + EXPECT_FALSE(navigation_observer3.last_navigation_succeeded()); + EXPECT_THAT(navigation_observer3.last_net_error_code(), + net::test::IsError(net::ERR_ACCESS_DENIED)); + EXPECT_EQ(net::FilePathToFileURL(TestFilePath()), + shell()->web_contents()->GetURL()); + EXPECT_EQ(base::ASCIIToUTF16(kErrorTitle), + shell()->web_contents()->GetTitle()); + + ASSERT_EQ(2u, test_browser_client.access_allowed_args().size()); + EXPECT_EQ(lnk_path, test_browser_client.access_allowed_args()[0].path); + EXPECT_EQ(AbsoluteFilePath(lnk_path), + test_browser_client.access_allowed_args()[0].absolute_path); + EXPECT_EQ(ProfilePath(), + test_browser_client.access_allowed_args()[0].profile_path); + + EXPECT_EQ(TestFilePath(), test_browser_client.access_allowed_args()[1].path); + EXPECT_EQ(AbsoluteFilePath(TestFilePath()), + test_browser_client.access_allowed_args()[1].absolute_path); + EXPECT_EQ(ProfilePath(), + test_browser_client.access_allowed_args()[1].profile_path); +} + +#endif // defined(OS_WIN) + +} // namespace +} // namespace content
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index 3d607d0..e40a0b3 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -24,10 +24,10 @@ #include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/data_url_loader_factory.h" #include "content/browser/devtools/devtools_instrumentation.h" -#include "content/browser/file_url_loader_factory.h" #include "content/browser/fileapi/file_system_url_loader_factory.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/frame_host/navigation_request_info.h" +#include "content/browser/loader/file_url_loader_factory.h" #include "content/browser/loader/navigation_loader_interceptor.h" #include "content/browser/loader/navigation_url_loader_delegate.h" #include "content/browser/loader/prefetch_url_loader_service.h"
diff --git a/content/browser/locks/lock_manager.cc b/content/browser/locks/lock_manager.cc index a927af3..d51862d 100644 --- a/content/browser/locks/lock_manager.cc +++ b/content/browser/locks/lock_manager.cc
@@ -307,7 +307,9 @@ LockManager* lock_manager_; }; -void LockManager::CreateService( +void LockManager::BindReceiver( + int render_process_id, + int render_frame_id, const url::Origin& origin, mojo::PendingReceiver<blink::mojom::LockManager> receiver) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -316,7 +318,8 @@ // and be the same opaque string seen in Service Worker client ids. const std::string client_id = base::GenerateGUID(); - receivers_.Add(this, std::move(receiver), {origin, client_id}); + receivers_.Add(this, std::move(receiver), + {client_id, render_process_id, render_frame_id, origin}); } void LockManager::RequestLock(
diff --git a/content/browser/locks/lock_manager.h b/content/browser/locks/lock_manager.h index af713df47..25ed9c95 100644 --- a/content/browser/locks/lock_manager.h +++ b/content/browser/locks/lock_manager.h
@@ -26,8 +26,13 @@ public: LockManager(); - void CreateService(const url::Origin& origin, - mojo::PendingReceiver<blink::mojom::LockManager> receiver); + // Binds |receiver| to this LockManager. |receiver| belongs to a frame or + // worker at |origin| hosted by |render_process_id|. If it belongs to a frame, + // |render_frame_id| identifies it, otherwise it is MSG_ROUTING_NONE. + void BindReceiver(int render_process_id, + int render_frame_id, + const url::Origin& origin, + mojo::PendingReceiver<blink::mojom::LockManager> receiver); // Request a lock. When the lock is acquired, |callback| will be invoked with // a LockHandle. @@ -56,8 +61,17 @@ // State for each client held in |receivers_|. struct ReceiverState { - url::Origin origin; std::string client_id; + + // Process owning this receiver. + int render_process_id; + + // Frame owning this receiver. MSG_ROUTING_NONE if the receiver is owned by + // a worker. + int render_frame_id; + + // Origin of the frame or worker owning this receiver. + url::Origin origin; }; bool IsGrantable(const url::Origin& origin,
diff --git a/content/browser/payments/payment_manager.cc b/content/browser/payments/payment_manager.cc index 9ffb7b6a..1739040 100644 --- a/content/browser/payments/payment_manager.cc +++ b/content/browser/payments/payment_manager.cc
@@ -25,13 +25,13 @@ PaymentManager::PaymentManager( PaymentAppContextImpl* payment_app_context, - mojo::InterfaceRequest<payments::mojom::PaymentManager> request) + mojo::PendingReceiver<payments::mojom::PaymentManager> receiver) : payment_app_context_(payment_app_context), - binding_(this, std::move(request)) { + receiver_(this, std::move(receiver)) { DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); DCHECK(payment_app_context); - binding_.set_connection_error_handler(base::BindOnce( + receiver_.set_disconnect_handler(base::BindOnce( &PaymentManager::OnConnectionError, weak_ptr_factory_.GetWeakPtr())); } @@ -43,15 +43,15 @@ scope_ = GURL(scope); if (!context_url_.is_valid()) { - binding_.CloseWithReason(0U, "Invalid context URL."); + receiver_.ResetWithReason(0U, "Invalid context URL."); return; } if (!scope_.is_valid()) { - binding_.CloseWithReason(1U, "Invalid scope URL."); + receiver_.ResetWithReason(1U, "Invalid scope URL."); return; } if (!url::IsSameOriginWith(context_url_, scope_)) { - binding_.CloseWithReason( + receiver_.ResetWithReason( 2U, "Scope URL is not from the same origin of the context URL."); return; }
diff --git a/content/browser/payments/payment_manager.h b/content/browser/payments/payment_manager.h index 3d0029f..1c778a36 100644 --- a/content/browser/payments/payment_manager.h +++ b/content/browser/payments/payment_manager.h
@@ -10,7 +10,8 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "content/common/content_export.h" -#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver.h" #include "third_party/blink/public/mojom/payments/payment_app.mojom.h" #include "url/gurl.h" @@ -22,7 +23,7 @@ public: PaymentManager( PaymentAppContextImpl* payment_app_context, - mojo::InterfaceRequest<payments::mojom::PaymentManager> request); + mojo::PendingReceiver<payments::mojom::PaymentManager> receiver); ~PaymentManager() override; @@ -52,7 +53,7 @@ const std::vector<payments::mojom::PaymentDelegation>& delegations, EnableDelegationsCallback callback) override; - // Called when an error is detected on binding_. + // Called when an error is detected on receiver_. void OnConnectionError(); void SetPaymentInstrumentIntermediateCallback( @@ -65,7 +66,7 @@ bool should_set_payment_app_info_; GURL context_url_; GURL scope_; - mojo::Binding<payments::mojom::PaymentManager> binding_; + mojo::Receiver<payments::mojom::PaymentManager> receiver_; base::WeakPtrFactory<PaymentManager> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(PaymentManager); };
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 2e38480..82ecd362 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -33,6 +33,7 @@ #include "cc/base/switches.h" #include "cc/input/input_handler.h" #include "cc/layers/layer.h" +#include "cc/metrics/begin_main_frame_metrics.h" #include "cc/mojo_embedder/async_layer_tree_frame_sink.h" #include "cc/resources/ui_resource_manager.h" #include "cc/trees/layer_tree_host.h" @@ -701,6 +702,11 @@ root_window_->OnCompositingDidCommit(); } +std::unique_ptr<cc::BeginMainFrameMetrics> +CompositorImpl::GetBeginMainFrameMetrics() { + return nullptr; +} + void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) { readback_layer_tree_->AddChild(layer); }
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h index a4ad3e64..c799299 100644 --- a/content/browser/renderer_host/compositor_impl_android.h +++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -135,6 +135,8 @@ const gfx::PresentationFeedback& feedback) override {} void RecordStartOfFrameMetrics() override {} void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) override {} + std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics() + override; // LayerTreeHostSingleThreadClient implementation. void DidSubmitCompositorFrame() override;
diff --git a/content/browser/renderer_host/input/fling_controller.cc b/content/browser/renderer_host/input/fling_controller.cc index 7776167..02df77f 100644 --- a/content/browser/renderer_host/input/fling_controller.cc +++ b/content/browser/renderer_host/input/fling_controller.cc
@@ -96,17 +96,22 @@ bool FlingController::ObserveAndMaybeConsumeGestureEvent( const GestureEventWithLatencyInfo& gesture_event) { + TRACE_EVENT0("input", "FlingController::ObserveAndMaybeConsumeGestureEvent"); // FlingCancel events arrive when a finger is touched down regardless of // whether there is an ongoing fling. These can affect state so if there's no // on-going fling we should just discard these without letting the rest of // the fling system see it. if (gesture_event.event.GetType() == WebInputEvent::kGestureFlingCancel && !fling_curve_) { + TRACE_EVENT_INSTANT0("input", "NoActiveFling", TRACE_EVENT_SCOPE_THREAD); return true; } - if (ObserveAndFilterForTapSuppression(gesture_event)) + if (ObserveAndFilterForTapSuppression(gesture_event)) { + TRACE_EVENT_INSTANT0("input", "FilterTapSuppression", + TRACE_EVENT_SCOPE_THREAD); return true; + } if (gesture_event.event.GetType() == WebInputEvent::kGestureScrollUpdate) { last_seen_scroll_update_ = gesture_event.event.TimeStamp();
diff --git a/content/browser/renderer_host/input/gesture_event_queue.cc b/content/browser/renderer_host/input/gesture_event_queue.cc index 412bb16..d318665 100644 --- a/content/browser/renderer_host/input/gesture_event_queue.cc +++ b/content/browser/renderer_host/input/gesture_event_queue.cc
@@ -56,7 +56,6 @@ bool GestureEventQueue::PassToFlingController( const GestureEventWithLatencyInfo& gesture_event) { - TRACE_EVENT0("input", "GestureEventQueue::QueueEvent"); return fling_controller_.ObserveAndMaybeConsumeGestureEvent(gesture_event); }
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 93d8f72..23ebf96 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1941,11 +1941,12 @@ } void RenderProcessHostImpl::CreateLockManager( + int render_frame_id, const url::Origin& origin, mojo::PendingReceiver<blink::mojom::LockManager> receiver) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - storage_partition_impl_->GetLockManager()->CreateService(origin, - std::move(receiver)); + storage_partition_impl_->GetLockManager()->BindReceiver( + GetID(), render_frame_id, origin, std::move(receiver)); } void RenderProcessHostImpl::CreatePermissionService( @@ -1956,6 +1957,13 @@ std::move(receiver)); } +void RenderProcessHostImpl::CreatePaymentManager( + mojo::PendingReceiver<payments::mojom::PaymentManager> receiver) { + static_cast<StoragePartitionImpl*>(GetStoragePartition()) + ->GetPaymentAppContext() + ->CreatePaymentManager(std::move(receiver)); +} + void RenderProcessHostImpl::CancelProcessShutdownDelayForUnload() { if (IsKeepAliveRefCountDisabled()) return; @@ -3000,7 +3008,6 @@ switches::kEnableDeJelly, switches::kDisableOriginTrialControlledBlinkFeatures, switches::kDisablePepper3DImageChromium, - switches::kDisablePerfetto, switches::kDisablePermissionsAPI, switches::kDisablePresentationAPI, switches::kDisableRGBA4444Textures,
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index b92bf6c3..a826a1e 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -505,10 +505,14 @@ return file_system_manager_impl_.get(); } - // Binds |receiver| to the LockManager instance owned by - // |storage_partition_impl_|, and is used by frames and workers via - // BrowserInterfaceBroker. + // Binds |receiver| to the LockManager owned by |storage_partition_impl_|. + // |receiver| belongs to a frame or worker at |origin| hosted by this process. + // If it belongs to a frame, |render_frame_id| identifies it, otherwise it is + // MSG_ROUTING_NONE. + // + // Used by frames and workers via BrowserInterfaceBroker. void CreateLockManager( + int render_frame_id, const url::Origin& origin, mojo::PendingReceiver<blink::mojom::LockManager> receiver) override; @@ -519,6 +523,12 @@ const url::Origin& origin, mojo::PendingReceiver<blink::mojom::PermissionService> receiver) override; + // Binds |receiver| to the PaymentManager instance owned by + // |storage_partition_impl_|, and is used by workers via + // BrowserInterfaceBroker. + void CreatePaymentManager( + mojo::PendingReceiver<payments::mojom::PaymentManager> receiver) override; + // Adds a CORB (Cross-Origin Read Blocking) exception for |process_id|. The // exception will be removed when the corresponding RenderProcessHostImpl is // destroyed (see |cleanup_corb_exception_for_plugin_upon_destruction_|).
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 64577267..3e006ec 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -636,8 +636,10 @@ } gfx::Size RenderWidgetHostViewAndroid::GetVisibleViewportSize() { + int pinned_bottom_adjust_dps = + std::max(0, (int)(view_.GetViewportInsetBottom() / view_.GetDipScale())); gfx::Rect requested_rect(GetRequestedRendererSize()); - requested_rect.Inset(gfx::Insets(0, 0, view_.GetViewportInsetBottom(), 0)); + requested_rect.Inset(gfx::Insets(0, 0, pinned_bottom_adjust_dps, 0)); return requested_rect.size(); }
diff --git a/content/browser/renderer_interface_binders.cc b/content/browser/renderer_interface_binders.cc index aad43961..7e58737 100644 --- a/content/browser/renderer_interface_binders.cc +++ b/content/browser/renderer_interface_binders.cc
@@ -16,7 +16,6 @@ #include "content/browser/gpu/gpu_process_host.h" #include "content/browser/native_file_system/native_file_system_manager_impl.h" #include "content/browser/notifications/platform_notification_context_impl.h" -#include "content/browser/payments/payment_manager.h" #include "content/browser/permissions/permission_service_context.h" #include "content/browser/quota_dispatcher_host.h" #include "content/browser/renderer_host/render_process_host_impl.h" @@ -160,13 +159,6 @@ parameterized_binder_registry_.AddInterface( base::BindRepeating(CreateWebSocketConnector)); - parameterized_binder_registry_.AddInterface(base::Bind( - [](mojo::PendingReceiver<payments::mojom::PaymentManager> receiver, - RenderProcessHost* host, const url::Origin& origin) { - static_cast<StoragePartitionImpl*>(host->GetStoragePartition()) - ->GetPaymentAppContext() - ->CreatePaymentManager(std::move(receiver)); - })); parameterized_binder_registry_.AddInterface(base::BindRepeating( [](mojo::PendingReceiver<blink::mojom::CacheStorage> receiver, RenderProcessHost* host, const url::Origin& origin) {
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc index 18b1987..3bdb94b 100644 --- a/content/browser/service_worker/embedded_worker_instance.cc +++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -720,8 +720,6 @@ params->worker_devtools_agent_route_id = MSG_ROUTING_NONE; params->wait_for_debugger = false; - params->v8_cache_options = GetV8CacheOptions(); - params->subresource_loader_updater = subresource_loader_updater_.BindNewPipeAndPassReceiver();
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index 234e700..36ec9013 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -96,7 +96,7 @@ if (!process) return; - process->CreateLockManager(origin, std::move(receiver)); + process->CreateLockManager(MSG_ROUTING_NONE, origin, std::move(receiver)); } void CreatePermissionServiceImpl( @@ -111,6 +111,17 @@ process->CreatePermissionService(origin, std::move(receiver)); } +void CreatePaymentManagerImpl( + int process_id, + mojo::PendingReceiver<payments::mojom::PaymentManager> receiver) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + auto* process = RenderProcessHost::FromID(process_id); + if (!process) + return; + + process->CreatePaymentManager(std::move(receiver)); +} + ServiceWorkerMetrics::EventType PurposeToEventType( blink::mojom::ControllerServiceWorkerPurpose purpose) { switch (purpose) { @@ -1424,6 +1435,16 @@ render_process_id_, std::move(receiver))); } +void ServiceWorkerProviderHost::CreatePaymentManager( + mojo::PendingReceiver<payments::mojom::PaymentManager> receiver) { + DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); + DCHECK(IsProviderForServiceWorker()); + RunOrPostTaskOnThread( + FROM_HERE, BrowserThread::UI, + base::BindOnce(&CreatePaymentManagerImpl, render_process_id_, + std::move(receiver))); +} + void ServiceWorkerProviderHost::SetExecutionReady() { DCHECK(!is_execution_ready()); TransitionToClientPhase(ClientPhase::kExecutionReady);
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h index df3f161..f896495 100644 --- a/content/browser/service_worker/service_worker_provider_host.h +++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -36,7 +36,8 @@ #include "services/network/public/mojom/fetch_api.mojom.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" #include "third_party/blink/public/mojom/locks/lock_manager.mojom-forward.h" -#include "third_party/blink/public/mojom/permissions/permission.mojom.h" +#include "third_party/blink/public/mojom/payments/payment_app.mojom-forward.h" +#include "third_party/blink/public/mojom/permissions/permission.mojom-forward.h" #include "third_party/blink/public/mojom/service_worker/service_worker_container.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h" @@ -431,6 +432,11 @@ void CreatePermissionService( mojo::PendingReceiver<blink::mojom::PermissionService> receiver); + // For service worker execution contexts. Forwards |receiver| to the process + // host on the UI thread. + void CreatePaymentManager( + mojo::PendingReceiver<payments::mojom::PaymentManager> receiver); + private: // For service worker clients. The flow is kInitial -> kResponseCommitted -> // kExecutionReady.
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc index ad160d5d6..bbc5fc0 100644 --- a/content/browser/service_worker/service_worker_version_unittest.cc +++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -104,15 +104,6 @@ protected: using FetchHandlerExistence = blink::mojom::FetchHandlerExistence; - struct RunningStateListener : public ServiceWorkerVersion::Observer { - RunningStateListener() : last_status(EmbeddedWorkerStatus::STOPPED) {} - ~RunningStateListener() override {} - void OnRunningStateChanged(ServiceWorkerVersion* version) override { - last_status = version->running_status(); - } - EmbeddedWorkerStatus last_status; - }; - struct CachedMetadataUpdateListener : public ServiceWorkerVersion::Observer { CachedMetadataUpdateListener() = default; ~CachedMetadataUpdateListener() override = default;
diff --git a/content/browser/tracing/background_tracing_active_scenario.cc b/content/browser/tracing/background_tracing_active_scenario.cc index fb390be..5014f622 100644 --- a/content/browser/tracing/background_tracing_active_scenario.cc +++ b/content/browser/tracing/background_tracing_active_scenario.cc
@@ -81,8 +81,7 @@ #if !defined(OS_ANDROID) // TODO(crbug.com/941318): Re-enable startup tracing for Android once all // Perfetto-related deadlocks are resolved. - if (!TracingControllerImpl::GetInstance()->IsTracing() && - tracing::TracingUsesPerfettoBackend()) { + if (!TracingControllerImpl::GetInstance()->IsTracing()) { tracing::TraceEventDataSource::GetInstance()->SetupStartupTracing( /*privacy_filtering_enabled=*/true); } @@ -196,8 +195,7 @@ #if !defined(OS_ANDROID) // TODO(crbug.com/941318): Re-enable startup tracing for Android once all // Perfetto-related deadlocks are resolved. - if (!TracingControllerImpl::GetInstance()->IsTracing() && - tracing::TracingUsesPerfettoBackend()) { + if (!TracingControllerImpl::GetInstance()->IsTracing()) { tracing::TraceEventDataSource::GetInstance()->SetupStartupTracing( /*privacy_filtering_enabled=*/false); }
diff --git a/content/browser/tracing/background_tracing_manager_browsertest.cc b/content/browser/tracing/background_tracing_manager_browsertest.cc index 390d9b1..fd1a1b96 100644 --- a/content/browser/tracing/background_tracing_manager_browsertest.cc +++ b/content/browser/tracing/background_tracing_manager_browsertest.cc
@@ -1616,8 +1616,7 @@ public: ProtoBackgroundTracingTest() { scoped_feature_list_.InitWithFeatures( - /*enabled_features=*/{features::kTracingPerfettoBackend, - features::kBackgroundTracingProtoOutput}, + /*enabled_features=*/{features::kBackgroundTracingProtoOutput}, /*disabled_features=*/{}); }
diff --git a/content/browser/tracing/startup_tracing_browsertest.cc b/content/browser/tracing/startup_tracing_browsertest.cc index 75fead8..f03ea41 100644 --- a/content/browser/tracing/startup_tracing_browsertest.cc +++ b/content/browser/tracing/startup_tracing_browsertest.cc
@@ -94,8 +94,7 @@ public: StartupTracingInProcessTest() { scoped_feature_list_.InitWithFeatures( - /*enabled_features=*/{features::kTracingPerfettoBackend, - features::kTracingServiceInProcess}, + /*enabled_features=*/{features::kTracingServiceInProcess}, /*disabled_features=*/{}); }
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc index 0123f12..a1a4c59 100644 --- a/content/browser/tracing/tracing_controller_impl.cc +++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -234,16 +234,6 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); auto metadata_dict = std::make_unique<base::DictionaryValue>(); - // trace_config_ can be null if the tracing controller finishes flushing - // traces before the Chrome tracing agent finishes flushing traces. Normally, - // 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_ && !tracing::TracingUsesPerfettoBackend()) { - DCHECK(IsTracing()); - metadata_dict->SetString("trace-config", trace_config_->ToString()); - } - metadata_dict->SetString("network-type", GetNetworkTypeString()); metadata_dict->SetString("product-version", GetContentClient()->browser()->GetProduct());
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index c0d8053..5c996179 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3667,13 +3667,15 @@ render_view_host->GetRoutingID(), history_offset, history_length)); } -void WebContentsImpl::ReloadFocusedFrame(bool bypass_cache) { +void WebContentsImpl::ReloadFocusedFrame() { RenderFrameHost* focused_frame = GetFocusedFrame(); if (!focused_frame) return; - focused_frame->Send(new FrameMsg_Reload( - focused_frame->GetRoutingID(), bypass_cache)); + // TODO(https://crbug.com/995428). This function is deprecated. Navigations + // are handled from the browser process. There is no need to send an IPC to + // the renderer process for this. + focused_frame->Send(new FrameMsg_Reload(focused_frame->GetRoutingID())); } std::vector<mojo::Remote<blink::mojom::PauseSubresourceLoadingHandle>>
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index d260705..72f7570 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -395,7 +395,7 @@ void Stop() override; void SetPageFrozen(bool frozen) override; std::unique_ptr<WebContents> Clone() override; - void ReloadFocusedFrame(bool bypass_cache) override; + void ReloadFocusedFrame() override; void Undo() override; void Redo() override; void Cut() override;
diff --git a/content/browser/worker_host/dedicated_worker_host.cc b/content/browser/worker_host/dedicated_worker_host.cc index 57848544..232de7e2 100644 --- a/content/browser/worker_host/dedicated_worker_host.cc +++ b/content/browser/worker_host/dedicated_worker_host.cc
@@ -426,6 +426,28 @@ ->CreateService(std::move(receiver)); } +void DedicatedWorkerHost::CreatePaymentManager( + mojo::PendingReceiver<payments::mojom::PaymentManager> receiver) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + RenderProcessHost* worker_process_host = GetProcessHost(); + if (!worker_process_host) + return; + worker_process_host->CreatePaymentManager(std::move(receiver)); +} + +void DedicatedWorkerHost::BindSmsReceiverReceiver( + mojo::PendingReceiver<blink::mojom::SmsReceiver> receiver) { + RenderFrameHostImpl* ancestor_render_frame_host = + GetAncestorRenderFrameHost(); + if (!ancestor_render_frame_host) { + // The ancestor frame may have already been closed. In that case, the worker + // will soon be terminated too, so abort the connection. + return; + } + + ancestor_render_frame_host->BindSmsReceiverReceiver(std::move(receiver)); +} + void DedicatedWorkerHost::ObserveNetworkServiceCrash( StoragePartitionImpl* storage_partition_impl) { auto params = network::mojom::URLLoaderFactoryParams::New();
diff --git a/content/browser/worker_host/dedicated_worker_host.h b/content/browser/worker_host/dedicated_worker_host.h index bb0b7dc0..58c1d326 100644 --- a/content/browser/worker_host/dedicated_worker_host.h +++ b/content/browser/worker_host/dedicated_worker_host.h
@@ -15,6 +15,8 @@ #include "services/service_manager/public/mojom/interface_provider.mojom.h" #include "third_party/blink/public/mojom/filesystem/file_system.mojom-forward.h" #include "third_party/blink/public/mojom/idle/idle_manager.mojom-forward.h" +#include "third_party/blink/public/mojom/payments/payment_app.mojom-forward.h" +#include "third_party/blink/public/mojom/sms/sms_receiver.mojom-forward.h" #include "third_party/blink/public/mojom/usb/web_usb_service.mojom-forward.h" #include "third_party/blink/public/mojom/websockets/websocket_connector.mojom-forward.h" #include "third_party/blink/public/mojom/worker/dedicated_worker_host.mojom.h" @@ -68,6 +70,10 @@ mojo::PendingReceiver<blink::mojom::FileSystemManager> receiver); void CreateIdleManager( mojo::PendingReceiver<blink::mojom::IdleManager> receiver); + void CreatePaymentManager( + mojo::PendingReceiver<payments::mojom::PaymentManager> receiver); + void BindSmsReceiverReceiver( + mojo::PendingReceiver<blink::mojom::SmsReceiver> receiver); // service_manager::mojom::InterfaceProvider: void GetInterface(const std::string& interface_name,
diff --git a/content/browser/worker_host/shared_worker_host.cc b/content/browser/worker_host/shared_worker_host.cc index ee1860ef..7c6e733 100644 --- a/content/browser/worker_host/shared_worker_host.cc +++ b/content/browser/worker_host/shared_worker_host.cc
@@ -347,6 +347,15 @@ worker_process_host->GetID(), MSG_ROUTING_NONE, std::move(receiver)); } +void SharedWorkerHost::CreatePaymentManager( + mojo::PendingReceiver<payments::mojom::PaymentManager> receiver) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + RenderProcessHost* worker_process_host = GetProcessHost(); + if (!worker_process_host) + return; + worker_process_host->CreatePaymentManager(std::move(receiver)); +} + void SharedWorkerHost::Destruct() { // Ask the service to destroy |this| which will terminate the worker. service_->DestroyHost(this);
diff --git a/content/browser/worker_host/shared_worker_host.h b/content/browser/worker_host/shared_worker_host.h index 1cb5ccfd..6ea3666 100644 --- a/content/browser/worker_host/shared_worker_host.h +++ b/content/browser/worker_host/shared_worker_host.h
@@ -28,6 +28,7 @@ #include "services/network/public/mojom/url_loader_factory.mojom.h" #include "services/service_manager/public/mojom/interface_provider.mojom.h" #include "third_party/blink/public/mojom/devtools/devtools_agent.mojom.h" +#include "third_party/blink/public/mojom/payments/payment_app.mojom-forward.h" #include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom.h" #include "third_party/blink/public/mojom/worker/shared_worker.mojom.h" #include "third_party/blink/public/mojom/worker/shared_worker_client.mojom.h" @@ -109,6 +110,8 @@ void CreateAppCacheBackend( mojo::PendingReceiver<blink::mojom::AppCacheBackend> receiver); + void CreatePaymentManager( + mojo::PendingReceiver<payments::mojom::PaymentManager> receiver); // Causes this instance to be deleted, which will terminate the worker. May // be done based on a UI action.
diff --git a/content/browser/worker_host/shared_worker_service_impl.cc b/content/browser/worker_host/shared_worker_service_impl.cc index 810415e..adaf93f 100644 --- a/content/browser/worker_host/shared_worker_service_impl.cc +++ b/content/browser/worker_host/shared_worker_service_impl.cc
@@ -17,7 +17,7 @@ #include "base/macros.h" #include "base/task/post_task.h" #include "content/browser/appcache/appcache_navigation_handle.h" -#include "content/browser/file_url_loader_factory.h" +#include "content/browser/loader/file_url_loader_factory.h" #include "content/browser/service_worker/service_worker_navigation_handle.h" #include "content/browser/storage_partition_impl.h" #include "content/browser/url_loader_factory_getter.h"
diff --git a/content/browser/worker_host/worker_script_fetch_initiator.cc b/content/browser/worker_host/worker_script_fetch_initiator.cc index ad639e3..634ecc39 100644 --- a/content/browser/worker_host/worker_script_fetch_initiator.cc +++ b/content/browser/worker_host/worker_script_fetch_initiator.cc
@@ -16,9 +16,9 @@ #include "base/task/post_task.h" #include "content/browser/appcache/appcache_navigation_handle.h" #include "content/browser/data_url_loader_factory.h" -#include "content/browser/file_url_loader_factory.h" #include "content/browser/fileapi/file_system_url_loader_factory.h" #include "content/browser/loader/browser_initiated_resource_request.h" +#include "content/browser/loader/file_url_loader_factory.h" #include "content/browser/navigation_subresource_loader_params.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_navigation_handle.h"
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index f6a5644..6b5e943 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -748,10 +748,9 @@ std::string /* message */, bool /* discard_duplicates */) -// Tells the renderer to reload the frame, optionally bypassing the cache while -// doing so. -IPC_MESSAGE_ROUTED1(FrameMsg_Reload, - bool /* bypass_cache */) +// TODO(https://crbug.com/995428): Deprecated. +// Tells the renderer to reload the frame. +IPC_MESSAGE_ROUTED0(FrameMsg_Reload) // Change the accessibility mode in the renderer process. IPC_MESSAGE_ROUTED1(FrameMsg_SetAccessibilityMode, ui::AXMode)
diff --git a/content/public/app/content_browser_manifest.cc b/content/public/app/content_browser_manifest.cc index 4b6d406..b9c64b4 100644 --- a/content/public/app/content_browser_manifest.cc +++ b/content/public/app/content_browser_manifest.cc
@@ -172,7 +172,6 @@ "blink.mojom.QuotaDispatcherHost", "blink.mojom.WebSocketConnector", "media.mojom.VideoDecodePerfHistory", - "payments.mojom.PaymentManager", "shape_detection.mojom.BarcodeDetectionProvider", "shape_detection.mojom.FaceDetectionProvider", "shape_detection.mojom.TextDetection"}) @@ -186,10 +185,9 @@ "blink.mojom.NotificationService", "blink.mojom.QuotaDispatcherHost", "blink.mojom.SerialService", - "blink.mojom.WebUsbService", "blink.mojom.SmsReceiver", + "blink.mojom.WebUsbService", "blink.mojom.WebSocketConnector", "media.mojom.VideoDecodePerfHistory", - "payments.mojom.PaymentManager", "shape_detection.mojom.BarcodeDetectionProvider", "shape_detection.mojom.FaceDetectionProvider", "shape_detection.mojom.TextDetection"}) @@ -204,7 +202,6 @@ "media.mojom.VideoDecodePerfHistory", "network.mojom.RestrictedCookieManager", "blink.mojom.WebSocketConnector", - "payments.mojom.PaymentManager", "shape_detection.mojom.BarcodeDetectionProvider", "shape_detection.mojom.FaceDetectionProvider", "shape_detection.mojom.TextDetection"}) @@ -231,7 +228,6 @@ "blink.mojom.QuotaDispatcherHost", "blink.mojom.SerialService", "blink.mojom.SharedWorkerConnector", - "blink.mojom.SmsReceiver", "blink.mojom.SpeechRecognizer", "blink.mojom.TextSuggestionHost", "blink.mojom.UnhandledTapNotifier", @@ -252,7 +248,6 @@ "mojom.ProcessInternalsHandler", "network.mojom.RestrictedCookieManager", "blink.mojom.WebSocketConnector", - "payments.mojom.PaymentManager", "payments.mojom.PaymentRequest", "resource_coordinator.mojom.DocumentCoordinationUnit", "shape_detection.mojom.BarcodeDetectionProvider",
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index de63a79..1cdc600 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -497,6 +497,12 @@ // Indicates whether a file path should be accessible via file URL given a // request from a browser context which lives within |profile_path|. + // + // On POSIX platforms, |absolute_path| is the path after resolving all + // symboling links. On Windows, if the file URL is a shortcut, + // IsFileAccessAllowed will be called twice: Once for the shortcut, which is + // treated like a redirect, and once for the destination path after following + // the shortcut, assuming access to the shortcut path was allowed. virtual bool IsFileAccessAllowed(const base::FilePath& path, const base::FilePath& absolute_path, const base::FilePath& profile_path);
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h index 56eaf82..ae365a1e 100644 --- a/content/public/browser/render_process_host.h +++ b/content/public/browser/render_process_host.h
@@ -35,7 +35,8 @@ #include "third_party/blink/public/mojom/filesystem/file_system.mojom-forward.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h" #include "third_party/blink/public/mojom/locks/lock_manager.mojom-forward.h" -#include "third_party/blink/public/mojom/permissions/permission.mojom.h" +#include "third_party/blink/public/mojom/payments/payment_app.mojom-forward.h" +#include "third_party/blink/public/mojom/permissions/permission.mojom-forward.h" #include "ui/gfx/native_widget_types.h" #if defined(OS_ANDROID) @@ -502,6 +503,7 @@ // only, and is only exposed here to support MockRenderProcessHost usage in // tests. virtual void CreateLockManager( + int render_frame_id, const url::Origin& origin, mojo::PendingReceiver<blink::mojom::LockManager> receiver) = 0; @@ -512,6 +514,12 @@ const url::Origin& origin, mojo::PendingReceiver<blink::mojom::PermissionService> receiver) = 0; + // Binds |receiver| to an instance of PaymentManager. This is for internal + // use only, and is only exposed here to support MockRenderProcessHost usage + // in tests. + virtual void CreatePaymentManager( + mojo::PendingReceiver<payments::mojom::PaymentManager> receiver) = 0; + // Returns the current number of active views in this process. Excludes // any RenderViewHosts that are swapped out. size_t GetActiveViewCount();
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h index dd1113e..6708e25 100644 --- a/content/public/browser/web_contents.h +++ b/content/public/browser/web_contents.h
@@ -629,7 +629,7 @@ virtual std::unique_ptr<WebContents> Clone() = 0; // Reloads the focused frame. - virtual void ReloadFocusedFrame(bool bypass_cache) = 0; + virtual void ReloadFocusedFrame() = 0; // Attains PauseSubresourceLoadingHandles for each frame in the web contents. // As long as these handles are not deleted, subresources will continue to be
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h index 1b6e80f4..1fc01f7 100644 --- a/content/public/test/mock_render_process_host.h +++ b/content/public/test/mock_render_process_host.h
@@ -179,12 +179,16 @@ void BindIndexedDB(mojo::PendingReceiver<blink::mojom::IDBFactory> receiver, const url::Origin& origin) override; void CreateLockManager( + int render_frame_id, const url::Origin& origin, mojo::PendingReceiver<blink::mojom::LockManager> receiver) override {} void CreatePermissionService( const url::Origin& origin, mojo::PendingReceiver<blink::mojom::PermissionService> receiver) override {} + void CreatePaymentManager( + mojo::PendingReceiver<payments::mojom::PaymentManager> receiver) + override {} void CleanupCorbExceptionForPluginUponDestruction() override; // IPC::Sender via RenderProcessHost.
diff --git a/content/renderer/compositor/layer_tree_view.cc b/content/renderer/compositor/layer_tree_view.cc index 1b4df2d..c6fac7a 100644 --- a/content/renderer/compositor/layer_tree_view.cc +++ b/content/renderer/compositor/layer_tree_view.cc
@@ -267,6 +267,11 @@ delegate_->RecordEndOfFrameMetrics(frame_begin_time); } +std::unique_ptr<cc::BeginMainFrameMetrics> +LayerTreeView::GetBeginMainFrameMetrics() { + return delegate_->GetBeginMainFrameMetrics(); +} + void LayerTreeView::DidSubmitCompositorFrame() {} void LayerTreeView::DidLoseLayerTreeFrameSink() {}
diff --git a/content/renderer/compositor/layer_tree_view.h b/content/renderer/compositor/layer_tree_view.h index 07351680..fa20900 100644 --- a/content/renderer/compositor/layer_tree_view.h +++ b/content/renderer/compositor/layer_tree_view.h
@@ -94,6 +94,8 @@ const gfx::PresentationFeedback& feedback) override; void RecordStartOfFrameMetrics() override; void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) override; + std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics() + override; // cc::LayerTreeHostSingleThreadClient implementation. void DidSubmitCompositorFrame() override;
diff --git a/content/renderer/compositor/layer_tree_view_delegate.h b/content/renderer/compositor/layer_tree_view_delegate.h index 667a4c0..028f472 100644 --- a/content/renderer/compositor/layer_tree_view_delegate.h +++ b/content/renderer/compositor/layer_tree_view_delegate.h
@@ -14,6 +14,7 @@ namespace cc { class LayerTreeFrameSink; +struct BeginMainFrameMetrics; struct ElementId; } // namespace cc @@ -82,6 +83,14 @@ // (at the same time Tracing measurements are taken). virtual void RecordStartOfFrameMetrics() = 0; virtual void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) = 0; + // Return metrics information for the stages of BeginMainFrame. This is + // ultimately implemented by Blink's LocalFrameUKMAggregator. It must be a + // distinct call from the FrameMetrics above because the BeginMainFrameMetrics + // for compositor latency must be gathered before the layer tree is + // committed to the compositor, which is before the call to + // RecordEndOfFrameMetrics. + virtual std::unique_ptr<cc::BeginMainFrameMetrics> + GetBeginMainFrameMetrics() = 0; // Notification of the beginning and end of LayerTreeHost::UpdateLayers, for // metrics collection.
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 488dcb4b..79cd638 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -2943,9 +2943,8 @@ msg_event); } -void RenderFrameImpl::OnReload(bool bypass_cache) { - frame_->StartReload(bypass_cache ? WebFrameLoadType::kReloadBypassingCache - : WebFrameLoadType::kReload); +void RenderFrameImpl::OnReload() { + frame_->StartReload(WebFrameLoadType::kReload); } bool RenderFrameImpl::RunJavaScriptDialog(JavaScriptDialogType type, @@ -3140,12 +3139,6 @@ return nullptr; } -void RenderFrameImpl::LoadErrorPage(int reason) { - LoadNavigationErrorPage(frame_->GetDocumentLoader(), - WebURLError(reason, frame_->GetDocument().Url()), - base::nullopt, true /* replace_current_item */); -} - void RenderFrameImpl::ExecuteJavaScript(const base::string16& javascript) { JavaScriptExecuteRequest(javascript, false, base::DoNothing()); }
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 676bdd48d..f1a995b 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -737,7 +737,6 @@ void DownloadURL(const blink::WebURLRequest& request, CrossOriginRedirects cross_origin_redirect_behavior, mojo::ScopedMessagePipeHandle blob_url_token) override; - void LoadErrorPage(int reason) override; void BeginNavigation(std::unique_ptr<blink::WebNavigationInfo> info) override; void WillSendSubmitEvent(const blink::WebFormElement& form) override; void DidCreateDocumentLoader( @@ -1138,7 +1137,8 @@ const std::string& message, bool discard_duplicates); void OnVisualStateRequest(uint64_t key); - void OnReload(bool bypass_cache); + // TODO(https://crbug.com/995428): Deprecated. + void OnReload(); void OnSetAccessibilityMode(ui::AXMode new_mode); void OnSnapshotAccessibilityTree(int callback_id, ui::AXMode ax_mode); void OnUpdateOpener(int opener_routing_id);
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index a27150f..32bac12f 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -1545,6 +1545,13 @@ GetWebWidget()->RecordEndOfFrameMetrics(frame_begin_time); } +std::unique_ptr<cc::BeginMainFrameMetrics> +RenderWidget::GetBeginMainFrameMetrics() { + if (GetWebWidget()) + return GetWebWidget()->GetBeginMainFrameMetrics(); + return nullptr; +} + void RenderWidget::BeginUpdateLayers() { if (GetWebWidget()) GetWebWidget()->BeginUpdateLayers();
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 12c3b27..82d0ab8 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -367,6 +367,9 @@ void DidCompletePageScaleAnimation() override; void RecordStartOfFrameMetrics() override; void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) override; + std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics() + override; + void BeginUpdateLayers() override; void EndUpdateLayers() override; void UpdateVisualState() override;
diff --git a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc b/content/renderer/service_worker/embedded_worker_instance_client_impl.cc index 009e06d2..0141d4d 100644 --- a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc +++ b/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
@@ -174,8 +174,6 @@ ? blink::WebEmbeddedWorkerStartData::kWaitForDebugger : blink::WebEmbeddedWorkerStartData::kDontWaitForDebugger; start_data->devtools_worker_token = params.devtools_worker_token; - start_data->v8_cache_options = - static_cast<blink::WebSettings::V8CacheOptions>(params.v8_cache_options); start_data->privacy_preferences = blink::PrivacyPreferences( params.renderer_preferences->enable_do_not_track, params.renderer_preferences->enable_referrers);
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 41cea1a..223ed71 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -947,6 +947,7 @@ "../browser/loader/cors_file_origin_browsertest.cc", "../browser/loader/cors_preflight_cache_browsertest.cc", "../browser/loader/cross_site_document_blocking_browsertest.cc", + "../browser/loader/file_url_loader_factory_browsertest.cc", "../browser/loader/loader_browsertest.cc", "../browser/loader/prefetch_browsertest.cc", "../browser/loader/prefetch_browsertest_base.cc",
diff --git a/content/test/data/media/peerconnection-call-data.html b/content/test/data/media/peerconnection-call-data.html index 67f7e5c..6a458391 100644 --- a/content/test/data/media/peerconnection-call-data.html +++ b/content/test/data/media/peerconnection-call-data.html
@@ -254,7 +254,12 @@ } function negotiate() { - negotiateBetween(gFirstConnection, gSecondConnection); + Promise.all([ + waitForConnectionToStabilizeIfNeeded(gFirstConnection), + waitForConnectionToStabilizeIfNeeded(gSecondConnection), + ]).then(() => { + negotiateBetween(gFirstConnection, gSecondConnection); + }); } function onRemoteStream(e, target) {
diff --git a/content/test/data/media/webrtc_test_utilities.js b/content/test/data/media/webrtc_test_utilities.js index 83f8fd8..328fa56 100644 --- a/content/test/data/media/webrtc_test_utilities.js +++ b/content/test/data/media/webrtc_test_utilities.js
@@ -145,6 +145,16 @@ }); } +function waitForConnectionToStabilizeIfNeeded(peerConnection) { + return new Promise((resolve, reject) => { + if (peerConnection.signalingState == 'stable') { + resolve(); + return; + } + return waitForConnectionToStabilize(peerConnection).then(resolve); + }); +} + // This very basic video verification algorithm will be satisfied if any // pixels are changed. function isVideoPlaying(pixels, previousPixels) {
diff --git a/content/test/stub_layer_tree_view_delegate.cc b/content/test/stub_layer_tree_view_delegate.cc index aefecb90..77f96db 100644 --- a/content/test/stub_layer_tree_view_delegate.cc +++ b/content/test/stub_layer_tree_view_delegate.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "cc/metrics/begin_main_frame_metrics.h" #include "cc/trees/layer_tree_frame_sink.h" #include "cc/trees/swap_promise.h" #include "components/viz/common/frame_sinks/copy_output_request.h" @@ -17,4 +18,9 @@ std::move(callback).Run(nullptr); } +std::unique_ptr<cc::BeginMainFrameMetrics> +StubLayerTreeViewDelegate::GetBeginMainFrameMetrics() { + return nullptr; +} + } // namespace content
diff --git a/content/test/stub_layer_tree_view_delegate.h b/content/test/stub_layer_tree_view_delegate.h index b7365ae..07768b83 100644 --- a/content/test/stub_layer_tree_view_delegate.h +++ b/content/test/stub_layer_tree_view_delegate.h
@@ -30,6 +30,8 @@ void DidBeginMainFrame() override {} void RecordStartOfFrameMetrics() override {} void RecordEndOfFrameMetrics(base::TimeTicks) override {} + std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics() + override; void BeginUpdateLayers() override {} void EndUpdateLayers() override {} void RequestNewLayerTreeFrameSink(
diff --git a/docs/infra/cq_builders.md b/docs/infra/cq_builders.md index 50415246..7411ba6 100644 --- a/docs/infra/cq_builders.md +++ b/docs/infra/cq_builders.md
@@ -344,9 +344,3 @@ * Experimental percentage: 10 -* [linux-chromeos-coverage-rel](https://ci.chromium.org/p/chromium/builders/luci.chromium.try/linux-chromeos-coverage-rel) ([`commit-queue.cfg` entry](https://cs.chromium.org/search/?q=package:%5Echromium$+file:commit-queue.cfg+chromium/try/linux-chromeos-coverage-rel)) ([matching builders](https://cs.chromium.org/search/?q=file:trybots.py+linux-chromeos-coverage-rel)) - - https://crbug.com/1000367 - - * Experimental percentage: 3 -
diff --git a/docs/security/sheriff.md b/docs/security/sheriff.md index a0d3e1f..97c4ba9 100644 --- a/docs/security/sheriff.md +++ b/docs/security/sheriff.md
@@ -150,11 +150,11 @@ * **If the report doesn't have enough information**, ask the reporter for more information, add the **Needs-Feedback** label and wait for 24 hours for a response. - * The [security bug template](https://bugs.chromium.org/p/chromium/issues/entry?template=Security+Bug) - asks reporters to attach files directly, not in zip or other archives, and - attach the source of any online demos they've created. If they've not done - so, please make sure all files needed to reproduce the issue are downloaded - and attached. +* The [security bug template](https://bugs.chromium.org/p/chromium/issues/entry?template=Security+Bug) + asks reporters to **attach files directly**, not in zip or other archives, and + not hosted at an external resource (e.g. Google Cloud Storage). If the report + mentions an online demo hosted somewhere, make sure the reporters attach the + the source code for the demo as well. * **If the bug is a security bug, but is only applicable to Chrome OS**: * The Chrome OS Security team now has their own sheriffing rotation. To get bugs into their triage queue, just set OS to the single value of "Chrome".
diff --git a/gpu/ipc/common/BUILD.gn b/gpu/ipc/common/BUILD.gn index 60eefa0..051e5df 100644 --- a/gpu/ipc/common/BUILD.gn +++ b/gpu/ipc/common/BUILD.gn
@@ -186,7 +186,7 @@ ] } -source_set("vulkan_ycbcr_info") { +component("vulkan_ycbcr_info") { sources = [ "vulkan_ycbcr_info.cc", "vulkan_ycbcr_info.h", @@ -194,6 +194,7 @@ deps = [ "//base", ] + configs += [ "//gpu:gpu_implementation" ] } mojom("interfaces") {
diff --git a/gpu/ipc/common/vulkan_ycbcr_info.h b/gpu/ipc/common/vulkan_ycbcr_info.h index 2c99091..91fa0348 100644 --- a/gpu/ipc/common/vulkan_ycbcr_info.h +++ b/gpu/ipc/common/vulkan_ycbcr_info.h
@@ -6,11 +6,12 @@ #define GPU_IPC_COMMON_VULKAN_YCBCR_INFO_H_ #include <stdint.h> +#include "gpu/gpu_export.h" namespace gpu { // Sampler Ycbcr conversion information. -struct VulkanYCbCrInfo { +struct GPU_EXPORT VulkanYCbCrInfo { VulkanYCbCrInfo(); VulkanYCbCrInfo(uint32_t image_format, uint64_t external_format,
diff --git a/gpu/vulkan/demo/vulkan_demo.h b/gpu/vulkan/demo/vulkan_demo.h index 2f665be..3d8cd19 100644 --- a/gpu/vulkan/demo/vulkan_demo.h +++ b/gpu/vulkan/demo/vulkan_demo.h
@@ -12,6 +12,7 @@ #include "gpu/vulkan/vulkan_swap_chain.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "ui/gfx/geometry/size.h" +#include "ui/platform_window/platform_window.h" #include "ui/platform_window/platform_window_delegate.h" class SkCanvas; @@ -27,7 +28,6 @@ namespace ui { class PlatformEventSource; -class PlatformWindow; } // namespace ui namespace gpu {
diff --git a/headless/test/headless_protocol_browsertest.cc b/headless/test/headless_protocol_browsertest.cc index a91b9da7..2ae8d2df 100644 --- a/headless/test/headless_protocol_browsertest.cc +++ b/headless/test/headless_protocol_browsertest.cc
@@ -212,8 +212,8 @@ HEADLESS_PROTOCOL_TEST(VirtualTimeInterrupt, "emulation/virtual-time-interrupt.js") -// Flaky on Linux & Mac. TODO(crbug.com/930717): Re-enable. -#if defined(OS_LINUX) || defined(OS_MACOSX) +// Flaky on Linux, Mac & Win. TODO(crbug.com/930717): Re-enable. +#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN) #define MAYBE_VirtualTimeCrossProcessNavigation \ DISABLED_VirtualTimeCrossProcessNavigation #else
diff --git a/infra/config/commit-queue.cfg b/infra/config/commit-queue.cfg index 5f8813fb..f2e527fc 100644 --- a/infra/config/commit-queue.cfg +++ b/infra/config/commit-queue.cfg
@@ -392,11 +392,6 @@ name: "chromium/try/ios-simulator-xcode-clang" experiment_percentage: 10 } - # https://crbug.com/1000367 - builders { - name: "chromium/try/linux-chromeos-coverage-rel" - experiment_percentage: 3 - } retry_config { single_quota: 1
diff --git a/infra/config/cr-buildbucket.cfg b/infra/config/cr-buildbucket.cfg index 615b1ebd14..da421e2 100644 --- a/infra/config/cr-buildbucket.cfg +++ b/infra/config/cr-buildbucket.cfg
@@ -4358,16 +4358,6 @@ mixins: "clang-coverage" name: "linux-chromeos-rel" } - # This builder replicates linux-chromeos-rel for code coverage experiment. - # TODO(crbug.com/1000367): Remove once linux-chromeos-coverage-rel is folded - # into linux-chromeos-rel. - builders { - mixins: "chromeos-try" - mixins: "goma-j150" - mixins: "builderless" - mixins: "clang-coverage" - name: "linux-chromeos-coverage-rel" - } builders { mixins: "linux-try"
diff --git a/ios/BUILD.gn b/ios/BUILD.gn index 93df8be..982619c 100644 --- a/ios/BUILD.gn +++ b/ios/BUILD.gn
@@ -45,9 +45,5 @@ "//ios/web_view:all_tests", "//ios/web_view/shell/test:all_tests", ] - - if (checkout_ios_webkit) { - deps += [ "//ios/third_party/webkit" ] - } } }
diff --git a/ios/chrome/browser/flags/BUILD.gn b/ios/chrome/browser/flags/BUILD.gn index e02dd67..9729dea 100644 --- a/ios/chrome/browser/flags/BUILD.gn +++ b/ios/chrome/browser/flags/BUILD.gn
@@ -29,6 +29,7 @@ "//components/security_state/core", "//components/send_tab_to_self", "//components/signin/core/browser", + "//components/signin/ios/browser", "//components/signin/public/base", "//components/strings:components_strings", "//components/sync/driver",
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 0baa5b92..7c0d781 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -41,6 +41,7 @@ #include "components/security_state/core/features.h" #include "components/send_tab_to_self/features.h" #include "components/signin/core/browser/account_reconcilor.h" +#include "components/signin/ios/browser/features.h" #include "components/signin/public/base/signin_switches.h" #include "components/strings/grit/components_strings.h" #include "components/sync/driver/sync_driver_switches.h" @@ -546,6 +547,10 @@ {"password-leak-detection", flag_descriptions::kPasswordLeakDetectionName, flag_descriptions::kPasswordLeakDetectionDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(password_manager::features::kLeakDetection)}, + {"force-startup-signin-promo", + flag_descriptions::kForceStartupSigninPromoName, + flag_descriptions::kForceStartupSigninPromoDescription, flags_ui::kOsIos, + FEATURE_VALUE_TYPE(signin::kForceStartupSigninPromo)}, }; // Add all switches from experimental flags to |command_line|.
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 31b84dc..e48485be 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -335,6 +335,11 @@ const char kSnapshotDrawViewDescription[] = "When enabled, snapshots will be taken using |-drawViewHierarchy:|."; +const char kForceStartupSigninPromoName[] = "Display the startup sign-in promo"; +const char kForceStartupSigninPromoDescription[] = + "When enabled, the startup sign-in promo is always displayed when starting " + "Chrome."; + const char kSyncSandboxName[] = "Use Chrome Sync sandbox"; const char kSyncSandboxDescription[] = "Connects to the testing server for Chrome Sync.";
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index 3104ed5..076c4f9 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -286,6 +286,10 @@ extern const char kSnapshotDrawViewName[]; extern const char kSnapshotDrawViewDescription[]; +// Title and description for the flag to trigger the startup sign-in promo. +extern const char kForceStartupSigninPromoName[]; +extern const char kForceStartupSigninPromoDescription[]; + // Title and description for the flag to control if Chrome Sync should use the // sandbox servers. extern const char kSyncSandboxName[];
diff --git a/ios/chrome/browser/main/browser_impl.h b/ios/chrome/browser/main/browser_impl.h index 1b9aaec..30f7b69 100644 --- a/ios/chrome/browser/main/browser_impl.h +++ b/ios/chrome/browser/main/browser_impl.h
@@ -13,6 +13,7 @@ @class TabModel; class WebStateList; +class WebStateListDelegate; namespace ios { class ChromeBrowserState; @@ -37,13 +38,16 @@ void RemoveObserver(BrowserObserver* observer) override; private: - // Exposed to allow unittests to pass in a mock TabModel. + // Exposed to allow unittests to inject a TabModel and WebStateList FRIEND_TEST_ALL_PREFIXES(BrowserImplTest, TestAccessors); - BrowserImpl(ios::ChromeBrowserState* browser_state, TabModel* tab_model); + BrowserImpl(ios::ChromeBrowserState* browser_state, + TabModel* tab_model, + std::unique_ptr<WebStateList> web_state_list); ios::ChromeBrowserState* browser_state_; __strong TabModel* tab_model_; - WebStateList* web_state_list_; + std::unique_ptr<WebStateListDelegate> web_state_list_delegate_; + std::unique_ptr<WebStateList> web_state_list_; base::ObserverList<BrowserObserver, /* check_empty= */ true> observers_; DISALLOW_COPY_AND_ASSIGN(BrowserImpl);
diff --git a/ios/chrome/browser/main/browser_impl.mm b/ios/chrome/browser/main/browser_impl.mm index c729d96..7b104c4b 100644 --- a/ios/chrome/browser/main/browser_impl.mm +++ b/ios/chrome/browser/main/browser_impl.mm
@@ -8,8 +8,11 @@ #include "base/memory/ptr_util.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/main/browser_observer.h" +#import "ios/chrome/browser/main/browser_web_state_list_delegate.h" #import "ios/chrome/browser/sessions/session_service_ios.h" #import "ios/chrome/browser/tabs/tab_model.h" +#import "ios/chrome/browser/web_state_list/web_state_list.h" +#import "ios/chrome/browser/web_state_list/web_state_list_delegate.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -18,18 +21,25 @@ BrowserImpl::BrowserImpl(ios::ChromeBrowserState* browser_state) : browser_state_(browser_state) { DCHECK(browser_state_); + + web_state_list_delegate_ = std::make_unique<BrowserWebStateListDelegate>(); + web_state_list_ = + std::make_unique<WebStateList>(web_state_list_delegate_.get()); + tab_model_ = [[TabModel alloc] initWithSessionService:[SessionServiceIOS sharedService] - browserState:browser_state_]; - web_state_list_ = tab_model_.webStateList; + browserState:browser_state_ + webStateList:web_state_list_.get()]; } BrowserImpl::BrowserImpl(ios::ChromeBrowserState* browser_state, - TabModel* tab_model) - : browser_state_(browser_state), tab_model_(tab_model) { + TabModel* tab_model, + std::unique_ptr<WebStateList> web_state_list) + : browser_state_(browser_state), + tab_model_(tab_model), + web_state_list_(std::move(web_state_list)) { DCHECK(browser_state_); - DCHECK(tab_model_); - web_state_list_ = tab_model_.webStateList; + DCHECK(tab_model.webStateList == web_state_list_.get()); } BrowserImpl::~BrowserImpl() { @@ -47,7 +57,7 @@ } WebStateList* BrowserImpl::GetWebStateList() const { - return web_state_list_; + return web_state_list_.get(); } void BrowserImpl::AddObserver(BrowserObserver* observer) {
diff --git a/ios/chrome/browser/main/browser_impl_unittest.mm b/ios/chrome/browser/main/browser_impl_unittest.mm index 323aa90..a2dc35ea 100644 --- a/ios/chrome/browser/main/browser_impl_unittest.mm +++ b/ios/chrome/browser/main/browser_impl_unittest.mm
@@ -19,29 +19,34 @@ class BrowserImplTest : public PlatformTest { protected: - BrowserImplTest() : web_state_list_(&web_state_list_delegate_) { + BrowserImplTest() + : web_state_list_( + std::make_unique<WebStateList>(&web_state_list_delegate_)) { TestChromeBrowserState::Builder test_cbs_builder; chrome_browser_state_ = test_cbs_builder.Build(); tab_model_ = [OCMockObject mockForClass:[TabModel class]]; - OCMStub([tab_model_ webStateList]).andReturn(&web_state_list_); + OCMStub([tab_model_ webStateList]).andReturn(web_state_list_.get()); } web::WebTaskEnvironment task_environment_; std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; FakeWebStateListDelegate web_state_list_delegate_; - WebStateList web_state_list_; + // Unique ptr to the web_state_list_ to transfer into new Browser instances. + std::unique_ptr<WebStateList> web_state_list_; id tab_model_; }; // Tests that the accessors return the expected values. TEST_F(BrowserImplTest, TestAccessors) { - BrowserImpl browser(chrome_browser_state_.get(), tab_model_); + WebStateList* web_state_list_weak_reference = web_state_list_.get(); + BrowserImpl browser(chrome_browser_state_.get(), tab_model_, + std::move(web_state_list_)); EXPECT_EQ(chrome_browser_state_.get(), browser.GetBrowserState()); EXPECT_EQ(tab_model_, browser.GetTabModel()); - EXPECT_EQ(&web_state_list_, browser.GetWebStateList()); + EXPECT_EQ(web_state_list_weak_reference, browser.GetWebStateList()); } // Tests that the BrowserDestroyed() callback is sent when a browser is deleted. @@ -53,7 +58,7 @@ // |-browserStateDestroyed| is expected to be executed before the // TabModelList's destructor. // TODO(crbug.com/783777): Remove when TabModel is no longer used. - [browser->GetTabModel() browserStateDestroyed]; + [browser->GetTabModel() disconnect]; browser = nullptr; EXPECT_TRUE(observer.browser_destroyed()); }
diff --git a/ios/chrome/browser/metrics/previous_session_info.mm b/ios/chrome/browser/metrics/previous_session_info.mm index a8d73f4..53df9f658 100644 --- a/ios/chrome/browser/metrics/previous_session_info.mm +++ b/ios/chrome/browser/metrics/previous_session_info.mm
@@ -120,21 +120,6 @@ @implementation PreviousSessionInfo -@synthesize availableDeviceStorage = _availableDeviceStorage; -@synthesize deviceBatteryLevel = _deviceBatteryLevel; -@synthesize deviceBatteryState = _deviceBatteryState; -@synthesize deviceThermalState = _deviceThermalState; -@synthesize deviceWasInLowPowerMode = _deviceWasInLowPowerMode; -@synthesize didBeginRecordingCurrentSession = _didBeginRecordingCurrentSession; -@synthesize didSeeMemoryWarningShortlyBeforeTerminating = - _didSeeMemoryWarningShortlyBeforeTerminating; -@synthesize isFirstSessionAfterOSUpgrade = _isFirstSessionAfterOSUpgrade; -@synthesize isFirstSessionAfterUpgrade = _isFirstSessionAfterUpgrade; -@synthesize isFirstSessionAfterLanguageChange = - _isFirstSessionAfterLanguageChange; -@synthesize OSVersion = _OSVersion; -@synthesize sessionEndTime = _sessionEndTime; - // Singleton PreviousSessionInfo. static PreviousSessionInfo* gSharedInstance = nil;
diff --git a/ios/chrome/browser/sessions/session_service_ios.mm b/ios/chrome/browser/sessions/session_service_ios.mm index f4578b2..eac1ccd 100644 --- a/ios/chrome/browser/sessions/session_service_ios.mm +++ b/ios/chrome/browser/sessions/session_service_ios.mm
@@ -211,6 +211,10 @@ SessionIOSFactory factory = [_pendingSessions objectForKey:sessionPath]; [_pendingSessions removeObjectForKey:sessionPath]; SessionIOS* session = factory(); + // Because the factory may be called asynchronously after the underlying + // web state list is destroyed, the session may be nil; if so, do nothing. + if (!session) + return; @try { NSError* error = nil;
diff --git a/ios/chrome/browser/snapshots/BUILD.gn b/ios/chrome/browser/snapshots/BUILD.gn index 676edde68..2e1c6ae0 100644 --- a/ios/chrome/browser/snapshots/BUILD.gn +++ b/ios/chrome/browser/snapshots/BUILD.gn
@@ -41,13 +41,13 @@ "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web:tab_id_tab_helper", "//ios/chrome/browser/web_state_list", + "//ios/third_party/webkit", "//ios/web/public", "//ui/gfx", ] libs = [ "QuartzCore.framework", "UIKit.framework", - "WebKit.framework", ] configs += [ "//build/config/compiler:enable_arc" ] }
diff --git a/ios/chrome/browser/sync/device_info_sync_service_factory.mm b/ios/chrome/browser/sync/device_info_sync_service_factory.mm index df61478f..2a14001 100644 --- a/ios/chrome/browser/sync/device_info_sync_service_factory.mm +++ b/ios/chrome/browser/sync/device_info_sync_service_factory.mm
@@ -14,6 +14,7 @@ #include "components/signin/public/base/device_id_helper.h" #include "components/sync/model/model_type_store_service.h" #include "components/sync_device_info/device_info_prefs.h" +#include "components/sync_device_info/device_info_sync_client.h" #include "components/sync_device_info/device_info_sync_service_impl.h" #include "components/sync_device_info/local_device_info_provider_impl.h" #include "ios/chrome/browser/application_context.h" @@ -26,6 +27,29 @@ #error "This file requires ARC support." #endif +namespace { + +class DeviceInfoSyncClient : public syncer::DeviceInfoSyncClient { + public: + explicit DeviceInfoSyncClient(PrefService* prefs) : prefs_(prefs) {} + ~DeviceInfoSyncClient() override = default; + + // syncer::DeviceInfoSyncClient: + std::string GetSigninScopedDeviceId() const override { + return signin::GetSigninScopedDeviceId(prefs_); + } + + // syncer::DeviceInfoSyncClient: + bool GetSendTabToSelfReceivingEnabled() const override { + return send_tab_to_self::IsReceivingEnabledByUserOnThisDevice(prefs_); + } + + private: + PrefService* const prefs_; +}; + +} // namespace + // static syncer::DeviceInfoSyncService* DeviceInfoSyncServiceFactory::GetForBrowserState( ios::ChromeBrowserState* browser_state) { @@ -74,21 +98,17 @@ ios::ChromeBrowserState* browser_state = ios::ChromeBrowserState::FromBrowserState(context); + auto device_info_sync_client = + std::make_unique<DeviceInfoSyncClient>(browser_state->GetPrefs()); auto local_device_info_provider = std::make_unique<syncer::LocalDeviceInfoProviderImpl>( - ::GetChannel(), ::GetVersionString(), - /*signin_scoped_device_id_callback=*/ - base::BindRepeating(&signin::GetSigninScopedDeviceId, - browser_state->GetPrefs()), - /*send_tab_to_self_receiving_enabled_callback=*/ - base::BindRepeating( - &send_tab_to_self::IsReceivingEnabledByUserOnThisDevice, - browser_state->GetPrefs())); + ::GetChannel(), ::GetVersionString(), device_info_sync_client.get()); auto device_prefs = std::make_unique<syncer::DeviceInfoPrefs>(browser_state->GetPrefs()); return std::make_unique<syncer::DeviceInfoSyncServiceImpl>( ModelTypeStoreServiceFactory::GetForBrowserState(browser_state) ->GetStoreFactory(), - std::move(local_device_info_provider), std::move(device_prefs)); + std::move(local_device_info_provider), std::move(device_prefs), + std::move(device_info_sync_client)); }
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.mm b/ios/chrome/browser/sync/ios_chrome_sync_client.mm index 93cde8a9..bac4d98 100644 --- a/ios/chrome/browser/sync/ios_chrome_sync_client.mm +++ b/ios/chrome/browser/sync/ios_chrome_sync_client.mm
@@ -225,13 +225,6 @@ NOTREACHED(); return nullptr; } - case syncer::DEPRECATED_ARTICLES: { - // DomDistillerService is used in iOS ReadingList. The distilled articles - // are saved separately and must not be synced. - // Add a not reached to avoid having ARTICLES sync be enabled silently. - NOTREACHED(); - return base::WeakPtr<syncer::SyncableService>(); - } case syncer::PASSWORDS: { return password_store_ ? password_store_->GetPasswordSyncableService() : base::WeakPtr<syncer::SyncableService>();
diff --git a/ios/chrome/browser/sync/ios_chrome_synced_tab_delegate.h b/ios/chrome/browser/sync/ios_chrome_synced_tab_delegate.h index 4ab66c9..206edce7 100644 --- a/ios/chrome/browser/sync/ios_chrome_synced_tab_delegate.h +++ b/ios/chrome/browser/sync/ios_chrome_synced_tab_delegate.h
@@ -27,7 +27,6 @@ SessionID GetWindowId() const override; SessionID GetSessionId() const override; bool IsBeingDestroyed() const override; - SessionID GetSourceTabID() const override; std::string GetExtensionAppId() const override; bool IsInitialBlankNavigation() const override; int GetCurrentEntryIndex() const override;
diff --git a/ios/chrome/browser/sync/ios_chrome_synced_tab_delegate.mm b/ios/chrome/browser/sync/ios_chrome_synced_tab_delegate.mm index 10973dc..50b85c5b 100644 --- a/ios/chrome/browser/sync/ios_chrome_synced_tab_delegate.mm +++ b/ios/chrome/browser/sync/ios_chrome_synced_tab_delegate.mm
@@ -55,12 +55,6 @@ return web_state_->IsBeingDestroyed(); } -// todo(pnoland): add logic to store and return the source tab id on ios. -// http://crbug/695241 -SessionID IOSChromeSyncedTabDelegate::GetSourceTabID() const { - return SessionID::InvalidValue(); -} - std::string IOSChromeSyncedTabDelegate::GetExtensionAppId() const { return std::string(); }
diff --git a/ios/chrome/browser/sync/profile_sync_service_factory_unittest.cc b/ios/chrome/browser/sync/profile_sync_service_factory_unittest.cc index b9adb43..dd246bb 100644 --- a/ios/chrome/browser/sync/profile_sync_service_factory_unittest.cc +++ b/ios/chrome/browser/sync/profile_sync_service_factory_unittest.cc
@@ -43,7 +43,7 @@ protected: // Returns the collection of default datatypes. std::vector<syncer::ModelType> DefaultDatatypes() { - static_assert(46 == syncer::ModelType::NUM_ENTRIES, + static_assert(39 == syncer::ModelType::NUM_ENTRIES, "When adding a new type, you probably want to add it here as " "well (assuming it is already enabled).");
diff --git a/ios/chrome/browser/tabs/tab_lifecycle.md b/ios/chrome/browser/tabs/tab_lifecycle.md index 4590a26..228fe8d 100644 --- a/ios/chrome/browser/tabs/tab_lifecycle.md +++ b/ios/chrome/browser/tabs/tab_lifecycle.md
@@ -10,13 +10,13 @@ AttachTabHelper(web_state.get()); ```` -When a `WebState` is added to a `TabModel`'s `WebStateList`, +When a `WebState` is added to a `Browser`'s `WebStateList`, `BrowserWebStateListDelegate` will invoke `AttachTabHelpers` if necessary. ```cpp -TabModel* tab_model = ...; +Browser* browser = ...; std::unique_ptr<web::WebState> web_state = ...; -[tab_model webStateList]->InsertWebState(0, std::move(web_state)); +browser->GetWebStateList()->InsertWebState(0, std::move(web_state)); ``` All Tab helpers are `WebStateUserData` thus they are destroyed after the
diff --git a/ios/chrome/browser/tabs/tab_model.h b/ios/chrome/browser/tabs/tab_model.h index 157e8ef..9e0cdfa0 100644 --- a/ios/chrome/browser/tabs/tab_model.h +++ b/ios/chrome/browser/tabs/tab_model.h
@@ -76,13 +76,16 @@ // in order to display the views associated with the tabs. Waits until the views // are ready. |browserState| cannot be nil. |service| cannot be nil; this class // creates intermediate SessionWindowIOS objects which must be consumed by a -// session service before they are deallocated. |window| can be nil to create -// an empty TabModel. In that case no notification will be sent during object -// creation. +// session service before they are deallocated. - (instancetype)initWithSessionService:(SessionServiceIOS*)service browserState:(ios::ChromeBrowserState*)browserState + webStateList:(WebStateList*)webStateList NS_DESIGNATED_INITIALIZER; +// Temporary backwards compatibility init which creates a webStateList. +- (instancetype)initWithSessionService:(SessionServiceIOS*)service + browserState:(ios::ChromeBrowserState*)browserState; + - (instancetype)init NS_UNAVAILABLE; // Add/modify tabs. @@ -129,9 +132,16 @@ // Sets whether the user is primarily interacting with this tab model. - (void)setPrimary:(BOOL)primary; -// Called when the browser state provided to this instance is being destroyed. +// Tells the receiver to disconnect from the model object it depends on. This +// should be called before destroying the browser state that the receiver was +// initialized with. +// It is safe to call this method multiple times. // At this point the tab model will no longer ever be active, and will likely be -// deallocated soon. +// deallocated soon. Calling any other methods or accessing any properties on +// the tab model after this is called is unsafe. +- (void)disconnect; + +// Legacy method name for -disconnect, will be deleted very soon. - (void)browserStateDestroyed; @end
diff --git a/ios/chrome/browser/tabs/tab_model.mm b/ios/chrome/browser/tabs/tab_model.mm index d58b598..430bcbeb 100644 --- a/ios/chrome/browser/tabs/tab_model.mm +++ b/ios/chrome/browser/tabs/tab_model.mm
@@ -215,11 +215,8 @@ } // anonymous namespace @interface TabModel ()<CRWWebStateObserver, WebStateListObserving> { - // Delegate for the WebStateList. - std::unique_ptr<WebStateListDelegate> _webStateListDelegate; - - // Underlying shared model implementation. - std::unique_ptr<WebStateList> _webStateList; + // Weak reference to the underlying shared model implementation. + WebStateList* _webStateList; // WebStateListObservers reacting to modifications of the model (may send // notification, translate and forward events, update metrics, ...). @@ -246,6 +243,10 @@ // Used to observe owned Tabs' WebStates. std::unique_ptr<web::WebStateObserver> _webStateObserver; + + // Legacy ivars for backwards compatibility with some tests + std::unique_ptr<WebStateListDelegate> _legacyWebStateListDelegate; + std::unique_ptr<WebStateList> _legacyOwnedWebStateList; } // Session window for the contents of the tab model. @@ -262,12 +263,11 @@ #pragma mark - Overriden - (void)dealloc { - // browserStateDestroyed should always have been called before destruction. + // -disconnect should always have been called before destruction. DCHECK(!_browserState); } #pragma mark - Public methods - - (TabUsageRecorder*)tabUsageRecorder { return _tabUsageRecorder.get(); } @@ -287,15 +287,14 @@ - (WebStateList*)webStateList { DCHECK(_webStateList); - return _webStateList.get(); + return _webStateList; } - (instancetype)initWithSessionService:(SessionServiceIOS*)service - browserState:(ios::ChromeBrowserState*)browserState { + browserState:(ios::ChromeBrowserState*)browserState + webStateList:(WebStateList*)webStateList { if ((self = [super init])) { - _webStateListDelegate = std::make_unique<BrowserWebStateListDelegate>(); - _webStateList = std::make_unique<WebStateList>(_webStateListDelegate.get()); - + _webStateList = webStateList; _browserState = browserState; DCHECK(_browserState); @@ -307,11 +306,12 @@ if (!_browserState->IsOffTheRecord()) { // Set up the usage recorder before tabs are created. _tabUsageRecorder = std::make_unique<TabUsageRecorder>( - _webStateList.get(), + _webStateList, PrerenderServiceFactory::GetForBrowserState(browserState)); } + std::unique_ptr<TabModelSyncedWindowDelegate> syncedWindowDelegate = - std::make_unique<TabModelSyncedWindowDelegate>(_webStateList.get()); + std::make_unique<TabModelSyncedWindowDelegate>(_webStateList); // Keep a weak ref to the the window delegate, which is then moved into // the web state list observers list. @@ -376,6 +376,17 @@ return self; } +- (instancetype)initWithSessionService:(SessionServiceIOS*)service + browserState:(ios::ChromeBrowserState*)browserState { + _legacyWebStateListDelegate = std::make_unique<BrowserWebStateListDelegate>(); + _legacyOwnedWebStateList = + std::make_unique<WebStateList>(_legacyWebStateListDelegate.get()); + + return [self initWithSessionService:service + browserState:browserState + webStateList:_legacyOwnedWebStateList.get()]; +} + - (web::WebState*)insertWebStateWithURL:(const GURL&)URL referrer:(const web::Referrer&)referrer transition:(ui::PageTransition)transition @@ -476,7 +487,7 @@ } // NOTE: This can be called multiple times, so must be robust against that. -- (void)browserStateDestroyed { +- (void)disconnect { if (!_browserState) return; @@ -502,20 +513,23 @@ _webStateList->RemoveObserver(webStateListObserver.get()); _webStateListObservers.clear(); _retainedWebStateListObservers = nil; + _webStateList = nullptr; _clearPoliciesTaskTracker.TryCancelAll(); _tabUsageRecorder.reset(); _webStateObserver.reset(); } +- (void)browserStateDestroyed { + [self disconnect]; +} + #pragma mark - SessionWindowRestoring(public) - (void)saveSessionImmediately:(BOOL)immediately { - // Do nothing if there are tabs in the model but no selected tab. This is - // a transitional state. - if ((!_webStateList->GetActiveWebState() && _webStateList->count()) || - !_browserState) + if (![self canSaveCurrentSession]) return; + NSString* statePath = base::SysUTF8ToNSString(_browserState->GetStatePath().AsUTF8Unsafe()); __weak TabModel* weakSelf = self; @@ -529,13 +543,28 @@ #pragma mark - Private methods +// YES if the current session can be saved. +- (BOOL)canSaveCurrentSession { + // A session requires an active browser state and web state list. + if (!_browserState || !_webStateList) + return NO; + // Sessions where there's no active tab shouldn't be saved, unless the web + // state list is empty. This is a transitional state. + if (!_webStateList->empty() && !_webStateList->GetActiveWebState()) + return NO; + + return YES; +} + - (SessionIOS*)sessionForSaving { + if (![self canSaveCurrentSession]) + return nil; // Build the array of sessions. Copy the session objects as the saving will // be done on a separate thread. // TODO(crbug.com/661986): This could get expensive especially since this // window may never be saved (if another call comes in before the delay). return [[SessionIOS alloc] - initWithWindows:@[ SerializeWebStateList(_webStateList.get()) ]]; + initWithWindows:@[ SerializeWebStateList(_webStateList) ]]; } - (BOOL)isWebUsageEnabled { @@ -567,7 +596,7 @@ web::WebState::CreateParams createParams(_browserState); DeserializeWebStateList( - _webStateList.get(), window, + _webStateList, window, base::BindRepeating(&web::WebState::CreateWithStorageSession, createParams)); @@ -658,7 +687,7 @@ &_clearPoliciesTaskTracker, base::CreateSingleThreadTaskRunner({web::WebThread::IO}), web::BrowserState::GetCertificatePolicyCache(_browserState), - _webStateList.get()); + _webStateList); // Normally, the session is saved after some timer expires but since the app // is about to enter the background send YES to save the session immediately.
diff --git a/ios/chrome/browser/tabs/tab_model_list_unittest.mm b/ios/chrome/browser/tabs/tab_model_list_unittest.mm index 83e7f60..6ab7936 100644 --- a/ios/chrome/browser/tabs/tab_model_list_unittest.mm +++ b/ios/chrome/browser/tabs/tab_model_list_unittest.mm
@@ -7,9 +7,11 @@ #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #include "ios/chrome/browser/browser_state/test_chrome_browser_state_manager.h" +#import "ios/chrome/browser/main/browser_web_state_list_delegate.h" #import "ios/chrome/browser/sessions/test_session_service.h" #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/tabs/tab_model_list_observer.h" +#import "ios/chrome/browser/web_state_list/web_state_list.h" #include "ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_state_manager.h" #include "ios/web/public/test/web_task_environment.h" #include "testing/gmock/include/gmock/gmock.h" @@ -40,18 +42,28 @@ TabModelListTest() : scoped_browser_state_manager_( std::make_unique<TestChromeBrowserStateManager>( - TestChromeBrowserState::Builder().Build())) {} + TestChromeBrowserState::Builder().Build())), + web_state_list_delegate_( + std::make_unique<BrowserWebStateListDelegate>()), + web_state_list_( + std::make_unique<WebStateList>(web_state_list_delegate_.get())), + otr_web_state_list_delegate_( + std::make_unique<BrowserWebStateListDelegate>()), + otr_web_state_list_( + std::make_unique<WebStateList>(web_state_list_delegate_.get())) {} TabModel* CreateTabModel() { return [[TabModel alloc] initWithSessionService:[[TestSessionService alloc] init] - browserState:browser_state()]; + browserState:browser_state() + webStateList:web_state_list_.get()]; } TabModel* CreateOffTheRecordTabModel() { return [[TabModel alloc] initWithSessionService:[[TestSessionService alloc] init] - browserState:otr_browser_state()]; + browserState:otr_browser_state() + webStateList:otr_web_state_list_.get()]; } NSArray<TabModel*>* RegisteredTabModels() { @@ -76,6 +88,12 @@ web::WebTaskEnvironment task_environment_; IOSChromeScopedTestingChromeBrowserStateManager scoped_browser_state_manager_; + std::unique_ptr<WebStateListDelegate> web_state_list_delegate_; + std::unique_ptr<WebStateList> web_state_list_; + + std::unique_ptr<WebStateListDelegate> otr_web_state_list_delegate_; + std::unique_ptr<WebStateList> otr_web_state_list_; + DISALLOW_COPY_AND_ASSIGN(TabModelListTest); }; @@ -105,7 +123,7 @@ EXPECT_CALL(observer, TabModelUnregisteredFromBrowserState( Eq(tab_model), Eq(otr_browser_state()))) .Times(0); - [tab_model browserStateDestroyed]; + [tab_model disconnect]; EXPECT_EQ([RegisteredTabModels() count], 0u); TabModelList::RemoveObserver(&observer); @@ -137,7 +155,7 @@ EXPECT_CALL(observer, TabModelUnregisteredFromBrowserState( Eq(tab_model), Eq(browser_state()))) .Times(0); - [tab_model browserStateDestroyed]; + [tab_model disconnect]; EXPECT_EQ([RegisteredOffTheRecordTabModels() count], 0u); TabModelList::RemoveObserver(&observer); @@ -156,8 +174,8 @@ EXPECT_NE([RegisteredTabModels() indexOfObject:tab_model2], static_cast<NSUInteger>(NSNotFound)); - [tab_model1 browserStateDestroyed]; - [tab_model2 browserStateDestroyed]; + [tab_model1 disconnect]; + [tab_model2 disconnect]; EXPECT_EQ([RegisteredTabModels() count], 0u); } @@ -175,8 +193,8 @@ EXPECT_NE([RegisteredOffTheRecordTabModels() indexOfObject:tab_model2], static_cast<NSUInteger>(NSNotFound)); - [tab_model1 browserStateDestroyed]; - [tab_model2 browserStateDestroyed]; + [tab_model1 disconnect]; + [tab_model2 disconnect]; EXPECT_EQ([RegisteredOffTheRecordTabModels() count], 0u); }
diff --git a/ios/chrome/browser/tabs/tab_model_unittest.mm b/ios/chrome/browser/tabs/tab_model_unittest.mm index 9cc927d..1e76a11 100644 --- a/ios/chrome/browser/tabs/tab_model_unittest.mm +++ b/ios/chrome/browser/tabs/tab_model_unittest.mm
@@ -13,6 +13,7 @@ #include "ios/chrome/browser/browser_state/test_chrome_browser_state_manager.h" #include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/infobars/infobar_manager_impl.h" +#import "ios/chrome/browser/main/browser_web_state_list_delegate.h" #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h" #import "ios/chrome/browser/ntp/new_tab_page_tab_helper_delegate.h" #include "ios/chrome/browser/sessions/ios_chrome_session_tab_helper.h" @@ -23,6 +24,7 @@ #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/web/chrome_web_client.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" +#import "ios/chrome/browser/web_state_list/web_state_list_delegate.h" #import "ios/chrome/browser/web_state_list/web_state_opener.h" #import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler.h" #import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler_factory.h" @@ -67,7 +69,11 @@ TabModelTest() : scoped_browser_state_manager_( std::make_unique<TestChromeBrowserStateManager>(base::FilePath())), - web_client_(std::make_unique<ChromeWebClient>()) { + web_client_(std::make_unique<ChromeWebClient>()), + web_state_list_delegate_( + std::make_unique<BrowserWebStateListDelegate>()), + web_state_list_( + std::make_unique<WebStateList>(web_state_list_delegate_.get())) { DCHECK_CURRENTLY_ON(web::WebThread::UI); if (GetParam() == NavigationManagerChoice::LEGACY) { @@ -105,7 +111,7 @@ if (tab_model_) { web_usage_enabler_->SetWebStateList(nullptr); @autoreleasepool { - [tab_model_ browserStateDestroyed]; + [tab_model_ disconnect]; tab_model_ = nil; } } @@ -118,7 +124,8 @@ SessionWindowIOS* session_window) { TabModel* tab_model([[TabModel alloc] initWithSessionService:session_service - browserState:chrome_browser_state_.get()]); + browserState:chrome_browser_state_.get() + webStateList:web_state_list_.get()]); [tab_model restoreSessionWindow:session_window forInitialRestore:YES]; [tab_model setPrimary:YES]; return tab_model; @@ -141,6 +148,8 @@ web::WebTaskEnvironment task_environment_; IOSChromeScopedTestingChromeBrowserStateManager scoped_browser_state_manager_; web::ScopedTestingWebClient web_client_; + std::unique_ptr<WebStateListDelegate> web_state_list_delegate_; + std::unique_ptr<WebStateList> web_state_list_; SessionWindowIOS* session_window_; std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; WebStateListWebUsageEnabler* web_usage_enabler_; @@ -183,8 +192,8 @@ openedByDOM:NO atIndex:0 inBackground:NO]; - [tab_model_ browserStateDestroyed]; - [tab_model_ browserStateDestroyed]; + [tab_model_ disconnect]; + [tab_model_ disconnect]; } TEST_P(TabModelTest, InsertUrlMultiple) {
diff --git a/ios/chrome/browser/test/BUILD.gn b/ios/chrome/browser/test/BUILD.gn index d5138a31..95574d6 100644 --- a/ios/chrome/browser/test/BUILD.gn +++ b/ios/chrome/browser/test/BUILD.gn
@@ -17,6 +17,7 @@ "//ios/chrome/browser/autocomplete", "//ios/chrome/browser/bookmarks", "//ios/chrome/browser/browser_state:test_support", + "//ios/chrome/browser/main", "//ios/chrome/browser/main:test_support", "//ios/chrome/browser/prerender", "//ios/chrome/browser/search_engines", @@ -27,6 +28,7 @@ "//ios/chrome/browser/ui/browser_view", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/web:web_internal", + "//ios/chrome/browser/web_state_list", "//ios/chrome/test:test_support", "//ios/chrome/test/base:perf_test_support", "//ios/public/provider/chrome/browser",
diff --git a/ios/chrome/browser/test/perf_test_with_bvc_ios.h b/ios/chrome/browser/test/perf_test_with_bvc_ios.h index 8aa0bc3..e91d627 100644 --- a/ios/chrome/browser/test/perf_test_with_bvc_ios.h +++ b/ios/chrome/browser/test/perf_test_with_bvc_ios.h
@@ -10,6 +10,8 @@ #include <memory> #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" +#import "ios/chrome/browser/main/browser_web_state_list_delegate.h" +#import "ios/chrome/browser/web_state_list/web_state_list.h" #include "ios/chrome/test/base/perf_test_ios.h" #include "ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_provider.h" #include "ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_state_manager.h" @@ -52,6 +54,11 @@ std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; std::unique_ptr<TestChromeBrowserState> incognito_chrome_browser_state_; + BrowserWebStateListDelegate web_state_list_delegate_; + + WebStateList web_state_list_; + WebStateList otr_web_state_list_; + TabModel* tab_model_; TabModel* otr_tab_model_;
diff --git a/ios/chrome/browser/test/perf_test_with_bvc_ios.mm b/ios/chrome/browser/test/perf_test_with_bvc_ios.mm index 183bce9..5318107 100644 --- a/ios/chrome/browser/test/perf_test_with_bvc_ios.mm +++ b/ios/chrome/browser/test/perf_test_with_bvc_ios.mm
@@ -46,7 +46,9 @@ web_client_(std::make_unique<ChromeWebClient>()), provider_(ios::CreateChromeBrowserProvider()), browser_state_manager_( - std::make_unique<TestChromeBrowserStateManager>(base::FilePath())) {} + std::make_unique<TestChromeBrowserStateManager>(base::FilePath())), + web_state_list_(&web_state_list_delegate_), + otr_web_state_list_(&web_state_list_delegate_) {} PerfTestWithBVC::PerfTestWithBVC(std::string testGroup, std::string firstLabel, @@ -65,7 +67,9 @@ web_client_(std::make_unique<ChromeWebClient>()), provider_(ios::CreateChromeBrowserProvider()), browser_state_manager_( - std::make_unique<TestChromeBrowserStateManager>(base::FilePath())) {} + std::make_unique<TestChromeBrowserStateManager>(base::FilePath())), + web_state_list_(&web_state_list_delegate_), + otr_web_state_list_(&web_state_list_delegate_) {} PerfTestWithBVC::~PerfTestWithBVC() {} @@ -102,13 +106,15 @@ // view controller, which is created in OpenStackView(). tab_model_ = [[TabModel alloc] initWithSessionService:[SessionServiceIOS sharedService] - browserState:chrome_browser_state_.get()]; + browserState:chrome_browser_state_.get() + webStateList:&web_state_list_]; [tab_model_ restoreSessionWindow:session.sessionWindows[0] forInitialRestore:YES]; otr_tab_model_ = [[TabModel alloc] initWithSessionService:[SessionServiceIOS sharedService] browserState:chrome_browser_state_ - ->GetOffTheRecordChromeBrowserState()]; + ->GetOffTheRecordChromeBrowserState() + webStateList:&otr_web_state_list_]; [otr_tab_model_ restoreSessionWindow:session.sessionWindows[0] forInitialRestore:YES]; @@ -149,7 +155,7 @@ bvc_ = nil; bvc_factory_ = nil; tab_model_ = nil; - [otr_tab_model_ browserStateDestroyed]; + [otr_tab_model_ disconnect]; otr_tab_model_ = nil; // The base class |TearDown| method calls the run loop so the
diff --git a/ios/chrome/browser/ui/badges/BUILD.gn b/ios/chrome/browser/ui/badges/BUILD.gn index 4d5efa3..069fe26 100644 --- a/ios/chrome/browser/ui/badges/BUILD.gn +++ b/ios/chrome/browser/ui/badges/BUILD.gn
@@ -17,8 +17,6 @@ sources = [ "badge_button.h", "badge_button.mm", - "badge_button_action_handler.h", - "badge_button_action_handler.mm", "badge_button_factory.h", "badge_button_factory.mm", "badge_consumer.h",
diff --git a/ios/chrome/browser/ui/badges/badge_button_action_handler.h b/ios/chrome/browser/ui/badges/badge_button_action_handler.h deleted file mode 100644 index 96f7446..0000000 --- a/ios/chrome/browser/ui/badges/badge_button_action_handler.h +++ /dev/null
@@ -1,30 +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 IOS_CHROME_BROWSER_UI_BADGES_BADGE_BUTTON_ACTION_HANDLER_H_ -#define IOS_CHROME_BROWSER_UI_BADGES_BADGE_BUTTON_ACTION_HANDLER_H_ - -#import <UIKit/UIKit.h> - -@protocol InfobarCommands; -@protocol BadgeDelegate; - -// Handler for the actions associated with the different badge buttons. -@interface BadgeButtonActionHandler : NSObject - -// The dispatcher for badge button actions. -@property(nonatomic, weak) id<InfobarCommands> dispatcher; - -// The command handler. -@property(nonatomic, weak) id<BadgeDelegate> buttonActionDelegate; - -// Action when a Passwords badge is tapped. -- (void)passwordsBadgeButtonTapped:(id)sender; - -// Action when the overflow badge is tapped. -- (void)overflowBadgeButtonTapped:(id)sender; - -@end - -#endif // IOS_CHROME_BROWSER_UI_BADGES_BADGE_BUTTON_ACTION_HANDLER_H_
diff --git a/ios/chrome/browser/ui/badges/badge_button_action_handler.mm b/ios/chrome/browser/ui/badges/badge_button_action_handler.mm deleted file mode 100644 index 5324e26..0000000 --- a/ios/chrome/browser/ui/badges/badge_button_action_handler.mm +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/badges/badge_button_action_handler.h" - -#include "base/mac/foundation_util.h" -#include "base/metrics/user_metrics.h" -#include "ios/chrome/browser/infobars/infobar_metrics_recorder.h" -#import "ios/chrome/browser/infobars/infobar_type.h" -#import "ios/chrome/browser/ui/badges/badge_button.h" -#import "ios/chrome/browser/ui/badges/badge_delegate.h" -#import "ios/chrome/browser/ui/commands/infobar_commands.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@implementation BadgeButtonActionHandler - -- (void)passwordsBadgeButtonTapped:(id)sender { - BadgeButton* badgeButton = base::mac::ObjCCastStrict<BadgeButton>(sender); - MobileMessagesBadgeState state; - if (badgeButton.accepted) { - state = MobileMessagesBadgeState::Active; - base::RecordAction( - base::UserMetricsAction("MobileMessagesBadgeAcceptedTapped")); - } else { - state = MobileMessagesBadgeState::Inactive; - base::RecordAction( - base::UserMetricsAction("MobileMessagesBadgeNonAcceptedTapped")); - } - InfobarMetricsRecorder* metricsRecorder; - if (badgeButton.badgeType == BadgeType::kBadgeTypePasswordSave) { - metricsRecorder = [[InfobarMetricsRecorder alloc] - initWithType:InfobarType::kInfobarTypePasswordSave]; - [self.dispatcher displayModalInfobar:InfobarType::kInfobarTypePasswordSave]; - } else if (badgeButton.badgeType == BadgeType::kBadgeTypePasswordUpdate) { - metricsRecorder = [[InfobarMetricsRecorder alloc] - initWithType:InfobarType::kInfobarTypePasswordUpdate]; - [self.dispatcher - displayModalInfobar:InfobarType::kInfobarTypePasswordUpdate]; - } - [metricsRecorder recordBadgeTappedInState:state]; -} - -- (void)overflowBadgeButtonTapped:(id)sender { - [self.buttonActionDelegate showOverflowMenu]; - // TODO(crbug.com/976901): Add metric for this action. -} - -@end
diff --git a/ios/chrome/browser/ui/badges/badge_button_factory.h b/ios/chrome/browser/ui/badges/badge_button_factory.h index cdbd3538..d003811 100644 --- a/ios/chrome/browser/ui/badges/badge_button_factory.h +++ b/ios/chrome/browser/ui/badges/badge_button_factory.h
@@ -11,18 +11,18 @@ @class BadgeButtonActionHandler; @class BadgeButton; +@protocol BadgeDelegate; // BadgeButtonFactory Factory creates BadgButton objects with certain // styles and configurations, depending on its type. @interface BadgeButtonFactory : NSObject -- (instancetype)initWithActionHandler:(BadgeButtonActionHandler*)actionHandler - NS_DESIGNATED_INITIALIZER; -- (instancetype)init NS_UNAVAILABLE; - // Yes if in Incognito mode. @property(nonatomic, assign) BOOL incognito; +// Action handler delegate for the buttons. +@property(nonatomic, weak) id<BadgeDelegate> delegate; + // Returns a properly configured BadgButton associated with |badgeType|. - (BadgeButton*)getBadgeButtonForBadgeType:(BadgeType)badgeType;
diff --git a/ios/chrome/browser/ui/badges/badge_button_factory.mm b/ios/chrome/browser/ui/badges/badge_button_factory.mm index c691bc8..1d3768c1 100644 --- a/ios/chrome/browser/ui/badges/badge_button_factory.mm +++ b/ios/chrome/browser/ui/badges/badge_button_factory.mm
@@ -6,8 +6,8 @@ #import "base/logging.h" #import "ios/chrome/browser/ui/badges/badge_button.h" -#import "ios/chrome/browser/ui/badges/badge_button_action_handler.h" #import "ios/chrome/browser/ui/badges/badge_constants.h" +#import "ios/chrome/browser/ui/badges/badge_delegate.h" #import "ios/chrome/common/colors/dynamic_color_util.h" #import "ios/chrome/common/colors/semantic_color_names.h" #include "ios/chrome/grit/ios_strings.h" @@ -17,23 +17,8 @@ #error "This file requires ARC support." #endif -@interface BadgeButtonFactory () - -// Action handlers for the buttons. -@property(nonatomic, strong) BadgeButtonActionHandler* actionHandler; - -@end - @implementation BadgeButtonFactory -- (instancetype)initWithActionHandler:(BadgeButtonActionHandler*)actionHandler { - self = [super init]; - if (self) { - _actionHandler = actionHandler; - } - return self; -} - - (BadgeButton*)getBadgeButtonForBadgeType:(BadgeType)badgeType { switch (badgeType) { case BadgeType::kBadgeTypePasswordSave: @@ -58,7 +43,7 @@ [self createButtonForType:BadgeType::kBadgeTypePasswordSave imageNamed:@"infobar_passwords_icon" renderingMode:UIImageRenderingModeAlwaysTemplate]; - [button addTarget:self.actionHandler + [button addTarget:self.delegate action:@selector(passwordsBadgeButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; button.accessibilityIdentifier = @@ -73,7 +58,7 @@ [self createButtonForType:BadgeType::kBadgeTypePasswordUpdate imageNamed:@"infobar_passwords_icon" renderingMode:UIImageRenderingModeAlwaysTemplate]; - [button addTarget:self.actionHandler + [button addTarget:self.delegate action:@selector(passwordsBadgeButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; button.accessibilityIdentifier = @@ -106,7 +91,7 @@ [self createButtonForType:BadgeType::kBadgeTypeOverflow imageNamed:@"wrench_badge" renderingMode:UIImageRenderingModeAlwaysTemplate]; - [button addTarget:self.actionHandler + [button addTarget:self.delegate action:@selector(overflowBadgeButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; button.accessibilityIdentifier = kBadgeButtonOverflowAccessibilityIdentifier;
diff --git a/ios/chrome/browser/ui/badges/badge_constants.h b/ios/chrome/browser/ui/badges/badge_constants.h index 85fcac6..99db012 100644 --- a/ios/chrome/browser/ui/badges/badge_constants.h +++ b/ios/chrome/browser/ui/badges/badge_constants.h
@@ -13,4 +13,7 @@ extern NSString* const kBadgeButtonIncognitoAccessibilityIdentifier; extern NSString* const kBadgeButtonOverflowAccessibilityIdentifier; +// A11y identifier for the Badge Popup Menu Table View. +extern NSString* const kBadgePopupMenuTableViewAccessibilityIdentifier; + #endif // IOS_CHROME_BROWSER_UI_BADGES_BADGE_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/badges/badge_constants.mm b/ios/chrome/browser/ui/badges/badge_constants.mm index 1a917cac..803194f 100644 --- a/ios/chrome/browser/ui/badges/badge_constants.mm +++ b/ios/chrome/browser/ui/badges/badge_constants.mm
@@ -19,3 +19,6 @@ NSString* const kBadgeButtonOverflowAccessibilityIdentifier = @"badgeButtonOverflowAXID"; + +NSString* const kBadgePopupMenuTableViewAccessibilityIdentifier = + @"badgePopupMenuOverflowAXID";
diff --git a/ios/chrome/browser/ui/badges/badge_delegate.h b/ios/chrome/browser/ui/badges/badge_delegate.h index 9c71a7e..538eeb4f 100644 --- a/ios/chrome/browser/ui/badges/badge_delegate.h +++ b/ios/chrome/browser/ui/badges/badge_delegate.h
@@ -5,10 +5,13 @@ #ifndef IOS_CHROME_BROWSER_UI_BADGES_BADGE_DELEGATE_H_ #define IOS_CHROME_BROWSER_UI_BADGES_BADGE_DELEGATE_H_ -// Protocol to communicate Badge actions to the coordinator. +// Protocol to communicate Badge actions to the mediator. @protocol BadgeDelegate -// Shows the badge overflow menu. -- (void)showOverflowMenu; +// Action when a Passwords badge is tapped. +- (void)passwordsBadgeButtonTapped:(id)sender; + +// Action when the overflow badge is tapped. +- (void)overflowBadgeButtonTapped:(id)sender; @end #endif // IOS_CHROME_BROWSER_UI_BADGES_BADGE_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/badges/badge_mediator.h b/ios/chrome/browser/ui/badges/badge_mediator.h index 31739f3..81e8e67 100644 --- a/ios/chrome/browser/ui/badges/badge_mediator.h +++ b/ios/chrome/browser/ui/badges/badge_mediator.h
@@ -7,11 +7,16 @@ #import <UIKit/UIKit.h> +#import "ios/chrome/browser/ui/badges/badge_delegate.h" + @protocol BadgeConsumer; +@protocol BadgeItem; +@protocol BrowserCoordinatorCommands; +@protocol InfobarCommands; class WebStateList; // A mediator object that updates the consumer when the state of badges changes. -@interface BadgeMediator : NSObject +@interface BadgeMediator : NSObject <BadgeDelegate> - (instancetype)initWithConsumer:(id<BadgeConsumer>)consumer webStateList:(WebStateList*)webStateList @@ -21,6 +26,10 @@ // Stops observing all objects. - (void)disconnect; +// The dispatcher for badge related actions. +@property(nonatomic, weak) id<InfobarCommands, BrowserCoordinatorCommands> + dispatcher; + @end #endif // IOS_CHROME_BROWSER_UI_BADGES_BADGE_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/badges/badge_mediator.mm b/ios/chrome/browser/ui/badges/badge_mediator.mm index e52367a..1180cb8 100644 --- a/ios/chrome/browser/ui/badges/badge_mediator.mm +++ b/ios/chrome/browser/ui/badges/badge_mediator.mm
@@ -4,12 +4,20 @@ #import "ios/chrome/browser/ui/badges/badge_mediator.h" +#include "base/mac/foundation_util.h" +#include "base/metrics/user_metrics.h" #include "ios/chrome/browser/infobars/infobar_badge_tab_helper.h" #include "ios/chrome/browser/infobars/infobar_badge_tab_helper_delegate.h" +#include "ios/chrome/browser/infobars/infobar_metrics_recorder.h" #import "ios/chrome/browser/infobars/infobar_type.h" +#import "ios/chrome/browser/ui/badges/badge_button.h" #import "ios/chrome/browser/ui/badges/badge_consumer.h" #import "ios/chrome/browser/ui/badges/badge_item.h" #import "ios/chrome/browser/ui/badges/badge_static_item.h" +#import "ios/chrome/browser/ui/badges/badge_tappable_item.h" +#import "ios/chrome/browser/ui/commands/browser_coordinator_commands.h" +#import "ios/chrome/browser/ui/commands/infobar_commands.h" +#import "ios/chrome/browser/ui/list_model/list_model.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h" #include "ios/web/public/browser_state.h" @@ -18,6 +26,14 @@ #error "This file requires ARC support." #endif +namespace { +// The number of Fullscreen badges +const int kNumberOfFullScrenBadges = 1; +// The minimum number of non-Fullscreen badges to display the overflow popup +// menu. +const int kMinimumNonFullScreenBadgesForOverflow = 2; +} + @interface BadgeMediator () <InfobarBadgeTabHelperDelegate, WebStateListObserving> { std::unique_ptr<WebStateListObserverBridge> _webStateListObserver; @@ -70,7 +86,7 @@ - (void)addInfobarBadge:(id<BadgeItem>)badgeItem { if (!self.badges) { - self.badges = [[NSMutableArray alloc] init]; + self.badges = [NSMutableArray array]; } [self.badges addObject:badgeItem]; [self updateBadgesShown]; @@ -96,6 +112,47 @@ } } +#pragma mark - BadgeDelegate + +- (void)passwordsBadgeButtonTapped:(id)sender { + BadgeButton* badgeButton = base::mac::ObjCCastStrict<BadgeButton>(sender); + MobileMessagesBadgeState state; + if (badgeButton.accepted) { + state = MobileMessagesBadgeState::Active; + base::RecordAction( + base::UserMetricsAction("MobileMessagesBadgeAcceptedTapped")); + } else { + state = MobileMessagesBadgeState::Inactive; + base::RecordAction( + base::UserMetricsAction("MobileMessagesBadgeNonAcceptedTapped")); + } + InfobarMetricsRecorder* metricsRecorder; + if (badgeButton.badgeType == BadgeType::kBadgeTypePasswordSave) { + metricsRecorder = [[InfobarMetricsRecorder alloc] + initWithType:InfobarType::kInfobarTypePasswordSave]; + [self.dispatcher displayModalInfobar:InfobarType::kInfobarTypePasswordSave]; + } else if (badgeButton.badgeType == BadgeType::kBadgeTypePasswordUpdate) { + metricsRecorder = [[InfobarMetricsRecorder alloc] + initWithType:InfobarType::kInfobarTypePasswordUpdate]; + [self.dispatcher + displayModalInfobar:InfobarType::kInfobarTypePasswordUpdate]; + } + [metricsRecorder recordBadgeTappedInState:state]; +} + +- (void)overflowBadgeButtonTapped:(id)sender { + NSMutableArray<id<BadgeItem>>* popupMenuBadges = + [[NSMutableArray alloc] init]; + // Get all non-fullscreen badges. + for (id<BadgeItem> item in self.badges) { + if (![item isFullScreen]) { + [popupMenuBadges addObject:item]; + } + } + [self.dispatcher displayPopupMenuWithBadgeItems:popupMenuBadges]; + // TODO(crbug.com/976901): Add metric for this action. +} + #pragma mark - WebStateListObserver - (void)webStateList:(WebStateList*)webStateList @@ -131,12 +188,20 @@ id<BadgeItem> displayedBadge; id<BadgeItem> fullScreenBadge; for (id<BadgeItem> item in self.badges) { - if (item.isFullScreen) { + if ([item isFullScreen]) { fullScreenBadge = item; } else { displayedBadge = item; } } + NSInteger count = [self.badges count]; + if (fullScreenBadge) { + count -= kNumberOfFullScrenBadges; + } + if (count >= kMinimumNonFullScreenBadgesForOverflow) { + displayedBadge = [[BadgeTappableItem alloc] + initWithBadgeType:BadgeType::kBadgeTypeOverflow]; + } [self.consumer updateDisplayedBadge:displayedBadge fullScreenBadge:fullScreenBadge]; } @@ -156,9 +221,11 @@ self.badges = [[NSArray arrayWithObjects:&infobarBadges[0] count:infobarBadges.size()] mutableCopy]; id<BadgeItem> displayedBadge; - // Set the last badge as the displayed badge, since there is currently only - // one Infobar with a badge. - if ([self.badges count] > 0) { + if ([self.badges count] > 1) { + // Show the overflow menu badge when there are multiple badges. + displayedBadge = [[BadgeTappableItem alloc] + initWithBadgeType:BadgeType::kBadgeTypeOverflow]; + } else if ([self.badges count] == 1) { displayedBadge = [self.badges lastObject]; } id<BadgeItem> fullScreenBadge;
diff --git a/ios/chrome/browser/ui/badges/badge_mediator_unittest.mm b/ios/chrome/browser/ui/badges/badge_mediator_unittest.mm index a759447..12dc1a8 100644 --- a/ios/chrome/browser/ui/badges/badge_mediator_unittest.mm +++ b/ios/chrome/browser/ui/badges/badge_mediator_unittest.mm
@@ -158,7 +158,7 @@ AddInfobar(); AddSecondInfobar(); EXPECT_EQ(badge_consumer_.displayedBadge.badgeType, - BadgeType::kBadgeTypePasswordUpdate); + BadgeType::kBadgeTypeOverflow); RemoveInfobar(); ASSERT_TRUE(badge_consumer_.displayedBadge); EXPECT_EQ(badge_consumer_.displayedBadge.badgeType,
diff --git a/ios/chrome/browser/ui/badges/badge_popup_menu_coordinator.mm b/ios/chrome/browser/ui/badges/badge_popup_menu_coordinator.mm index 9aee30c5..5ee73b82 100644 --- a/ios/chrome/browser/ui/badges/badge_popup_menu_coordinator.mm +++ b/ios/chrome/browser/ui/badges/badge_popup_menu_coordinator.mm
@@ -6,6 +6,7 @@ #include "base/logging.h" #import "ios/chrome/browser/infobars/infobar_type.h" +#import "ios/chrome/browser/ui/badges/badge_constants.h" #import "ios/chrome/browser/ui/badges/badge_item.h" #import "ios/chrome/browser/ui/badges/badge_popup_menu_item.h" #import "ios/chrome/browser/ui/popup_menu/public/cells/popup_menu_item.h" @@ -45,6 +46,8 @@ self.popupViewController = [[PopupMenuTableViewController alloc] init]; self.popupViewController.baseViewController = self.baseViewController; self.popupViewController.delegate = self; + self.popupViewController.tableView.accessibilityIdentifier = + kBadgePopupMenuTableViewAccessibilityIdentifier; self.consumer = self.popupViewController; [self.consumer setPopupMenuItems:self.popupMenuItems]; self.popupMenuPresenter = [[PopupMenuPresenter alloc] init];
diff --git a/ios/chrome/browser/ui/badges/badge_popup_menu_item.mm b/ios/chrome/browser/ui/badges/badge_popup_menu_item.mm index eab7ba6..23864cb 100644 --- a/ios/chrome/browser/ui/badges/badge_popup_menu_item.mm +++ b/ios/chrome/browser/ui/badges/badge_popup_menu_item.mm
@@ -71,6 +71,7 @@ withStyler:(ChromeTableViewStyler*)styler { [super configureCell:cell withStyler:styler]; cell.titleLabel.text = self.title; + cell.accessibilityTraits = UIAccessibilityTraitButton; UIImage* badgeImage; switch (self.badgeType) { case BadgeType::kBadgeTypePasswordSave:
diff --git a/ios/chrome/browser/ui/badges/badge_view_controller.mm b/ios/chrome/browser/ui/badges/badge_view_controller.mm index 73d239e..ccb00aa 100644 --- a/ios/chrome/browser/ui/badges/badge_view_controller.mm +++ b/ios/chrome/browser/ui/badges/badge_view_controller.mm
@@ -169,10 +169,4 @@ [self.stackView insertArrangedSubview:_fullScreenBadge atIndex:0]; } -#pragma mark - Helpers - -- (void)updateDisplayedBadges { - self.displayedBadge = [self.badges lastObject]; -} - @end
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/ui/browser_view/BUILD.gn index 8ba80242..cfa78c6 100644 --- a/ios/chrome/browser/ui/browser_view/BUILD.gn +++ b/ios/chrome/browser/ui/browser_view/BUILD.gn
@@ -81,6 +81,7 @@ "//ios/chrome/browser/ui/autofill/form_input_accessory", "//ios/chrome/browser/ui/autofill/manual_fill", "//ios/chrome/browser/ui/autofill/manual_fill:manual_fill_ui", + "//ios/chrome/browser/ui/badges:badges_popup_menu", "//ios/chrome/browser/ui/bookmarks", "//ios/chrome/browser/ui/browser_container", "//ios/chrome/browser/ui/browser_container:ui", @@ -166,6 +167,7 @@ "//ios/public/provider/chrome/browser/ui", "//ios/public/provider/chrome/browser/voice", "//ios/third_party/material_components_ios", + "//ios/third_party/webkit", "//ios/web", "//ios/web/common", "//ios/web/public", @@ -183,7 +185,6 @@ "MessageUI.framework", "Photos.framework", "UIKit.framework", - "WebKit.framework", ] } @@ -267,6 +268,7 @@ "//ios/chrome/test/app:test_support", "//ios/chrome/test/earl_grey:test_support", "//ios/third_party/earl_grey:earl_grey+link", + "//ios/third_party/webkit", "//ios/web:earl_grey_test_support", "//ios/web/public/test", "//ios/web/public/test/http_server", @@ -275,7 +277,6 @@ ] libs = [ "UIKit.framework", - "WebKit.framework", "XCTest.framework", ] }
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm index 8762be02..0b69cf98 100644 --- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm +++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -22,6 +22,7 @@ #import "ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_coordinator.h" #import "ios/chrome/browser/ui/autofill/manual_fill/all_password_coordinator.h" #import "ios/chrome/browser/ui/autofill/manual_fill/manual_fill_injection_handler.h" +#import "ios/chrome/browser/ui/badges/badge_popup_menu_coordinator.h" #import "ios/chrome/browser/ui/browser_container/browser_container_coordinator.h" #import "ios/chrome/browser/ui/browser_view/browser_view_controller+private.h" #import "ios/chrome/browser/ui/browser_view/browser_view_controller.h" @@ -29,6 +30,7 @@ #import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/commands/browser_coordinator_commands.h" #import "ios/chrome/browser/ui/commands/command_dispatcher.h" +#import "ios/chrome/browser/ui/commands/infobar_commands.h" #import "ios/chrome/browser/ui/download/ar_quick_look_coordinator.h" #import "ios/chrome/browser/ui/download/pass_kit_coordinator.h" #import "ios/chrome/browser/ui/open_in/open_in_mediator.h" @@ -90,6 +92,10 @@ @property(nonatomic, strong) AutofillAddCreditCardCoordinator* addCreditCardCoordinator; +// Coordinator for the badge popup menu. +@property(nonatomic, strong) + BadgePopupMenuCoordinator* badgePopupMenuCoordinator; + // Coordinator in charge of the presenting autofill options above the // keyboard. @property(nonatomic, strong) @@ -213,6 +219,15 @@ dismissOmnibox:dismissOmnibox]; } +- (void)displayPopupMenuWithBadgeItems:(NSArray<id<BadgeItem>>*)badgeItems { + self.badgePopupMenuCoordinator = [[BadgePopupMenuCoordinator alloc] + initWithBaseViewController:self.viewController]; + self.badgePopupMenuCoordinator.dispatcher = + static_cast<id<InfobarCommands>>(self.dispatcher); + [self.badgePopupMenuCoordinator setBadgeItemsToShow:badgeItems]; + [self.badgePopupMenuCoordinator start]; +} + #pragma mark - Private // Instantiates a BrowserViewController.
diff --git a/ios/chrome/browser/ui/commands/BUILD.gn b/ios/chrome/browser/ui/commands/BUILD.gn index 32b7034..c08a3b1 100644 --- a/ios/chrome/browser/ui/commands/BUILD.gn +++ b/ios/chrome/browser/ui/commands/BUILD.gn
@@ -8,7 +8,6 @@ sources = [ "activity_service_commands.h", "application_commands.h", - "badge_commands.h", "browser_commands.h", "browser_coordinator_commands.h", "browsing_data_commands.h",
diff --git a/ios/chrome/browser/ui/commands/badge_commands.h b/ios/chrome/browser/ui/commands/badge_commands.h deleted file mode 100644 index 778eda6..0000000 --- a/ios/chrome/browser/ui/commands/badge_commands.h +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_COMMANDS_BADGE_COMMANDS_H_ -#define IOS_CHROME_BROWSER_UI_COMMANDS_BADGE_COMMANDS_H_ - -#import <Foundation/Foundation.h> - -@protocol BadgeItem; - -@protocol BadgeCommands <NSObject> -// Displays the Badge popup menu showing |badgeItems|. -- (void)displayPopupMenuWithBadgeItems:(NSArray<id<BadgeItem>>*)badgeItems; -@end - -#endif // IOS_CHROME_BROWSER_UI_COMMANDS_BADGE_COMMANDS_H_
diff --git a/ios/chrome/browser/ui/commands/browser_coordinator_commands.h b/ios/chrome/browser/ui/commands/browser_coordinator_commands.h index 8aeaa92..84d6225 100644 --- a/ios/chrome/browser/ui/commands/browser_coordinator_commands.h +++ b/ios/chrome/browser/ui/commands/browser_coordinator_commands.h
@@ -7,6 +7,8 @@ #import <Foundation/Foundation.h> +@protocol BadgeItem; + // Protocol for commands that will be handled by the BrowserCoordinator. // TODO(crbug.com/906662) : Rename this protocol to one that is more descriptive // and representative of the contents. @@ -24,6 +26,9 @@ // Shows the AddCreditCard UI. - (void)showAddCreditCard; +// Displays the Badge popup menu showing |badgeItems|. +- (void)displayPopupMenuWithBadgeItems:(NSArray<id<BadgeItem>>*)badgeItems; + @end #endif // IOS_CHROME_BROWSER_UI_COMMANDS_BROWSER_COORDINATOR_COMMANDS_H_
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm index d7ddcd8a..d0729d66 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm +++ b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
@@ -23,7 +23,6 @@ #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h" #import "ios/chrome/browser/overlays/public/overlay_presenter.h" #include "ios/chrome/browser/search_engines/template_url_service_factory.h" -#import "ios/chrome/browser/ui/badges/badge_button_action_handler.h" #import "ios/chrome/browser/ui/badges/badge_button_factory.h" #import "ios/chrome/browser/ui/badges/badge_delegate.h" #import "ios/chrome/browser/ui/badges/badge_mediator.h" @@ -73,8 +72,7 @@ const int kLocationAuthorizationStatusCount = 5; } // namespace -@interface LocationBarCoordinator () <BadgeDelegate, - LoadQueryCommands, +@interface LocationBarCoordinator () <LoadQueryCommands, LocationBarDelegate, LocationBarViewControllerDelegate, LocationBarConsumer> { @@ -175,16 +173,9 @@ self.omniboxPopupCoordinator.webStateList = self.webStateList; [self.omniboxPopupCoordinator start]; - // Create an action handler that will handle the action to take for button - // taps. - BadgeButtonActionHandler* actionHandler = - [[BadgeButtonActionHandler alloc] init]; - actionHandler.dispatcher = static_cast<id<InfobarCommands>>(self.dispatcher); - actionHandler.buttonActionDelegate = self; // Create button factory that wil be used by the ViewController to get // BadgeButtons for a BadgeType. - BadgeButtonFactory* buttonFactory = - [[BadgeButtonFactory alloc] initWithActionHandler:actionHandler]; + BadgeButtonFactory* buttonFactory = [[BadgeButtonFactory alloc] init]; buttonFactory.incognito = isIncognito; self.badgeViewController = [[BadgeViewController alloc] initWithButtonFactory:buttonFactory]; @@ -195,6 +186,10 @@ self.badgeMediator = [[BadgeMediator alloc] initWithConsumer:self.badgeViewController webStateList:self.webStateList]; + self.badgeMediator.dispatcher = + static_cast<id<InfobarCommands, BrowserCoordinatorCommands>>( + self.dispatcher); + buttonFactory.delegate = self.badgeMediator; _fullscreenBadgeObserver = std::make_unique<FullscreenUIUpdater>(self.badgeViewController); FullscreenControllerFactory::GetInstance() @@ -262,13 +257,6 @@ return self.omniboxCoordinator.animatee; } -#pragma mark - BadgeDelegate - -- (void)showOverflowMenu { - // TODO(crbug.com/976901): Retrieve badges to show in overflow menu and send - // signal to BVC. -} - #pragma mark - LoadQueryCommands - (void)loadQuery:(NSString*)query immediately:(BOOL)immediately {
diff --git a/ios/chrome/browser/ui/main/browser_view_wrangler.mm b/ios/chrome/browser/ui/main/browser_view_wrangler.mm index c615f1a..61b9769 100644 --- a/ios/chrome/browser/ui/main/browser_view_wrangler.mm +++ b/ios/chrome/browser/ui/main/browser_view_wrangler.mm
@@ -255,7 +255,7 @@ WebStateList* webStateList = self.mainBrowser->GetWebStateList(); breakpad::StopMonitoringTabStateForWebStateList(webStateList); breakpad::StopMonitoringURLsForWebStateList(webStateList); - [tabModel browserStateDestroyed]; + [tabModel disconnect]; _activeWebStateObservationForwarders[webStateList] = nullptr; webStateList->RemoveObserver(_webStateListObserver.get()); webStateList->RemoveObserver(_webStateListForwardingObserver.get()); @@ -269,7 +269,7 @@ TabModel* tabModel = self.otrBrowser->GetTabModel(); WebStateList* webStateList = self.otrBrowser->GetWebStateList(); breakpad::StopMonitoringTabStateForWebStateList(webStateList); - [tabModel browserStateDestroyed]; + [tabModel disconnect]; _activeWebStateObservationForwarders[webStateList] = nullptr; webStateList->RemoveObserver(_webStateListObserver.get()); webStateList->RemoveObserver(_webStateListForwardingObserver.get());
diff --git a/ios/chrome/browser/ui/promos/BUILD.gn b/ios/chrome/browser/ui/promos/BUILD.gn index b0499b10..7dfff4e 100644 --- a/ios/chrome/browser/ui/promos/BUILD.gn +++ b/ios/chrome/browser/ui/promos/BUILD.gn
@@ -11,6 +11,7 @@ ] deps = [ "//base", + "//components/signin/ios/browser", "//components/signin/public/base", "//components/version_info", "//ios/chrome/app:tests_hook",
diff --git a/ios/chrome/browser/ui/promos/signin_promo_view_controller.mm b/ios/chrome/browser/ui/promos/signin_promo_view_controller.mm index 0a52f43..882b212 100644 --- a/ios/chrome/browser/ui/promos/signin_promo_view_controller.mm +++ b/ios/chrome/browser/ui/promos/signin_promo_view_controller.mm
@@ -8,6 +8,7 @@ #include "base/metrics/user_metrics.h" #include "base/strings/sys_string_conversions.h" #include "base/version.h" +#include "components/signin/ios/browser/features.h" #include "components/signin/public/base/signin_metrics.h" #include "components/version_info/version_info.h" #include "ios/chrome/app/tests_hook.h" @@ -178,6 +179,9 @@ + (BOOL)shouldBePresentedForBrowserState: (ios::ChromeBrowserState*)browserState { + if (signin::ForceStartupSigninPromo()) + return YES; + if (tests_hook::DisableSigninRecallPromo()) return NO;
diff --git a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm index ffdf772..3cf3c75 100644 --- a/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/google_services/accounts_table_view_controller.mm
@@ -245,7 +245,8 @@ item.text = l10n_util::GetNSString(IDS_IOS_OPTIONS_ACCOUNTS_ADD_ACCOUNT_BUTTON); item.accessibilityIdentifier = kSettingsAccountsTableViewAddAccountCellId; - item.image = [UIImage imageNamed:@"settings_accounts_add_account"]; + item.image = [[UIImage imageNamed:@"settings_accounts_add_account"] + imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; return item; }
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn index d2e5296..a50dfc2 100644 --- a/ios/chrome/browser/web/BUILD.gn +++ b/ios/chrome/browser/web/BUILD.gn
@@ -420,10 +420,10 @@ "//base/test:test_support", "//ios/chrome/browser/browser_state:test_support", "//ios/chrome/test/base:perf_test_support", + "//ios/third_party/webkit", "//ios/web/common:web_view_creation_util", "//ios/web/public/test", ] - libs = [ "WebKit.framework" ] } source_set("feature_flags") {
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index 4f2fe8ee..a891341 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -266,6 +266,7 @@ "//ios/chrome/test/app:test_support", "//ios/testing/earl_grey:earl_grey_support", "//ios/third_party/material_components_ios", + "//ios/third_party/webkit", "//ios/web", "//ios/web:earl_grey_test_support", "//ios/web/common", @@ -290,7 +291,6 @@ libs = [ "OCHamcrest.framework", - "WebKit.framework", "XCTest.framework", "IOKit.framework", ]
diff --git a/ios/showcase/badges/BUILD.gn b/ios/showcase/badges/BUILD.gn index fc484955..7fdc441 100644 --- a/ios/showcase/badges/BUILD.gn +++ b/ios/showcase/badges/BUILD.gn
@@ -10,6 +10,8 @@ deps = [ "//ios/chrome/browser/infobars:badge", "//ios/chrome/browser/ui/badges", + "//ios/chrome/browser/ui/badges:badges_popup_menu", + "//ios/chrome/browser/ui/util", "//ios/chrome/common/ui_util", "//ios/showcase/common", ] @@ -26,6 +28,7 @@ "//ios/chrome/browser/infobars:badge", "//ios/chrome/browser/ui/badges:public", "//ios/chrome/test/earl_grey:test_support", + "//ios/showcase/badges", "//ios/showcase/test", ] configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/ios/showcase/badges/sc_badge_coordinator.h b/ios/showcase/badges/sc_badge_coordinator.h index 59b8d5a..2625ab8 100644 --- a/ios/showcase/badges/sc_badge_coordinator.h +++ b/ios/showcase/badges/sc_badge_coordinator.h
@@ -7,6 +7,10 @@ #import "ios/showcase/common/navigation_coordinator.h" +// A11y identifier for button that will replace the displayed badge with the +// overflow badge button. +extern NSString* const kSCDisplayedBadgeToggleButton; + @interface SCBadgeCoordinator : NSObject <NavigationCoordinator> @end
diff --git a/ios/showcase/badges/sc_badge_coordinator.mm b/ios/showcase/badges/sc_badge_coordinator.mm index 429081b..ba71dee7d 100644 --- a/ios/showcase/badges/sc_badge_coordinator.mm +++ b/ios/showcase/badges/sc_badge_coordinator.mm
@@ -7,45 +7,91 @@ #include "ios/chrome/browser/infobars/infobar_badge_model.h" #import "ios/chrome/browser/ui/badges/badge_button_factory.h" #import "ios/chrome/browser/ui/badges/badge_consumer.h" +#import "ios/chrome/browser/ui/badges/badge_delegate.h" +#import "ios/chrome/browser/ui/badges/badge_popup_menu_coordinator.h" #import "ios/chrome/browser/ui/badges/badge_static_item.h" +#import "ios/chrome/browser/ui/badges/badge_tappable_item.h" #import "ios/chrome/browser/ui/badges/badge_view_controller.h" +#import "ios/chrome/browser/ui/util/named_guide.h" +#import "ios/chrome/browser/ui/util/named_guide_util.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif +NSString* const kSCDisplayedBadgeToggleButton = + @"kSCDisplayedBadgeToggleButtonAXID"; + @interface BadgeContainerViewController : UIViewController @property(nonatomic, strong) BadgeViewController* centeredChildViewController; +@property(nonatomic, weak) id<BadgeConsumer> consumer; @end @implementation BadgeContainerViewController - (void)viewDidLoad { [super viewDidLoad]; + + UIStackView* stackView = [[UIStackView alloc] init]; + stackView.translatesAutoresizingMaskIntoConstraints = NO; + stackView.axis = UILayoutConstraintAxisHorizontal; + [self.view addSubview:stackView]; + [NSLayoutConstraint activateConstraints:@[ + [stackView.widthAnchor constraintEqualToConstant:400], + [stackView.heightAnchor constraintEqualToConstant:100] + ]]; + AddSameCenterConstraints(stackView, self.view); + [self addChildViewController:self.centeredChildViewController]; - [self.view addSubview:self.centeredChildViewController.view]; + [stackView addArrangedSubview:self.centeredChildViewController.view]; [self didMoveToParentViewController:self.centeredChildViewController]; self.centeredChildViewController.view .translatesAutoresizingMaskIntoConstraints = NO; - AddSameCenterConstraints(self.centeredChildViewController.view, self.view); [NSLayoutConstraint activateConstraints:@[ [self.centeredChildViewController.view.widthAnchor constraintGreaterThanOrEqualToConstant:1], [self.centeredChildViewController.view.heightAnchor constraintEqualToConstant:100] ]]; + + UIButton* button = [UIButton buttonWithType:UIButtonTypeSystem]; + button.accessibilityIdentifier = kSCDisplayedBadgeToggleButton; + [button setTitle:@"Show Overflow badge" forState:UIControlStateNormal]; + [button addTarget:self + action:@selector(addSecondBadge:) + forControlEvents:UIControlEventTouchUpInside]; + [stackView addArrangedSubview:button]; + UIView* containerView = self.view; containerView.backgroundColor = [UIColor whiteColor]; self.title = @"Badges"; + AddNamedGuidesToView(@[ kBadgeOverflowMenuGuide ], self.view); + BadgeStaticItem* incognitoItem = [[BadgeStaticItem alloc] + initWithBadgeType:BadgeType::kBadgeTypeIncognito]; + InfobarBadgeModel* passwordBadgeItem = [[InfobarBadgeModel alloc] + initWithInfobarType:InfobarType::kInfobarTypePasswordSave]; + [self.consumer setupWithDisplayedBadge:passwordBadgeItem + fullScreenBadge:incognitoItem]; +} + +- (void)addSecondBadge:(id)sender { + BadgeStaticItem* incognitoItem = [[BadgeStaticItem alloc] + initWithBadgeType:BadgeType::kBadgeTypeIncognito]; + BadgeTappableItem* displayedBadge = [[BadgeTappableItem alloc] + initWithBadgeType:BadgeType::kBadgeTypeOverflow]; + [self.consumer setupWithDisplayedBadge:displayedBadge + fullScreenBadge:incognitoItem]; } @end -@interface SCBadgeCoordinator () +@interface SCBadgeCoordinator () <BadgeDelegate> @property(nonatomic, strong) BadgeContainerViewController* containerViewController; @property(nonatomic, strong) BadgeViewController* badgeViewController; @property(nonatomic, weak) id<BadgeConsumer> consumer; +@property(nonatomic, strong) + BadgePopupMenuCoordinator* badgePopupMenuCoordinator; @end @implementation SCBadgeCoordinator @@ -53,21 +99,28 @@ - (void)start { self.containerViewController = [[BadgeContainerViewController alloc] init]; - BadgeButtonFactory* buttonFactory = - [[BadgeButtonFactory alloc] initWithActionHandler:nil]; + BadgeButtonFactory* buttonFactory = [[BadgeButtonFactory alloc] init]; + buttonFactory.delegate = self; self.badgeViewController = [[BadgeViewController alloc] initWithButtonFactory:buttonFactory]; self.consumer = self.badgeViewController; + self.containerViewController.consumer = self.badgeViewController; self.containerViewController.centeredChildViewController = self.badgeViewController; [self.baseViewController pushViewController:self.containerViewController animated:YES]; - BadgeStaticItem* incognitoItem = [[BadgeStaticItem alloc] - initWithBadgeType:BadgeType::kBadgeTypeIncognito]; - InfobarBadgeModel* passwordBadgeItem = [[InfobarBadgeModel alloc] - initWithInfobarType:InfobarType::kInfobarTypePasswordSave]; - [self.consumer setupWithDisplayedBadge:passwordBadgeItem - fullScreenBadge:incognitoItem]; +} + +- (void)passwordsBadgeButtonTapped:(id)sender { +} + +- (void)overflowBadgeButtonTapped:(id)sender { + self.badgePopupMenuCoordinator = [[BadgePopupMenuCoordinator alloc] + initWithBaseViewController:self.containerViewController]; + NSArray* badgeItems = @[ [[InfobarBadgeModel alloc] + initWithInfobarType:InfobarType::kInfobarTypePasswordSave] ]; + [self.badgePopupMenuCoordinator setBadgeItemsToShow:badgeItems]; + [self.badgePopupMenuCoordinator start]; } @end
diff --git a/ios/showcase/badges/sc_badge_egtest.mm b/ios/showcase/badges/sc_badge_egtest.mm index 11f8c80f..f008253 100644 --- a/ios/showcase/badges/sc_badge_egtest.mm +++ b/ios/showcase/badges/sc_badge_egtest.mm
@@ -6,6 +6,7 @@ #import "ios/chrome/browser/ui/badges/badge_constants.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" +#import "ios/showcase/badges/sc_badge_coordinator.h" #import "ios/showcase/test/showcase_eg_utils.h" #import "ios/showcase/test/showcase_test_case.h" @@ -50,4 +51,32 @@ assertWithMatcher:grey_sufficientlyVisible()]; } +// Tests that the overflow badge presents and that the popup menu is presented +// when it is tapped. +- (void)testOverflowbadge { + // Tap on button to show the overflow badge. + [[EarlGrey selectElementWithMatcher:grey_accessibilityID( + kSCDisplayedBadgeToggleButton)] + performAction:grey_tap()]; + + // Assert that overflow badge is shown and tap on it. + [[EarlGrey selectElementWithMatcher: + grey_allOf(grey_accessibilityID( + kBadgeButtonOverflowAccessibilityIdentifier), + grey_sufficientlyVisible(), nil)] + assertWithMatcher:grey_sufficientlyVisible()]; + [[EarlGrey + selectElementWithMatcher:grey_accessibilityID( + kBadgeButtonOverflowAccessibilityIdentifier)] + performAction:grey_tap()]; + + // Assert that the badge overflow popup menu is being presented. + [[EarlGrey + selectElementWithMatcher: + grey_allOf(grey_accessibilityID( + kBadgePopupMenuTableViewAccessibilityIdentifier), + grey_sufficientlyVisible(), nil)] + assertWithMatcher:grey_sufficientlyVisible()]; +} + @end
diff --git a/ios/third_party/earl_grey/BUILD.gn b/ios/third_party/earl_grey/BUILD.gn index 710332d1..1c9a57a 100644 --- a/ios/third_party/earl_grey/BUILD.gn +++ b/ios/third_party/earl_grey/BUILD.gn
@@ -290,6 +290,7 @@ deps = [ "//build/config/ios:xctest", "//ios/third_party/fishhook", + "//ios/third_party/webkit", ] public_deps = [ "//ios/third_party/ochamcrest:ochamcrest+link", @@ -306,7 +307,6 @@ "IOKit.framework", "QuartzCore.framework", "UIKit.framework", - "WebKit.framework", "XCTest.framework", ] public_configs = [ ":config" ]
diff --git a/ios/third_party/earl_grey2/BUILD.gn b/ios/third_party/earl_grey2/BUILD.gn index e5deb17..11190f93 100644 --- a/ios/third_party/earl_grey2/BUILD.gn +++ b/ios/third_party/earl_grey2/BUILD.gn
@@ -386,6 +386,7 @@ "//build/config/ios:xctest", "//ios/third_party/edo", "//ios/third_party/fishhook", + "//ios/third_party/webkit", ] public_deps = [ @@ -400,7 +401,6 @@ "Foundation.framework", "IOKit.framework", "QuartzCore.framework", - "WebKit.framework", ] public_configs = [ ":config" ]
diff --git a/ios/third_party/webkit/BUILD.gn b/ios/third_party/webkit/BUILD.gn index b3ccc594..c6fbbd5 100644 --- a/ios/third_party/webkit/BUILD.gn +++ b/ios/third_party/webkit/BUILD.gn
@@ -5,8 +5,20 @@ import("//build/config/gclient_args.gni") import("//build/config/ios/ios_sdk.gni") +group("webkit") { + if (checkout_ios_webkit) { + deps = [ + ":compile_webkit", + ] + } + + all_dependent_configs = [ ":_webkit_config" ] +} + if (checkout_ios_webkit) { - action("webkit") { + action("compile_webkit") { + visibility = [ ":webkit" ] + script = "build_webkit.py" inputs = [ @@ -52,3 +64,20 @@ ] } } + +config("_webkit_config") { + if (checkout_ios_webkit) { + # From the ld documentation: "Directories specified with -F are searched in + # the order they appear on the command line and before the default search + # path." + common_flags = [ + "-F", + rebase_path("$target_out_dir/Debug-iphonesimulator/", root_build_dir), + ] + + cflags = common_flags + ldflags = common_flags + } + + libs = [ "WebKit.framework" ] +}
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index f4aea84..7f99aaab 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -39,6 +39,7 @@ ":threads", "//base", "//components/leveldb_proto", + "//ios/third_party/webkit", "//ios/web/common", "//ios/web/download", "//ios/web/favicon", @@ -66,8 +67,6 @@ "web_client.mm", ] - libs = [ "WebKit.framework" ] - configs += [ "//build/config/compiler:enable_arc" ] }
diff --git a/ios/web/common/features.mm b/ios/web/common/features.mm index 1b118fd..357e0e6 100644 --- a/ios/web/common/features.mm +++ b/ios/web/common/features.mm
@@ -21,7 +21,7 @@ "CrashOnUnexpectedURLChange", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kHistoryClobberWorkaround{ - "WKWebViewHistoryClobberWorkaround", base::FEATURE_ENABLED_BY_DEFAULT}; + "WKWebViewHistoryClobberWorkaround", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kBlockUniversalLinksInOffTheRecordMode{ "BlockUniversalLinksInOffTheRecord", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/ios/web/navigation/wk_based_navigation_manager_impl.mm b/ios/web/navigation/wk_based_navigation_manager_impl.mm index ac3b2c1..10dc540 100644 --- a/ios/web/navigation/wk_based_navigation_manager_impl.mm +++ b/ios/web/navigation/wk_based_navigation_manager_impl.mm
@@ -108,9 +108,19 @@ restoration_timer_ = std::make_unique<base::ElapsedTimer>(); } else if (!wk_navigation_util::IsRestoreSessionUrl(url)) { is_restore_session_in_progress_ = false; - DCHECK(restoration_timer_); - UMA_HISTOGRAM_TIMES(kRestoreNavigationTime, restoration_timer_->Elapsed()); - restoration_timer_.reset(); + // It's possible for there to be pending navigations for a session that is + // going to be restored (such as for the -ForwardHistoryClobber workaround). + // In this case, the pending navigation will start while the navigation + // manager is in restore mode. There are other edges cases where a restore + // session finishes without trigger it's start, such as when restoring some + // with some app specific or blocked URLs, or when WKWebView's + // backForwardList state is out of sync. See crbug.com/1008026 for more + // details. + if (restoration_timer_) { + UMA_HISTOGRAM_TIMES(kRestoreNavigationTime, + restoration_timer_->Elapsed()); + restoration_timer_.reset(); + } for (base::OnceClosure& callback : restore_session_completion_callbacks_) { std::move(callback).Run();
diff --git a/ios/web/net/cookies/BUILD.gn b/ios/web/net/cookies/BUILD.gn index b0e418af..dfeed04 100644 --- a/ios/web/net/cookies/BUILD.gn +++ b/ios/web/net/cookies/BUILD.gn
@@ -8,6 +8,7 @@ deps = [ "//base", "//ios/net", + "//ios/third_party/webkit", "//ios/web/common", "//ios/web/public", "//ios/web/web_state/ui:wk_web_view_configuration_provider", @@ -22,7 +23,5 @@ "wk_http_system_cookie_store.mm", ] - libs = [ "WebKit.framework" ] - configs += [ "//build/config/compiler:enable_arc" ] }
diff --git a/ios/web/public/BUILD.gn b/ios/web/public/BUILD.gn index 49bb079..e5c556a 100644 --- a/ios/web/public/BUILD.gn +++ b/ios/web/public/BUILD.gn
@@ -16,6 +16,7 @@ ] deps = [ + "//ios/third_party/webkit", "//ios/web/common", "//ios/web/common:user_agent", "//ios/web/public/deprecated", @@ -32,8 +33,6 @@ "web_state_user_data.h", ] - libs = [ "WebKit.framework" ] - configs += [ "//build/config/compiler:enable_arc" ] }
diff --git a/ios/web/public/webui/BUILD.gn b/ios/web/public/webui/BUILD.gn index 4f59e437..b824393 100644 --- a/ios/web/public/webui/BUILD.gn +++ b/ios/web/public/webui/BUILD.gn
@@ -7,6 +7,7 @@ source_set("webui") { deps = [ "//base", + "//ios/third_party/webkit", "//net", ] @@ -19,7 +20,5 @@ "web_ui_ios_message_handler.h", ] - libs = [ "WebKit.framework" ] - configs += [ "//build/config/compiler:enable_arc" ] }
diff --git a/ios/web/test/fakes/BUILD.gn b/ios/web/test/fakes/BUILD.gn index bbfc030..438b1cdb 100644 --- a/ios/web/test/fakes/BUILD.gn +++ b/ios/web/test/fakes/BUILD.gn
@@ -8,6 +8,7 @@ deps = [ "//base", + "//ios/third_party/webkit", "//ios/web/navigation", "//ios/web/navigation:core", "//ios/web/public", @@ -38,6 +39,4 @@ "mock_interstitial_delegate.h", "mock_interstitial_delegate.mm", ] - - libs = [ "WebKit.framework" ] }
diff --git a/ios/web/web_state/BUILD.gn b/ios/web/web_state/BUILD.gn index 23abe86..33c4adc 100644 --- a/ios/web/web_state/BUILD.gn +++ b/ios/web/web_state/BUILD.gn
@@ -9,6 +9,7 @@ ":context_menu", ":web_state_impl_header", "//base", + "//ios/third_party/webkit", "//ios/web/common", "//ios/web/js_messaging", "//ios/web/navigation", @@ -43,8 +44,6 @@ "web_state_policy_decider_bridge.mm", ] - libs = [ "WebKit.framework" ] - configs += [ "//build/config/compiler:enable_arc" ] }
diff --git a/ios/web/web_state/ui/BUILD.gn b/ios/web/web_state/ui/BUILD.gn index 0b66a6af..94898ff8 100644 --- a/ios/web/web_state/ui/BUILD.gn +++ b/ios/web/web_state/ui/BUILD.gn
@@ -10,6 +10,7 @@ ":crw_web_view_navigation_proxy", "//base", "//ios/net", + "//ios/third_party/webkit", "//ios/web:core", "//ios/web/browsing_data", "//ios/web/common", @@ -65,8 +66,6 @@ "js_window_error_manager.mm", ] - libs = [ "WebKit.framework" ] - configs += [ "//build/config/compiler:enable_arc" ] } @@ -75,7 +74,9 @@ "crw_web_view_navigation_proxy.h", ] - libs = [ "WebKit.framework" ] + deps = [ + "//ios/third_party/webkit", + ] configs += [ "//build/config/compiler:enable_arc" ] } @@ -104,6 +105,7 @@ source_set("wk_web_view_configuration_provider") { deps = [ "//base", + "//ios/third_party/webkit", "//ios/web/common", "//ios/web/js_messaging", "//ios/web/public", @@ -117,7 +119,5 @@ "wk_web_view_configuration_provider_observer.h", ] - libs = [ "WebKit.framework" ] - configs += [ "//build/config/compiler:enable_arc" ] }
diff --git a/ios/web/web_state/ui/controller/BUILD.gn b/ios/web/web_state/ui/controller/BUILD.gn index ebb6a6ee..c38eac6 100644 --- a/ios/web/web_state/ui/controller/BUILD.gn +++ b/ios/web/web_state/ui/controller/BUILD.gn
@@ -10,6 +10,7 @@ ] deps = [ + "//ios/third_party/webkit", "//ios/web/navigation:core", "//ios/web/net", "//ios/web/public", @@ -19,7 +20,5 @@ "//url", ] - libs = [ "WebKit.framework" ] - configs += [ "//build/config/compiler:enable_arc" ] }
diff --git a/ios/web_view/internal/sync/web_view_device_info_sync_service_factory.mm b/ios/web_view/internal/sync/web_view_device_info_sync_service_factory.mm index 94f359a..10c4447 100644 --- a/ios/web_view/internal/sync/web_view_device_info_sync_service_factory.mm +++ b/ios/web_view/internal/sync/web_view_device_info_sync_service_factory.mm
@@ -12,6 +12,7 @@ #include "components/signin/public/base/device_id_helper.h" #include "components/sync/model/model_type_store_service.h" #include "components/sync_device_info/device_info_prefs.h" +#include "components/sync_device_info/device_info_sync_client.h" #include "components/sync_device_info/device_info_sync_service_impl.h" #include "components/sync_device_info/local_device_info_provider_impl.h" #include "components/version_info/version_info.h" @@ -22,6 +23,27 @@ #error "This file requires ARC support." #endif +namespace { + +class DeviceInfoSyncClient : public syncer::DeviceInfoSyncClient { + public: + explicit DeviceInfoSyncClient(PrefService* prefs) : prefs_(prefs) {} + ~DeviceInfoSyncClient() override = default; + + // syncer::DeviceInfoSyncClient: + std::string GetSigninScopedDeviceId() const override { + return signin::GetSigninScopedDeviceId(prefs_); + } + + // syncer::DeviceInfoSyncClient: + bool GetSendTabToSelfReceivingEnabled() const override { return false; } + + private: + PrefService* const prefs_; +}; + +} // namespace + namespace ios_web_view { // static @@ -52,22 +74,21 @@ web::BrowserState* context) const { WebViewBrowserState* browser_state = WebViewBrowserState::FromBrowserState(context); + + auto device_info_sync_client = + std::make_unique<DeviceInfoSyncClient>(browser_state->GetPrefs()); auto local_device_info_provider = std::make_unique<syncer::LocalDeviceInfoProviderImpl>( version_info::Channel::STABLE, version_info::GetVersionNumber(), - /*signin_scoped_device_id_callback=*/ - base::BindRepeating(&signin::GetSigninScopedDeviceId, - browser_state->GetPrefs()), - /*send_tab_to_self_receiving_enabled_callback=*/ - base::BindRepeating([]() { return false; })); - + device_info_sync_client.get()); auto device_prefs = std::make_unique<syncer::DeviceInfoPrefs>(browser_state->GetPrefs()); return std::make_unique<syncer::DeviceInfoSyncServiceImpl>( WebViewModelTypeStoreServiceFactory::GetForBrowserState(browser_state) ->GetStoreFactory(), - std::move(local_device_info_provider), std::move(device_prefs)); + std::move(local_device_info_provider), std::move(device_prefs), + std::move(device_info_sync_client)); } } // namespace ios_web_view
diff --git a/ios/web_view/shell/BUILD.gn b/ios/web_view/shell/BUILD.gn index 362d975a..d8c6c6a1 100644 --- a/ios/web_view/shell/BUILD.gn +++ b/ios/web_view/shell/BUILD.gn
@@ -105,6 +105,7 @@ deps = [ ":shell_auth_service_interface", ":shell_risk_data_loader_interface", + "//ios/third_party/webkit", "//ios/web_view:web_view+link", ios_web_view_shell_auth_service, ios_web_view_shell_risk_data_loader, @@ -121,7 +122,6 @@ "Security.framework", "SystemConfiguration.framework", "UIKit.framework", - "WebKit.framework", "resolv", ]
diff --git a/ios/web_view/shell/test/BUILD.gn b/ios/web_view/shell/test/BUILD.gn index f11dc763..945fb76 100644 --- a/ios/web_view/shell/test/BUILD.gn +++ b/ios/web_view/shell/test/BUILD.gn
@@ -38,6 +38,7 @@ deps = [ "//base", "//base/test:test_support", + "//ios/third_party/webkit", "//ios/web_view/shell", ] @@ -46,10 +47,7 @@ "//ios/third_party/earl_grey:earl_grey+link", ] - libs = [ - "WebKit.framework", - "XCTest.framework", - ] + libs = [ "XCTest.framework" ] sources = [ "earl_grey/web_view_shell_matchers.h",
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn index 7d2cb05..cdd05c7c 100644 --- a/media/base/BUILD.gn +++ b/media/base/BUILD.gn
@@ -111,6 +111,8 @@ "channel_mixer.h", "channel_mixing_matrix.cc", "channel_mixing_matrix.h", + "color_plane_layout.cc", + "color_plane_layout.h", "container_names.cc", "container_names.h", "content_decryption_module.cc",
diff --git a/media/base/color_plane_layout.cc b/media/base/color_plane_layout.cc new file mode 100644 index 0000000..da4fbdc --- /dev/null +++ b/media/base/color_plane_layout.cc
@@ -0,0 +1,30 @@ +// 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 "media/base/color_plane_layout.h" + +namespace media { + +ColorPlaneLayout::ColorPlaneLayout() = default; + +ColorPlaneLayout::ColorPlaneLayout(int32_t stride, size_t offset, size_t size) + : stride(stride), offset(offset), size(size) {} + +ColorPlaneLayout::~ColorPlaneLayout() = default; + +bool ColorPlaneLayout::operator==(const ColorPlaneLayout& rhs) const { + return stride == rhs.stride && offset == rhs.offset && size == rhs.size; +} + +bool ColorPlaneLayout::operator!=(const ColorPlaneLayout& rhs) const { + return !(*this == rhs); +} + +std::ostream& operator<<(std::ostream& ostream, const ColorPlaneLayout& plane) { + ostream << "(" << plane.stride << ", " << plane.offset << ", " << plane.size + << ")"; + return ostream; +} + +} // namespace media
diff --git a/media/base/color_plane_layout.h b/media/base/color_plane_layout.h new file mode 100644 index 0000000..922cc1b --- /dev/null +++ b/media/base/color_plane_layout.h
@@ -0,0 +1,43 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_COLOR_PLANE_LAYOUT_H_ +#define MEDIA_BASE_COLOR_PLANE_LAYOUT_H_ + +#include <stddef.h> +#include <stdint.h> + +#include <ostream> + +#include "media/base/media_export.h" + +namespace media { + +// Encapsulates a color plane's memory layout: (stride, offset, size) +// stride: in bytes of a plane. Note that stride can be negative if the image +// layout is bottom-up. +// offset: in bytes of a plane, which stands for the offset of a start point of +// a color plane from a buffer FD. +// size: in bytes of a plane. This |size| bytes data must contain all the data +// a decoder will access (e.g. visible area and padding). +struct MEDIA_EXPORT ColorPlaneLayout { + ColorPlaneLayout(); + ColorPlaneLayout(int32_t stride, size_t offset, size_t size); + ~ColorPlaneLayout(); + + bool operator==(const ColorPlaneLayout& rhs) const; + bool operator!=(const ColorPlaneLayout& rhs) const; + + int32_t stride = 0; + size_t offset = 0; + size_t size = 0; +}; + +// Outputs ColorPlaneLayout to stream. +MEDIA_EXPORT std::ostream& operator<<(std::ostream& ostream, + const ColorPlaneLayout& plane); + +} // namespace media + +#endif // MEDIA_BASE_COLOR_PLANE_LAYOUT_H_
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index 0eb03fde..e6957b81 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc
@@ -19,6 +19,7 @@ #include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "build/build_config.h" +#include "media/base/color_plane_layout.h" #include "media/base/format_utils.h" #include "media/base/limits.h" #include "media/base/timestamp_constants.h" @@ -141,7 +142,7 @@ static base::Optional<VideoFrameLayout> GetDefaultLayout( VideoPixelFormat format, const gfx::Size& coded_size) { - std::vector<VideoFrameLayout::Plane> planes; + std::vector<ColorPlaneLayout> planes; switch (format) { case PIXEL_FORMAT_I420: { @@ -149,22 +150,21 @@ int uv_height = (coded_size.height() + 1) / 2; int uv_stride = uv_width; int uv_size = uv_stride * uv_height; - planes = std::vector<VideoFrameLayout::Plane>{ - VideoFrameLayout::Plane(coded_size.width(), 0, coded_size.GetArea()), - VideoFrameLayout::Plane(uv_stride, coded_size.GetArea(), uv_size), - VideoFrameLayout::Plane(uv_stride, coded_size.GetArea() + uv_size, - uv_size), + planes = std::vector<ColorPlaneLayout>{ + ColorPlaneLayout(coded_size.width(), 0, coded_size.GetArea()), + ColorPlaneLayout(uv_stride, coded_size.GetArea(), uv_size), + ColorPlaneLayout(uv_stride, coded_size.GetArea() + uv_size, uv_size), }; break; } case PIXEL_FORMAT_Y16: - planes = std::vector<VideoFrameLayout::Plane>{VideoFrameLayout::Plane( + planes = std::vector<ColorPlaneLayout>{ColorPlaneLayout( coded_size.width() * 2, 0, coded_size.GetArea() * 2)}; break; case PIXEL_FORMAT_ARGB: - planes = std::vector<VideoFrameLayout::Plane>{VideoFrameLayout::Plane( + planes = std::vector<ColorPlaneLayout>{ColorPlaneLayout( coded_size.width() * 4, 0, coded_size.GetArea() * 4)}; break; @@ -173,9 +173,9 @@ int uv_height = (coded_size.height() + 1) / 2; int uv_stride = uv_width * 2; int uv_size = uv_stride * uv_height; - planes = std::vector<VideoFrameLayout::Plane>{ - VideoFrameLayout::Plane(coded_size.width(), 0, coded_size.GetArea()), - VideoFrameLayout::Plane(uv_stride, coded_size.GetArea(), uv_size), + planes = std::vector<ColorPlaneLayout>{ + ColorPlaneLayout(coded_size.width(), 0, coded_size.GetArea()), + ColorPlaneLayout(uv_stride, coded_size.GetArea(), uv_size), }; break; }
diff --git a/media/base/video_frame_layout.cc b/media/base/video_frame_layout.cc index 4700132..eec8480d 100644 --- a/media/base/video_frame_layout.cc +++ b/media/base/video_frame_layout.cc
@@ -29,9 +29,9 @@ return result.str(); } -std::vector<VideoFrameLayout::Plane> PlanesFromStrides( +std::vector<ColorPlaneLayout> PlanesFromStrides( const std::vector<int32_t> strides) { - std::vector<VideoFrameLayout::Plane> planes(strides.size()); + std::vector<ColorPlaneLayout> planes(strides.size()); for (size_t i = 0; i < strides.size(); i++) { planes[i].stride = strides[i]; } @@ -101,7 +101,7 @@ base::Optional<VideoFrameLayout> VideoFrameLayout::CreateWithPlanes( VideoPixelFormat format, const gfx::Size& coded_size, - std::vector<Plane> planes, + std::vector<ColorPlaneLayout> planes, size_t buffer_addr_align, uint64_t modifier) { // NOTE: Even if format is UNKNOWN, it is valid if coded_sizes is not Empty(). @@ -117,7 +117,7 @@ base::Optional<VideoFrameLayout> VideoFrameLayout::CreateMultiPlanar( VideoPixelFormat format, const gfx::Size& coded_size, - std::vector<Plane> planes, + std::vector<ColorPlaneLayout> planes, size_t buffer_addr_align, uint64_t modifier) { // NOTE: Even if format is UNKNOWN, it is valid if coded_sizes is not Empty(). @@ -132,7 +132,7 @@ VideoFrameLayout::VideoFrameLayout(VideoPixelFormat format, const gfx::Size& coded_size, - std::vector<Plane> planes, + std::vector<ColorPlaneLayout> planes, bool is_multi_planar, size_t buffer_addr_align, uint64_t modifier) @@ -149,23 +149,6 @@ VideoFrameLayout& VideoFrameLayout::operator=(const VideoFrameLayout&) = default; -std::ostream& operator<<(std::ostream& ostream, - const VideoFrameLayout::Plane& plane) { - ostream << "(" << plane.stride << ", " << plane.offset << ", " << plane.size - << ")"; - return ostream; -} - -bool VideoFrameLayout::Plane::operator==( - const VideoFrameLayout::Plane& rhs) const { - return stride == rhs.stride && offset == rhs.offset && size == rhs.size; -} - -bool VideoFrameLayout::Plane::operator!=( - const VideoFrameLayout::Plane& rhs) const { - return !(*this == rhs); -} - bool VideoFrameLayout::operator==(const VideoFrameLayout& rhs) const { return format_ == rhs.format_ && coded_size_ == rhs.coded_size_ && planes_ == rhs.planes_ && is_multi_planar_ == rhs.is_multi_planar_ &&
diff --git a/media/base/video_frame_layout.h b/media/base/video_frame_layout.h index 086eb95..c7f59083 100644 --- a/media/base/video_frame_layout.h +++ b/media/base/video_frame_layout.h
@@ -14,6 +14,7 @@ #include <vector> #include "base/optional.h" +#include "media/base/color_plane_layout.h" #include "media/base/media_export.h" #include "media/base/video_types.h" #include "ui/gfx/geometry/size.h" @@ -36,27 +37,6 @@ // without inspecting av_frame_get_buffer() first. static constexpr size_t kBufferAddressAlignment = 32; - struct Plane { - Plane() = default; - Plane(int32_t stride, size_t offset, size_t size) - : stride(stride), offset(offset), size(size) {} - - bool operator==(const Plane& rhs) const; - bool operator!=(const Plane& rhs) const; - - // Strides in bytes of a plane. Note that stride can be negative if the - // image layout is bottom-up. - int32_t stride = 0; - - // Offset in bytes of a plane, which stands for the offset of a start point - // of a color plane from a buffer fd. - size_t offset = 0; - - // Size in bytes of a plane. This |size| bytes data must contain all the - // data a decoder will access (e.g. visible area and padding). - size_t size = 0; - }; - // Factory functions. // |format| and |coded_size| must be specified. // |is_single_planar| is optional. It describes planes can be stored (although @@ -84,7 +64,7 @@ static base::Optional<VideoFrameLayout> CreateWithPlanes( VideoPixelFormat format, const gfx::Size& coded_size, - std::vector<Plane> planes, + std::vector<ColorPlaneLayout> planes, size_t buffer_addr_align = kBufferAddressAlignment, uint64_t modifier = gfx::NativePixmapHandle::kNoModifier); @@ -94,7 +74,7 @@ static base::Optional<VideoFrameLayout> CreateMultiPlanar( VideoPixelFormat format, const gfx::Size& coded_size, - std::vector<Plane> planes, + std::vector<ColorPlaneLayout> planes, size_t buffer_addr_align = kBufferAddressAlignment, uint64_t modifier = gfx::NativePixmapHandle::kNoModifier); @@ -112,7 +92,7 @@ // Returns number of planes. Note that num_planes >= num_buffers. size_t num_planes() const { return planes_.size(); } - const std::vector<Plane>& planes() const { return planes_; } + const std::vector<ColorPlaneLayout>& planes() const { return planes_; } bool operator==(const VideoFrameLayout& rhs) const; bool operator!=(const VideoFrameLayout& rhs) const; @@ -128,7 +108,7 @@ private: VideoFrameLayout(VideoPixelFormat format, const gfx::Size& coded_size, - std::vector<Plane> planes, + std::vector<ColorPlaneLayout> planes, bool is_multi_planar, size_t buffer_addr_align, uint64_t modifier); @@ -143,7 +123,7 @@ gfx::Size coded_size_; // Layout property for each color planes, e.g. stride and buffer offset. - std::vector<Plane> planes_; + std::vector<ColorPlaneLayout> planes_; // Set to true when a format uses multiple backing buffers to store its // planes. Used by code for V4L2 API at the moment. @@ -160,10 +140,6 @@ uint64_t modifier_; }; -// Outputs VideoFrameLayout::Plane to stream. -MEDIA_EXPORT std::ostream& operator<<(std::ostream& ostream, - const VideoFrameLayout::Plane& plane); - // Outputs VideoFrameLayout to stream. MEDIA_EXPORT std::ostream& operator<<(std::ostream& ostream, const VideoFrameLayout& layout);
diff --git a/media/base/video_frame_layout_unittest.cc b/media/base/video_frame_layout_unittest.cc index 297f234..17ad2a9c 100644 --- a/media/base/video_frame_layout_unittest.cc +++ b/media/base/video_frame_layout_unittest.cc
@@ -22,12 +22,11 @@ namespace { -std::vector<VideoFrameLayout::Plane> CreatePlanes( - const std::vector<int32_t>& strides, - const std::vector<size_t>& offsets, - const std::vector<size_t>& sizes) { +std::vector<ColorPlaneLayout> CreatePlanes(const std::vector<int32_t>& strides, + const std::vector<size_t>& offsets, + const std::vector<size_t>& sizes) { LOG_ASSERT(strides.size() == offsets.size()); - std::vector<VideoFrameLayout::Plane> planes(strides.size()); + std::vector<ColorPlaneLayout> planes(strides.size()); for (size_t i = 0; i < strides.size(); i++) { planes[i].stride = strides[i]; planes[i].offset = offsets[i];
diff --git a/media/base/video_frame_unittest.cc b/media/base/video_frame_unittest.cc index c7a0816..a7f3008 100644 --- a/media/base/video_frame_unittest.cc +++ b/media/base/video_frame_unittest.cc
@@ -18,6 +18,7 @@ #include "base/strings/stringprintf.h" #include "build/build_config.h" #include "gpu/command_buffer/common/mailbox_holder.h" +#include "media/base/color_plane_layout.h" #include "media/base/simple_sync_token_client.h" #include "media/video/fake_gpu_memory_buffer.h" #include "testing/gtest/include/gtest/gtest.h" @@ -420,7 +421,7 @@ std::vector<int32_t> strides = {384, 192, 192}; std::vector<size_t> offsets = {0, 100, 200}; std::vector<size_t> sizes = {100, 50, 50}; - std::vector<VideoFrameLayout::Plane> planes(strides.size()); + std::vector<ColorPlaneLayout> planes(strides.size()); for (size_t i = 0; i < planes.size(); i++) { planes[i].stride = strides[i];
diff --git a/media/capture/video/chromeos/mojom/BUILD.gn b/media/capture/video/chromeos/mojom/BUILD.gn index 23dc55e..f98d89e 100644 --- a/media/capture/video/chromeos/mojom/BUILD.gn +++ b/media/capture/video/chromeos/mojom/BUILD.gn
@@ -15,7 +15,6 @@ ] deps = [ - "//components/arc/mojom:camera_intent", "//components/chromeos_camera/common", "//media/capture/mojom:image_capture", "//media/mojo/mojom",
diff --git a/media/capture/video/chromeos/mojom/camera_app.mojom b/media/capture/video/chromeos/mojom/camera_app.mojom index 0a81a4f..b58b594f 100644 --- a/media/capture/video/chromeos/mojom/camera_app.mojom +++ b/media/capture/video/chromeos/mojom/camera_app.mojom
@@ -4,7 +4,6 @@ module cros.mojom; -import "components/arc/mojom/camera_intent.mojom"; import "media/capture/mojom/image_capture.mojom"; import "media/capture/video/chromeos/mojom/camera_common.mojom"; import "media/capture/video/chromeos/mojom/camera_metadata.mojom"; @@ -56,22 +55,6 @@ IsSupported() => (bool is_supported); }; -// Interface for communication between Chrome Camera App (Remote) and Chrome -// (Receiver). -interface CameraAppHelper { - // Sends the captured result |data| for corresponding intent recognized by - // |intent_id| back to ARC. The handler should handle |data| and may notify - // the intent caller according to the intention of the |action|. |is_success| - // will be set to true if the ARC received the result and set to false for - // invalid input. - HandleCameraResult(uint32 intent_id, arc.mojom.CameraIntentAction action, - array<uint8> data) - => (bool is_success); - - // Checks if device is under tablet mode currently. - IsTabletMode() => (bool is_tablet_mode); -}; - // Inner interface that used to communicate between browser process (Remote) and // the Video Capture service (Receiver). interface CameraAppDeviceBridge {
diff --git a/media/gpu/linux/platform_video_frame_utils.cc b/media/gpu/linux/platform_video_frame_utils.cc index 453c328..4c060197 100644 --- a/media/gpu/linux/platform_video_frame_utils.cc +++ b/media/gpu/linux/platform_video_frame_utils.cc
@@ -8,6 +8,7 @@ #include "base/bind_helpers.h" #include "base/files/scoped_file.h" #include "build/build_config.h" +#include "media/base/color_plane_layout.h" #include "media/base/format_utils.h" #include "media/base/scopedfd_helper.h" #include "media/base/video_frame_layout.h" @@ -48,7 +49,7 @@ return nullptr; const size_t num_planes = VideoFrame::NumPlanes(pixel_format); - std::vector<VideoFrameLayout::Plane> planes(num_planes); + std::vector<ColorPlaneLayout> planes(num_planes); for (size_t i = 0; i < num_planes; ++i) { planes[i].stride = pixmap->GetDmaBufPitch(i); planes[i].offset = pixmap->GetDmaBufOffset(i);
diff --git a/media/gpu/linux/platform_video_frame_utils_unittest.cc b/media/gpu/linux/platform_video_frame_utils_unittest.cc index ccaf0ad..67ca7b3 100644 --- a/media/gpu/linux/platform_video_frame_utils_unittest.cc +++ b/media/gpu/linux/platform_video_frame_utils_unittest.cc
@@ -17,6 +17,7 @@ #include "base/numerics/safe_conversions.h" #include "base/optional.h" #include "base/time/time.h" +#include "media/base/color_plane_layout.h" #include "media/base/format_utils.h" #include "media/base/video_frame.h" #include "media/base/video_frame_layout.h" @@ -89,7 +90,7 @@ const size_t num_planes = video_frame->layout().num_planes(); ASSERT_EQ(native_pixmap->ExportHandle().planes.size(), num_planes); for (size_t i = 0; i < num_planes; i++) { - const VideoFrameLayout::Plane& plane = video_frame->layout().planes()[i]; + const ColorPlaneLayout& plane = video_frame->layout().planes()[i]; // The original and duplicated FDs should be different. EXPECT_NE(native_pixmap->GetDmaBufFd(i), video_frame->DmabufFds()[i].get()); EXPECT_EQ(native_pixmap->GetDmaBufPitch(i),
diff --git a/media/gpu/test/video_frame_helpers.cc b/media/gpu/test/video_frame_helpers.cc index 38e86ef..31aa838f3 100644 --- a/media/gpu/test/video_frame_helpers.cc +++ b/media/gpu/test/video_frame_helpers.cc
@@ -10,6 +10,7 @@ #include "base/bind_helpers.h" #include "base/memory/scoped_refptr.h" #include "gpu/ipc/common/gpu_memory_buffer_support.h" +#include "media/base/color_plane_layout.h" #include "media/base/format_utils.h" #include "media/base/video_frame.h" #include "media/gpu/buildflags.h" @@ -318,7 +319,7 @@ const gfx::Size& size) { const size_t num_planes = VideoFrame::NumPlanes(format); - std::vector<VideoFrameLayout::Plane> planes(num_planes); + std::vector<ColorPlaneLayout> planes(num_planes); const auto strides = VideoFrame::ComputeStrides(format, size); size_t offset = 0; for (size_t i = 0; i < num_planes; ++i) {
diff --git a/media/gpu/v4l2/BUILD.gn b/media/gpu/v4l2/BUILD.gn index 4e63c6e..33f9efb0 100644 --- a/media/gpu/v4l2/BUILD.gn +++ b/media/gpu/v4l2/BUILD.gn
@@ -121,6 +121,7 @@ ] deps = [ ":v4l2", + "//media:test_support", "//testing/gtest", "//ui/gfx:test_support", "//ui/gl",
diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc index 6a6d6db..6385b207 100644 --- a/media/gpu/v4l2/v4l2_device.cc +++ b/media/gpu/v4l2/v4l2_device.cc
@@ -18,6 +18,7 @@ #include "base/numerics/safe_conversions.h" #include "build/build_config.h" #include "media/base/bind_to_current_loop.h" +#include "media/base/color_plane_layout.h" #include "media/base/video_types.h" #include "media/gpu/macros.h" #include "media/gpu/v4l2/generic_v4l2_device.h" @@ -1555,7 +1556,7 @@ return base::nullopt; } // Reserve capacity in advance to prevent unnecessary vector reallocation. - std::vector<VideoFrameLayout::Plane> planes; + std::vector<ColorPlaneLayout> planes; planes.reserve(num_color_planes); for (size_t i = 0; i < num_buffers; ++i) { const v4l2_plane_pix_format& plane_format = pix_mp.plane_fmt[i];
diff --git a/media/gpu/v4l2/v4l2_device_unittest.cc b/media/gpu/v4l2/v4l2_device_unittest.cc index 7888b33..3d91c38a 100644 --- a/media/gpu/v4l2/v4l2_device_unittest.cc +++ b/media/gpu/v4l2/v4l2_device_unittest.cc
@@ -8,6 +8,7 @@ #include <sstream> #include <vector> +#include "media/base/color_plane_layout.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/native_pixmap_handle.h" @@ -78,7 +79,7 @@ ASSERT_TRUE(layout.has_value()); EXPECT_EQ(PIXEL_FORMAT_NV12, layout->format()); EXPECT_EQ(gfx::Size(300, 180), layout->coded_size()); - std::vector<VideoFrameLayout::Plane> expected_planes( + std::vector<ColorPlaneLayout> expected_planes( {{320, 0u, 86400u}, {320, 57600u, 28800u}}); EXPECT_EQ(expected_planes, layout->planes()); EXPECT_EQ(layout->is_multi_planar(), false); @@ -103,7 +104,7 @@ ASSERT_TRUE(layout.has_value()); EXPECT_EQ(PIXEL_FORMAT_NV12, layout->format()); EXPECT_EQ(gfx::Size(300, 180), layout->coded_size()); - std::vector<VideoFrameLayout::Plane> expected_planes( + std::vector<ColorPlaneLayout> expected_planes( {{320, 0u, 57600u}, {320, 0u, 28800u}}); EXPECT_EQ(expected_planes, layout->planes()); EXPECT_EQ(layout->is_multi_planar(), true); @@ -128,7 +129,7 @@ ASSERT_TRUE(layout.has_value()); EXPECT_EQ(PIXEL_FORMAT_I420, layout->format()); EXPECT_EQ(gfx::Size(300, 180), layout->coded_size()); - std::vector<VideoFrameLayout::Plane> expected_planes( + std::vector<ColorPlaneLayout> expected_planes( {{320, 0u, 86400}, {160, 57600u, 14400u}, {160, 72000u, 14400u}}); EXPECT_EQ(expected_planes, layout->planes()); std::ostringstream ostream;
diff --git a/media/gpu/v4l2/v4l2_slice_video_decoder.cc b/media/gpu/v4l2/v4l2_slice_video_decoder.cc index b2d3de0..63b0c41 100644 --- a/media/gpu/v4l2/v4l2_slice_video_decoder.cc +++ b/media/gpu/v4l2/v4l2_slice_video_decoder.cc
@@ -55,7 +55,7 @@ return false; } - const std::vector<VideoFrameLayout::Plane>& planes = frame->layout().planes(); + const auto& planes = frame->layout().planes(); for (size_t i = frame->DmabufFds().size() - 1; i >= target_num_fds; --i) { // Assume that an fd is a duplicate of a previous plane's fd if offset != 0. // Otherwise, if offset == 0, return error as surface_it may be pointing to
diff --git a/media/gpu/v4l2/v4l2_vda_helpers.cc b/media/gpu/v4l2/v4l2_vda_helpers.cc index 5d9743f9..ddf47621 100644 --- a/media/gpu/v4l2/v4l2_vda_helpers.cc +++ b/media/gpu/v4l2/v4l2_vda_helpers.cc
@@ -4,6 +4,7 @@ #include "media/gpu/v4l2/v4l2_vda_helpers.h" +#include "media/base/color_plane_layout.h" #include "media/gpu/macros.h" #include "media/gpu/v4l2/v4l2_device.h" #include "media/gpu/v4l2/v4l2_image_processor.h" @@ -25,8 +26,7 @@ case V4L2_PIX_FMT_MM21: num_planes = 2; return VideoFrameLayout::CreateMultiPlanar( - PIXEL_FORMAT_NV12, size, - std::vector<VideoFrameLayout::Plane>(num_planes)); + PIXEL_FORMAT_NV12, size, std::vector<ColorPlaneLayout>(num_planes)); default: VideoPixelFormat pixel_format = @@ -38,8 +38,7 @@ return VideoFrameLayout::Create(pixel_format, size); else return VideoFrameLayout::CreateMultiPlanar( - pixel_format, size, - std::vector<VideoFrameLayout::Plane>(num_planes)); + pixel_format, size, std::vector<ColorPlaneLayout>(num_planes)); break; } }
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc index 3c8138d..ee49c63 100644 --- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc +++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -27,6 +27,7 @@ #include "base/trace_event/trace_event.h" #include "media/base/bind_to_current_loop.h" #include "media/base/bitstream_buffer.h" +#include "media/base/color_plane_layout.h" #include "media/base/scopedfd_helper.h" #include "media/base/unaligned_shared_memory.h" #include "media/base/video_frame_layout.h" @@ -243,7 +244,7 @@ // TODO(hiroh): Decide the appropriate planar in some way. auto input_layout = VideoFrameLayout::CreateMultiPlanar( config.input_format, visible_size_, - std::vector<VideoFrameLayout::Plane>( + std::vector<ColorPlaneLayout>( VideoFrame::NumPlanes(config.input_format))); if (!input_layout) { VLOGF(1) << "Invalid image processor input layout"; @@ -658,7 +659,7 @@ // TODO(hiroh): Decide the appropriate planar in some way. auto input_layout = VideoFrameLayout::CreateMultiPlanar( format, new_frame_size, - std::vector<VideoFrameLayout::Plane>(VideoFrame::NumPlanes(format))); + std::vector<ColorPlaneLayout>(VideoFrame::NumPlanes(format))); if (!input_layout) { VLOGF(1) << "Invalid image processor input layout"; return false;
diff --git a/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc b/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc index 4341b83..a77a545 100644 --- a/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc +++ b/media/gpu/vaapi/vaapi_dmabuf_video_frame_mapper.cc
@@ -8,6 +8,7 @@ #include "base/bind_helpers.h" #include "base/memory/ptr_util.h" #include "build/build_config.h" +#include "media/base/color_plane_layout.h" #include "media/gpu/linux/platform_video_frame_utils.h" #include "media/gpu/macros.h" #include "media/gpu/vaapi/vaapi_utils.h" @@ -42,7 +43,7 @@ } // All the planes are stored in the same buffer, VAImage.va_buffer. - std::vector<VideoFrameLayout::Plane> planes(num_planes); + std::vector<ColorPlaneLayout> planes(num_planes); std::vector<uint8_t*> addrs(num_planes, nullptr); for (size_t i = 0; i < num_planes; i++) { planes[i].stride = va_image->image()->pitches[i];
diff --git a/media/gpu/video_encode_accelerator_unittest.cc b/media/gpu/video_encode_accelerator_unittest.cc index 9736e629..df09d3b6 100644 --- a/media/gpu/video_encode_accelerator_unittest.cc +++ b/media/gpu/video_encode_accelerator_unittest.cc
@@ -47,6 +47,7 @@ #include "media/base/bind_to_current_loop.h" #include "media/base/bitstream_buffer.h" #include "media/base/cdm_context.h" +#include "media/base/color_plane_layout.h" #include "media/base/decoder_buffer.h" #include "media/base/media.h" #include "media/base/media_switches.h" @@ -2113,7 +2114,7 @@ CHECK_LE(num_planes, 3u); uint8_t* frame_data[3] = {}; - std::vector<VideoFrameLayout::Plane> planes(num_planes); + std::vector<ColorPlaneLayout> planes(num_planes); size_t offset = position; // All the planes are stored in the same buffer, aligned_in_file_data[0]. for (size_t i = 0; i < num_planes; i++) { @@ -2671,7 +2672,7 @@ CHECK_LE(num_planes, 3u); std::vector<char, AlignedAllocator<char, kPlatformBufferAlignment>> aligned_data[3]; - std::vector<VideoFrameLayout::Plane> planes(num_planes); + std::vector<ColorPlaneLayout> planes(num_planes); std::vector<size_t> buffer_sizes(num_planes); uint8_t* frame_data[3] = {}; // This VideoFrame is dummy. Each plane is stored in a separate buffer and
diff --git a/media/mojo/mojom/video_frame_mojom_traits.cc b/media/mojo/mojom/video_frame_mojom_traits.cc index d1ec35e..799aafe 100644 --- a/media/mojo/mojom/video_frame_mojom_traits.cc +++ b/media/mojo/mojom/video_frame_mojom_traits.cc
@@ -10,6 +10,7 @@ #include "base/logging.h" #include "build/build_config.h" #include "gpu/ipc/common/gpu_memory_buffer_support.h" +#include "media/base/color_plane_layout.h" #include "media/base/format_utils.h" #include "media/mojo/common/mojo_shared_buffer_video_frame.h" #include "mojo/public/cpp/base/time_mojom_traits.h" @@ -173,7 +174,7 @@ if (num_planes != dmabuf_fds_data.size()) return false; - std::vector<media::VideoFrameLayout::Plane> planes(num_planes); + std::vector<media::ColorPlaneLayout> planes(num_planes); for (size_t i = 0; i < num_planes; i++) { planes[i].stride = strides[i]; planes[i].offset = 0;
diff --git a/media/mojo/mojom/video_frame_mojom_traits_unittest.cc b/media/mojo/mojom/video_frame_mojom_traits_unittest.cc index 945097e..e743a74 100644 --- a/media/mojo/mojom/video_frame_mojom_traits_unittest.cc +++ b/media/mojo/mojom/video_frame_mojom_traits_unittest.cc
@@ -11,6 +11,7 @@ #include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/common/mailbox_holder.h" #include "gpu/command_buffer/common/sync_token.h" +#include "media/base/color_plane_layout.h" #include "media/base/video_frame.h" #include "media/mojo/common/mojo_shared_buffer_video_frame.h" #include "media/mojo/mojom/traits_test_service.mojom.h" @@ -107,8 +108,8 @@ std::vector<size_t> sizes = {1280 * 720, 1280 * 720 / 2}; auto layout = media::VideoFrameLayout::CreateWithPlanes( PIXEL_FORMAT_NV12, gfx::Size(1280, 720), - {media::VideoFrameLayout::Plane(strides[0], 0, sizes[0]), - media::VideoFrameLayout::Plane(strides[1], 0, sizes[1])}); + {media::ColorPlaneLayout(strides[0], 0, sizes[0]), + media::ColorPlaneLayout(strides[1], 0, sizes[1])}); // DMABUF needs device to create, use file fd instead. std::vector<int> fake_fds = {open("/dev/null", O_RDWR),
diff --git a/net/cert/cert_verify_proc_builtin.cc b/net/cert/cert_verify_proc_builtin.cc index 68a28d86..5984834 100644 --- a/net/cert/cert_verify_proc_builtin.cc +++ b/net/cert/cert_verify_proc_builtin.cc
@@ -43,6 +43,9 @@ constexpr base::TimeDelta kMaxVerificationTime = base::TimeDelta::FromSeconds(60); +constexpr base::TimeDelta kPerAttemptMinVerificationTimeLimit = + base::TimeDelta::FromSeconds(5); + DEFINE_CERT_ERROR_ID(kPathLacksEVPolicy, "Path does not have an EV policy"); RevocationPolicy NoRevocationChecking() { @@ -589,13 +592,8 @@ // This implementation is simplistic, and looks only for the presence of the // kUnacceptableSignatureAlgorithm error somewhere among the built paths. bool CanTryAgainWithWeakerDigestPolicy(const CertPathBuilder::Result& result) { - for (const auto& path : result.paths) { - if (path->errors.ContainsError( - cert_errors::kUnacceptableSignatureAlgorithm)) - return true; - } - - return false; + return result.AnyPathContainsError( + cert_errors::kUnacceptableSignatureAlgorithm); } int CertVerifyProcBuiltin::VerifyInternal( @@ -672,6 +670,12 @@ const auto& cur_attempt = attempts[cur_attempt_index]; verification_type = cur_attempt.verification_type; + // If a previous attempt used up most/all of the deadline, extend the + // deadline a little bit to give this verification attempt a chance at + // success. + deadline = std::max( + deadline, base::TimeTicks::Now() + kPerAttemptMinVerificationTimeLimit); + // Run the attempt through the path builder. result = TryBuildPath( target, &intermediates, ssl_trust_store.get(), verification_time, @@ -679,9 +683,23 @@ flags, ocsp_response, crl_set, net_fetcher_.get(), ev_metadata, &checked_revocation_for_some_path); - if (result.HasValidPath() || result.exceeded_deadline) + if (result.HasValidPath()) break; + if (result.exceeded_deadline) { + if (verification_type == VerificationType::kEV && + result.AnyPathContainsError(cert_errors::kUnableToCheckRevocation)) { + // EV verification failed due to deadline exceeded and unable to check + // revocation. Try the non-EV attempt even though the deadline has been + // reached, since a revocation checking failure on EV should be a + // soft-fail. (Since the non-EV attempt generally will not be using + // revocation checking it hopefully won't hit the deadline too.) + continue; + } + // Otherwise, stop immediately if an attempt exceeds the deadline. + break; + } + // If this path building attempt (may have) failed due to the chain using a // weak signature algorithm, enqueue a similar attempt but with weaker // signature algorithms (SHA1) permitted.
diff --git a/net/cert/cert_verify_proc_builtin_unittest.cc b/net/cert/cert_verify_proc_builtin_unittest.cc index cb43e260..3b939fc 100644 --- a/net/cert/cert_verify_proc_builtin_unittest.cc +++ b/net/cert/cert_verify_proc_builtin_unittest.cc
@@ -10,6 +10,7 @@ #include "net/base/test_completion_callback.h" #include "net/cert/cert_verify_proc.h" #include "net/cert/crl_set.h" +#include "net/cert/ev_root_ca_metadata.h" #include "net/cert/internal/system_trust_store.h" #include "net/cert_net/cert_net_fetcher_impl.h" #include "net/log/net_log_with_source.h" @@ -296,4 +297,77 @@ EXPECT_THAT(error, IsOk()); } +#if defined(PLATFORM_USES_CHROMIUM_EV_METADATA) +// Tests that if the verification deadline is exceeded during EV revocation +// checking, the certificate is verified as non-EV. +TEST_F(CertVerifyProcBuiltinTest, EVRevocationCheckDeadline) { + std::unique_ptr<CertBuilder> leaf, intermediate, root; + CreateChain(&leaf, &intermediate, &root); + ASSERT_TRUE(leaf && intermediate && root); + + // Add test EV policy to leaf and intermediate. + static const char kEVTestCertPolicy[] = "1.2.3.4"; + leaf->SetCertificatePolicies({kEVTestCertPolicy}); + intermediate->SetCertificatePolicies({kEVTestCertPolicy}); + + const base::TimeDelta timeout_increment = + CertNetFetcherImpl::GetDefaultTimeoutForTesting() + + base::TimeDelta::FromMilliseconds(1); + const int expected_request_count = + GetCertVerifyProcBuiltinTimeLimitForTesting() / timeout_increment + 1; + + EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP); + ASSERT_TRUE(test_server.InitializeAndListen()); + + // Set up the test intermediate to have enough OCSP urls that if all the + // requests hang the deadline will be exceeded. + std::vector<GURL> ocsp_urls; + std::vector<base::RunLoop> runloops(expected_request_count); + for (int i = 0; i < expected_request_count; ++i) { + std::string path = base::StringPrintf("/hung/%i", i); + ocsp_urls.emplace_back(test_server.GetURL(path)); + test_server.RegisterRequestHandler( + base::BindRepeating(&test_server::HandlePrefixedRequest, path, + base::BindRepeating(&HangRequestAndCallback, + runloops[i].QuitClosure()))); + } + intermediate->SetCaIssuersAndOCSPUrls({}, ocsp_urls); + + test_server.StartAcceptingConnections(); + + // Consider the root of the test chain a valid EV root for the test policy. + ScopedTestEVPolicy scoped_test_ev_policy( + EVRootCAMetadata::GetInstance(), + X509Certificate::CalculateFingerprint256(root->GetCertBuffer()), + kEVTestCertPolicy); + + scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain(); + ASSERT_TRUE(chain.get()); + + CertVerifyResult verify_result; + TestCompletionCallback verify_callback; + Verify(chain.get(), "www.example.com", + /*flags=*/0, + /*additional_trust_anchors=*/{root->GetX509Certificate()}, + &verify_result, verify_callback.callback()); + + for (int i = 0; i < expected_request_count; i++) { + // Wait for request #|i| to be made. + runloops[i].Run(); + // Advance virtual time to cause the timeout task to become runnable. + task_environment().AdvanceClock(timeout_increment); + } + + // Once |expected_request_count| requests have been made and timed out, the + // overall deadline should be reached, causing the EV verification attempt to + // fail. + int error = verify_callback.WaitForResult(); + // EV uses soft-fail revocation checking, therefore verification result + // should be OK but not EV. + EXPECT_THAT(error, IsOk()); + EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_IS_EV); + EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED); +} +#endif // defined(PLATFORM_USES_CHROMIUM_EV_METADATA) + } // namespace net
diff --git a/net/cert/internal/path_builder.cc b/net/cert/internal/path_builder.cc index 8da4222..e67fc240 100644 --- a/net/cert/internal/path_builder.cc +++ b/net/cert/internal/path_builder.cc
@@ -525,6 +525,15 @@ return GetBestValidPath() != nullptr; } +bool CertPathBuilder::Result::AnyPathContainsError(CertErrorId error_id) const { + for (const auto& path : paths) { + if (path->errors.ContainsError(error_id)) + return true; + } + + return false; +} + const CertPathBuilderResultPath* CertPathBuilder::Result::GetBestValidPath() const { const CertPathBuilderResultPath* result_path = GetBestPathPossiblyInvalid();
diff --git a/net/cert/internal/path_builder.h b/net/cert/internal/path_builder.h index 7dba3e5..5f3dbb7 100644 --- a/net/cert/internal/path_builder.h +++ b/net/cert/internal/path_builder.h
@@ -116,6 +116,9 @@ // Returns true if there was a valid path. bool HasValidPath() const; + // Returns true if any of the attempted paths contain |error_id|. + bool AnyPathContainsError(CertErrorId error_id) const; + // Returns the CertPathBuilderResultPath for the best valid path, or nullptr // if there was none. const CertPathBuilderResultPath* GetBestValidPath() const;
diff --git a/net/http/http_response_info.cc b/net/http/http_response_info.cc index d03f76da..1dc154e 100644 --- a/net/http/http_response_info.cc +++ b/net/http/http_response_info.cc
@@ -429,6 +429,7 @@ case CONNECTION_INFO_QUIC_46: case CONNECTION_INFO_QUIC_47: case CONNECTION_INFO_QUIC_48: + case CONNECTION_INFO_QUIC_49: case CONNECTION_INFO_QUIC_99: case CONNECTION_INFO_QUIC_999: return true; @@ -497,6 +498,8 @@ return "http/2+quic/47"; case CONNECTION_INFO_QUIC_48: return "http/2+quic/48"; + case CONNECTION_INFO_QUIC_49: + return "http/2+quic/49"; case CONNECTION_INFO_QUIC_99: return "http/2+quic/99"; case CONNECTION_INFO_HTTP0_9:
diff --git a/net/http/http_response_info.h b/net/http/http_response_info.h index ff80d89..68087a5 100644 --- a/net/http/http_response_info.h +++ b/net/http/http_response_info.h
@@ -64,6 +64,7 @@ CONNECTION_INFO_QUIC_47 = 26, CONNECTION_INFO_QUIC_999 = 27, CONNECTION_INFO_QUIC_48 = 28, + CONNECTION_INFO_QUIC_49 = 29, NUM_OF_CONNECTION_INFOS, };
diff --git a/net/http/http_stream_factory_unittest.cc b/net/http/http_stream_factory_unittest.cc index fb873fe..65a5b24 100644 --- a/net/http/http_stream_factory_unittest.cc +++ b/net/http/http_stream_factory_unittest.cc
@@ -3296,7 +3296,7 @@ scoped_refptr<HttpResponseHeaders> headers( base::MakeRefCounted<HttpResponseHeaders>("")); - headers->AddHeader("alt-svc: quic=\":443\"; v=\"99,48,47,46,43,39\""); + headers->AddHeader("alt-svc: quic=\":443\"; v=\"99,49,48,47,46,43,39\""); session_->http_stream_factory()->ProcessAlternativeServices( session_.get(), network_isolation_key, headers.get(), origin); @@ -3329,7 +3329,8 @@ base::MakeRefCounted<HttpResponseHeaders>("")); headers->AddHeader( "alt-svc: " - "h3-Q099=\":443\",h3-Q048=\":443\",h3-Q047=\":443\",h3-Q043=\":443\",h3-" + "h3-Q099=\":443\",h3-Q049=\":443\",h3-Q048=\":443\",h3-Q047=\":443\",h3-" + "Q043=\":443\",h3-" "Q039=\":443\""); session_->http_stream_factory()->ProcessAlternativeServices( @@ -3337,6 +3338,7 @@ quic::ParsedQuicVersionVector versions = { {quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_99}, + {quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_49}, {quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_48}, {quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_47}, {quic::PROTOCOL_QUIC_CRYPTO, quic::QUIC_VERSION_43},
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h index e49323c..9d9dac6 100644 --- a/net/log/net_log_event_type_list.h +++ b/net/log/net_log_event_type_list.h
@@ -3265,9 +3265,17 @@ // } EVENT_TYPE(COOKIE_SET_BLOCKED_BY_NETWORK_DELEGATE) -// +// Event emitted when cookies are associated with domain but not sent +// and received but not stored +// { +// "exclusion_reason": <Exclusion flags> +// } +EVENT_TYPE(COOKIE_INCLUSION_STATUS) + +// ----------------------------------------------------------------------------- // HTTP/3 events. -// +// ----------------------------------------------------------------------------- + // Event emitted when peer created control stream type is received. EVENT_TYPE(HTTP3_PEER_CONTROL_STREAM_CREATED)
diff --git a/net/quic/mock_decrypter.cc b/net/quic/mock_decrypter.cc index 9576ea7..809650d 100644 --- a/net/quic/mock_decrypter.cc +++ b/net/quic/mock_decrypter.cc
@@ -76,6 +76,10 @@ return 0; } +size_t MockDecrypter::GetNoncePrefixSize() const { + return 0; +} + size_t MockDecrypter::GetIVSize() const { return 0; }
diff --git a/net/quic/mock_decrypter.h b/net/quic/mock_decrypter.h index 5b7f0e22..acd7ee0 100644 --- a/net/quic/mock_decrypter.h +++ b/net/quic/mock_decrypter.h
@@ -41,6 +41,7 @@ size_t* output_length, size_t max_output_length) override; size_t GetKeySize() const override; + size_t GetNoncePrefixSize() const override; size_t GetIVSize() const override; quic::QuicStringPiece GetKey() const override; quic::QuicStringPiece GetNoncePrefix() const override;
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h index f2a1ebd..da86be66 100644 --- a/net/quic/quic_flags_list.h +++ b/net/quic/quic_flags_list.h
@@ -83,7 +83,7 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_unified_iw_options, false) // Number of packets that the pacing sender allows in bursts during pacing. -QUIC_FLAG(int32_t, FLAGS_quic_lumpy_pacing_size, 1) +QUIC_FLAG(int32_t, FLAGS_quic_lumpy_pacing_size, 2) // Congestion window fraction that the pacing sender allows in bursts during // pacing. @@ -173,6 +173,9 @@ FLAGS_quic_reloadable_flag_send_quic_fallback_server_config_on_leto_error, false) +// If true, enable QUIC version 49. +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_version_49, false) + // If true, GFE will not request private keys when fetching QUIC ServerConfigs // from Leto. QUIC_FLAG(bool, @@ -205,13 +208,6 @@ // If true, use predictable version negotiation versions. QUIC_FLAG(bool, FLAGS_quic_disable_version_negotiation_grease_randomness, false) -// If true and --quic_lumpy_pacing_size is 1, QUIC will use a lumpy size of two -// for pacing. -QUIC_FLAG( - bool, - FLAGS_quic_reloadable_flag_quic_change_default_lumpy_pacing_size_to_two, - true) - // If true, do not add connection ID of packets with unknown connection ID // and no version to time wait list, instead, send appropriate responses // depending on the packets' sizes and drop them.
diff --git a/net/quic/quic_http_stream.cc b/net/quic/quic_http_stream.cc index ab1a31f..6cd7318 100644 --- a/net/quic/quic_http_stream.cc +++ b/net/quic/quic_http_stream.cc
@@ -99,6 +99,8 @@ return HttpResponseInfo::CONNECTION_INFO_QUIC_47; case quic::QUIC_VERSION_48: return HttpResponseInfo::CONNECTION_INFO_QUIC_48; + case quic::QUIC_VERSION_49: + return HttpResponseInfo::CONNECTION_INFO_QUIC_49; case quic::QUIC_VERSION_99: return HttpResponseInfo::CONNECTION_INFO_QUIC_99; case quic::QUIC_VERSION_RESERVED_FOR_NEGOTIATION:
diff --git a/net/quic/quic_test_packet_maker.cc b/net/quic/quic_test_packet_maker.cc index 8ab3faa..8fa8bc8 100644 --- a/net/quic/quic_test_packet_maker.cc +++ b/net/quic/quic_test_packet_maker.cc
@@ -12,6 +12,7 @@ #include "net/quic/mock_crypto_client_stream.h" #include "net/quic/quic_chromium_client_session.h" #include "net/quic/quic_http_utils.h" +#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h" #include "net/third_party/quiche/src/quic/core/http/http_constants.h" #include "net/third_party/quiche/src/quic/core/quic_framer.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" @@ -163,6 +164,13 @@ quic::QuicFramer framer(quic::test::SupportedVersions(version_), clock_->Now(), perspective_, quic::kQuicDefaultConnectionIdLength); + framer.SetInitialObfuscators(perspective_ == quic::Perspective::IS_CLIENT + ? header_.destination_connection_id + : header_.source_connection_id); + if (encryption_level_ != quic::ENCRYPTION_INITIAL) { + framer.SetEncrypter(encryption_level_, + std::make_unique<quic::NullEncrypter>(perspective_)); + } size_t max_plaintext_size = framer.GetMaxPlaintextSize(quic::kDefaultMaxPacketSize); char buffer[quic::kDefaultMaxPacketSize]; @@ -185,7 +193,7 @@ payloads, true, encryption_level_); } size_t encrypted_size = framer.EncryptInPlace( - quic::ENCRYPTION_INITIAL, header_.packet_number, + encryption_level_, header_.packet_number, GetStartOfEncryptedData(framer.transport_version(), header_), length, quic::kDefaultMaxPacketSize, buffer); EXPECT_EQ(quic::kDefaultMaxPacketSize, encrypted_size); @@ -618,6 +626,13 @@ quic::QuicFramer framer(quic::test::SupportedVersions(version_), clock_->Now(), perspective_, quic::kQuicDefaultConnectionIdLength); + framer.SetInitialObfuscators(perspective_ == quic::Perspective::IS_CLIENT + ? header_.destination_connection_id + : header_.source_connection_id); + if (encryption_level_ != quic::ENCRYPTION_INITIAL) { + framer.SetEncrypter(encryption_level_, + std::make_unique<quic::NullEncrypter>(perspective_)); + } quic::QuicFrames frames; quic::QuicFrame ack_frame(&ack); frames.push_back(ack_frame); @@ -638,8 +653,8 @@ quic::test::BuildUnsizedDataPacket(&framer, header_, frames)); char buffer[quic::kMaxOutgoingPacketSize]; size_t encrypted_size = - framer.EncryptPayload(quic::ENCRYPTION_INITIAL, header_.packet_number, - *packet, buffer, quic::kMaxOutgoingPacketSize); + framer.EncryptPayload(encryption_level_, header_.packet_number, *packet, + buffer, quic::kMaxOutgoingPacketSize); EXPECT_NE(0u, encrypted_size); quic::QuicReceivedPacket encrypted(buffer, encrypted_size, clock_->Now(), false); @@ -1086,6 +1101,13 @@ quic::QuicFramer framer(quic::test::SupportedVersions(version_), clock_->Now(), perspective_, quic::kQuicDefaultConnectionIdLength); + framer.SetInitialObfuscators(perspective_ == quic::Perspective::IS_CLIENT + ? header_.destination_connection_id + : header_.source_connection_id); + if (encryption_level_ != quic::ENCRYPTION_INITIAL) { + framer.SetEncrypter(encryption_level_, + std::make_unique<quic::NullEncrypter>(perspective_)); + } if (data_producer != nullptr) { framer.set_data_producer(data_producer); } @@ -1117,8 +1139,8 @@ &framer, header, frames_copy, max_plaintext_size)); char buffer[quic::kMaxOutgoingPacketSize]; size_t encrypted_size = - framer.EncryptPayload(quic::ENCRYPTION_INITIAL, header.packet_number, - *packet, buffer, quic::kMaxOutgoingPacketSize); + framer.EncryptPayload(encryption_level_, header.packet_number, *packet, + buffer, quic::kMaxOutgoingPacketSize); EXPECT_NE(0u, encrypted_size); quic::QuicReceivedPacket encrypted(buffer, encrypted_size, clock_->Now(), false);
diff --git a/net/test/cert_builder.cc b/net/test/cert_builder.cc index b61df8db..74c0bea6 100644 --- a/net/test/cert_builder.cc +++ b/net/test/cert_builder.cc
@@ -291,6 +291,36 @@ SetExtension(SubjectAltNameOid(), FinishCBB(cbb.get())); } +void CertBuilder::SetCertificatePolicies( + const std::vector<std::string>& policy_oids) { + // From RFC 5280: + // certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation + // + // PolicyInformation ::= SEQUENCE { + // policyIdentifier CertPolicyId, + // policyQualifiers SEQUENCE SIZE (1..MAX) OF + // PolicyQualifierInfo OPTIONAL } + // + // CertPolicyId ::= OBJECT IDENTIFIER + bssl::ScopedCBB cbb; + CBB certificate_policies; + ASSERT_TRUE(CBB_init(cbb.get(), 64)); + ASSERT_TRUE( + CBB_add_asn1(cbb.get(), &certificate_policies, CBS_ASN1_SEQUENCE)); + for (const auto& oid : policy_oids) { + CBB policy_information, policy_identifier; + ASSERT_TRUE(CBB_add_asn1(&certificate_policies, &policy_information, + CBS_ASN1_SEQUENCE)); + ASSERT_TRUE( + CBB_add_asn1(&policy_information, &policy_identifier, CBS_ASN1_OBJECT)); + ASSERT_TRUE( + CBB_add_asn1_oid_from_text(&policy_identifier, oid.data(), oid.size())); + ASSERT_TRUE(CBB_flush(&certificate_policies)); + } + + SetExtension(CertificatePoliciesOid(), FinishCBB(cbb.get())); +} + void CertBuilder::SetValidity(base::Time not_before, base::Time not_after) { // From RFC 5280: // Validity ::= SEQUENCE {
diff --git a/net/test/cert_builder.h b/net/test/cert_builder.h index 153e739..e8a3d35 100644 --- a/net/test/cert_builder.h +++ b/net/test/cert_builder.h
@@ -74,6 +74,10 @@ // Sets the SAN for the certificate to a single dNSName. void SetSubjectAltName(const std::string& dns_name); + // Sets the certificatePolicies extension with the specified policyIdentifier + // OIDs, which must be specified in dotted string notation (e.g. "1.2.3.4"). + void SetCertificatePolicies(const std::vector<std::string>& policy_oids); + void SetValidity(base::Time not_before, base::Time not_after); // Sets the signature algorithm for the certificate to either
diff --git a/net/test/spawned_test_server/base_test_server.cc b/net/test/spawned_test_server/base_test_server.cc index 2f62512..dbe05b6 100644 --- a/net/test/spawned_test_server/base_test_server.cc +++ b/net/test/spawned_test_server/base_test_server.cc
@@ -331,7 +331,7 @@ return host_port_pair_; } -const base::DictionaryValue& BaseTestServer::server_data() const { +const base::Value& BaseTestServer::server_data() const { DCHECK(server_data_); return *server_data_; } @@ -513,19 +513,22 @@ int* port) { VLOG(1) << "Server data: " << server_data; base::JSONReader json_reader; - std::unique_ptr<base::Value> value( - json_reader.ReadToValueDeprecated(server_data)); - if (!value.get() || !value->is_dict()) { + base::Optional<base::Value> value(json_reader.ReadToValue(server_data)); + if (!value || !value->is_dict()) { LOG(ERROR) << "Could not parse server data: " << json_reader.GetErrorMessage(); return false; } - server_data_.reset(static_cast<base::DictionaryValue*>(value.release())); - if (!server_data_->GetInteger("port", port)) { + server_data_ = std::move(value); + + base::Optional<int> port_value = server_data_->FindIntKey("port"); + if (!port_value) { LOG(ERROR) << "Could not find port value"; return false; } + + *port = *port_value; if ((*port <= 0) || (*port > std::numeric_limits<uint16_t>::max())) { LOG(ERROR) << "Invalid port value: " << port; return false;
diff --git a/net/test/spawned_test_server/base_test_server.h b/net/test/spawned_test_server/base_test_server.h index c21e0e0..a10f786 100644 --- a/net/test/spawned_test_server/base_test_server.h +++ b/net/test/spawned_test_server/base_test_server.h
@@ -19,15 +19,13 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/optional.h" +#include "base/values.h" #include "net/base/host_port_pair.h" #include "net/ssl/ssl_client_cert_type.h" class GURL; -namespace base { -class DictionaryValue; -} - namespace net { class AddressList; @@ -407,7 +405,7 @@ const HostPortPair& host_port_pair() const; const base::FilePath& document_root() const { return document_root_; } - const base::DictionaryValue& server_data() const; + const base::Value& server_data() const; std::string GetScheme() const; bool GetAddressList(AddressList* address_list) const WARN_UNUSED_RESULT; @@ -513,7 +511,7 @@ HostPortPair host_port_pair_; // Holds the data sent from the server (e.g., port number). - std::unique_ptr<base::DictionaryValue> server_data_; + base::Optional<base::Value> server_data_; // If |type_| is TYPE_HTTPS or TYPE_WSS, the TLS settings to use for the test // server.
diff --git a/net/test/spawned_test_server/remote_test_server.cc b/net/test/spawned_test_server/remote_test_server.cc index d29e762..302f390f 100644 --- a/net/test/spawned_test_server/remote_test_server.cc +++ b/net/test/spawned_test_server/remote_test_server.cc
@@ -150,10 +150,9 @@ } if (ocsp_proxy_) { - const base::Value* ocsp_port_value = server_data().FindKey("ocsp_port"); - if (ocsp_port_value && ocsp_port_value->is_int()) { - ocsp_proxy_->Start( - IPEndPoint(config_.address(), ocsp_port_value->GetInt())); + base::Optional<int> ocsp_port_value = server_data().FindIntKey("ocsp_port"); + if (ocsp_port_value) { + ocsp_proxy_->Start(IPEndPoint(config_.address(), *ocsp_port_value)); } else { LOG(WARNING) << "testserver.py didn't return ocsp_port."; }
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index ff03d8c..7590b1a 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc
@@ -58,6 +58,7 @@ #include "net/http/http_util.h" #include "net/log/net_log.h" #include "net/log/net_log_event_type.h" +#include "net/log/net_log_values.h" #include "net/log/net_log_with_source.h" #include "net/nqe/network_quality_estimator.h" #include "net/proxy_resolution/proxy_info.h" @@ -671,6 +672,13 @@ status.AddExclusionReason( CanonicalCookie::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES); } + if (!status.IsInclude()) { + request_->net_log().AddEvent( + NetLogEventType::COOKIE_INCLUSION_STATUS, [&] { + return NetLogParamsWithString("exclusion_reason", + status.GetDebugString()); + }); + } maybe_sent_cookies.push_back({cookie_with_status.cookie, status}); } @@ -749,6 +757,11 @@ CanonicalCookie::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES); } if (!returned_status.IsInclude()) { + request_->net_log().AddEvent( + NetLogEventType::COOKIE_INCLUSION_STATUS, [&] { + return NetLogParamsWithString("exclusion_reason", + returned_status.GetDebugString()); + }); OnSetCookieResult(options, cookie_to_return, std::move(cookie_string), returned_status); continue;
diff --git a/services/tracing/public/cpp/trace_event_agent.cc b/services/tracing/public/cpp/trace_event_agent.cc index 53ee5d0..41f5fe4e 100644 --- a/services/tracing/public/cpp/trace_event_agent.cc +++ b/services/tracing/public/cpp/trace_event_agent.cc
@@ -81,7 +81,7 @@ void TraceEventAgent::StartTracing(const std::string& config, base::TimeTicks coordinator_time, StartTracingCallback callback) { - DCHECK(!IsBoundForTesting() || !TracingUsesPerfettoBackend()); + DCHECK(!IsBoundForTesting()); DCHECK(!recorder_); #if defined(__native_client__) // NaCl and system times are offset by a bit, so subtract some time from @@ -101,7 +101,7 @@ void TraceEventAgent::StopAndFlush( mojo::PendingRemote<mojom::Recorder> recorder) { - DCHECK(!IsBoundForTesting() || !TracingUsesPerfettoBackend()); + DCHECK(!IsBoundForTesting()); DCHECK(!recorder_); recorder_.Bind(std::move(recorder)); @@ -120,7 +120,7 @@ void TraceEventAgent::RequestBufferStatus( RequestBufferStatusCallback callback) { - DCHECK(!IsBoundForTesting() || !TracingUsesPerfettoBackend()); + DCHECK(!IsBoundForTesting()); base::trace_event::TraceLogStatus status = base::trace_event::TraceLog::GetInstance()->GetStatus(); std::move(callback).Run(status.event_capacity, status.event_count);
diff --git a/services/tracing/public/cpp/trace_startup.cc b/services/tracing/public/cpp/trace_startup.cc index f38c451..2f22b0c 100644 --- a/services/tracing/public/cpp/trace_startup.cc +++ b/services/tracing/public/cpp/trace_startup.cc
@@ -45,7 +45,6 @@ if (startup_config->IsEnabled()) { const TraceConfig& trace_config = startup_config->GetTraceConfig(); - if (TracingUsesPerfettoBackend()) { if (trace_config.IsCategoryGroupEnabled( TRACE_DISABLED_BY_DEFAULT("cpu_profiler"))) { TracingSamplerProfiler::SetupStartupTracing(); @@ -53,7 +52,6 @@ TraceEventDataSource::GetInstance()->SetupStartupTracing( startup_config->GetSessionOwner() == TraceStartupConfig::SessionOwner::kBackgroundTracing); - } uint8_t modes = TraceLog::RECORDING_MODE; if (!trace_config.event_filters().empty()) @@ -66,9 +64,8 @@ LOG(ERROR) << "Start " << switches::kTraceToConsole << " with CategoryFilter '" << trace_config.ToCategoryFilterString() << "'."; - if (TracingUsesPerfettoBackend()) - TraceEventDataSource::GetInstance()->SetupStartupTracing( - /*privacy_filtering_enabled=*/false); + TraceEventDataSource::GetInstance()->SetupStartupTracing( + /*privacy_filtering_enabled=*/false); trace_log->SetEnabled(trace_config, TraceLog::RECORDING_MODE); } }
diff --git a/services/tracing/public/cpp/tracing_features.cc b/services/tracing/public/cpp/tracing_features.cc index df6c26c..439d971 100644 --- a/services/tracing/public/cpp/tracing_features.cc +++ b/services/tracing/public/cpp/tracing_features.cc
@@ -18,18 +18,6 @@ namespace features { -// Enables the perfetto tracing backend. For startup tracing, pass the -// --enable-perfetto flag instead. -const base::Feature kTracingPerfettoBackend { - "TracingPerfettoBackend", -#if defined(IS_CHROMECAST) - - base::FEATURE_DISABLED_BY_DEFAULT -#else - base::FEATURE_ENABLED_BY_DEFAULT -#endif -}; - // Causes the BackgroundTracingManager to upload proto messages via UMA, // rather than JSON via the crash frontend. const base::Feature kBackgroundTracingProtoOutput{ @@ -62,28 +50,6 @@ namespace tracing { -bool TracingUsesPerfettoBackend() { - // This is checked early at startup, so feature list may not be initialized. - // So, for startup tracing cases there is no way to control the backend using - // feature list. - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisablePerfetto)) { - return false; - } - - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnablePerfetto)) { - return true; - } - - if (base::FeatureList::GetInstance()) { - return base::FeatureList::IsEnabled(features::kTracingPerfettoBackend); - } - - return features::kTracingPerfettoBackend.default_state == - base::FEATURE_ENABLED_BY_DEFAULT; -} - bool ShouldSetupSystemTracing() { #if defined(OS_ANDROID) if (base::android::BuildInfo::GetInstance()->is_debug_android()) { @@ -91,7 +57,7 @@ } #endif // defined(OS_ANDROID) if (base::FeatureList::GetInstance()) { - return base::FeatureList::IsEnabled(features::kTracingPerfettoBackend); + return base::FeatureList::IsEnabled(features::kEnablePerfettoSystemTracing); } return features::kEnablePerfettoSystemTracing.default_state == base::FEATURE_ENABLED_BY_DEFAULT;
diff --git a/services/tracing/public/cpp/tracing_features.h b/services/tracing/public/cpp/tracing_features.h index e53a4918..9bd1a12 100644 --- a/services/tracing/public/cpp/tracing_features.h +++ b/services/tracing/public/cpp/tracing_features.h
@@ -16,9 +16,6 @@ // The features should be documented alongside the definition of their values // in the .cc file. extern const COMPONENT_EXPORT(TRACING_CPP) base::Feature - kTracingPerfettoBackend; - -extern const COMPONENT_EXPORT(TRACING_CPP) base::Feature kTracingServiceInProcess; extern const COMPONENT_EXPORT(TRACING_CPP) base::Feature @@ -34,8 +31,6 @@ namespace tracing { -bool COMPONENT_EXPORT(TRACING_CPP) TracingUsesPerfettoBackend(); - // Returns true if the system tracing Perfetto producer should be setup. This // can be influenced by the feature above or other situations (like debug // android builds).
diff --git a/services/tracing/tracing_service.cc b/services/tracing/tracing_service.cc index 444890cc..09bd16e 100644 --- a/services/tracing/tracing_service.cc +++ b/services/tracing/tracing_service.cc
@@ -179,25 +179,13 @@ void TracingService::OnStart() { tracing_agent_registry_ = std::make_unique<AgentRegistry>(); - if (TracingUsesPerfettoBackend()) { - auto perfetto_coordinator = std::make_unique<PerfettoTracingCoordinator>( - tracing_agent_registry_.get(), - base::BindRepeating(&TracingService::OnCoordinatorConnectionClosed, - base::Unretained(this))); - registry_.AddInterface( - base::BindRepeating(&PerfettoTracingCoordinator::BindCoordinatorRequest, - base::Unretained(perfetto_coordinator.get()))); - tracing_coordinator_ = std::move(perfetto_coordinator); - } else { - auto tracing_coordinator = std::make_unique<Coordinator>( - tracing_agent_registry_.get(), - base::BindRepeating(&TracingService::OnCoordinatorConnectionClosed, - base::Unretained(this))); - registry_.AddInterface( - base::BindRepeating(&Coordinator::BindCoordinatorRequest, - base::Unretained(tracing_coordinator.get()))); - tracing_coordinator_ = std::move(tracing_coordinator); - } + tracing_coordinator_ = std::make_unique<PerfettoTracingCoordinator>( + tracing_agent_registry_.get(), + base::BindRepeating(&TracingService::OnCoordinatorConnectionClosed, + base::Unretained(this))); + registry_.AddInterface( + base::BindRepeating(&PerfettoTracingCoordinator::BindCoordinatorRequest, + base::Unretained(tracing_coordinator_.get()))); registry_.AddInterface( base::BindRepeating(&ConsumerHost::BindConsumerRequest,
diff --git a/services/tracing/tracing_service.h b/services/tracing/tracing_service.h index 0ff7bbfa3..65697fc8 100644 --- a/services/tracing/tracing_service.h +++ b/services/tracing/tracing_service.h
@@ -17,7 +17,7 @@ #include "services/service_manager/public/cpp/service_binding.h" #include "services/service_manager/public/mojom/service.mojom.h" #include "services/tracing/agent_registry.h" -#include "services/tracing/coordinator.h" +#include "services/tracing/perfetto/perfetto_tracing_coordinator.h" namespace tracing { @@ -45,7 +45,7 @@ const service_manager::BindSourceInfo&> registry_; std::unique_ptr<tracing::AgentRegistry> tracing_agent_registry_; - std::unique_ptr<Coordinator> tracing_coordinator_; + std::unique_ptr<PerfettoTracingCoordinator> tracing_coordinator_; std::unique_ptr<ServiceListener> service_listener_;
diff --git a/services/viz/privileged/mojom/compositing/display_private.mojom b/services/viz/privileged/mojom/compositing/display_private.mojom index de364997..1e456c1 100644 --- a/services/viz/privileged/mojom/compositing/display_private.mojom +++ b/services/viz/privileged/mojom/compositing/display_private.mojom
@@ -93,7 +93,7 @@ DidCompleteSwapWithSize(gfx.mojom.Size size); // Notifies that a swap has occurred with a new size. - [EnableIf=use_x11] + [EnableIf=is_linux] DidCompleteSwapWithNewSize(gfx.mojom.Size size); // Notifies the client of the result of context creation attempt. On Android we can't
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 9c6d529..6bc847a 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -708,1616 +708,6 @@ } ] }, - "linux-chromeos-coverage-rel-dummy": { - "additional_compile_targets": [ - "gn_all" - ], - "gtest_tests": [ - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "accessibility_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "angle_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "app_list_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "app_shell_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "ash_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "aura_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "base_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "base_util_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "blink_common_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "blink_fuzzer_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "blink_heap_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "blink_platform_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "webkit_unit_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "blink_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "boringssl_crypto_tests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "boringssl_ssl_tests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ], - "shards": 10 - }, - "test": "browser_tests" - }, - { - "args": [ - "--disable-features=VizDisplayCompositor" - ], - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "non_viz_browser_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ], - "shards": 10 - }, - "test": "browser_tests" - }, - { - "args": [ - "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0", - "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_browser_tests.filter" - ], - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "webui_html_imports_polyfill_browser_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "browser_tests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "cacheinvalidation_unittests" - }, - { - "args": [ - "--gtest_filter=-*UsingRealWebcam*" - ], - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "capture_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "cast_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "cc_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "chrome_app_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "chromedriver_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "chromeos_components_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "chromeos_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "color_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "components_browsertests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "components_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "compositor_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ], - "shards": 6 - }, - "test": "content_browsertests" - }, - { - "args": [ - "--disable-features=VizDisplayCompositor" - ], - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "non_viz_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ], - "shards": 10 - }, - "test": "content_browsertests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "content_unittests" - }, - { - "args": [ - "--disable-features=VizDisplayCompositor" - ], - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "non_viz_content_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "content_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "crypto_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "dbus_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "device_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "display_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "events_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "exo_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "extensions_browsertests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "extensions_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "filesystem_service_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "gcm_unit_tests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "gfx_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "gin_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "gl_unittests_ozone" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "google_apis_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "gpu_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "gwp_asan_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ], - "shards": 3 - }, - "test": "interactive_ui_tests" - }, - { - "args": [ - "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0", - "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter" - ], - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "webui_html_imports_polyfill_interactive_ui_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "interactive_ui_tests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "ipc_tests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "jingle_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "keyboard_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "latency_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "leveldb_service_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "libjingle_xmpp_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "media_blink_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "media_service_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "media_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "message_center_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "midi_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "mojo_core_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "mojo_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "nacl_helper_nonsfi_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "nacl_loader_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "native_theme_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "net_unittests" - }, - { - "args": [ - "--ozone-platform=headless" - ], - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "ozone_gl_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "ozone_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "ozone_x11_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "pdf_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "perfetto_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "ppapi_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "printing_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "remoting_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "sandbox_linux_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "service_manager_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "services_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "shell_dialogs_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "skia_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "snapshot_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "sql_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "storage_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "sync_integration_tests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "traffic_annotation_auditor_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "ui_base_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "ui_chromeos_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "ui_touch_selection_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "unit_tests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "url_unittests" - }, - { - "experiment_percentage": 100, - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "usage_time_limit_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "views_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "viz_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "wayland_client_perftests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "wm_unittests" - }, - { - "isolate_coverage_data": true, - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-16.04" - } - ] - }, - "test": "wtf_unittests" - } - ] - }, "linux-chromeos-dbg": { "gtest_tests": [ { @@ -3819,6 +2209,7 @@ ], "gtest_tests": [ { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -3834,6 +2225,7 @@ "test": "accessibility_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -3849,6 +2241,7 @@ "test": "angle_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -3864,6 +2257,7 @@ "test": "app_list_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -3879,6 +2273,7 @@ "test": "app_shell_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -3894,6 +2289,7 @@ "test": "ash_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -3909,6 +2305,7 @@ "test": "aura_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -3924,6 +2321,7 @@ "test": "base_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -3939,6 +2337,7 @@ "test": "base_util_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -3954,6 +2353,7 @@ "test": "blink_common_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -3969,6 +2369,7 @@ "test": "blink_fuzzer_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -3984,6 +2385,7 @@ "test": "blink_heap_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -3999,6 +2401,7 @@ "test": "blink_platform_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4015,6 +2418,7 @@ "test": "blink_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4030,6 +2434,7 @@ "test": "boringssl_crypto_tests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4045,6 +2450,7 @@ "test": "boringssl_ssl_tests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4064,6 +2470,7 @@ "args": [ "--disable-features=VizDisplayCompositor" ], + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4085,6 +2492,7 @@ "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0", "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_browser_tests.filter" ], + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4101,6 +2509,7 @@ "test": "browser_tests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4119,6 +2528,7 @@ "args": [ "--gtest_filter=-*UsingRealWebcam*" ], + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4134,6 +2544,7 @@ "test": "capture_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4149,6 +2560,7 @@ "test": "cast_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4164,6 +2576,7 @@ "test": "cc_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4179,6 +2592,7 @@ "test": "chrome_app_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4194,6 +2608,7 @@ "test": "chromedriver_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4209,6 +2624,7 @@ "test": "chromeos_components_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4224,6 +2640,7 @@ "test": "chromeos_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4239,6 +2656,7 @@ "test": "color_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4254,6 +2672,7 @@ "test": "components_browsertests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4269,6 +2688,7 @@ "test": "components_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4284,6 +2704,7 @@ "test": "compositor_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4303,6 +2724,7 @@ "args": [ "--disable-features=VizDisplayCompositor" ], + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4320,6 +2742,7 @@ "test": "content_browsertests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4338,6 +2761,7 @@ "args": [ "--disable-features=VizDisplayCompositor" ], + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4354,6 +2778,7 @@ "test": "content_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4369,6 +2794,7 @@ "test": "crypto_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4384,6 +2810,7 @@ "test": "dbus_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4399,6 +2826,7 @@ "test": "device_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4414,6 +2842,7 @@ "test": "display_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4429,6 +2858,7 @@ "test": "events_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4444,6 +2874,7 @@ "test": "exo_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4459,6 +2890,7 @@ "test": "extensions_browsertests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4474,6 +2906,7 @@ "test": "extensions_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4489,6 +2922,7 @@ "test": "filesystem_service_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4504,6 +2938,7 @@ "test": "gcm_unit_tests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4519,6 +2954,7 @@ "test": "gfx_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4534,6 +2970,7 @@ "test": "gin_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4549,6 +2986,7 @@ "test": "gl_unittests_ozone" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4564,6 +3002,7 @@ "test": "google_apis_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4579,6 +3018,7 @@ "test": "gpu_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4594,6 +3034,7 @@ "test": "gwp_asan_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4614,6 +3055,7 @@ "--disable-blink-features=HTMLImports,ShadowDOMV0,CustomElementsV0", "--test-launcher-filter-file=../../testing/buildbot/filters/webui_html_imports_polyfill_interactive_ui_tests.filter" ], + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4630,6 +3072,7 @@ "test": "interactive_ui_tests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4645,6 +3088,7 @@ "test": "ipc_tests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4660,6 +3104,7 @@ "test": "jingle_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4675,6 +3120,7 @@ "test": "keyboard_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4690,6 +3136,7 @@ "test": "latency_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4705,6 +3152,7 @@ "test": "leveldb_service_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4720,6 +3168,7 @@ "test": "libjingle_xmpp_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4735,6 +3184,7 @@ "test": "media_blink_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4750,6 +3200,7 @@ "test": "media_service_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4765,6 +3216,7 @@ "test": "media_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4780,6 +3232,7 @@ "test": "message_center_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4795,6 +3248,7 @@ "test": "midi_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4810,6 +3264,7 @@ "test": "mojo_core_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4825,6 +3280,7 @@ "test": "mojo_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4840,6 +3296,7 @@ "test": "nacl_helper_nonsfi_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4855,6 +3312,7 @@ "test": "nacl_loader_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4870,6 +3328,7 @@ "test": "native_theme_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4888,6 +3347,7 @@ "args": [ "--ozone-platform=headless" ], + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4903,6 +3363,7 @@ "test": "ozone_gl_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4918,6 +3379,7 @@ "test": "ozone_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4933,6 +3395,7 @@ "test": "ozone_x11_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4948,6 +3411,7 @@ "test": "pdf_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4963,6 +3427,7 @@ "test": "perfetto_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4978,6 +3443,7 @@ "test": "ppapi_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -4993,6 +3459,7 @@ "test": "printing_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5008,6 +3475,7 @@ "test": "remoting_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5023,6 +3491,7 @@ "test": "sandbox_linux_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5038,6 +3507,7 @@ "test": "service_manager_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5053,6 +3523,7 @@ "test": "services_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5068,6 +3539,7 @@ "test": "shell_dialogs_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5083,6 +3555,7 @@ "test": "skia_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5098,6 +3571,7 @@ "test": "snapshot_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5113,6 +3587,7 @@ "test": "sql_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5128,6 +3603,7 @@ "test": "storage_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5143,6 +3619,7 @@ "test": "sync_integration_tests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5158,6 +3635,7 @@ "test": "traffic_annotation_auditor_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5173,6 +3651,7 @@ "test": "ui_base_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5188,6 +3667,7 @@ "test": "ui_chromeos_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5203,6 +3683,7 @@ "test": "ui_touch_selection_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5218,6 +3699,7 @@ "test": "unit_tests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5234,6 +3716,7 @@ }, { "experiment_percentage": 100, + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5249,6 +3732,7 @@ "test": "usage_time_limit_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5264,6 +3748,7 @@ "test": "views_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5279,6 +3764,7 @@ "test": "viz_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5294,6 +3780,7 @@ "test": "wayland_client_perftests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5309,6 +3796,7 @@ "test": "wm_unittests" }, { + "isolate_coverage_data": true, "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py"
diff --git a/testing/buildbot/generate_buildbot_json.py b/testing/buildbot/generate_buildbot_json.py index 64370c6..7218462 100755 --- a/testing/buildbot/generate_buildbot_json.py +++ b/testing/buildbot/generate_buildbot_json.py
@@ -1049,8 +1049,6 @@ 'win32-dbg', 'win-archive-dbg', 'win32-archive-dbg', - # code coverage, see https://crbug.com/1000367. - 'linux-chromeos-coverage-rel-dummy', ] def get_internal_waterfalls(self):
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index bfdaf5e..56001b981 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -781,21 +781,6 @@ }, 'os_type': 'chromeos', }, - # Replicate linux-chromeos-rel for code coverage experiment. - # TODO(crbug.com/1000367): Remove once linux-chromeos-coverage-rel is - # folded into linux-chromeos-rel. - 'linux-chromeos-coverage-rel-dummy': { - 'mixins': [ - 'linux-xenial', - 'code-coverage', - ], - 'additional_compile_targets': [ - 'gn_all', - ], - 'test_suites': { - 'gtest_tests': 'linux_chromeos_gtests', - }, - }, 'linux-chromeos-dbg': { 'mixins': [ 'linux-xenial', @@ -807,6 +792,7 @@ 'linux-chromeos-rel': { 'mixins': [ 'linux-xenial', + 'code-coverage', ], 'additional_compile_targets': [ 'gn_all',
diff --git a/third_party/.gitignore b/third_party/.gitignore index a0870189..9b8f5b31 100644 --- a/third_party/.gitignore +++ b/third_party/.gitignore
@@ -73,6 +73,7 @@ /emoji-segmenter/src /errorprone/lib /espresso/lib/ +/expat/src /eyesfree/src /feed/src /ffmpeg
diff --git a/third_party/blink/common/indexeddb/indexeddb_key_path.cc b/third_party/blink/common/indexeddb/indexeddb_key_path.cc index ec2b618e..552d541 100644 --- a/third_party/blink/common/indexeddb/indexeddb_key_path.cc +++ b/third_party/blink/common/indexeddb/indexeddb_key_path.cc
@@ -18,12 +18,12 @@ : type_(mojom::IDBKeyPathType::Array), array_(array) {} IndexedDBKeyPath::IndexedDBKeyPath(const IndexedDBKeyPath& other) = default; -IndexedDBKeyPath::IndexedDBKeyPath(IndexedDBKeyPath&& other) noexcept = default; +IndexedDBKeyPath::IndexedDBKeyPath(IndexedDBKeyPath&& other) = default; IndexedDBKeyPath::~IndexedDBKeyPath() = default; IndexedDBKeyPath& IndexedDBKeyPath::operator=(const IndexedDBKeyPath& other) = default; -IndexedDBKeyPath& IndexedDBKeyPath::operator=( - IndexedDBKeyPath&& other) noexcept = default; +IndexedDBKeyPath& IndexedDBKeyPath::operator=(IndexedDBKeyPath&& other) = + default; const std::vector<base::string16>& IndexedDBKeyPath::array() const { DCHECK(type_ == blink::mojom::IDBKeyPathType::Array);
diff --git a/third_party/blink/common/indexeddb/indexeddb_metadata.cc b/third_party/blink/common/indexeddb/indexeddb_metadata.cc index 50d5845..93497320 100644 --- a/third_party/blink/common/indexeddb/indexeddb_metadata.cc +++ b/third_party/blink/common/indexeddb/indexeddb_metadata.cc
@@ -23,15 +23,15 @@ IndexedDBIndexMetadata::IndexedDBIndexMetadata( const IndexedDBIndexMetadata& other) = default; -IndexedDBIndexMetadata::IndexedDBIndexMetadata( - IndexedDBIndexMetadata&& other) noexcept = default; +IndexedDBIndexMetadata::IndexedDBIndexMetadata(IndexedDBIndexMetadata&& other) = + default; IndexedDBIndexMetadata::~IndexedDBIndexMetadata() = default; IndexedDBIndexMetadata& IndexedDBIndexMetadata::operator=( const IndexedDBIndexMetadata& other) = default; IndexedDBIndexMetadata& IndexedDBIndexMetadata::operator=( - IndexedDBIndexMetadata&& other) noexcept = default; + IndexedDBIndexMetadata&& other) = default; bool IndexedDBIndexMetadata::operator==( const IndexedDBIndexMetadata& other) const { @@ -56,14 +56,14 @@ IndexedDBObjectStoreMetadata::IndexedDBObjectStoreMetadata( const IndexedDBObjectStoreMetadata& other) = default; IndexedDBObjectStoreMetadata::IndexedDBObjectStoreMetadata( - IndexedDBObjectStoreMetadata&& other) noexcept = default; + IndexedDBObjectStoreMetadata&& other) = default; IndexedDBObjectStoreMetadata::~IndexedDBObjectStoreMetadata() = default; IndexedDBObjectStoreMetadata& IndexedDBObjectStoreMetadata::operator=( const IndexedDBObjectStoreMetadata& other) = default; IndexedDBObjectStoreMetadata& IndexedDBObjectStoreMetadata::operator=( - IndexedDBObjectStoreMetadata&& other) noexcept = default; + IndexedDBObjectStoreMetadata&& other) = default; bool IndexedDBObjectStoreMetadata::operator==( const IndexedDBObjectStoreMetadata& other) const { @@ -87,14 +87,14 @@ IndexedDBDatabaseMetadata::IndexedDBDatabaseMetadata( const IndexedDBDatabaseMetadata& other) = default; IndexedDBDatabaseMetadata::IndexedDBDatabaseMetadata( - IndexedDBDatabaseMetadata&& other) noexcept = default; + IndexedDBDatabaseMetadata&& other) = default; IndexedDBDatabaseMetadata::~IndexedDBDatabaseMetadata() = default; IndexedDBDatabaseMetadata& IndexedDBDatabaseMetadata::operator=( const IndexedDBDatabaseMetadata& other) = default; IndexedDBDatabaseMetadata& IndexedDBDatabaseMetadata::operator=( - IndexedDBDatabaseMetadata&& other) noexcept = default; + IndexedDBDatabaseMetadata&& other) = default; bool IndexedDBDatabaseMetadata::operator==( const IndexedDBDatabaseMetadata& other) const {
diff --git a/third_party/blink/common/mediastream/media_devices.cc b/third_party/blink/common/mediastream/media_devices.cc index 93df201..3661b4b 100644 --- a/third_party/blink/common/mediastream/media_devices.cc +++ b/third_party/blink/common/mediastream/media_devices.cc
@@ -13,8 +13,7 @@ WebMediaDeviceInfo::WebMediaDeviceInfo(const WebMediaDeviceInfo& other) = default; -WebMediaDeviceInfo::WebMediaDeviceInfo(WebMediaDeviceInfo&& other) noexcept = - default; +WebMediaDeviceInfo::WebMediaDeviceInfo(WebMediaDeviceInfo&& other) = default; WebMediaDeviceInfo::WebMediaDeviceInfo(const std::string& device_id, const std::string& label, @@ -36,8 +35,8 @@ WebMediaDeviceInfo& WebMediaDeviceInfo::operator=( const WebMediaDeviceInfo& other) = default; -WebMediaDeviceInfo& WebMediaDeviceInfo::operator=( - WebMediaDeviceInfo&& other) noexcept = default; +WebMediaDeviceInfo& WebMediaDeviceInfo::operator=(WebMediaDeviceInfo&& other) = + default; bool operator==(const WebMediaDeviceInfo& first, const WebMediaDeviceInfo& second) {
diff --git a/third_party/blink/common/messaging/cloneable_message.cc b/third_party/blink/common/messaging/cloneable_message.cc index 2984fd1..5c3ee7e8 100644 --- a/third_party/blink/common/messaging/cloneable_message.cc +++ b/third_party/blink/common/messaging/cloneable_message.cc
@@ -12,9 +12,8 @@ namespace blink { CloneableMessage::CloneableMessage() = default; -CloneableMessage::CloneableMessage(CloneableMessage&&) noexcept = default; -CloneableMessage& CloneableMessage::operator=(CloneableMessage&&) noexcept = - default; +CloneableMessage::CloneableMessage(CloneableMessage&&) = default; +CloneableMessage& CloneableMessage::operator=(CloneableMessage&&) = default; CloneableMessage::~CloneableMessage() = default; CloneableMessage CloneableMessage::ShallowClone() const {
diff --git a/third_party/blink/common/messaging/transferable_message.cc b/third_party/blink/common/messaging/transferable_message.cc index 07ac9bbc..4a69d0aa 100644 --- a/third_party/blink/common/messaging/transferable_message.cc +++ b/third_party/blink/common/messaging/transferable_message.cc
@@ -9,10 +9,9 @@ namespace blink { TransferableMessage::TransferableMessage() = default; -TransferableMessage::TransferableMessage(TransferableMessage&&) noexcept = +TransferableMessage::TransferableMessage(TransferableMessage&&) = default; +TransferableMessage& TransferableMessage::operator=(TransferableMessage&&) = default; -TransferableMessage& TransferableMessage::operator=( - TransferableMessage&&) noexcept = default; TransferableMessage::~TransferableMessage() = default; } // namespace blink
diff --git a/third_party/blink/public/common/indexeddb/indexeddb_key_path.h b/third_party/blink/public/common/indexeddb/indexeddb_key_path.h index 8ebe10c..9f5422c8 100644 --- a/third_party/blink/public/common/indexeddb/indexeddb_key_path.h +++ b/third_party/blink/public/common/indexeddb/indexeddb_key_path.h
@@ -22,10 +22,10 @@ explicit IndexedDBKeyPath(const base::string16&); explicit IndexedDBKeyPath(const std::vector<base::string16>&); IndexedDBKeyPath(const IndexedDBKeyPath& other); - IndexedDBKeyPath(IndexedDBKeyPath&& other) noexcept; + IndexedDBKeyPath(IndexedDBKeyPath&& other); ~IndexedDBKeyPath(); IndexedDBKeyPath& operator=(const IndexedDBKeyPath& other); - IndexedDBKeyPath& operator=(IndexedDBKeyPath&& other) noexcept; + IndexedDBKeyPath& operator=(IndexedDBKeyPath&& other); bool IsNull() const { return type_ == blink::mojom::IDBKeyPathType::Null; } bool operator==(const IndexedDBKeyPath& other) const;
diff --git a/third_party/blink/public/common/indexeddb/indexeddb_metadata.h b/third_party/blink/public/common/indexeddb/indexeddb_metadata.h index 15663f60..7bb37c9e 100644 --- a/third_party/blink/public/common/indexeddb/indexeddb_metadata.h +++ b/third_party/blink/public/common/indexeddb/indexeddb_metadata.h
@@ -26,10 +26,10 @@ bool unique, bool multi_entry); IndexedDBIndexMetadata(const IndexedDBIndexMetadata& other); - IndexedDBIndexMetadata(IndexedDBIndexMetadata&& other) noexcept; + IndexedDBIndexMetadata(IndexedDBIndexMetadata&& other); ~IndexedDBIndexMetadata(); IndexedDBIndexMetadata& operator=(const IndexedDBIndexMetadata& other); - IndexedDBIndexMetadata& operator=(IndexedDBIndexMetadata&& other) noexcept; + IndexedDBIndexMetadata& operator=(IndexedDBIndexMetadata&& other); bool operator==(const IndexedDBIndexMetadata& other) const; base::string16 name; @@ -50,12 +50,11 @@ bool auto_increment, int64_t max_index_id); IndexedDBObjectStoreMetadata(const IndexedDBObjectStoreMetadata& other); - IndexedDBObjectStoreMetadata(IndexedDBObjectStoreMetadata&& other) noexcept; + IndexedDBObjectStoreMetadata(IndexedDBObjectStoreMetadata&& other); ~IndexedDBObjectStoreMetadata(); IndexedDBObjectStoreMetadata& operator=( const IndexedDBObjectStoreMetadata& other); - IndexedDBObjectStoreMetadata& operator=( - IndexedDBObjectStoreMetadata&& other) noexcept; + IndexedDBObjectStoreMetadata& operator=(IndexedDBObjectStoreMetadata&& other); bool operator==(const IndexedDBObjectStoreMetadata& other) const; base::string16 name; @@ -77,11 +76,10 @@ int64_t version, int64_t max_object_store_id); IndexedDBDatabaseMetadata(const IndexedDBDatabaseMetadata& other); - IndexedDBDatabaseMetadata(IndexedDBDatabaseMetadata&& other) noexcept; + IndexedDBDatabaseMetadata(IndexedDBDatabaseMetadata&& other); ~IndexedDBDatabaseMetadata(); IndexedDBDatabaseMetadata& operator=(const IndexedDBDatabaseMetadata& other); - IndexedDBDatabaseMetadata& operator=( - IndexedDBDatabaseMetadata&& other) noexcept; + IndexedDBDatabaseMetadata& operator=(IndexedDBDatabaseMetadata&& other); bool operator==(const IndexedDBDatabaseMetadata& other) const; base::string16 name;
diff --git a/third_party/blink/public/common/mediastream/media_devices.h b/third_party/blink/public/common/mediastream/media_devices.h index 0d63e575..d87affeb 100644 --- a/third_party/blink/public/common/mediastream/media_devices.h +++ b/third_party/blink/public/common/mediastream/media_devices.h
@@ -27,7 +27,7 @@ struct BLINK_COMMON_EXPORT WebMediaDeviceInfo { WebMediaDeviceInfo(); WebMediaDeviceInfo(const WebMediaDeviceInfo& other); - WebMediaDeviceInfo(WebMediaDeviceInfo&& other) noexcept; + WebMediaDeviceInfo(WebMediaDeviceInfo&& other); WebMediaDeviceInfo( const std::string& device_id, const std::string& label, @@ -37,7 +37,7 @@ const media::VideoCaptureDeviceDescriptor& descriptor); ~WebMediaDeviceInfo(); WebMediaDeviceInfo& operator=(const WebMediaDeviceInfo& other); - WebMediaDeviceInfo& operator=(WebMediaDeviceInfo&& other) noexcept; + WebMediaDeviceInfo& operator=(WebMediaDeviceInfo&& other); std::string device_id; std::string label;
diff --git a/third_party/blink/public/common/messaging/cloneable_message.h b/third_party/blink/public/common/messaging/cloneable_message.h index de9952d..8dbd9106 100644 --- a/third_party/blink/public/common/messaging/cloneable_message.h +++ b/third_party/blink/public/common/messaging/cloneable_message.h
@@ -21,8 +21,8 @@ // This type can be serialized as a blink::mojom::CloneableMessage struct. struct BLINK_COMMON_EXPORT CloneableMessage { CloneableMessage(); - CloneableMessage(CloneableMessage&&) noexcept; - CloneableMessage& operator=(CloneableMessage&&) noexcept; + CloneableMessage(CloneableMessage&&); + CloneableMessage& operator=(CloneableMessage&&); ~CloneableMessage(); // Returns a shallow clone of this message. |encoded_message| in the clone
diff --git a/third_party/blink/public/common/messaging/transferable_message.h b/third_party/blink/public/common/messaging/transferable_message.h index 5eef63c..2d87363 100644 --- a/third_party/blink/public/common/messaging/transferable_message.h +++ b/third_party/blink/public/common/messaging/transferable_message.h
@@ -22,8 +22,8 @@ // type can be serialized as a blink::mojom::TransferableMessage struct. struct BLINK_COMMON_EXPORT TransferableMessage : public CloneableMessage { TransferableMessage(); - TransferableMessage(TransferableMessage&&) noexcept; - TransferableMessage& operator=(TransferableMessage&&) noexcept; + TransferableMessage(TransferableMessage&&); + TransferableMessage& operator=(TransferableMessage&&); ~TransferableMessage(); // Any ports being transferred as part of this message.
diff --git a/third_party/blink/public/mojom/service_worker/embedded_worker.mojom b/third_party/blink/public/mojom/service_worker/embedded_worker.mojom index f05400c..9433fee 100644 --- a/third_party/blink/public/mojom/service_worker/embedded_worker.mojom +++ b/third_party/blink/public/mojom/service_worker/embedded_worker.mojom
@@ -21,7 +21,6 @@ import "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom"; import "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom"; import "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom"; -import "third_party/blink/public/mojom/v8_cache_options.mojom"; import "third_party/blink/public/mojom/worker/worker_content_settings_proxy.mojom"; import "third_party/blink/public/mojom/web_feature/web_feature.mojom"; import "url/mojom/url.mojom"; @@ -77,9 +76,6 @@ // True if this service worker has been installed. bool is_installed; - // Determines how eagerly V8 creates the code cache. - V8CacheOptions v8_cache_options; - // Used to set up fetch requests. RendererPreferences renderer_preferences;
diff --git a/third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h b/third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h index 75f3ae16..81edd69 100644 --- a/third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h +++ b/third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h
@@ -42,9 +42,8 @@ WebScopedVirtualTimePauser(); ~WebScopedVirtualTimePauser(); - WebScopedVirtualTimePauser(WebScopedVirtualTimePauser&& other) noexcept; - WebScopedVirtualTimePauser& operator=( - WebScopedVirtualTimePauser&& other) noexcept; + WebScopedVirtualTimePauser(WebScopedVirtualTimePauser&& other); + WebScopedVirtualTimePauser& operator=(WebScopedVirtualTimePauser&& other); WebScopedVirtualTimePauser(const WebScopedVirtualTimePauser&) = delete; WebScopedVirtualTimePauser& operator=(const WebScopedVirtualTimePauser&) =
diff --git a/third_party/blink/public/platform/web_string.h b/third_party/blink/public/platform/web_string.h index e4fda4f6..ffd1da0 100644 --- a/third_party/blink/public/platform/web_string.h +++ b/third_party/blink/public/platform/web_string.h
@@ -102,10 +102,10 @@ BLINK_PLATFORM_EXPORT WebString(const WebUChar* data, size_t len); BLINK_PLATFORM_EXPORT WebString(const WebString&); - BLINK_PLATFORM_EXPORT WebString(WebString&&) noexcept; + BLINK_PLATFORM_EXPORT WebString(WebString&&); BLINK_PLATFORM_EXPORT WebString& operator=(const WebString&); - BLINK_PLATFORM_EXPORT WebString& operator=(WebString&&) noexcept; + BLINK_PLATFORM_EXPORT WebString& operator=(WebString&&); BLINK_PLATFORM_EXPORT void Reset();
diff --git a/third_party/blink/public/web/DEPS b/third_party/blink/public/web/DEPS index 58f3066d..e2f15930 100644 --- a/third_party/blink/public/web/DEPS +++ b/third_party/blink/public/web/DEPS
@@ -14,6 +14,7 @@ "+cc/input/overscroll_behavior.h", "+cc/input/layer_selection_bound.h", "+cc/layers/layer.h", + "+cc/metrics/begin_main_frame_metrics.h", "+cc/paint/element_id.h", "+cc/paint/paint_canvas.h", "+cc/paint/paint_flags.h",
diff --git a/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h b/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h index 99f47f5..8451b86 100644 --- a/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h +++ b/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h
@@ -73,8 +73,8 @@ VideoCaptureSettings(const VideoCaptureSettings& other); VideoCaptureSettings& operator=(const VideoCaptureSettings& other); - VideoCaptureSettings(VideoCaptureSettings&& other) noexcept; - VideoCaptureSettings& operator=(VideoCaptureSettings&& other) noexcept; + VideoCaptureSettings(VideoCaptureSettings&& other); + VideoCaptureSettings& operator=(VideoCaptureSettings&& other); ~VideoCaptureSettings(); bool HasValue() const { return !failed_constraint_name_; } @@ -193,8 +193,8 @@ const AudioProcessingProperties& audio_processing_properties); AudioCaptureSettings(const AudioCaptureSettings& other); AudioCaptureSettings& operator=(const AudioCaptureSettings& other); - AudioCaptureSettings(AudioCaptureSettings&& other) noexcept; - AudioCaptureSettings& operator=(AudioCaptureSettings&& other) noexcept; + AudioCaptureSettings(AudioCaptureSettings&& other); + AudioCaptureSettings& operator=(AudioCaptureSettings&& other); bool HasValue() const { return !failed_constraint_name_; }
diff --git a/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h b/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h index 199bdeb2..c89e6e9 100644 --- a/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h +++ b/third_party/blink/public/web/modules/mediastream/media_stream_constraints_util_sets.h
@@ -159,8 +159,8 @@ DiscreteSet(const DiscreteSet& other) = default; DiscreteSet& operator=(const DiscreteSet& other) = default; - DiscreteSet(DiscreteSet&& other) noexcept = default; - DiscreteSet& operator=(DiscreteSet&& other) noexcept = default; + DiscreteSet(DiscreteSet&& other) = default; + DiscreteSet& operator=(DiscreteSet&& other) = default; ~DiscreteSet() = default; bool Contains(const T& value) const {
diff --git a/third_party/blink/public/web/modules/mediastream/media_stream_video_source.h b/third_party/blink/public/web/modules/mediastream/media_stream_video_source.h index 5e50d1b..ed5967f 100644 --- a/third_party/blink/public/web/modules/mediastream/media_stream_video_source.h +++ b/third_party/blink/public/web/modules/mediastream/media_stream_video_source.h
@@ -285,8 +285,8 @@ const VideoTrackFormatCallback& format_callback, std::unique_ptr<VideoTrackAdapterSettings> adapter_settings, const ConstraintsCallback& callback); - PendingTrackInfo(PendingTrackInfo&& other) noexcept; - PendingTrackInfo& operator=(PendingTrackInfo&& other) noexcept; + PendingTrackInfo(PendingTrackInfo&& other); + PendingTrackInfo& operator=(PendingTrackInfo&& other); ~PendingTrackInfo(); MediaStreamVideoTrack* track;
diff --git a/third_party/blink/public/web/web_embedded_worker_start_data.h b/third_party/blink/public/web/web_embedded_worker_start_data.h index c4e3d06..be3cf43 100644 --- a/third_party/blink/public/web/web_embedded_worker_start_data.h +++ b/third_party/blink/public/web/web_embedded_worker_start_data.h
@@ -38,7 +38,6 @@ #include "third_party/blink/public/platform/web_content_security_policy.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url.h" -#include "third_party/blink/public/web/web_settings.h" namespace blink { @@ -54,15 +53,12 @@ // Unique worker token used by DevTools to attribute different instrumentation // to the same worker. base::UnguessableToken devtools_worker_token; - WebSettings::V8CacheOptions v8_cache_options; network::mojom::IPAddressSpace address_space; PrivacyPreferences privacy_preferences; - WebEmbeddedWorkerStartData() - : wait_for_debugger_mode(kDontWaitForDebugger), - v8_cache_options(WebSettings::V8CacheOptions::kDefault) {} + WebEmbeddedWorkerStartData() : wait_for_debugger_mode(kDontWaitForDebugger) {} }; } // namespace blink
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h index 31837ad0..7e5ee23 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -353,9 +353,6 @@ CrossOriginRedirects cross_origin_redirect_behavior, mojo::ScopedMessagePipeHandle blob_url_token) {} - // The client should load an error page in the current frame. - virtual void LoadErrorPage(int reason) {} - // Navigational queries ------------------------------------------------ // Requests the client to begin a navigation for this frame.
diff --git a/third_party/blink/public/web/web_widget.h b/third_party/blink/public/web/web_widget.h index bc31142..700d7448 100644 --- a/third_party/blink/public/web/web_widget.h +++ b/third_party/blink/public/web/web_widget.h
@@ -34,6 +34,7 @@ #include "base/callback.h" #include "base/time/time.h" #include "cc/input/browser_controls_state.h" +#include "cc/metrics/begin_main_frame_metrics.h" #include "cc/paint/element_id.h" #include "cc/trees/layer_tree_host_client.h" #include "third_party/blink/public/platform/web_common.h" @@ -103,6 +104,17 @@ // any metrics that depend upon the main frame total time. virtual void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) {} + // Return metrics information for the stages of BeginMainFrame. This is + // ultimately implemented by Blink's LocalFrameUKMAggregator. It must be a + // distinct call from the FrameMetrics above because the BeginMainFrameMetrics + // for compositor latency must be gathered before the layer tree is + // committed to the compositor, which is before the call to + // RecordEndOfFrameMetrics. + virtual std::unique_ptr<cc::BeginMainFrameMetrics> + GetBeginMainFrameMetrics() { + return nullptr; + } + // Methods called to mark the beginning and end of input processing work // before rAF scripts are executed. Only called when gathering main frame // UMA and UKM. That is, when RecordStartOfFrameMetrics has been called, and
diff --git a/third_party/blink/renderer/bindings/bindings.gni b/third_party/blink/renderer/bindings/bindings.gni index 3ba7f441..0b9a7778 100644 --- a/third_party/blink/renderer/bindings/bindings.gni +++ b/third_party/blink/renderer/bindings/bindings.gni
@@ -210,6 +210,7 @@ "core/v8/v8_binding_for_testing.cc", "core/v8/v8_binding_for_testing.h", "core/v8/window_proxy_test.cc", + "core/v8/world_safe_v8_reference_test.cc", "core/v8/v8_object_builder_test.cc", "core/v8/v8_script_runner_test.cc", "core/v8/serialization/serialized_script_value_test.cc",
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.cc b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.cc index 0f2accb..8d3b1b2 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.cc
@@ -12,9 +12,8 @@ namespace blink { -namespace { - -std::unique_ptr<DummyPageHolder> CreateDummyPageHolder(const KURL& url) { +std::unique_ptr<DummyPageHolder> V8TestingScope::CreateDummyPageHolder( + const KURL& url) { std::unique_ptr<DummyPageHolder> holder = std::make_unique<DummyPageHolder>(); if (url.IsValid()) { holder->GetFrame().Loader().CommitNavigation( @@ -25,8 +24,6 @@ return holder; } -} // namespace - V8TestingScope::V8TestingScope(const KURL& url) : holder_(CreateDummyPageHolder(url)), handle_scope_(GetIsolate()),
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h index d22214d6..ba8125b 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h +++ b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h
@@ -27,6 +27,9 @@ STACK_ALLOCATED(); public: + // TODO(keishi): Define CreateDummyPageHolder in DummyPageHolder. + static std::unique_ptr<DummyPageHolder> CreateDummyPageHolder( + const KURL& url); explicit V8TestingScope(const KURL& url = KURL()); ScriptState* GetScriptState() const; ExecutionContext* GetExecutionContext() const;
diff --git a/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.cc b/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.cc index 6bc84e4..7ee67ac 100644 --- a/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.cc +++ b/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.cc
@@ -40,9 +40,6 @@ v8::Local<v8::Value> value) { if (!value->IsObject()) return; - // TODO(crbug.com/v8/9713): Let JSModuleNamespaceObject have CreationContext. - if (value->IsModuleNamespaceObject()) - return; ScriptState* script_state = ScriptState::From(value.As<v8::Object>()->CreationContext());
diff --git a/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h b/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h index f3bb51bc..92ee8ca 100644 --- a/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h +++ b/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h
@@ -47,40 +47,57 @@ // provides accessors that check whether the value is accessed in the same world // or not, also provides an accessor that clones the value when accessed across // worlds. +// +// TODO(crbug.com/1008765): Allow WorldSafeV8Reference created/set not in +// context. template <typename V8Type> class WorldSafeV8Reference final { DISALLOW_NEW(); public: WorldSafeV8Reference() = default; + explicit WorldSafeV8Reference(v8::Isolate* isolate, v8::Local<V8Type> value) - : v8_reference_(isolate, value), - world_(&DOMWrapperWorld::Current(isolate)) { - WorldSafeV8ReferenceInternal::MaybeCheckCreationContextWorld(*world_.get(), - value); + : v8_reference_(isolate, value) { + // Basically, |world_| is a world when this V8 reference is created. + // However, when this V8 reference isn't created in context and value is + // object, we set |world_| to a value's creation cotext's world. + if (isolate->InContext()) { + world_ = &DOMWrapperWorld::Current(isolate); + WorldSafeV8ReferenceInternal::MaybeCheckCreationContextWorld( + *world_.get(), value); + } else if (value->IsObject()) { + ScriptState* script_state = + ScriptState::From(value.template As<v8::Object>()->CreationContext()); + world_ = &script_state->World(); + } } ~WorldSafeV8Reference() = default; - // Returns the V8 reference. Crashes if |target_script_state|'s world is - // different from this V8 reference's world. + // Returns the V8 reference. Crashes if |world_| is set and it is + // different from |target_script_state|'s world. v8::Local<V8Type> Get(ScriptState* target_script_state) const { DCHECK(!v8_reference_.IsEmpty()); - CHECK_EQ(world_.get(), &target_script_state->World()); + if (world_) { + CHECK_EQ(world_.get(), &target_script_state->World()); + } return v8_reference_.NewLocal(target_script_state->GetIsolate()); } // Returns a V8 reference that is safe to access in |target_script_state|. // The return value may be a cloned object. v8::Local<V8Type> GetAcrossWorld(ScriptState* target_script_state) const { + CHECK(world_); return WorldSafeV8ReferenceInternal::ToWorldSafeValue( target_script_state, v8_reference_, *world_.get()) .template As<V8Type>(); } - // Sets a new V8 reference. Crashes if |new_value|'s world is different from - // this V8 reference's world. + // Sets a new V8 reference. Crashes if |world_| is set and it is + // different from |new_value|'s world. void Set(v8::Isolate* isolate, v8::Local<V8Type> new_value) { DCHECK(!new_value.IsEmpty()); + CHECK(isolate->InContext()); const DOMWrapperWorld& new_world = DOMWrapperWorld::Current(isolate); WorldSafeV8ReferenceInternal::MaybeCheckCreationContextWorld(new_world, new_value); @@ -93,6 +110,7 @@ // world of this V8 reference will be |new_value|'s world. void SetAcrossWorld(v8::Isolate* isolate, v8::Local<V8Type> new_value) { DCHECK(!new_value.IsEmpty()); + CHECK(isolate->InContext()); const DOMWrapperWorld& new_world = DOMWrapperWorld::Current(isolate); v8_reference_.Set(isolate, new_value); world_ = WrapRefCounted(&new_world);
diff --git a/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference_test.cc b/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference_test.cc new file mode 100644 index 0000000..8f16674 --- /dev/null +++ b/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference_test.cc
@@ -0,0 +1,63 @@ +// 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 "third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h" + +#include "testing/gmock/include/gmock/gmock-matchers.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" +#include "third_party/blink/renderer/core/frame/settings.h" +#include "third_party/blink/renderer/core/testing/dummy_page_holder.h" +#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" +#include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "v8/include/v8.h" + +namespace blink { + +class DummyPageHolder; +class KURL; + +namespace { + +class IsolateOnlyV8TestingScope { + STACK_ALLOCATED(); + + public: + IsolateOnlyV8TestingScope(const KURL& url = KURL()) + : holder_(V8TestingScope::CreateDummyPageHolder(url)), + handle_scope_(GetIsolate()) {} + + v8::Isolate* GetIsolate() const { + return ToScriptStateForMainWorld(holder_->GetDocument().GetFrame()) + ->GetIsolate(); + } + + private: + std::unique_ptr<DummyPageHolder> holder_; + v8::HandleScope handle_scope_; +}; + +// http://crbug.com/1007504, http://crbug.com/1008425 +TEST(WorldSafeV8ReferenceTest, CreatedWhenNotInContext) { + WorldSafeV8Reference<v8::Value> v8_reference; + v8::Local<v8::Value> value; + { + IsolateOnlyV8TestingScope scope1; + v8::Isolate* isolate = scope1.GetIsolate(); + CHECK(isolate); + CHECK(!isolate->InContext()); + + value = v8::Null(isolate); + v8_reference = WorldSafeV8Reference<v8::Value>(isolate, value); + EXPECT_FALSE(v8_reference.IsEmpty()); + } + V8TestingScope scope2; + ScriptState* script_state = scope2.GetScriptState(); + EXPECT_EQ(v8_reference.Get(script_state), value); +} + +} // namespace + +} // namespace blink
diff --git a/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.h.tmpl b/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.h.tmpl index 52ad7d9..f33388f 100644 --- a/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.h.tmpl +++ b/third_party/blink/renderer/build/scripts/core/css/templates/style_property_shorthand.h.tmpl
@@ -64,7 +64,7 @@ const StylePropertyShorthand& transitionShorthandForParsing(); // Returns an empty list if the property is not a shorthand. -const StylePropertyShorthand& shorthandForProperty(CSSPropertyID); +CORE_EXPORT const StylePropertyShorthand& shorthandForProperty(CSSPropertyID); // Return the list of shorthands for a given longhand. // The client must pass in an empty result vector.
diff --git a/third_party/blink/renderer/core/DEPS b/third_party/blink/renderer/core/DEPS index 61297fef..b196a99b 100644 --- a/third_party/blink/renderer/core/DEPS +++ b/third_party/blink/renderer/core/DEPS
@@ -44,6 +44,7 @@ "+cc/layers/picture_layer.h", "+cc/layers/scrollbar_layer_interface.h", "+cc/layers/surface_layer.h", + "+cc/metrics/begin_main_frame_metrics.h", "+cc/paint/display_item_list.h", "+cc/paint/paint_canvas.h", "+cc/paint/paint_flags.h",
diff --git a/third_party/blink/renderer/core/animation/BUILD.gn b/third_party/blink/renderer/core/animation/BUILD.gn index a048dcf..824fe595 100644 --- a/third_party/blink/renderer/core/animation/BUILD.gn +++ b/third_party/blink/renderer/core/animation/BUILD.gn
@@ -160,6 +160,8 @@ "inert_effect.h", "interpolable_length.cc", "interpolable_length.h", + "interpolable_shadow.cc", + "interpolable_shadow.h", "interpolable_value.cc", "interpolable_value.h", "interpolated_svg_path_source.h", @@ -202,8 +204,6 @@ "scroll_timeline.h", "scroll_timeline_util.cc", "scroll_timeline_util.h", - "shadow_interpolation_functions.cc", - "shadow_interpolation_functions.h", "side_index.h", "size_interpolation_functions.cc", "size_interpolation_functions.h",
diff --git a/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc index fa454dd..fb5cbf7 100644 --- a/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_border_image_length_box_interpolation_type.cc
@@ -365,6 +365,8 @@ ListInterpolationFunctions::Composite( underlying_value_owner, underlying_fraction, *this, value, ListInterpolationFunctions::LengthMatchingStrategy::kEqual, + WTF::BindRepeating( + ListInterpolationFunctions::InterpolableValuesKnownCompatible), WTF::BindRepeating(NonInterpolableSidesAreCompatible), WTF::BindRepeating(CompositeSide)); }
diff --git a/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc index 86b713ad..1a787a8 100644 --- a/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_custom_list_interpolation_type.cc
@@ -127,6 +127,8 @@ ListInterpolationFunctions::Composite( underlying_value_owner, underlying_fraction, *this, value, ListInterpolationFunctions::LengthMatchingStrategy::kEqual, + WTF::BindRepeating( + ListInterpolationFunctions::InterpolableValuesKnownCompatible), GetNonInterpolableValuesAreCompatibleCallback(), WTF::BindRepeating(composite_callback, WTF::Unretained(inner_interpolation_type_.get()),
diff --git a/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.cc index f26a25a..07864c91 100644 --- a/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_length_list_interpolation_type.cc
@@ -148,6 +148,8 @@ underlying_value_owner, underlying_fraction, *this, value, ListInterpolationFunctions::LengthMatchingStrategy::kLowestCommonMultiple, WTF::BindRepeating( + ListInterpolationFunctions::InterpolableValuesKnownCompatible), + WTF::BindRepeating( ListInterpolationFunctions::VerifyNoNonInterpolableValues), WTF::BindRepeating([](UnderlyingValue& underlying_value, double underlying_fraction,
diff --git a/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc index 463cf6f6..32e5a11 100644 --- a/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_shadow_list_interpolation_type.cc
@@ -8,8 +8,8 @@ #include <utility> #include "base/memory/ptr_util.h" +#include "third_party/blink/renderer/core/animation/interpolable_shadow.h" #include "third_party/blink/renderer/core/animation/list_interpolation_functions.h" -#include "third_party/blink/renderer/core/animation/shadow_interpolation_functions.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css/css_value_list.h" @@ -44,8 +44,8 @@ const ShadowDataVector& shadows = shadow_list->Shadows(); return ListInterpolationFunctions::CreateList( shadows.size(), [&shadows, zoom](wtf_size_t index) { - return ShadowInterpolationFunctions::ConvertShadowData(shadows[index], - zoom); + return InterpolationValue( + InterpolableShadow::Create(shadows[index], zoom)); }); } @@ -116,8 +116,8 @@ const auto& value_list = To<CSSValueList>(value); return ListInterpolationFunctions::CreateList( value_list.length(), [&value_list](wtf_size_t index) { - return ShadowInterpolationFunctions::MaybeConvertCSSValue( - value_list.Item(index)); + return InterpolationValue( + InterpolableShadow::MaybeConvertCSSValue(value_list.Item(index))); }); } @@ -127,7 +127,12 @@ return ListInterpolationFunctions::MaybeMergeSingles( std::move(start), std::move(end), ListInterpolationFunctions::LengthMatchingStrategy::kPadToLargest, - WTF::BindRepeating(ShadowInterpolationFunctions::MaybeMergeSingles)); + WTF::BindRepeating( + [](InterpolationValue&& start_item, InterpolationValue&& end_item) { + return InterpolableShadow::MaybeMergeSingles( + std::move(start_item.interpolable_value), + std::move(end_item.interpolable_value)); + })); } InterpolationValue @@ -145,9 +150,10 @@ ListInterpolationFunctions::Composite( underlying_value_owner, underlying_fraction, *this, value, ListInterpolationFunctions::LengthMatchingStrategy::kPadToLargest, + WTF::BindRepeating(InterpolableShadow::CompatibleForCompositing), WTF::BindRepeating( - ShadowInterpolationFunctions::NonInterpolableValuesAreCompatible), - WTF::BindRepeating(ShadowInterpolationFunctions::Composite)); + ListInterpolationFunctions::VerifyNoNonInterpolableValues), + WTF::BindRepeating(InterpolableShadow::Composite)); } static scoped_refptr<ShadowList> CreateShadowList( @@ -159,12 +165,11 @@ wtf_size_t length = interpolable_list.length(); if (length == 0) return nullptr; - const NonInterpolableList& non_interpolable_list = - ToNonInterpolableList(*non_interpolable_value); ShadowDataVector shadows; - for (wtf_size_t i = 0; i < length; i++) - shadows.push_back(ShadowInterpolationFunctions::CreateShadowData( - *interpolable_list.Get(i), non_interpolable_list.Get(i), state)); + for (wtf_size_t i = 0; i < length; i++) { + shadows.push_back(To<InterpolableShadow>(interpolable_list.Get(i)) + ->CreateShadowData(state)); + } return ShadowList::Adopt(shadows); }
diff --git a/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.cc index 181f65e..7ae4e510 100644 --- a/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_size_list_interpolation_type.cc
@@ -165,6 +165,8 @@ underlying_value_owner, underlying_fraction, *this, value, ListInterpolationFunctions::LengthMatchingStrategy::kLowestCommonMultiple, WTF::BindRepeating( + ListInterpolationFunctions::InterpolableValuesKnownCompatible), + WTF::BindRepeating( SizeInterpolationFunctions::NonInterpolableValuesAreCompatible), WTF::BindRepeating(SizeInterpolationFunctions::Composite)); }
diff --git a/third_party/blink/renderer/core/animation/filter_interpolation_functions.cc b/third_party/blink/renderer/core/animation/filter_interpolation_functions.cc index dd4a2b4..6355d93 100644 --- a/third_party/blink/renderer/core/animation/filter_interpolation_functions.cc +++ b/third_party/blink/renderer/core/animation/filter_interpolation_functions.cc
@@ -6,7 +6,7 @@ #include <memory> #include "third_party/blink/renderer/core/animation/interpolable_length.h" -#include "third_party/blink/renderer/core/animation/shadow_interpolation_functions.h" +#include "third_party/blink/renderer/core/animation/interpolable_shadow.h" #include "third_party/blink/renderer/core/css/css_function_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/resolver/filter_operation_resolver.h" @@ -106,11 +106,10 @@ break; } - case FilterOperation::DROP_SHADOW: { - result = - ShadowInterpolationFunctions::MaybeConvertCSSValue(filter.Item(0)); + case FilterOperation::DROP_SHADOW: + result.interpolable_value = + InterpolableShadow::MaybeConvertCSSValue(filter.Item(0)); break; - } default: NOTREACHED(); @@ -152,11 +151,10 @@ To<BlurFilterOperation>(filter).StdDeviation(), zoom)); break; - case FilterOperation::DROP_SHADOW: { - result = ShadowInterpolationFunctions::ConvertShadowData( + case FilterOperation::DROP_SHADOW: + result.interpolable_value = InterpolableShadow::Create( To<DropShadowFilterOperation>(filter).Shadow(), zoom); break; - } case FilterOperation::REFERENCE: return nullptr; @@ -194,7 +192,7 @@ return InterpolableLength::CreateNeutral(); case FilterOperation::DROP_SHADOW: - return ShadowInterpolationFunctions::CreateNeutralInterpolableValue(); + return InterpolableShadow::CreateNeutral(); default: NOTREACHED(); @@ -247,9 +245,8 @@ } case FilterOperation::DROP_SHADOW: { - ShadowData shadow_data = ShadowInterpolationFunctions::CreateShadowData( - interpolable_value, non_interpolable_value.TypeNonInterpolableValue(), - state); + ShadowData shadow_data = + To<InterpolableShadow>(interpolable_value).CreateShadowData(state); if (shadow_data.GetColor().IsCurrentColor()) shadow_data.OverrideColor(Color::kBlack); return DropShadowFilterOperation::Create(shadow_data);
diff --git a/third_party/blink/renderer/core/animation/interpolable_length.cc b/third_party/blink/renderer/core/animation/interpolable_length.cc index 66925c6a..30f9484 100644 --- a/third_party/blink/renderer/core/animation/interpolable_length.cc +++ b/third_party/blink/renderer/core/animation/interpolable_length.cc
@@ -142,8 +142,8 @@ expression_ = &expression; } -std::unique_ptr<InterpolableValue> InterpolableLength::Clone() const { - return std::make_unique<InterpolableLength>(*this); +InterpolableLength* InterpolableLength::RawClone() const { + return new InterpolableLength(*this); } bool InterpolableLength::HasPercentage() const {
diff --git a/third_party/blink/renderer/core/animation/interpolable_length.h b/third_party/blink/renderer/core/animation/interpolable_length.h index 3f0948b2..071d604 100644 --- a/third_party/blink/renderer/core/animation/interpolable_length.h +++ b/third_party/blink/renderer/core/animation/interpolable_length.h
@@ -49,25 +49,31 @@ bool HasPercentage() const; void SubtractFromOneHundredPercent(); + std::unique_ptr<InterpolableLength> Clone() const { + return std::unique_ptr<InterpolableLength>(RawClone()); + } + std::unique_ptr<InterpolableLength> CloneAndZero() const { + return std::unique_ptr<InterpolableLength>(RawCloneAndZero()); + } + // InterpolableValue: + void Interpolate(const InterpolableValue& to, + const double progress, + InterpolableValue& result) const final; bool IsLength() const final { return true; } bool Equals(const InterpolableValue& other) const final { NOTREACHED(); return false; } - std::unique_ptr<InterpolableValue> Clone() const final; - std::unique_ptr<InterpolableValue> CloneAndZero() const final { - return std::make_unique<InterpolableLength>(CSSLengthArray()); - } void Scale(double scale) final; void ScaleAndAdd(double scale, const InterpolableValue& other) final; void AssertCanInterpolateWith(const InterpolableValue& other) const final; private: - // InterpolableValue: - void Interpolate(const InterpolableValue& to, - const double progress, - InterpolableValue& result) const final; + InterpolableLength* RawClone() const final; + InterpolableLength* RawCloneAndZero() const final { + return new InterpolableLength(CSSLengthArray()); + } bool IsLengthArray() const { return type_ == Type::kLengthArray; } bool IsExpression() const { return type_ == Type::kExpression; }
diff --git a/third_party/blink/renderer/core/animation/interpolable_shadow.cc b/third_party/blink/renderer/core/animation/interpolable_shadow.cc new file mode 100644 index 0000000..9aa7e20 --- /dev/null +++ b/third_party/blink/renderer/core/animation/interpolable_shadow.cc
@@ -0,0 +1,203 @@ +// 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 "third_party/blink/renderer/core/animation/interpolable_shadow.h" + +#include <memory> +#include "third_party/blink/renderer/core/animation/css_color_interpolation_type.h" +#include "third_party/blink/renderer/core/animation/underlying_value.h" +#include "third_party/blink/renderer/core/css/css_identifier_value.h" +#include "third_party/blink/renderer/core/css/css_shadow_value.h" +#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" +#include "third_party/blink/renderer/platform/geometry/float_point.h" + +namespace blink { +namespace { +std::unique_ptr<InterpolableLength> MaybeConvertLength( + const CSSPrimitiveValue* value) { + if (value) + return InterpolableLength::MaybeConvertCSSValue(*value); + return InterpolableLength::CreatePixels(0); +} + +std::unique_ptr<InterpolableValue> MaybeConvertColor(const CSSValue* value) { + if (value) + return CSSColorInterpolationType::MaybeCreateInterpolableColor(*value); + return CSSColorInterpolationType::CreateInterpolableColor( + StyleColor::CurrentColor()); +} +} // namespace + +InterpolableShadow::InterpolableShadow( + std::unique_ptr<InterpolableLength> x, + std::unique_ptr<InterpolableLength> y, + std::unique_ptr<InterpolableLength> blur, + std::unique_ptr<InterpolableLength> spread, + std::unique_ptr<InterpolableValue> color, + ShadowStyle shadow_style) + : x_(std::move(x)), + y_(std::move(y)), + blur_(std::move(blur)), + spread_(std::move(spread)), + color_(std::move(color)), + shadow_style_(shadow_style) { + DCHECK(x_); + DCHECK(y_); + DCHECK(blur_); + DCHECK(spread_); + DCHECK(color_); +} + +// static +std::unique_ptr<InterpolableShadow> InterpolableShadow::Create( + const ShadowData& shadow_data, + double zoom) { + return std::make_unique<InterpolableShadow>( + InterpolableLength::CreatePixels(shadow_data.X() / zoom), + InterpolableLength::CreatePixels(shadow_data.Y() / zoom), + InterpolableLength::CreatePixels(shadow_data.Blur() / zoom), + InterpolableLength::CreatePixels(shadow_data.Spread() / zoom), + CSSColorInterpolationType::CreateInterpolableColor( + shadow_data.GetColor()), + shadow_data.Style()); +} + +// static +std::unique_ptr<InterpolableShadow> InterpolableShadow::CreateNeutral() { + return Create(ShadowData::NeutralValue(), 1); +} + +// static +std::unique_ptr<InterpolableShadow> InterpolableShadow::MaybeConvertCSSValue( + const CSSValue& value) { + const auto* shadow = DynamicTo<CSSShadowValue>(value); + if (!shadow) + return nullptr; + + ShadowStyle shadow_style = kNormal; + if (shadow->style) { + if (shadow->style->GetValueID() != CSSValueID::kInset) + return nullptr; + shadow_style = kInset; + } + + std::unique_ptr<InterpolableLength> x = MaybeConvertLength(shadow->x.Get()); + std::unique_ptr<InterpolableLength> y = MaybeConvertLength(shadow->y.Get()); + std::unique_ptr<InterpolableLength> blur = + MaybeConvertLength(shadow->blur.Get()); + std::unique_ptr<InterpolableLength> spread = + MaybeConvertLength(shadow->spread.Get()); + std::unique_ptr<InterpolableValue> color = MaybeConvertColor(shadow->color); + + // If any of the conversations failed, we can't represent this CSSValue. + if (!x || !y || !blur || !spread || !color) + return nullptr; + + return std::make_unique<InterpolableShadow>( + std::move(x), std::move(y), std::move(blur), std::move(spread), + std::move(color), shadow_style); +} + +// static +PairwiseInterpolationValue InterpolableShadow::MaybeMergeSingles( + std::unique_ptr<InterpolableValue> start, + std::unique_ptr<InterpolableValue> end) { + if (To<InterpolableShadow>(start.get())->shadow_style_ != + To<InterpolableShadow>(end.get())->shadow_style_) + return nullptr; + return PairwiseInterpolationValue(std::move(start), std::move(end)); +} + +// static +bool InterpolableShadow::CompatibleForCompositing(const InterpolableValue* from, + const InterpolableValue* to) { + return To<InterpolableShadow>(from)->shadow_style_ == + To<InterpolableShadow>(to)->shadow_style_; +} + +// static +void InterpolableShadow::Composite(UnderlyingValue& underlying_value, + double underlying_fraction, + const InterpolableValue& interpolable_value, + const NonInterpolableValue*) { + InterpolableShadow& underlying_shadow = + To<InterpolableShadow>(underlying_value.MutableInterpolableValue()); + const InterpolableShadow& interpolable_shadow = + To<InterpolableShadow>(interpolable_value); + DCHECK_EQ(underlying_shadow.shadow_style_, interpolable_shadow.shadow_style_); + underlying_shadow.ScaleAndAdd(underlying_fraction, interpolable_shadow); +} + +ShadowData InterpolableShadow::CreateShadowData( + const StyleResolverState& state) const { + const CSSToLengthConversionData& conversion_data = + state.CssToLengthConversionData(); + Length shadow_x = x_->CreateLength(conversion_data, kValueRangeAll); + Length shadow_y = y_->CreateLength(conversion_data, kValueRangeAll); + Length shadow_blur = + blur_->CreateLength(conversion_data, kValueRangeNonNegative); + Length shadow_spread = spread_->CreateLength(conversion_data, kValueRangeAll); + DCHECK(shadow_x.IsFixed() && shadow_y.IsFixed() && shadow_blur.IsFixed() && + shadow_spread.IsFixed()); + return ShadowData( + FloatPoint(shadow_x.Value(), shadow_y.Value()), shadow_blur.Value(), + shadow_spread.Value(), shadow_style_, + CSSColorInterpolationType::ResolveInterpolableColor(*color_, state)); +} + +InterpolableShadow* InterpolableShadow::RawClone() const { + return new InterpolableShadow(x_->Clone(), y_->Clone(), blur_->Clone(), + spread_->Clone(), color_->Clone(), + shadow_style_); +} + +InterpolableShadow* InterpolableShadow::RawCloneAndZero() const { + return new InterpolableShadow(x_->CloneAndZero(), y_->CloneAndZero(), + blur_->CloneAndZero(), spread_->CloneAndZero(), + color_->CloneAndZero(), shadow_style_); +} + +void InterpolableShadow::Scale(double scale) { + x_->Scale(scale); + y_->Scale(scale); + blur_->Scale(scale); + spread_->Scale(scale); + color_->Scale(scale); +} + +void InterpolableShadow::ScaleAndAdd(double scale, + const InterpolableValue& other) { + const InterpolableShadow& other_shadow = To<InterpolableShadow>(other); + x_->ScaleAndAdd(scale, *other_shadow.x_); + y_->ScaleAndAdd(scale, *other_shadow.y_); + blur_->ScaleAndAdd(scale, *other_shadow.blur_); + spread_->ScaleAndAdd(scale, *other_shadow.spread_); + color_->ScaleAndAdd(scale, *other_shadow.color_); +} + +void InterpolableShadow::AssertCanInterpolateWith( + const InterpolableValue& other) const { + const InterpolableShadow& other_shadow = To<InterpolableShadow>(other); + DCHECK_EQ(shadow_style_, other_shadow.shadow_style_); + x_->AssertCanInterpolateWith(*other_shadow.x_); + y_->AssertCanInterpolateWith(*other_shadow.y_); + blur_->AssertCanInterpolateWith(*other_shadow.blur_); + spread_->AssertCanInterpolateWith(*other_shadow.spread_); + color_->AssertCanInterpolateWith(*other_shadow.color_); +} + +void InterpolableShadow::Interpolate(const InterpolableValue& to, + const double progress, + InterpolableValue& result) const { + const InterpolableShadow& to_shadow = To<InterpolableShadow>(to); + InterpolableShadow& result_shadow = To<InterpolableShadow>(result); + + x_->Interpolate(*to_shadow.x_, progress, *result_shadow.x_); + y_->Interpolate(*to_shadow.y_, progress, *result_shadow.y_); + blur_->Interpolate(*to_shadow.blur_, progress, *result_shadow.blur_); + spread_->Interpolate(*to_shadow.spread_, progress, *result_shadow.spread_); + color_->Interpolate(*to_shadow.color_, progress, *result_shadow.color_); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/animation/interpolable_shadow.h b/third_party/blink/renderer/core/animation/interpolable_shadow.h new file mode 100644 index 0000000..6bcc378 --- /dev/null +++ b/third_party/blink/renderer/core/animation/interpolable_shadow.h
@@ -0,0 +1,94 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLABLE_SHADOW_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLABLE_SHADOW_H_ + +#include <memory> +#include "third_party/blink/renderer/core/animation/interpolable_length.h" +#include "third_party/blink/renderer/core/animation/interpolable_value.h" +#include "third_party/blink/renderer/core/animation/interpolation_value.h" +#include "third_party/blink/renderer/core/animation/pairwise_interpolation_value.h" +#include "third_party/blink/renderer/core/style/shadow_data.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" + +namespace blink { + +class CSSValue; +class StyleResolverState; +class UnderlyingValue; + +// Represents a CSS shadow value (such as [0] or [1]), converted into a form +// that can be interpolated from/to. +// +// [0]: https://drafts.csswg.org/css-backgrounds-3/#typedef-shadow +// [1]: https://drafts.fxtf.org/filter-effects/#funcdef-filter-drop-shadow +class InterpolableShadow : public InterpolableValue { + public: + InterpolableShadow(std::unique_ptr<InterpolableLength> x, + std::unique_ptr<InterpolableLength> y, + std::unique_ptr<InterpolableLength> blur, + std::unique_ptr<InterpolableLength> spread, + std::unique_ptr<InterpolableValue> color, + ShadowStyle); + + static std::unique_ptr<InterpolableShadow> Create(const ShadowData&, + double zoom); + static std::unique_ptr<InterpolableShadow> CreateNeutral(); + + static std::unique_ptr<InterpolableShadow> MaybeConvertCSSValue( + const CSSValue&); + + // Helpers for CSSListInterpolationFunctions. + static PairwiseInterpolationValue MaybeMergeSingles( + std::unique_ptr<InterpolableValue> start, + std::unique_ptr<InterpolableValue> end); + static bool CompatibleForCompositing(const InterpolableValue*, + const InterpolableValue*); + static void Composite(UnderlyingValue&, + double underlying_fraction, + const InterpolableValue&, + const NonInterpolableValue*); + + // Convert this InterpolableShadow back into a ShadowData class, usually to be + // applied to the style after interpolating it. + ShadowData CreateShadowData(const StyleResolverState&) const; + + // InterpolableValue implementation: + void Interpolate(const InterpolableValue& to, + const double progress, + InterpolableValue& result) const final; + bool IsShadow() const final { return true; } + bool Equals(const InterpolableValue& other) const final { + NOTREACHED(); + return false; + } + void Scale(double scale) final; + void ScaleAndAdd(double scale, const InterpolableValue& other) final; + void AssertCanInterpolateWith(const InterpolableValue& other) const final; + + private: + InterpolableShadow* RawClone() const final; + InterpolableShadow* RawCloneAndZero() const final; + + // The interpolable components of a shadow. These should all be non-null. + std::unique_ptr<InterpolableLength> x_; + std::unique_ptr<InterpolableLength> y_; + std::unique_ptr<InterpolableLength> blur_; + std::unique_ptr<InterpolableLength> spread_; + std::unique_ptr<InterpolableValue> color_; + + ShadowStyle shadow_style_; +}; + +template <> +struct DowncastTraits<InterpolableShadow> { + static bool AllowFrom(const InterpolableValue& interpolable_value) { + return interpolable_value.IsShadow(); + } +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLABLE_SHADOW_H_
diff --git a/third_party/blink/renderer/core/animation/interpolable_value.cc b/third_party/blink/renderer/core/animation/interpolable_value.cc index 1f3c0ebc..504f7aa 100644 --- a/third_party/blink/renderer/core/animation/interpolable_value.cc +++ b/third_party/blink/renderer/core/animation/interpolable_value.cc
@@ -63,11 +63,11 @@ } } -std::unique_ptr<InterpolableValue> InterpolableList::CloneAndZero() const { - auto result = std::make_unique<InterpolableList>(length()); +InterpolableList* InterpolableList::RawCloneAndZero() const { + auto* result = new InterpolableList(length()); for (wtf_size_t i = 0; i < length(); i++) result->Set(i, values_[i]->CloneAndZero()); - return std::move(result); + return result; } void InterpolableNumber::Scale(double scale) {
diff --git a/third_party/blink/renderer/core/animation/interpolable_value.h b/third_party/blink/renderer/core/animation/interpolable_value.h index 8531e99..65915fa 100644 --- a/third_party/blink/renderer/core/animation/interpolable_value.h +++ b/third_party/blink/renderer/core/animation/interpolable_value.h
@@ -23,59 +23,74 @@ public: virtual ~InterpolableValue() = default; + // Interpolates from |this| InterpolableValue towards |to| at the given + // |progress|, placing the output in |result|. That is: + // + // result = this * (1 - progress) + to * progress + // + // Callers must make sure that |this|, |to|, and |result| are all of the same + // concrete subclass. + virtual void Interpolate(const InterpolableValue& to, + const double progress, + InterpolableValue& result) const = 0; + virtual bool IsNumber() const { return false; } virtual bool IsBool() const { return false; } virtual bool IsList() const { return false; } virtual bool IsLength() const { return false; } + virtual bool IsShadow() const { return false; } // TODO(alancutter): Remove Equals(). virtual bool Equals(const InterpolableValue&) const = 0; - virtual std::unique_ptr<InterpolableValue> Clone() const = 0; - virtual std::unique_ptr<InterpolableValue> CloneAndZero() const = 0; virtual void Scale(double scale) = 0; virtual void ScaleAndAdd(double scale, const InterpolableValue& other) = 0; virtual void AssertCanInterpolateWith( const InterpolableValue& other) const = 0; + // Clone this value, optionally zeroing out the components at the same time. + // These are not virtual to allow for covariant return types; see + // documentation on RawClone/RawCloneAndZero. + std::unique_ptr<InterpolableValue> Clone() const { + return std::unique_ptr<InterpolableValue>(RawClone()); + } + std::unique_ptr<InterpolableValue> CloneAndZero() const { + return std::unique_ptr<InterpolableValue>(RawCloneAndZero()); + } + private: - virtual void Interpolate(const InterpolableValue& to, - const double progress, - InterpolableValue& result) const = 0; - - friend class LegacyStyleInterpolation; - friend class TransitionInterpolation; - friend class PairwisePrimitiveInterpolation; - - // Keep interpolate private, but allow calls within the hierarchy without - // knowledge of type. - friend class InterpolableNumber; - friend class InterpolableList; - - friend class AnimationInterpolableValueTest; + // Helper methods to allow covariant Clone/CloneAndZero methods. Concrete + // subclasses should not expose these methods publically, but instead should + // declare their own version of Clone/CloneAndZero with a concrete return type + // if it is useful for their clients. + virtual InterpolableValue* RawClone() const = 0; + virtual InterpolableValue* RawCloneAndZero() const = 0; }; class CORE_EXPORT InterpolableNumber final : public InterpolableValue { public: explicit InterpolableNumber(double value) : value_(value) {} - bool IsNumber() const final { return true; } double Value() const { return value_; } - bool Equals(const InterpolableValue& other) const final; - std::unique_ptr<InterpolableValue> Clone() const final { - return std::make_unique<InterpolableNumber>(value_); - } - std::unique_ptr<InterpolableValue> CloneAndZero() const final { - return std::make_unique<InterpolableNumber>(0); - } - void Scale(double scale) final; - void ScaleAndAdd(double scale, const InterpolableValue& other) final; void Set(double value) { value_ = value; } - void AssertCanInterpolateWith(const InterpolableValue& other) const final; - private: + // InterpolableValue void Interpolate(const InterpolableValue& to, const double progress, InterpolableValue& result) const final; + bool IsNumber() const final { return true; } + bool Equals(const InterpolableValue& other) const final; + void Scale(double scale) final; + void ScaleAndAdd(double scale, const InterpolableValue& other) final; + void AssertCanInterpolateWith(const InterpolableValue& other) const final; + + private: + InterpolableNumber* RawClone() const final { + return new InterpolableNumber(value_); + } + InterpolableNumber* RawCloneAndZero() const final { + return new InterpolableNumber(0); + } + double value_; }; @@ -96,10 +111,6 @@ Set(i, other.values_[i]->Clone()); } - bool IsList() const final { return true; } - void Set(wtf_size_t position, std::unique_ptr<InterpolableValue> value) { - values_[position] = std::move(value); - } const InterpolableValue* Get(wtf_size_t position) const { return values_[position].get(); } @@ -107,19 +118,25 @@ return values_[position]; } wtf_size_t length() const { return values_.size(); } - bool Equals(const InterpolableValue& other) const final; - std::unique_ptr<InterpolableValue> Clone() const final { - return std::make_unique<InterpolableList>(*this); + void Set(wtf_size_t position, std::unique_ptr<InterpolableValue> value) { + values_[position] = std::move(value); } - std::unique_ptr<InterpolableValue> CloneAndZero() const final; + + // InterpolableValue + void Interpolate(const InterpolableValue& to, + const double progress, + InterpolableValue& result) const final; + bool IsList() const final { return true; } + bool Equals(const InterpolableValue& other) const final; void Scale(double scale) final; void ScaleAndAdd(double scale, const InterpolableValue& other) final; void AssertCanInterpolateWith(const InterpolableValue& other) const final; private: - void Interpolate(const InterpolableValue& to, - const double progress, - InterpolableValue& result) const final; + InterpolableList* RawClone() const final { + return new InterpolableList(*this); + } + InterpolableList* RawCloneAndZero() const final; Vector<std::unique_ptr<InterpolableValue>> values_; };
diff --git a/third_party/blink/renderer/core/animation/interpolation_value.h b/third_party/blink/renderer/core/animation/interpolation_value.h index 75c5d35..17ccf02 100644 --- a/third_party/blink/renderer/core/animation/interpolation_value.h +++ b/third_party/blink/renderer/core/animation/interpolation_value.h
@@ -27,11 +27,11 @@ InterpolationValue(std::nullptr_t) {} - InterpolationValue(InterpolationValue&& other) noexcept + InterpolationValue(InterpolationValue&& other) : interpolable_value(std::move(other.interpolable_value)), non_interpolable_value(std::move(other.non_interpolable_value)) {} - void operator=(InterpolationValue&& other) noexcept { + void operator=(InterpolationValue&& other) { interpolable_value = std::move(other.interpolable_value); non_interpolable_value = std::move(other.non_interpolable_value); }
diff --git a/third_party/blink/renderer/core/animation/list_interpolation_functions.cc b/third_party/blink/renderer/core/animation/list_interpolation_functions.cc index c23539d..146f840 100644 --- a/third_party/blink/renderer/core/animation/list_interpolation_functions.cc +++ b/third_party/blink/renderer/core/animation/list_interpolation_functions.cc
@@ -281,6 +281,27 @@ NonInterpolableList::Create(std::move(new_non_interpolable_values)); } +static bool InterpolableListsAreCompatible( + const InterpolableList& a, + const InterpolableList& b, + wtf_size_t length, + ListInterpolationFunctions::LengthMatchingStrategy length_matching_strategy, + ListInterpolationFunctions::InterpolableValuesAreCompatibleCallback + interpolable_values_are_compatible) { + for (wtf_size_t i = 0; i < length; i++) { + if (length_matching_strategy == + ListInterpolationFunctions::LengthMatchingStrategy:: + kLowestCommonMultiple || + (i < a.length() && i < b.length())) { + if (!interpolable_values_are_compatible.Run(a.Get(i % a.length()), + b.Get(i % b.length()))) { + return false; + } + } + } + return true; +} + static bool NonInterpolableListsAreCompatible( const NonInterpolableList& a, const NonInterpolableList& b, @@ -315,6 +336,7 @@ const InterpolationType& type, const InterpolationValue& value, LengthMatchingStrategy length_matching_strategy, + InterpolableValuesAreCompatibleCallback interpolable_values_are_compatible, NonInterpolableValuesAreCompatibleCallback non_interpolable_values_are_compatible, CompositeItemCallback composite_item) { @@ -346,10 +368,20 @@ return; } - const NonInterpolableList& non_interpolable_list = - ToNonInterpolableList(*value.non_interpolable_value); const wtf_size_t final_length = MatchLengths(underlying_length, value_length, length_matching_strategy); + + if (!InterpolableListsAreCompatible( + ToInterpolableList( + *underlying_value_owner.Value().interpolable_value), + interpolable_list, final_length, length_matching_strategy, + interpolable_values_are_compatible)) { + underlying_value_owner.Set(type, value); + return; + } + + const NonInterpolableList& non_interpolable_list = + ToNonInterpolableList(*value.non_interpolable_value); if (!NonInterpolableListsAreCompatible( ToNonInterpolableList( *underlying_value_owner.Value().non_interpolable_value),
diff --git a/third_party/blink/renderer/core/animation/list_interpolation_functions.h b/third_party/blink/renderer/core/animation/list_interpolation_functions.h index a254bc4..1cd58ff 100644 --- a/third_party/blink/renderer/core/animation/list_interpolation_functions.h +++ b/third_party/blink/renderer/core/animation/list_interpolation_functions.h
@@ -49,6 +49,9 @@ const InterpolationValue&, EqualNonInterpolableValuesCallback); + using InterpolableValuesAreCompatibleCallback = + base::RepeatingCallback<bool(const InterpolableValue*, + const InterpolableValue*)>; using NonInterpolableValuesAreCompatibleCallback = base::RepeatingCallback<bool(const NonInterpolableValue*, const NonInterpolableValue*)>; @@ -62,9 +65,16 @@ const InterpolationType&, const InterpolationValue&, LengthMatchingStrategy, + InterpolableValuesAreCompatibleCallback, NonInterpolableValuesAreCompatibleCallback, CompositeItemCallback); + // Used when the interpolable values are known to always be compatible. + static bool InterpolableValuesKnownCompatible(const InterpolableValue* a, + const InterpolableValue* b) { + return true; + } + // We are moving towards elimination of |NonInterpolableValue|, and expect // more clients to assert no more usage with this function. static bool VerifyNoNonInterpolableValues(const NonInterpolableValue* a,
diff --git a/third_party/blink/renderer/core/animation/list_interpolation_functions_test.cc b/third_party/blink/renderer/core/animation/list_interpolation_functions_test.cc index 01929f8..23ac9fa3 100644 --- a/third_party/blink/renderer/core/animation/list_interpolation_functions_test.cc +++ b/third_party/blink/renderer/core/animation/list_interpolation_functions_test.cc
@@ -105,6 +105,27 @@ }); } +// A simple helper to specify which InterpolableValues in an InterpolableList +// should be considered compatible. +class InterpolableValuesCompatibilityHelper { + public: + // The input |answers| vector must be at least as large as the + // InterpolableList being tested, or |AreCompatible| will DCHECK. + InterpolableValuesCompatibilityHelper(Vector<bool> answers) + : answers_(answers), current_index_(0) {} + + // Callers should pass a reference to this function to + // ListInterpolationFunctions::Composite. + bool AreCompatible(const InterpolableValue*, const InterpolableValue*) { + DCHECK(current_index_ < answers_.size()); + return answers_.at(current_index_++); + } + + private: + Vector<bool> answers_; + wtf_size_t current_index_; +}; + bool NonInterpolableValuesAreCompatible(const NonInterpolableValue* a, const NonInterpolableValue* b) { return (a ? ToTestNonInterpolableValue(*a).GetValue() : 0) == @@ -193,6 +214,8 @@ ListInterpolationFunctions::Composite( owner, 1.0, interpolation_type, list2, ListInterpolationFunctions::LengthMatchingStrategy::kEqual, + WTF::BindRepeating( + ListInterpolationFunctions::InterpolableValuesKnownCompatible), WTF::BindRepeating(NonInterpolableValuesAreCompatible), WTF::BindRepeating(Composite)); @@ -218,6 +241,8 @@ ListInterpolationFunctions::Composite( owner, 1.0, interpolation_type, list2, ListInterpolationFunctions::LengthMatchingStrategy::kEqual, + WTF::BindRepeating( + ListInterpolationFunctions::InterpolableValuesKnownCompatible), WTF::BindRepeating(NonInterpolableValuesAreCompatible), WTF::BindRepeating(Composite)); @@ -230,7 +255,39 @@ // If one (or more) of the element pairs are incompatible, the list as a whole // is non-interpolable. We expect the underlying value to be replaced. -TEST(ListInterpolationFunctionsTest, EqualCompositeIncompatibleValues) { +TEST(ListInterpolationFunctionsTest, + EqualCompositeIncompatibleInterpolableValues) { + auto list1 = CreateInterpolableList({1.0, 2.0, 3.0}); + auto list2 = CreateInterpolableList({4.0, 5.0, 6.0}); + + InterpolableValuesCompatibilityHelper compatibility_helper( + {true, false, true}); + + PropertyHandle property_handle(GetCSSPropertyZIndex()); + CSSNumberInterpolationType interpolation_type(property_handle); + UnderlyingValueOwner owner; + owner.Set(interpolation_type, std::move(list1)); + + ListInterpolationFunctions::Composite( + owner, 1.0, interpolation_type, list2, + ListInterpolationFunctions::LengthMatchingStrategy::kEqual, + WTF::BindRepeating(&InterpolableValuesCompatibilityHelper::AreCompatible, + WTF::Unretained(&compatibility_helper)), + WTF::BindRepeating(NonInterpolableValuesAreCompatible), + WTF::BindRepeating(Composite)); + + const auto& result = ToInterpolableList(*owner.Value().interpolable_value); + + ASSERT_EQ(result.length(), 3u); + EXPECT_EQ(ToInterpolableNumber(result.Get(0))->Value(), 4.0); + EXPECT_EQ(ToInterpolableNumber(result.Get(1))->Value(), 5.0); + EXPECT_EQ(ToInterpolableNumber(result.Get(2))->Value(), 6.0); +} + +// If one (or more) of the element pairs are incompatible, the list as a whole +// is non-interpolable. We expect the underlying value to be replaced. +TEST(ListInterpolationFunctionsTest, + EqualCompositeIncompatibleNonInterpolableValues) { auto list1 = CreateInterpolableList({{1.0, 1}, {2.0, 2}, {3.0, 3}}); auto list2 = CreateInterpolableList({{4.0, 1}, {5.0, 4}, {6.0, 3}}); @@ -242,6 +299,8 @@ ListInterpolationFunctions::Composite( owner, 1.0, interpolation_type, list2, ListInterpolationFunctions::LengthMatchingStrategy::kEqual, + WTF::BindRepeating( + ListInterpolationFunctions::InterpolableValuesKnownCompatible), WTF::BindRepeating(NonInterpolableValuesAreCompatible), WTF::BindRepeating(Composite));
diff --git a/third_party/blink/renderer/core/animation/pairwise_interpolation_value.h b/third_party/blink/renderer/core/animation/pairwise_interpolation_value.h index 39e6c57..87bb431 100644 --- a/third_party/blink/renderer/core/animation/pairwise_interpolation_value.h +++ b/third_party/blink/renderer/core/animation/pairwise_interpolation_value.h
@@ -28,7 +28,7 @@ PairwiseInterpolationValue(std::nullptr_t) {} - PairwiseInterpolationValue(PairwiseInterpolationValue&& other) noexcept + PairwiseInterpolationValue(PairwiseInterpolationValue&& other) : start_interpolable_value(std::move(other.start_interpolable_value)), end_interpolable_value(std::move(other.end_interpolable_value)), non_interpolable_value(std::move(other.non_interpolable_value)) {}
diff --git a/third_party/blink/renderer/core/animation/shadow_interpolation_functions.cc b/third_party/blink/renderer/core/animation/shadow_interpolation_functions.cc deleted file mode 100644 index 5274b9f..0000000 --- a/third_party/blink/renderer/core/animation/shadow_interpolation_functions.cc +++ /dev/null
@@ -1,195 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/core/animation/shadow_interpolation_functions.h" - -#include <memory> -#include "third_party/blink/renderer/core/animation/css_color_interpolation_type.h" -#include "third_party/blink/renderer/core/animation/interpolable_length.h" -#include "third_party/blink/renderer/core/animation/interpolation_value.h" -#include "third_party/blink/renderer/core/animation/non_interpolable_value.h" -#include "third_party/blink/renderer/core/animation/underlying_value.h" -#include "third_party/blink/renderer/core/css/css_identifier_value.h" -#include "third_party/blink/renderer/core/css/css_shadow_value.h" -#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" -#include "third_party/blink/renderer/core/style/shadow_data.h" -#include "third_party/blink/renderer/platform/geometry/float_point.h" - -namespace blink { - -enum ShadowComponentIndex : unsigned { - kShadowX, - kShadowY, - kShadowBlur, - kShadowSpread, - kShadowColor, - kShadowComponentIndexCount, -}; - -class ShadowNonInterpolableValue : public NonInterpolableValue { - public: - ~ShadowNonInterpolableValue() final = default; - - static scoped_refptr<ShadowNonInterpolableValue> Create( - ShadowStyle shadow_style) { - return base::AdoptRef(new ShadowNonInterpolableValue(shadow_style)); - } - - ShadowStyle Style() const { return style_; } - - DECLARE_NON_INTERPOLABLE_VALUE_TYPE(); - - private: - ShadowNonInterpolableValue(ShadowStyle shadow_style) : style_(shadow_style) {} - - ShadowStyle style_; -}; - -DEFINE_NON_INTERPOLABLE_VALUE_TYPE(ShadowNonInterpolableValue); -DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(ShadowNonInterpolableValue); - -bool ShadowInterpolationFunctions::NonInterpolableValuesAreCompatible( - const NonInterpolableValue* a, - const NonInterpolableValue* b) { - return ToShadowNonInterpolableValue(*a).Style() == - ToShadowNonInterpolableValue(*b).Style(); -} - -PairwiseInterpolationValue ShadowInterpolationFunctions::MaybeMergeSingles( - InterpolationValue&& start, - InterpolationValue&& end) { - if (!NonInterpolableValuesAreCompatible(start.non_interpolable_value.get(), - end.non_interpolable_value.get())) - return nullptr; - return PairwiseInterpolationValue(std::move(start.interpolable_value), - std::move(end.interpolable_value), - std::move(start.non_interpolable_value)); -} - -InterpolationValue ShadowInterpolationFunctions::ConvertShadowData( - const ShadowData& shadow_data, - double zoom) { - auto interpolable_list = - std::make_unique<InterpolableList>(kShadowComponentIndexCount); - interpolable_list->Set( - kShadowX, InterpolableLength::CreatePixels(shadow_data.X() / zoom)); - interpolable_list->Set( - kShadowY, InterpolableLength::CreatePixels(shadow_data.Y() / zoom)); - interpolable_list->Set( - kShadowBlur, InterpolableLength::CreatePixels(shadow_data.Blur() / zoom)); - interpolable_list->Set(kShadowSpread, InterpolableLength::CreatePixels( - shadow_data.Spread() / zoom)); - interpolable_list->Set(kShadowColor, - CSSColorInterpolationType::CreateInterpolableColor( - shadow_data.GetColor())); - return InterpolationValue( - std::move(interpolable_list), - ShadowNonInterpolableValue::Create(shadow_data.Style())); -} - -InterpolationValue ShadowInterpolationFunctions::MaybeConvertCSSValue( - const CSSValue& value) { - const auto* shadow = DynamicTo<CSSShadowValue>(value); - if (!shadow) - return nullptr; - - ShadowStyle style = kNormal; - if (shadow->style) { - if (shadow->style->GetValueID() == CSSValueID::kInset) - style = kInset; - else - return nullptr; - } - - auto interpolable_list = - std::make_unique<InterpolableList>(kShadowComponentIndexCount); - static_assert(kShadowX == 0, "Enum ordering check."); - static_assert(kShadowY == 1, "Enum ordering check."); - static_assert(kShadowBlur == 2, "Enum ordering check."); - static_assert(kShadowSpread == 3, "Enum ordering check."); - const CSSPrimitiveValue* lengths[] = { - shadow->x.Get(), - shadow->y.Get(), - shadow->blur.Get(), - shadow->spread.Get(), - }; - for (wtf_size_t i = 0; i < base::size(lengths); i++) { - if (lengths[i]) { - InterpolationValue length_field( - InterpolableLength::MaybeConvertCSSValue(*lengths[i])); - if (!length_field) - return nullptr; - DCHECK(!length_field.non_interpolable_value); - interpolable_list->Set(i, std::move(length_field.interpolable_value)); - } else { - interpolable_list->Set(i, InterpolableLength::CreatePixels(0)); - } - } - - if (shadow->color) { - std::unique_ptr<InterpolableValue> interpolable_color = - CSSColorInterpolationType::MaybeCreateInterpolableColor(*shadow->color); - if (!interpolable_color) - return nullptr; - interpolable_list->Set(kShadowColor, std::move(interpolable_color)); - } else { - interpolable_list->Set(kShadowColor, - CSSColorInterpolationType::CreateInterpolableColor( - StyleColor::CurrentColor())); - } - - return InterpolationValue(std::move(interpolable_list), - ShadowNonInterpolableValue::Create(style)); -} - -std::unique_ptr<InterpolableValue> -ShadowInterpolationFunctions::CreateNeutralInterpolableValue() { - return ConvertShadowData(ShadowData::NeutralValue(), 1).interpolable_value; -} - -void ShadowInterpolationFunctions::Composite( - UnderlyingValue& underlying_value, - double underlying_fraction, - const InterpolableValue& interpolable_value, - const NonInterpolableValue* non_interpolable_value) { - DCHECK(NonInterpolableValuesAreCompatible( - underlying_value.GetNonInterpolableValue(), non_interpolable_value)); - InterpolableList& underlying_interpolable_list = - ToInterpolableList(underlying_value.MutableInterpolableValue()); - const InterpolableList& interpolable_list = - ToInterpolableList(interpolable_value); - underlying_interpolable_list.ScaleAndAdd(underlying_fraction, - interpolable_list); -} - -ShadowData ShadowInterpolationFunctions::CreateShadowData( - const InterpolableValue& interpolable_value, - const NonInterpolableValue* non_interpolable_value, - const StyleResolverState& state) { - const InterpolableList& interpolable_list = - ToInterpolableList(interpolable_value); - const ShadowNonInterpolableValue& shadow_non_interpolable_value = - ToShadowNonInterpolableValue(*non_interpolable_value); - const CSSToLengthConversionData& conversion_data = - state.CssToLengthConversionData(); - Length shadow_x = To<InterpolableLength>(*interpolable_list.Get(kShadowX)) - .CreateLength(conversion_data, kValueRangeAll); - Length shadow_y = To<InterpolableLength>(*interpolable_list.Get(kShadowY)) - .CreateLength(conversion_data, kValueRangeAll); - Length shadow_blur = - To<InterpolableLength>(*interpolable_list.Get(kShadowBlur)) - .CreateLength(conversion_data, kValueRangeNonNegative); - Length shadow_spread = - To<InterpolableLength>(*interpolable_list.Get(kShadowSpread)) - .CreateLength(conversion_data, kValueRangeAll); - DCHECK(shadow_x.IsFixed() && shadow_y.IsFixed() && shadow_blur.IsFixed() && - shadow_spread.IsFixed()); - return ShadowData(FloatPoint(shadow_x.Value(), shadow_y.Value()), - shadow_blur.Value(), shadow_spread.Value(), - shadow_non_interpolable_value.Style(), - CSSColorInterpolationType::ResolveInterpolableColor( - *interpolable_list.Get(kShadowColor), state)); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/animation/shadow_interpolation_functions.h b/third_party/blink/renderer/core/animation/shadow_interpolation_functions.h deleted file mode 100644 index 7745390..0000000 --- a/third_party/blink/renderer/core/animation/shadow_interpolation_functions.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SHADOW_INTERPOLATION_FUNCTIONS_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SHADOW_INTERPOLATION_FUNCTIONS_H_ - -#include <memory> -#include "third_party/blink/renderer/core/animation/interpolation_value.h" -#include "third_party/blink/renderer/core/animation/pairwise_interpolation_value.h" - -namespace blink { - -class ShadowData; -class CSSValue; -class StyleResolverState; -class UnderlyingValue; - -class ShadowInterpolationFunctions { - public: - static InterpolationValue ConvertShadowData(const ShadowData&, double zoom); - static InterpolationValue MaybeConvertCSSValue(const CSSValue&); - static std::unique_ptr<InterpolableValue> CreateNeutralInterpolableValue(); - static bool NonInterpolableValuesAreCompatible(const NonInterpolableValue*, - const NonInterpolableValue*); - static PairwiseInterpolationValue MaybeMergeSingles( - InterpolationValue&& start, - InterpolationValue&& end); - static void Composite(UnderlyingValue&, - double underlying_fraction, - const InterpolableValue&, - const NonInterpolableValue*); - static ShadowData CreateShadowData(const InterpolableValue&, - const NonInterpolableValue*, - const StyleResolverState&); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_SHADOW_INTERPOLATION_FUNCTIONS_H_
diff --git a/third_party/blink/renderer/core/css/BUILD.gn b/third_party/blink/renderer/core/css/BUILD.gn index 1cf96b76b..afd5ae1 100644 --- a/third_party/blink/renderer/core/css/BUILD.gn +++ b/third_party/blink/renderer/core/css/BUILD.gn
@@ -616,6 +616,7 @@ "cssom/css_unit_value_test.cc", "cssom/css_unparsed_value_test.cc", "cssom/css_unsupported_color_value_test.cc", + "cssom/inline_style_property_map_test.cc", "cssom/paint_worklet_style_property_map_test.cc", "cssom/prepopulated_computed_style_property_map_test.cc", "drag_update_test.cc",
diff --git a/third_party/blink/renderer/core/css/css_selector_list.h b/third_party/blink/renderer/core/css/css_selector_list.h index 4d38b09..51f354b 100644 --- a/third_party/blink/renderer/core/css/css_selector_list.h +++ b/third_party/blink/renderer/core/css/css_selector_list.h
@@ -67,8 +67,7 @@ public: CSSSelectorList() : selector_array_(nullptr) {} - CSSSelectorList(CSSSelectorList&& o) noexcept - : selector_array_(o.selector_array_) { + CSSSelectorList(CSSSelectorList&& o) : selector_array_(o.selector_array_) { o.selector_array_ = nullptr; } @@ -82,7 +81,7 @@ bool HasPseudoWhere() const; bool RequiresExpansion() const; - CSSSelectorList& operator=(CSSSelectorList&& o) noexcept { + CSSSelectorList& operator=(CSSSelectorList&& o) { DCHECK(this != &o); DeleteSelectorsIfNeeded(); selector_array_ = o.selector_array_;
diff --git a/third_party/blink/renderer/core/css/cssom/css_position_value.cc b/third_party/blink/renderer/core/css/cssom/css_position_value.cc index cff142e..552b408 100644 --- a/third_party/blink/renderer/core/css/cssom/css_position_value.cc +++ b/third_party/blink/renderer/core/css/cssom/css_position_value.cc
@@ -95,10 +95,11 @@ } CSSPositionValue* CSSPositionValue::FromCSSValue(const CSSValue& value) { - const auto& pair = To<CSSValuePair>(value); - - CSSNumericValue* x = FromSingleValue(pair.First()); - CSSNumericValue* y = FromSingleValue(pair.Second()); + const auto* pair = DynamicTo<CSSValuePair>(&value); + if (!pair) + return nullptr; + CSSNumericValue* x = FromSingleValue(pair->First()); + CSSNumericValue* y = FromSingleValue(pair->Second()); DCHECK(x); DCHECK(y);
diff --git a/third_party/blink/renderer/core/css/cssom/inline_style_property_map_test.cc b/third_party/blink/renderer/core/css/cssom/inline_style_property_map_test.cc new file mode 100644 index 0000000..87412c2 --- /dev/null +++ b/third_party/blink/renderer/core/css/cssom/inline_style_property_map_test.cc
@@ -0,0 +1,39 @@ +// 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 "third_party/blink/renderer/core/css/cssom/inline_style_property_map.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/css/properties/css_property.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/core/style_property_shorthand.h" + +namespace blink { + +TEST(InlineStylePropertyMapTest, PendingSubstitutionValueCrash) { + // Test that trying to reify any longhands with a CSSPendingSubstitutionValue + // does not cause a crash. + + Document* document = MakeGarbageCollected<Document>(); + Element* div = document->CreateRawElement(html_names::kDivTag); + InlineStylePropertyMap map(div); + + // For each shorthand, create a declaration with a var() reference and try + // reifying all longhands. + for (CSSPropertyID property_id : CSSPropertyIDList()) { + const CSSProperty& shorthand = CSSProperty::Get(property_id); + if (!shorthand.IsShorthand()) + continue; + div->SetInlineStyleProperty(property_id, "var(--dummy)"); + const StylePropertyShorthand& longhands = shorthandForProperty(property_id); + for (unsigned i = 0; i < longhands.length(); i++) { + map.get(document, + longhands.properties()[i]->GetCSSPropertyName().ToAtomicString(), + ASSERT_NO_EXCEPTION); + } + } +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/style_value_factory.cc b/third_party/blink/renderer/core/css/cssom/style_value_factory.cc index 56a30af..f9c4384 100644 --- a/third_party/blink/renderer/core/css/cssom/style_value_factory.cc +++ b/third_party/blink/renderer/core/css/cssom/style_value_factory.cc
@@ -131,10 +131,11 @@ return CreateStyleValue(value); } case CSSPropertyID::kGridAutoFlow: { - const auto& value_list = To<CSSValueList>(value); - // Only single keywords are supported in level 1. - if (value_list.length() == 1U) - return CreateStyleValue(value_list.Item(0)); + if (const auto* value_list = DynamicTo<CSSValueList>(value)) { + // Only single keywords are supported in level 1. + if (value_list->length() == 1U) + return CreateStyleValue(value_list->Item(0)); + } return nullptr; } case CSSPropertyID::kTransform: @@ -150,10 +151,11 @@ case CSSPropertyID::kTransformOrigin: return CSSPositionValue::FromCSSValue(value); case CSSPropertyID::kOffsetRotate: { - const auto& value_list = To<CSSValueList>(value); - // Only single keywords are supported in level 1. - if (value_list.length() == 1U) - return CreateStyleValue(value_list.Item(0)); + if (const auto* value_list = DynamicTo<CSSValueList>(&value)) { + // Only single keywords are supported in level 1. + if (value_list->length() == 1U) + return CreateStyleValue(value_list->Item(0)); + } return nullptr; } case CSSPropertyID::kAlignItems: { @@ -171,10 +173,11 @@ if (value.IsIdentifierValue()) return CreateStyleValue(value); - const auto& value_list = To<CSSValueList>(value); - // Only single keywords are supported in level 1. - if (value_list.length() == 1U) - return CreateStyleValue(value_list.Item(0)); + if (const auto* value_list = DynamicTo<CSSValueList>(&value)) { + // Only single keywords are supported in level 1. + if (value_list->length() == 1U) + return CreateStyleValue(value_list->Item(0)); + } return nullptr; } case CSSPropertyID::kTextIndent: { @@ -189,10 +192,11 @@ } case CSSPropertyID::kTransitionProperty: case CSSPropertyID::kTouchAction: { - const auto& value_list = To<CSSValueList>(value); - // Only single values are supported in level 1. - if (value_list.length() == 1U) - return CreateStyleValue(value_list.Item(0)); + if (const auto* value_list = DynamicTo<CSSValueList>(value)) { + // Only single values are supported in level 1. + if (value_list->length() == 1U) + return CreateStyleValue(value_list->Item(0)); + } return nullptr; } case CSSPropertyID::kWillChange: {
diff --git a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc index 20ea659..ca3b3f1 100644 --- a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc +++ b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
@@ -1136,6 +1136,7 @@ ordered_named_auto_repeat_grid_lines_( is_row_axis ? style.AutoRepeatOrderedNamedGridColumnLines() : style.AutoRepeatOrderedNamedGridRowLines()) {} + virtual ~OrderedNamedLinesCollector() = default; bool IsEmpty() const { return ordered_named_grid_lines_.IsEmpty() &&
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.cc b/third_party/blink/renderer/core/display_lock/display_lock_context.cc index 3d2b4c0..c64cb15 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
@@ -1030,7 +1030,7 @@ : context_(context) {} DisplayLockContext::ScopedForcedUpdate::ScopedForcedUpdate( - ScopedForcedUpdate&& other) noexcept + ScopedForcedUpdate&& other) : context_(other.context_) { other.context_ = nullptr; }
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.h b/third_party/blink/renderer/core/display_lock/display_lock_context.h index 0a330de..aea4ef0 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context.h +++ b/third_party/blink/renderer/core/display_lock/display_lock_context.h
@@ -76,7 +76,7 @@ DISALLOW_NEW(); public: - ScopedForcedUpdate(ScopedForcedUpdate&&) noexcept; + ScopedForcedUpdate(ScopedForcedUpdate&&); ~ScopedForcedUpdate(); private:
diff --git a/third_party/blink/renderer/core/editing/layout_selection.cc b/third_party/blink/renderer/core/editing/layout_selection.cc index 00040d2..73cfe0f 100644 --- a/third_party/blink/renderer/core/editing/layout_selection.cc +++ b/third_party/blink/renderer/core/editing/layout_selection.cc
@@ -178,7 +178,7 @@ public: OldSelectedNodes() : paint_range(MakeGarbageCollected<SelectionPaintRange>()) {} - OldSelectedNodes(OldSelectedNodes&& other) noexcept { + OldSelectedNodes(OldSelectedNodes&& other) { paint_range = other.paint_range; selected_map = std::move(other.selected_map); } @@ -205,8 +205,7 @@ HeapHashSet<Member<const Node>>&& passed_selected_objects) : paint_range(passed_paint_range), selected_objects(std::move(passed_selected_objects)) {} - NewPaintRangeAndSelectedNodes( - NewPaintRangeAndSelectedNodes&& other) noexcept { + NewPaintRangeAndSelectedNodes(NewPaintRangeAndSelectedNodes&& other) { paint_range = other.paint_range; selected_objects = std::move(other.selected_objects); }
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc index 26522457..e6721f5 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.cc +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.cc
@@ -663,11 +663,6 @@ blob_url_token.PassPipe()); } -void LocalFrameClientImpl::LoadErrorPage(int reason) { - if (web_frame_->Client()) - web_frame_->Client()->LoadErrorPage(reason); -} - bool LocalFrameClientImpl::NavigateBackForward(int offset) const { WebViewImpl* webview = web_frame_->ViewImpl(); DCHECK(webview->Client());
diff --git a/third_party/blink/renderer/core/exported/local_frame_client_impl.h b/third_party/blink/renderer/core/exported/local_frame_client_impl.h index a7e1a80..600bd620 100644 --- a/third_party/blink/renderer/core/exported/local_frame_client_impl.h +++ b/third_party/blink/renderer/core/exported/local_frame_client_impl.h
@@ -142,7 +142,6 @@ void ForwardResourceTimingToParent(const WebResourceTimingInfo&) override; void DownloadURL(const ResourceRequest&, DownloadCrossOriginRedirects) override; - void LoadErrorPage(int reason) override; bool NavigateBackForward(int offset) const override; void DidAccessInitialDocument() override; void DidDisplayInsecureContent() override;
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index 834be89..a6645451 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -1584,6 +1584,18 @@ .RecordEndOfFrameMetrics(frame_begin_time, base::TimeTicks::Now()); } +std::unique_ptr<cc::BeginMainFrameMetrics> +WebViewImpl::GetBeginMainFrameMetrics() { + if (!MainFrameImpl()) + return nullptr; + + return MainFrameImpl() + ->GetFrame() + ->View() + ->EnsureUkmAggregator() + .GetBeginMainFrameMetrics(); +} + void WebViewImpl::UpdateLifecycle(WebWidget::LifecycleUpdate requested_update, WebWidget::LifecycleUpdateReason reason) { TRACE_EVENT0("blink", "WebViewImpl::updateAllLifecyclePhases");
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h index 5be09c8..7c28228 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.h +++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -69,6 +69,7 @@ namespace cc { class Layer; +struct BeginMainFrameMetrics; class ScopedDeferMainFrameUpdate; } @@ -455,6 +456,7 @@ void EndCommitCompositorFrame(); void RecordStartOfFrameMetrics(); void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time); + std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics(); void UpdateLifecycle(WebWidget::LifecycleUpdate requested_update, WebWidget::LifecycleUpdateReason reason); void ThemeChanged();
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h index 075f067..cce38835 100644 --- a/third_party/blink/renderer/core/frame/local_frame_client.h +++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -192,7 +192,6 @@ virtual void DownloadURL(const ResourceRequest&, DownloadCrossOriginRedirects) = 0; - virtual void LoadErrorPage(int reason) = 0; virtual bool NavigateBackForward(int offset) const = 0;
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc index f0ac3c4..b90e9d64 100644 --- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc +++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc
@@ -7,6 +7,7 @@ #include "base/format_macros.h" #include "base/rand_util.h" #include "base/time/default_tick_clock.h" +#include "cc/metrics/begin_main_frame_metrics.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_recorder.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -24,7 +25,7 @@ start_time_(clock_->NowTicks()) {} LocalFrameUkmAggregator::ScopedUkmHierarchicalTimer::ScopedUkmHierarchicalTimer( - ScopedUkmHierarchicalTimer&& other) noexcept + ScopedUkmHierarchicalTimer&& other) : aggregator_(other.aggregator_), metric_index_(other.metric_index_), clock_(other.clock_), @@ -124,6 +125,48 @@ in_main_frame_update_ = true; } +std::unique_ptr<cc::BeginMainFrameMetrics> +LocalFrameUkmAggregator::GetBeginMainFrameMetrics() { + DCHECK(InMainFrame()); + + // Use the main_frame_percentage_records_ because they are the ones that + // only count time between the Begin and End of a main frame update. + std::unique_ptr<cc::BeginMainFrameMetrics> metrics_data = + std::make_unique<cc::BeginMainFrameMetrics>(); + metrics_data->handle_input_events = + main_frame_percentage_records_[static_cast<unsigned>( + MetricId::kHandleInputEvents)] + .interval_duration; + metrics_data->animate = + main_frame_percentage_records_[static_cast<unsigned>(MetricId::kAnimate)] + .interval_duration; + metrics_data->style_update = + main_frame_percentage_records_[static_cast<unsigned>(MetricId::kStyle)] + .interval_duration; + metrics_data->layout_update = + main_frame_percentage_records_[static_cast<unsigned>(MetricId::kLayout)] + .interval_duration; + metrics_data->prepaint = + main_frame_percentage_records_[static_cast<unsigned>(MetricId::kPrePaint)] + .interval_duration; + metrics_data->composite = + main_frame_percentage_records_[static_cast<unsigned>( + MetricId::kCompositing)] + .interval_duration; + metrics_data->paint = + main_frame_percentage_records_[static_cast<unsigned>(MetricId::kPaint)] + .interval_duration; + metrics_data->scrolling_coordinator = + main_frame_percentage_records_[static_cast<unsigned>( + MetricId::kScrollingCoordinator)] + .interval_duration; + metrics_data->composite_commit = + main_frame_percentage_records_[static_cast<unsigned>( + MetricId::kCompositingCommit)] + .interval_duration; + return metrics_data; +} + void LocalFrameUkmAggregator::SetTickClockForTesting( const base::TickClock* clock) { clock_ = clock;
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h index 44c3f87..e3421225 100644 --- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h +++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h
@@ -14,6 +14,10 @@ class TickClock; } +namespace cc { +struct BeginMainFrameMetrics; +} + namespace ukm { class UkmRecorder; } @@ -195,7 +199,7 @@ STACK_ALLOCATED(); public: - ScopedUkmHierarchicalTimer(ScopedUkmHierarchicalTimer&&) noexcept; + ScopedUkmHierarchicalTimer(ScopedUkmHierarchicalTimer&&); ~ScopedUkmHierarchicalTimer(); private: @@ -238,6 +242,12 @@ bool InMainFrame() { return in_main_frame_update_; } + // Populate a BeginMainFrameMetrics structure with the latency numbers for + // the most recent frame. Must be called when within a main frame update. + // That is, after calling BeginMainFrame and before calling + // RecordEndOfFrameMetrics. + std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics(); + // The caller is the owner of the |clock|. The |clock| must outlive the // LocalFrameUkmAggregator. void SetTickClockForTesting(const base::TickClock* clock);
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc index a9bef6df..458fa838 100644 --- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc +++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h" #include "base/test/test_mock_time_task_runner.h" +#include "cc/metrics/begin_main_frame_metrics.h" #include "components/ukm/test_ukm_recorder.h" #include "testing/gtest/include/gtest/gtest.h" @@ -246,4 +247,43 @@ expected_percentage); } +TEST_F(LocalFrameUkmAggregatorTest, LatencyDataIsPopulated) { + // Although the tests use a mock clock, the UKM aggregator checks if the + // system has a high resolution clock before recording results. As a result, + // the tests will fail if the system does not have a high resolution clock. + if (!base::TimeTicks::IsHighResolution()) + return; + + // The initial interval is always zero, so we should see one set of metrics + // for the initial frame, regardless of the initial interval. + FramesToNextEventForTest(1); + unsigned millisecond_for_step = 1; + aggregator().BeginMainFrame(); + for (int i = 0; i < LocalFrameUkmAggregator::kCount; ++i) { + auto timer = + aggregator().GetScopedTimer(i % LocalFrameUkmAggregator::kCount); + test_task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(millisecond_for_step)); + } + + // Need to populate before the end of the frame. + std::unique_ptr<cc::BeginMainFrameMetrics> metrics_data = + aggregator().GetBeginMainFrameMetrics(); + EXPECT_EQ(metrics_data->handle_input_events.InMillisecondsF(), + millisecond_for_step); + EXPECT_EQ(metrics_data->animate.InMillisecondsF(), millisecond_for_step); + EXPECT_EQ(metrics_data->style_update.InMillisecondsF(), millisecond_for_step); + EXPECT_EQ(metrics_data->layout_update.InMillisecondsF(), + millisecond_for_step); + EXPECT_EQ(metrics_data->prepaint.InMillisecondsF(), millisecond_for_step); + EXPECT_EQ(metrics_data->composite.InMillisecondsF(), millisecond_for_step); + EXPECT_EQ(metrics_data->paint.InMillisecondsF(), millisecond_for_step); + EXPECT_EQ(metrics_data->scrolling_coordinator.InMillisecondsF(), + millisecond_for_step); + EXPECT_EQ(metrics_data->composite_commit.InMillisecondsF(), + millisecond_for_step); + // Do not check the value in metrics_data.update_layers because it + // is not set by the aggregator. +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index 7d3faaac..e4f78f3 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -350,6 +350,18 @@ .RecordEndOfFrameMetrics(frame_begin_time, base::TimeTicks::Now()); } +std::unique_ptr<cc::BeginMainFrameMetrics> +WebFrameWidgetImpl::GetBeginMainFrameMetrics() { + if (!LocalRootImpl()) + return nullptr; + + return LocalRootImpl() + ->GetFrame() + ->View() + ->EnsureUkmAggregator() + .GetBeginMainFrameMetrics(); +} + void WebFrameWidgetImpl::UpdateLifecycle(LifecycleUpdate requested_update, LifecycleUpdateReason reason) { TRACE_EVENT0("blink", "WebFrameWidgetImpl::updateAllLifecyclePhases");
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h index e111f8d7..43da8465 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
@@ -52,6 +52,7 @@ namespace cc { class Layer; +struct BeginMainFrameMetrics; } namespace blink { @@ -89,6 +90,8 @@ void EndCommitCompositorFrame() override; void RecordStartOfFrameMetrics() override; void RecordEndOfFrameMetrics(base::TimeTicks) override; + std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics() + override; void UpdateLifecycle(LifecycleUpdate requested_update, LifecycleUpdateReason reason) override; void ThemeChanged() override;
diff --git a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc index 950529614..7d1b83e 100644 --- a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc +++ b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
@@ -91,6 +91,11 @@ web_view_->RecordEndOfFrameMetrics(frame_begin_time); } +std::unique_ptr<cc::BeginMainFrameMetrics> +WebViewFrameWidget::GetBeginMainFrameMetrics() { + return web_view_->GetBeginMainFrameMetrics(); +} + void WebViewFrameWidget::UpdateLifecycle(LifecycleUpdate requested_update, LifecycleUpdateReason reason) { web_view_->UpdateLifecycle(requested_update, reason);
diff --git a/third_party/blink/renderer/core/frame/web_view_frame_widget.h b/third_party/blink/renderer/core/frame/web_view_frame_widget.h index 5024fa08..4b58d5d8 100644 --- a/third_party/blink/renderer/core/frame/web_view_frame_widget.h +++ b/third_party/blink/renderer/core/frame/web_view_frame_widget.h
@@ -58,6 +58,8 @@ void EndCommitCompositorFrame() override; void RecordStartOfFrameMetrics() override; void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) override; + std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics() + override; void UpdateLifecycle(LifecycleUpdate requested_update, LifecycleUpdateReason reason) override; void ThemeChanged() override;
diff --git a/third_party/blink/renderer/core/html/forms/resources/.clang-format b/third_party/blink/renderer/core/html/forms/resources/.clang-format index ea647be..ce154cc8 100644 --- a/third_party/blink/renderer/core/html/forms/resources/.clang-format +++ b/third_party/blink/renderer/core/html/forms/resources/.clang-format
@@ -1,7 +1,6 @@ --- BasedOnStyle: Chromium Language: JavaScript -ColumnLimit: 120 CommentPragmas: .*\@.* AllowShortBlocksOnASingleLine: false AllowShortFunctionsOnASingleLine: None
diff --git a/third_party/blink/renderer/core/html/forms/resources/PRESUBMIT.py b/third_party/blink/renderer/core/html/forms/resources/PRESUBMIT.py new file mode 100644 index 0000000..f284658 --- /dev/null +++ b/third_party/blink/renderer/core/html/forms/resources/PRESUBMIT.py
@@ -0,0 +1,14 @@ +# 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. + +def _CheckChangeOnUploadOrCommit(input_api, output_api): + return input_api.canned_checks.CheckPatchFormatted(input_api, output_api, + check_js=True) + +def CheckChangeOnUpload(input_api, output_api): + return _CheckChangeOnUploadOrCommit(input_api, output_api) + + +def CheckChangeOnCommit(input_api, output_api): + return _CheckChangeOnUploadOrCommit(input_api, output_api)
diff --git a/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js b/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js index 7ef248a8..006f968 100644 --- a/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js +++ b/third_party/blink/renderer/core/html/forms/resources/calendarPicker.js
@@ -33,7 +33,15 @@ /** * @enum {number} */ -var WeekDay = {Sunday: 0, Monday: 1, Tuesday: 2, Wednesday: 3, Thursday: 4, Friday: 5, Saturday: 6}; +var WeekDay = { + Sunday: 0, + Monday: 1, + Tuesday: 2, + Wednesday: 3, + Thursday: 4, + Friday: 5, + Saturday: 6 +}; /** * @type {Object} @@ -45,7 +53,10 @@ weekStartDay: WeekDay.Sunday, dayLabels: ['S', 'M', 'T', 'W', 'T', 'F', 'S'], ampmLabels: ['AM', 'PM'], - shortMonthLabels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'], + shortMonthLabels: [ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sept', 'Oct', + 'Nov', 'Dec' + ], isLocaleRTL: false, isFormControlsRefreshEnabled: false, mode: 'date', @@ -109,14 +120,15 @@ if (year <= 1867 || year == 1868 && month <= 9) return ''; if (!japaneseEraFormatter) { - japaneseEraFormatter = new Intl.DateTimeFormat('ja-JP-u-ca-japanese', - {era: 'long'}); + japaneseEraFormatter = + new Intl.DateTimeFormat('ja-JP-u-ca-japanese', {era: 'long'}); } // Produce the era for day 16 because it's almost the midpoint of a month. // 275760-09-13 is the last valid date in ECMAScript. We apply day 7 in that // case because it's the midpoint between 09-01 and 09-13. let sampleDay = year == 275760 && month == 8 ? 7 : 16; - let sampleDayString = japaneseEraFormatter.format(new Date(year, month, sampleDay)); + let sampleDayString = + japaneseEraFormatter.format(new Date(year, month, sampleDay)); let nenIndex = sampleDayString.indexOf('\u5e74'); if (nenIndex == -1) return ''; @@ -271,7 +283,8 @@ * @return {!boolean} */ Day.prototype.equals = function(other) { - return other instanceof Day && this.year === other.year && this.month === other.month && this.date === other.date; + return other instanceof Day && this.year === other.year && + this.month === other.month && this.date === other.date; }; /** @@ -350,7 +363,8 @@ var yearString = String(this.year); if (yearString.length < 4) yearString = ('000' + yearString).substr(-4, 4); - return yearString + '-' + ('0' + (this.month + 1)).substr(-2, 2) + '-' + ('0' + this.date).substr(-2, 2); + return yearString + '-' + ('0' + (this.month + 1)).substr(-2, 2) + '-' + + ('0' + this.date).substr(-2, 2); }; /** @@ -358,8 +372,13 @@ */ Day.prototype.format = function() { if (!Day.formatter) { - Day.formatter = new Intl.DateTimeFormat( - getLocale(), {weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', timeZone: 'UTC'}); + Day.formatter = new Intl.DateTimeFormat(getLocale(), { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric', + timeZone: 'UTC' + }); } return Day.formatter.format(this.startDate()); }; @@ -390,7 +409,8 @@ */ this.week = week; // Number of years per year is either 52 or 53. - if (this.week < 1 || (this.week > 52 && this.week > Week.numberOfWeeksInYear(this.year))) { + if (this.week < 1 || + (this.week > 52 && this.week > Week.numberOfWeeksInYear(this.year))) { var normalizedWeek = Week.createFromDay(this.firstDay()); this.year = normalizedWeek.year; this.week = normalizedWeek.week; @@ -438,11 +458,14 @@ if (isNaN(date.valueOf())) throw 'Invalid date'; var year = date.getUTCFullYear(); - if (year <= Week.Maximum.year && Week.weekOneStartDateForYear(year + 1).getTime() <= date.getTime()) + if (year <= Week.Maximum.year && + Week.weekOneStartDateForYear(year + 1).getTime() <= date.getTime()) year++; - else if (year > 1 && Week.weekOneStartDateForYear(year).getTime() > date.getTime()) + else if ( + year > 1 && Week.weekOneStartDateForYear(year).getTime() > date.getTime()) year--; - var week = 1 + Week._numberOfWeeksSinceDate(Week.weekOneStartDateForYear(year), date); + var week = 1 + + Week._numberOfWeeksSinceDate(Week.weekOneStartDateForYear(year), date); return new Week(year, week); }; @@ -456,7 +479,10 @@ year++; else if (year > 1 && Week.weekOneStartDayForYear(year) > day) year--; - var week = Math.floor(1 + (day.valueOf() - Week.weekOneStartDayForYear(year).valueOf()) / MillisecondsPerWeek); + var week = Math.floor( + 1 + + (day.valueOf() - Week.weekOneStartDayForYear(year).valueOf()) / + MillisecondsPerWeek); return new Week(year, week); }; @@ -465,7 +491,8 @@ */ Week.createFromToday = function() { var now = new Date(); - return Week.createFromDate(createUTCDate(now.getFullYear(), now.getMonth(), now.getDate())); + return Week.createFromDate( + createUTCDate(now.getFullYear(), now.getMonth(), now.getDate())); }; /** @@ -501,7 +528,9 @@ return 0; else if (year === Week.Maximum.year) return Week.Maximum.week; - return Week._numberOfWeeksSinceDate(Week.weekOneStartDateForYear(year), Week.weekOneStartDateForYear(year + 1)); + return Week._numberOfWeeksSinceDate( + Week.weekOneStartDateForYear(year), + Week.weekOneStartDateForYear(year + 1)); }; /** @@ -510,7 +539,8 @@ * @return {!number} */ Week._numberOfWeeksSinceDate = function(baseDate, date) { - return Math.floor((date.getTime() - baseDate.getTime()) / MillisecondsPerWeek); + return Math.floor( + (date.getTime() - baseDate.getTime()) / MillisecondsPerWeek); }; /** @@ -518,7 +548,8 @@ * @return {!boolean} */ Week.prototype.equals = function(other) { - return other instanceof Week && this.year === other.year && this.week === other.week; + return other instanceof Week && this.year === other.year && + this.week === other.week; }; /** @@ -616,7 +647,9 @@ * @type {number} * @const */ - this.month = month % MonthsPerYear < 0 ? month % MonthsPerYear + MonthsPerYear : month % MonthsPerYear; + this.month = month % MonthsPerYear < 0 ? + month % MonthsPerYear + MonthsPerYear : + month % MonthsPerYear; }; Month.ISOStringRegExp = /^(\d+)-(\d+)$/; @@ -688,7 +721,8 @@ * @return {!boolean} */ Month.prototype.equals = function(other) { - return other instanceof Month && this.year === other.year && this.month === other.month; + return other instanceof Month && this.year === other.year && + this.month === other.month; }; /** @@ -772,8 +806,9 @@ */ Month.prototype.toLocaleString = function() { if (global.params.locale === 'ja') - return '' + this.year + '\u5e74' + formatJapaneseImperialEra(this.year, this.month) + ' ' + (this.month + 1) + - '\u6708'; + return '' + this.year + '\u5e74' + + formatJapaneseImperialEra(this.year, this.month) + ' ' + + (this.month + 1) + '\u6708'; return window.pagePopupController.formatMonth(this.year, this.month); }; @@ -932,7 +967,8 @@ * @return {!boolean} */ AnimationManager.prototype._needsTimer = function() { - return this._runningAnimatorCount > 0 || this.hasListener(AnimationManager.EventTypeAnimationFrameWillFinish); + return this._runningAnimatorCount > 0 || + this.hasListener(AnimationManager.EventTypeAnimationFrameWillFinish); }; /** @@ -1093,7 +1129,8 @@ this.progress += (now - this._lastStepTime) / this.duration; this.progress = Math.min(1.0, this.progress); this._lastStepTime = now; - this.currentValue = this.timingFunction(this.progress) * this._delta + this._from; + this.currentValue = + this.timingFunction(this.progress) * this._delta + this._from; this.step(this); if (this.progress === 1.0) { this.stop(); @@ -1155,15 +1192,16 @@ * @param {!number} t */ FlingGestureAnimator.prototype._valueAtTime = function(t) { - return FlingGestureAnimator._P0 * Math.exp(-FlingGestureAnimator._P2 * t) - FlingGestureAnimator._P1 * t - - FlingGestureAnimator._P0; + return FlingGestureAnimator._P0 * Math.exp(-FlingGestureAnimator._P2 * t) - + FlingGestureAnimator._P1 * t - FlingGestureAnimator._P0; }; /** * @param {!number} t */ FlingGestureAnimator.prototype._velocityAtTime = function(t) { - return -FlingGestureAnimator._P0 * FlingGestureAnimator._P2 * Math.exp(-FlingGestureAnimator._P2 * t) - + return -FlingGestureAnimator._P0 * FlingGestureAnimator._P2 * + Math.exp(-FlingGestureAnimator._P2 * t) - FlingGestureAnimator._P1; }; @@ -1171,7 +1209,9 @@ * @param {!number} v */ FlingGestureAnimator.prototype._timeAtVelocity = function(v) { - return -Math.log((v + FlingGestureAnimator._P1) / (-FlingGestureAnimator._P0 * FlingGestureAnimator._P2)) / + return -Math.log( + (v + FlingGestureAnimator._P1) / + (-FlingGestureAnimator._P0 * FlingGestureAnimator._P2)) / FlingGestureAnimator._P2; }; @@ -1190,7 +1230,8 @@ this.stop(); return; } - var position = this._valueAtTime(this._elapsedTime + this._timeOffset) - this._positionOffset; + var position = this._valueAtTime(this._elapsedTime + this._timeOffset) - + this._positionOffset; if (this.initialVelocity < 0) position = -position; this.currentValue = position + this.initialValue; @@ -1271,7 +1312,8 @@ * @type {Element} * @const */ - this.contentElement = createElement('div', ScrollView.ClassNameScrollViewContent); + this.contentElement = + createElement('div', ScrollView.ClassNameScrollViewContent); this.element.appendChild(this.contentElement); /** * @type {number} @@ -1370,7 +1412,8 @@ */ ScrollView.prototype.onWindowTouchEnd = function(event) { if (Math.abs(this._lastTouchVelocity) > 0.01) { - this._scrollAnimator = new FlingGestureAnimator(this._lastTouchVelocity, this._contentOffset); + this._scrollAnimator = + new FlingGestureAnimator(this._lastTouchVelocity, this._contentOffset); this._scrollAnimator.step = this.onFlingGestureAnimatorStep; this._scrollAnimator.start(); } @@ -1487,7 +1530,9 @@ */ ScrollView.prototype.setContentOffset = function(value) { console.assert(isFinite(value)); - value = Math.min(this.maximumContentOffset - this._height, Math.max(this.minimumContentOffset, Math.floor(value))); + value = Math.min( + this.maximumContentOffset - this._height, + Math.max(this.minimumContentOffset, Math.floor(value))); if (this._contentOffset === value) return; this._contentOffset = value; @@ -1497,11 +1542,12 @@ }; ScrollView.prototype._updateScrollContent = function() { - var newPartitionNumber = Math.floor(this._contentOffset / ScrollView.PartitionHeight); + var newPartitionNumber = + Math.floor(this._contentOffset / ScrollView.PartitionHeight); var partitionChanged = this._partitionNumber !== newPartitionNumber; this._partitionNumber = newPartitionNumber; - this.contentElement.style.webkitTransform = - 'translate(0, ' + (-this.contentPositionForContentOffset(this._contentOffset)) + 'px)'; + this.contentElement.style.webkitTransform = 'translate(0, ' + + (-this.contentPositionForContentOffset(this._contentOffset)) + 'px)'; if (this.delegate && partitionChanged) this.delegate.scrollViewDidChangePartition(this); }; @@ -1554,14 +1600,17 @@ * @return {!Array} An array to keep thrown away cells. */ ListCell.prototype._recycleBin = function() { - console.assert(false, 'NOT REACHED: ListCell.prototype._recycleBin needs to be overridden.'); + console.assert( + false, + 'NOT REACHED: ListCell.prototype._recycleBin needs to be overridden.'); return []; }; ListCell.prototype.throwAway = function() { this.hide(); - var limit = typeof this.constructor.RecycleBinLimit === 'undefined' ? ListCell.DefaultRecycleBinLimit : - this.constructor.RecycleBinLimit; + var limit = typeof this.constructor.RecycleBinLimit === 'undefined' ? + ListCell.DefaultRecycleBinLimit : + this.constructor.RecycleBinLimit; var recycleBin = this._recycleBin(); if (recycleBin.length < limit) recycleBin.push(this); @@ -1684,10 +1733,13 @@ return; this._needsUpdateCells = needsUpdateCells; if (this._needsUpdateCells) - AnimationManager.shared.on(AnimationManager.EventTypeAnimationFrameWillFinish, this.onAnimationFrameWillFinish); + AnimationManager.shared.on( + AnimationManager.EventTypeAnimationFrameWillFinish, + this.onAnimationFrameWillFinish); else AnimationManager.shared.removeListener( - AnimationManager.EventTypeAnimationFrameWillFinish, this.onAnimationFrameWillFinish); + AnimationManager.EventTypeAnimationFrameWillFinish, + this.onAnimationFrameWillFinish); }; /** @@ -1703,7 +1755,9 @@ * @return {!number} */ ListView.prototype.rowAtScrollOffset = function(offset) { - console.assert(false, 'NOT REACHED: ListView.prototype.rowAtScrollOffset needs to be overridden.'); + console.assert( + false, + 'NOT REACHED: ListView.prototype.rowAtScrollOffset needs to be overridden.'); return 0; }; @@ -1712,7 +1766,9 @@ * @return {!number} Scroll offset in pixels. */ ListView.prototype.scrollOffsetForRow = function(row) { - console.assert(false, 'NOT REACHED: ListView.prototype.scrollOffsetForRow needs to be overridden.'); + console.assert( + false, + 'NOT REACHED: ListView.prototype.scrollOffsetForRow needs to be overridden.'); return 0; }; @@ -1727,7 +1783,8 @@ cell = this.prepareNewCell(row); cell.attachTo(this.scrollView.contentElement); cell.setWidth(this._width); - cell.setPosition(this.scrollView.contentPositionForContentOffset(this.scrollOffsetForRow(row))); + cell.setPosition(this.scrollView.contentPositionForContentOffset( + this.scrollOffsetForRow(row))); this._cells[row] = cell; return cell; }; @@ -1737,7 +1794,9 @@ * @return {!ListCell} */ ListView.prototype.prepareNewCell = function(row) { - console.assert(false, 'NOT REACHED: ListView.prototype.prepareNewCell should be overridden.'); + console.assert( + false, + 'NOT REACHED: ListView.prototype.prepareNewCell should be overridden.'); return new ListCell(); }; @@ -1760,7 +1819,8 @@ * @return {!number} */ ListView.prototype.lastVisibleRow = function() { - return this.rowAtScrollOffset(this.scrollView.contentOffset() + this.scrollView.height() - 1); + return this.rowAtScrollOffset( + this.scrollView.contentOffset() + this.scrollView.height() - 1); }; /** @@ -1796,7 +1856,8 @@ for (var i = firstVisibleRow; i <= lastVisibleRow; ++i) { var cell = this._cells[i]; if (cell) - cell.setPosition(this.scrollView.contentPositionForContentOffset(this.scrollOffsetForRow(cell.row))); + cell.setPosition(this.scrollView.contentPositionForContentOffset( + this.scrollOffsetForRow(cell.row))); else this.addCellIfNecessary(i); } @@ -1843,7 +1904,8 @@ * @param {?Event} event */ ListView.prototype.onClick = function(event) { - var clickedCellElement = enclosingNodeOrSelfWithClass(event.target, ListCell.ClassNameListCell); + var clickedCellElement = + enclosingNodeOrSelfWithClass(event.target, ListCell.ClassNameListCell); if (!clickedCellElement) return; var clickedCell = clickedCellElement.$view; @@ -1889,13 +1951,15 @@ * @param {!ScrollView} scrollView */ function ScrubbyScrollBar(scrollView) { - View.call(this, createElement('div', ScrubbyScrollBar.ClassNameScrubbyScrollBar)); + View.call( + this, createElement('div', ScrubbyScrollBar.ClassNameScrubbyScrollBar)); /** * @type {!Element} * @const */ - this.thumb = createElement('div', ScrubbyScrollBar.ClassNameScrubbyScrollThumb); + this.thumb = + createElement('div', ScrubbyScrollBar.ClassNameScrubbyScrollThumb); this.element.appendChild(this.thumb); /** @@ -1955,7 +2019,8 @@ this._setThumbPositionFromEventPosition(touch.clientY); if (this._thumbStyleTopAnimator) this._thumbStyleTopAnimator.stop(); - this._timer = setInterval(this.onScrollTimer, ScrubbyScrollBar.ScrollInterval); + this._timer = + setInterval(this.onScrollTimer, ScrubbyScrollBar.ScrollInterval); window.addEventListener('touchmove', this.onWindowTouchMove, false); window.addEventListener('touchend', this.onWindowTouchEnd, false); event.stopPropagation(); @@ -1980,7 +2045,8 @@ this._thumbStyleTopAnimator.step = this.onThumbStyleTopAnimationStep; this._thumbStyleTopAnimator.setFrom(this.thumb.offsetTop); this._thumbStyleTopAnimator.setTo((this._height - this._thumbHeight) / 2); - this._thumbStyleTopAnimator.timingFunction = AnimationTimingFunction.EaseInOut; + this._thumbStyleTopAnimator.timingFunction = + AnimationTimingFunction.EaseInOut; this._thumbStyleTopAnimator.duration = 100; this._thumbStyleTopAnimator.start(); @@ -2023,15 +2089,19 @@ /** * @param {number} position */ -ScrubbyScrollBar.prototype._setThumbPositionFromEventPosition = function(position) { +ScrubbyScrollBar.prototype._setThumbPositionFromEventPosition = function( + position) { var thumbMin = ScrubbyScrollBar.ThumbMargin; - var thumbMax = this._height - this._thumbHeight - ScrubbyScrollBar.ThumbMargin * 2; - var y = position - this.element.getBoundingClientRect().top - this.element.clientTop + this.element.scrollTop; + var thumbMax = + this._height - this._thumbHeight - ScrubbyScrollBar.ThumbMargin * 2; + var y = position - this.element.getBoundingClientRect().top - + this.element.clientTop + this.element.scrollTop; var thumbPosition = y - this._thumbHeight / 2; thumbPosition = Math.max(thumbPosition, thumbMin); thumbPosition = Math.min(thumbPosition, thumbMax); this.thumb.style.top = thumbPosition + 'px'; - this._thumbPosition = 1.0 - (thumbPosition - thumbMin) / (thumbMax - thumbMin) * 2; + this._thumbPosition = + 1.0 - (thumbPosition - thumbMin) / (thumbMax - thumbMin) * 2; }; /** @@ -2044,7 +2114,8 @@ window.addEventListener('mouseup', this.onWindowMouseUp, false); if (this._thumbStyleTopAnimator) this._thumbStyleTopAnimator.stop(); - this._timer = setInterval(this.onScrollTimer, ScrubbyScrollBar.ScrollInterval); + this._timer = + setInterval(this.onScrollTimer, ScrubbyScrollBar.ScrollInterval); event.stopPropagation(); event.preventDefault(); }; @@ -2064,7 +2135,8 @@ this._thumbStyleTopAnimator.step = this.onThumbStyleTopAnimationStep; this._thumbStyleTopAnimator.setFrom(this.thumb.offsetTop); this._thumbStyleTopAnimator.setTo((this._height - this._thumbHeight) / 2); - this._thumbStyleTopAnimator.timingFunction = AnimationTimingFunction.EaseInOut; + this._thumbStyleTopAnimator.timingFunction = + AnimationTimingFunction.EaseInOut; this._thumbStyleTopAnimator.duration = 100; this._thumbStyleTopAnimator.start(); @@ -2103,21 +2175,26 @@ */ this.label = createElement('div', YearListCell.ClassNameLabel, '----'); this.element.appendChild(this.label); - this.label.style.height = (YearListCell.GetHeight() - YearListCell.BorderBottomWidth) + 'px'; - this.label.style.lineHeight = (YearListCell.GetHeight() - YearListCell.BorderBottomWidth) + 'px'; + this.label.style.height = + (YearListCell.GetHeight() - YearListCell.BorderBottomWidth) + 'px'; + this.label.style.lineHeight = + (YearListCell.GetHeight() - YearListCell.BorderBottomWidth) + 'px'; /** * @type {!Array} Array of the 12 month button elements. * @const */ this.monthButtons = []; - var monthChooserElement = createElement('div', YearListCell.ClassNameMonthChooser); + var monthChooserElement = + createElement('div', YearListCell.ClassNameMonthChooser); for (var r = 0; r < YearListCell.ButtonRows; ++r) { - var buttonsRow = createElement('div', YearListCell.ClassNameMonthButtonsRow); + var buttonsRow = + createElement('div', YearListCell.ClassNameMonthButtonsRow); buttonsRow.setAttribute('role', 'row'); for (var c = 0; c < YearListCell.ButtonColumns; ++c) { var month = c + r * YearListCell.ButtonColumns; - var button = createElement('div', YearListCell.ClassNameMonthButton, shortMonthLabels[month]); + var button = createElement( + 'div', YearListCell.ClassNameMonthButton, shortMonthLabels[month]); button.setAttribute('role', 'gridcell'); button.dataset.month = month; buttonsRow.appendChild(button); @@ -2148,7 +2225,7 @@ return YearListCell._HeightRefresh; } return YearListCell._Height; -} +}; YearListCell.BorderBottomWidth = 1; YearListCell.ButtonRows = 3; YearListCell.ButtonColumns = 4; @@ -2159,7 +2236,7 @@ return YearListCell._SelectedHeightRefresh; } return YearListCell._SelectedHeight; -} +}; YearListCell.ClassNameYearListCell = 'year-list-cell'; YearListCell.ClassNameLabel = 'label'; YearListCell.ClassNameMonthChooser = 'month-chooser'; @@ -2241,9 +2318,11 @@ */ this._maximumMonth = maximumMonth; - this.scrollView.minimumContentOffset = (this._minimumMonth.year - 1) * YearListCell.GetHeight(); + this.scrollView.minimumContentOffset = + (this._minimumMonth.year - 1) * YearListCell.GetHeight(); this.scrollView.maximumContentOffset = - (this._maximumMonth.year - 1) * YearListCell.GetHeight() + YearListCell.GetSelectedHeight(); + (this._maximumMonth.year - 1) * YearListCell.GetHeight() + + YearListCell.GetSelectedHeight(); /** * @type {!Object} @@ -2280,13 +2359,14 @@ YearListView._Height = YearListCell._SelectedHeight - 1; YearListView._VisibleYearsRefresh = 4; -YearListView._HeightRefresh = YearListCell._SelectedHeightRefresh - 1 + YearListView._VisibleYearsRefresh * YearListCell._HeightRefresh; +YearListView._HeightRefresh = YearListCell._SelectedHeightRefresh - 1 + + YearListView._VisibleYearsRefresh * YearListCell._HeightRefresh; YearListView.GetHeight = function() { if (global.params.isFormControlsRefreshEnabled) { return YearListView._HeightRefresh; } return YearListView._Height; -} +}; YearListView.EventTypeYearListViewDidHide = 'yearListViewDidHide'; YearListView.EventTypeYearListViewDidSelectMonth = 'yearListViewDidSelectMonth'; @@ -2295,24 +2375,30 @@ */ YearListView.prototype.onTouchStart = function(event) { var touch = event.touches[0]; - var monthButtonElement = enclosingNodeOrSelfWithClass(touch.target, YearListCell.ClassNameMonthButton); + var monthButtonElement = enclosingNodeOrSelfWithClass( + touch.target, YearListCell.ClassNameMonthButton); if (!monthButtonElement) return; - var cellElement = enclosingNodeOrSelfWithClass(monthButtonElement, YearListCell.ClassNameYearListCell); + var cellElement = enclosingNodeOrSelfWithClass( + monthButtonElement, YearListCell.ClassNameYearListCell); var cell = cellElement.$view; - this.highlightMonth(new Month(cell.row + 1, parseInt(monthButtonElement.dataset.month, 10))); + this.highlightMonth( + new Month(cell.row + 1, parseInt(monthButtonElement.dataset.month, 10))); }; /** * @param {?Event} event */ YearListView.prototype.onMouseOver = function(event) { - var monthButtonElement = enclosingNodeOrSelfWithClass(event.target, YearListCell.ClassNameMonthButton); + var monthButtonElement = enclosingNodeOrSelfWithClass( + event.target, YearListCell.ClassNameMonthButton); if (!monthButtonElement) return; - var cellElement = enclosingNodeOrSelfWithClass(monthButtonElement, YearListCell.ClassNameYearListCell); + var cellElement = enclosingNodeOrSelfWithClass( + monthButtonElement, YearListCell.ClassNameYearListCell); var cell = cellElement.$view; - this.highlightMonth(new Month(cell.row + 1, parseInt(monthButtonElement.dataset.month, 10))); + this.highlightMonth( + new Month(cell.row + 1, parseInt(monthButtonElement.dataset.month, 10))); this._ignoreMouseOutUntillNextMouseOver = false; }; @@ -2322,7 +2408,8 @@ YearListView.prototype.onMouseOut = function(event) { if (this._ignoreMouseOutUntillNextMouseOver) return; - var monthButtonElement = enclosingNodeOrSelfWithClass(event.target, YearListCell.ClassNameMonthButton); + var monthButtonElement = enclosingNodeOrSelfWithClass( + event.target, YearListCell.ClassNameMonthButton); if (!monthButtonElement) { this.dehighlightMonth(); } @@ -2333,7 +2420,8 @@ * @override */ YearListView.prototype.setWidth = function(width) { - ListView.prototype.setWidth.call(this, width - this.scrubbyScrollBar.element.offsetWidth); + ListView.prototype.setWidth.call( + this, width - this.scrubbyScrollBar.element.offsetWidth); this.element.style.width = width + 'px'; }; @@ -2359,8 +2447,9 @@ * @param {!YearListView.RowAnimationDirection} direction */ YearListView.prototype._animateRow = function(row, direction) { - var fromValue = - direction === YearListView.RowAnimationDirection.Closing ? YearListCell.GetSelectedHeight() : YearListCell.GetHeight(); + var fromValue = direction === YearListView.RowAnimationDirection.Closing ? + YearListCell.GetSelectedHeight() : + YearListCell.GetHeight(); var oldAnimator = this._runningAnimators[row]; if (oldAnimator) { oldAnimator.stop(); @@ -2371,11 +2460,14 @@ animator.step = this.onCellHeightAnimatorStep; animator.setFrom(fromValue); animator.setTo( - direction === YearListView.RowAnimationDirection.Opening ? YearListCell.GetSelectedHeight() : YearListCell.GetHeight()); + direction === YearListView.RowAnimationDirection.Opening ? + YearListCell.GetSelectedHeight() : + YearListCell.GetHeight()); animator.timingFunction = AnimationTimingFunction.EaseInOut; animator.duration = 300; animator.row = row; - animator.on(Animator.EventTypeDidAnimationStop, this.onCellHeightAnimatorDidStop); + animator.on( + Animator.EventTypeDidAnimationStop, this.onCellHeightAnimatorDidStop); this._runningAnimators[row] = animator; this._animatingRows.push(row); this._animatingRows.sort(); @@ -2410,14 +2502,19 @@ var year = this.selectedRow + 1; if (this.selectedRow !== oldSelectedRow) { var month = this.highlightedMonth ? this.highlightedMonth.month : 0; - this.dispatchEvent(YearListView.EventTypeYearListViewDidSelectMonth, this, new Month(year, month)); + this.dispatchEvent( + YearListView.EventTypeYearListViewDidSelectMonth, this, + new Month(year, month)); this.scrollView.scrollTo(this.selectedRow * YearListCell.GetHeight(), true); } else { - var monthButton = enclosingNodeOrSelfWithClass(event.target, YearListCell.ClassNameMonthButton); + var monthButton = enclosingNodeOrSelfWithClass( + event.target, YearListCell.ClassNameMonthButton); if (!monthButton || monthButton.getAttribute('aria-disabled') == 'true') return; var month = parseInt(monthButton.dataset.month, 10); - this.dispatchEvent(YearListView.EventTypeYearListViewDidSelectMonth, this, new Month(year, month)); + this.dispatchEvent( + YearListView.EventTypeYearListViewDidSelectMonth, this, + new Month(year, month)); this.hide(); } }; @@ -2438,9 +2535,12 @@ for (var i = 0; i < rowsWithIrregularHeight.length; ++i) { var row = rowsWithIrregularHeight[i]; var animator = this._runningAnimators[row]; - var rowHeight = animator ? animator.currentValue : YearListCell.GetSelectedHeight(); - if (remainingOffset <= (row - lastAnimatingRow) * YearListCell.GetHeight()) { - return lastAnimatingRow + Math.floor(remainingOffset / YearListCell.GetHeight()); + var rowHeight = + animator ? animator.currentValue : YearListCell.GetSelectedHeight(); + if (remainingOffset <= + (row - lastAnimatingRow) * YearListCell.GetHeight()) { + return lastAnimatingRow + + Math.floor(remainingOffset / YearListCell.GetHeight()); } remainingOffset -= (row - lastAnimatingRow) * YearListCell.GetHeight(); if (remainingOffset <= (rowHeight - YearListCell.GetHeight())) @@ -2448,7 +2548,8 @@ remainingOffset -= rowHeight - YearListCell.GetHeight(); lastAnimatingRow = row; } - return lastAnimatingRow + Math.floor(remainingOffset / YearListCell.GetHeight()); + return lastAnimatingRow + + Math.floor(remainingOffset / YearListCell.GetHeight()); }; /** @@ -2465,7 +2566,8 @@ var animator = this._runningAnimators[animatingRow]; scrollOffset += animator.currentValue - YearListCell.GetHeight(); } - if (this.selectedRow > -1 && this.selectedRow < row && !this._runningAnimators[this.selectedRow]) { + if (this.selectedRow > -1 && this.selectedRow < row && + !this._runningAnimators[this.selectedRow]) { scrollOffset += YearListCell.GetSelectedHeight() - YearListCell.GetHeight(); } return scrollOffset; @@ -2477,14 +2579,17 @@ * @override */ YearListView.prototype.prepareNewCell = function(row) { - var cell = YearListCell._recycleBin.pop() || new YearListCell(global.params.shortMonthLabels); + var cell = YearListCell._recycleBin.pop() || + new YearListCell(global.params.shortMonthLabels); cell.reset(row); cell.setSelected(this.selectedRow === row); for (var i = 0; i < cell.monthButtons.length; ++i) { var month = new Month(row + 1, i); cell.monthButtons[i].id = month.toString(); cell.monthButtons[i].setAttribute( - 'aria-disabled', this._minimumMonth > month || this._maximumMonth < month ? 'true' : 'false'); + 'aria-disabled', + this._minimumMonth > month || this._maximumMonth < month ? 'true' : + 'false'); cell.monthButtons[i].setAttribute('aria-label', month.toLocaleString()); } if (this.highlightedMonth && row === this.highlightedMonth.year - 1) { @@ -2532,7 +2637,8 @@ for (var i = firstVisibleRow; i <= lastVisibleRow; ++i) { var cell = this._cells[i]; if (cell) - cell.setPosition(this.scrollView.contentPositionForContentOffset(this.scrollOffsetForRow(cell.row))); + cell.setPosition(this.scrollView.contentPositionForContentOffset( + this.scrollOffsetForRow(cell.row))); else this.addCellIfNecessary(i); } @@ -2548,7 +2654,8 @@ var selectedCell = this._cells[this.selectedRow]; if (selectedCell) selectedCell.setSelected(false); - this._animateRow(this.selectedRow, YearListView.RowAnimationDirection.Closing); + this._animateRow( + this.selectedRow, YearListView.RowAnimationDirection.Closing); this.selectedRow = ListView.NoSelection; this.setNeedsUpdateCells(true); }; @@ -2578,7 +2685,8 @@ this.selectedRow = row; if (this.selectedRow !== ListView.NoSelection) { var selectedCell = this._cells[this.selectedRow]; - this._animateRow(this.selectedRow, YearListView.RowAnimationDirection.Opening); + this._animateRow( + this.selectedRow, YearListView.RowAnimationDirection.Opening); if (selectedCell) selectedCell.setSelected(true); var month = this.highlightedMonth ? this.highlightedMonth.month : 0; @@ -2653,14 +2761,14 @@ YearListView.prototype.setSelectedMonth = function(month) { this._selectedMonth = month; -} +}; YearListView.prototype.showSelectedMonth = function() { var monthButton = this.buttonForMonth(this._selectedMonth); if (monthButton) { monthButton.classList.add(YearListCell.ClassNameSelected); } -} +}; /** * @param {!Month} month @@ -2685,7 +2793,8 @@ this.highlightMonth(month); this.select(this.highlightedMonth.year - 1); - this.dispatchEvent(YearListView.EventTypeYearListViewDidSelectMonth, this, month); + this.dispatchEvent( + YearListView.EventTypeYearListViewDidSelectMonth, this, month); this.scrollView.scrollTo(this.selectedRow * YearListCell.GetHeight(), true); return true; }; @@ -2702,17 +2811,24 @@ if (global.params.isLocaleRTL ? key == 'ArrowRight' : key == 'ArrowLeft') eventHandled = this._moveHighlightTo(this.highlightedMonth.previous()); else if (key == 'ArrowUp') - eventHandled = this._moveHighlightTo(this.highlightedMonth.previous(YearListCell.ButtonColumns)); - else if (global.params.isLocaleRTL ? key == 'ArrowLeft' : key == 'ArrowRight') + eventHandled = this._moveHighlightTo( + this.highlightedMonth.previous(YearListCell.ButtonColumns)); + else if ( + global.params.isLocaleRTL ? key == 'ArrowLeft' : key == 'ArrowRight') eventHandled = this._moveHighlightTo(this.highlightedMonth.next()); else if (key == 'ArrowDown') - eventHandled = this._moveHighlightTo(this.highlightedMonth.next(YearListCell.ButtonColumns)); + eventHandled = this._moveHighlightTo( + this.highlightedMonth.next(YearListCell.ButtonColumns)); else if (key == 'PageUp') - eventHandled = this._moveHighlightTo(this.highlightedMonth.previous(MonthsPerYear)); + eventHandled = + this._moveHighlightTo(this.highlightedMonth.previous(MonthsPerYear)); else if (key == 'PageDown') - eventHandled = this._moveHighlightTo(this.highlightedMonth.next(MonthsPerYear)); + eventHandled = + this._moveHighlightTo(this.highlightedMonth.next(MonthsPerYear)); else if (key == 'Enter') { - this.dispatchEvent(YearListView.EventTypeYearListViewDidSelectMonth, this, this.highlightedMonth); + this.dispatchEvent( + YearListView.EventTypeYearListViewDidSelectMonth, this, + this.highlightedMonth); this.hide(); eventHandled = true; } @@ -2801,21 +2917,25 @@ * @param {!number} maxWidth Maximum width in pixels. */ function MonthPopupButton(maxWidth) { - View.call(this, createElement('button', MonthPopupButton.ClassNameMonthPopupButton)); + View.call( + this, + createElement('button', MonthPopupButton.ClassNameMonthPopupButton)); this.element.setAttribute('aria-label', global.params.axShowMonthSelector); /** * @type {!Element} * @const */ - this.labelElement = createElement('span', MonthPopupButton.ClassNameMonthPopupButtonLabel, '-----'); + this.labelElement = createElement( + 'span', MonthPopupButton.ClassNameMonthPopupButtonLabel, '-----'); this.element.appendChild(this.labelElement); /** * @type {!Element} * @const */ - this.disclosureTriangleIcon = createElement('span', MonthPopupButton.ClassNameDisclosureTriangle); + this.disclosureTriangleIcon = + createElement('span', MonthPopupButton.ClassNameDisclosureTriangle); this.disclosureTriangleIcon.innerHTML = '<svg width=\'7\' height=\'5\'><polygon points=\'0,1 7,1 3.5,5\' style=\'fill:#000000;\' /></svg>'; this.element.appendChild(this.disclosureTriangleIcon); @@ -2858,7 +2978,9 @@ * @param {!Month} month */ MonthPopupButton.prototype.setCurrentMonth = function(month) { - this.labelElement.textContent = this._useShortMonth ? month.toShortLocaleString() : month.toLocaleString(); + this.labelElement.textContent = this._useShortMonth ? + month.toShortLocaleString() : + month.toLocaleString(); }; /** @@ -2873,15 +2995,21 @@ * @extends View */ function CalendarNavigationButton() { - View.call(this, createElement('button', CalendarNavigationButton.ClassNameCalendarNavigationButton)); + View.call( + this, + createElement( + 'button', + CalendarNavigationButton.ClassNameCalendarNavigationButton)); /** * @type {number} Threshold for starting repeating clicks in milliseconds. */ - this.repeatingClicksStartingThreshold = CalendarNavigationButton.DefaultRepeatingClicksStartingThreshold; + this.repeatingClicksStartingThreshold = + CalendarNavigationButton.DefaultRepeatingClicksStartingThreshold; /** * @type {number} Interval between reapeating clicks in milliseconds. */ - this.reapeatingClicksInterval = CalendarNavigationButton.DefaultRepeatingClicksInterval; + this.reapeatingClicksInterval = + CalendarNavigationButton.DefaultRepeatingClicksInterval; /** * @type {?number} The ID for the timeout that triggers the repeating clicks. */ @@ -2897,7 +3025,8 @@ CalendarNavigationButton.DefaultRepeatingClicksInterval = 300; CalendarNavigationButton.LeftMargin = 4; CalendarNavigationButton.Width = 24; -CalendarNavigationButton.ClassNameCalendarNavigationButton = 'calendar-navigation-button'; +CalendarNavigationButton.ClassNameCalendarNavigationButton = + 'calendar-navigation-button'; CalendarNavigationButton.EventTypeButtonClick = 'buttonClick'; CalendarNavigationButton.EventTypeRepeatingButtonClick = 'repeatingButtonClick'; @@ -2921,7 +3050,8 @@ CalendarNavigationButton.prototype.onTouchStart = function(event) { if (this._timer !== null) return; - this._timer = setTimeout(this.onRepeatingClick, this.repeatingClicksStartingThreshold); + this._timer = + setTimeout(this.onRepeatingClick, this.repeatingClicksStartingThreshold); window.addEventListener('touchend', this.onWindowTouchEnd, false); }; @@ -2942,7 +3072,8 @@ CalendarNavigationButton.prototype.onMouseDown = function(event) { if (this._timer !== null) return; - this._timer = setTimeout(this.onRepeatingClick, this.repeatingClicksStartingThreshold); + this._timer = + setTimeout(this.onRepeatingClick, this.repeatingClicksStartingThreshold); window.addEventListener('mouseup', this.onWindowMouseUp, false); }; @@ -2961,8 +3092,10 @@ * @param {?Event} event */ CalendarNavigationButton.prototype.onRepeatingClick = function(event) { - this.dispatchEvent(CalendarNavigationButton.EventTypeRepeatingButtonClick, this); - this._timer = setTimeout(this.onRepeatingClick, this.reapeatingClicksInterval); + this.dispatchEvent( + CalendarNavigationButton.EventTypeRepeatingButtonClick, this); + this._timer = + setTimeout(this.onRepeatingClick, this.reapeatingClicksInterval); }; /** @@ -2971,19 +3104,25 @@ * @param {!CalendarPicker} calendarPicker */ function CalendarHeaderView(calendarPicker) { - View.call(this, createElement('div', CalendarHeaderView.ClassNameCalendarHeaderView)); + View.call( + this, + createElement('div', CalendarHeaderView.ClassNameCalendarHeaderView)); this.calendarPicker = calendarPicker; - this.calendarPicker.on(CalendarPicker.EventTypeCurrentMonthChanged, this.onCurrentMonthChanged); + this.calendarPicker.on( + CalendarPicker.EventTypeCurrentMonthChanged, this.onCurrentMonthChanged); - var titleElement = createElement('div', CalendarHeaderView.ClassNameCalendarTitle); + var titleElement = + createElement('div', CalendarHeaderView.ClassNameCalendarTitle); this.element.appendChild(titleElement); /** * @type {!MonthPopupButton} */ this.monthPopupButton = new MonthPopupButton( - this.calendarPicker.calendarTableView.width() - CalendarTableView.GetBorderWidth() * 2 - - CalendarNavigationButton.Width * 3 - CalendarNavigationButton.LeftMargin * 2); + this.calendarPicker.calendarTableView.width() - + CalendarTableView.GetBorderWidth() * 2 - + CalendarNavigationButton.Width * 3 - + CalendarNavigationButton.LeftMargin * 2); this.monthPopupButton.attachTo(titleElement); /** @@ -2992,9 +3131,14 @@ */ this._previousMonthButton = new CalendarNavigationButton(); this._previousMonthButton.attachTo(this); - this._previousMonthButton.on(CalendarNavigationButton.EventTypeButtonClick, this.onNavigationButtonClick); - this._previousMonthButton.on(CalendarNavigationButton.EventTypeRepeatingButtonClick, this.onNavigationButtonClick); - this._previousMonthButton.element.setAttribute('aria-label', global.params.axShowPreviousMonth); + this._previousMonthButton.on( + CalendarNavigationButton.EventTypeButtonClick, + this.onNavigationButtonClick); + this._previousMonthButton.on( + CalendarNavigationButton.EventTypeRepeatingButtonClick, + this.onNavigationButtonClick); + this._previousMonthButton.element.setAttribute( + 'aria-label', global.params.axShowPreviousMonth); if (!global.params.isFormControlsRefreshEnabled) { /** @@ -3003,13 +3147,17 @@ */ this._todayButton = new CalendarNavigationButton(); this._todayButton.attachTo(this); - this._todayButton.on(CalendarNavigationButton.EventTypeButtonClick, this.onNavigationButtonClick); - this._todayButton.element.classList.add(CalendarHeaderView.GetClassNameTodayButton()); + this._todayButton.on( + CalendarNavigationButton.EventTypeButtonClick, + this.onNavigationButtonClick); + this._todayButton.element.classList.add( + CalendarHeaderView.GetClassNameTodayButton()); var monthContainingToday = Month.createFromToday(); this._todayButton.setDisabled( monthContainingToday < this.calendarPicker.minimumMonth || monthContainingToday > this.calendarPicker.maximumMonth); - this._todayButton.element.setAttribute('aria-label', global.params.todayLabel); + this._todayButton.element.setAttribute( + 'aria-label', global.params.todayLabel); } /** @@ -3018,16 +3166,25 @@ */ this._nextMonthButton = new CalendarNavigationButton(); this._nextMonthButton.attachTo(this); - this._nextMonthButton.on(CalendarNavigationButton.EventTypeButtonClick, this.onNavigationButtonClick); - this._nextMonthButton.on(CalendarNavigationButton.EventTypeRepeatingButtonClick, this.onNavigationButtonClick); - this._nextMonthButton.element.setAttribute('aria-label', global.params.axShowNextMonth); + this._nextMonthButton.on( + CalendarNavigationButton.EventTypeButtonClick, + this.onNavigationButtonClick); + this._nextMonthButton.on( + CalendarNavigationButton.EventTypeRepeatingButtonClick, + this.onNavigationButtonClick); + this._nextMonthButton.element.setAttribute( + 'aria-label', global.params.axShowNextMonth); if (global.params.isLocaleRTL) { - this._nextMonthButton.element.innerHTML = CalendarHeaderView.GetBackwardTriangle(); - this._previousMonthButton.element.innerHTML = CalendarHeaderView.GetForwardTriangle(); + this._nextMonthButton.element.innerHTML = + CalendarHeaderView.GetBackwardTriangle(); + this._previousMonthButton.element.innerHTML = + CalendarHeaderView.GetForwardTriangle(); } else { - this._nextMonthButton.element.innerHTML = CalendarHeaderView.GetForwardTriangle(); - this._previousMonthButton.element.innerHTML = CalendarHeaderView.GetBackwardTriangle(); + this._nextMonthButton.element.innerHTML = + CalendarHeaderView.GetForwardTriangle(); + this._previousMonthButton.element.innerHTML = + CalendarHeaderView.GetBackwardTriangle(); } } @@ -3046,7 +3203,7 @@ return CalendarHeaderView._ForwardTriangleRefresh; } return CalendarHeaderView._ForwardTriangle; -} +}; CalendarHeaderView._BackwardTriangle = '<svg width=\'4\' height=\'7\'><polygon points=\'0,3.5 4,7 4,0\' style=\'fill:#6e6e6e;\' /></svg>'; CalendarHeaderView._BackwardTriangleRefresh = @@ -3058,7 +3215,7 @@ return CalendarHeaderView._BackwardTriangleRefresh; } return CalendarHeaderView._BackwardTriangle; -} +}; CalendarHeaderView.ClassNameCalendarHeaderView = 'calendar-header-view'; CalendarHeaderView.ClassNameCalendarTitle = 'calendar-title'; CalendarHeaderView.ClassNameTodayButton = 'today-button'; @@ -3068,23 +3225,27 @@ return CalendarHeaderView.ClassNameTodayButtonRefresh; } return CalendarHeaderView.ClassNameTodayButton; -} +}; CalendarHeaderView.prototype.onCurrentMonthChanged = function() { this.monthPopupButton.setCurrentMonth(this.calendarPicker.currentMonth()); this._previousMonthButton.setDisabled( - this.disabled || this.calendarPicker.currentMonth() <= this.calendarPicker.minimumMonth); + this.disabled || + this.calendarPicker.currentMonth() <= this.calendarPicker.minimumMonth); this._nextMonthButton.setDisabled( - this.disabled || this.calendarPicker.currentMonth() >= this.calendarPicker.maximumMonth); + this.disabled || + this.calendarPicker.currentMonth() >= this.calendarPicker.maximumMonth); }; CalendarHeaderView.prototype.onNavigationButtonClick = function(sender) { if (sender === this._previousMonthButton) this.calendarPicker.setCurrentMonth( - this.calendarPicker.currentMonth().previous(), CalendarPicker.NavigationBehavior.WithAnimation); + this.calendarPicker.currentMonth().previous(), + CalendarPicker.NavigationBehavior.WithAnimation); else if (sender === this._nextMonthButton) this.calendarPicker.setCurrentMonth( - this.calendarPicker.currentMonth().next(), CalendarPicker.NavigationBehavior.WithAnimation); + this.calendarPicker.currentMonth().next(), + CalendarPicker.NavigationBehavior.WithAnimation); else this.calendarPicker.selectRangeContainingDay(Day.createFromToday()); }; @@ -3095,19 +3256,24 @@ CalendarHeaderView.prototype.setDisabled = function(disabled) { this.disabled = disabled; if (global.params.isFormControlsRefreshEnabled) { - this._previousMonthButton.element.style.visibility = this.disabled ? 'hidden' : 'visible'; - this._nextMonthButton.element.style.visibility = this.disabled ? 'hidden' : 'visible'; + this._previousMonthButton.element.style.visibility = + this.disabled ? 'hidden' : 'visible'; + this._nextMonthButton.element.style.visibility = + this.disabled ? 'hidden' : 'visible'; } this.monthPopupButton.element.disabled = this.disabled; this._previousMonthButton.setDisabled( - this.disabled || this.calendarPicker.currentMonth() <= this.calendarPicker.minimumMonth); + this.disabled || + this.calendarPicker.currentMonth() <= this.calendarPicker.minimumMonth); this._nextMonthButton.setDisabled( - this.disabled || this.calendarPicker.currentMonth() >= this.calendarPicker.maximumMonth); + this.disabled || + this.calendarPicker.currentMonth() >= this.calendarPicker.maximumMonth); if (this._todayButton) { var monthContainingToday = Month.createFromToday(); this._todayButton.setDisabled( - this.disabled || monthContainingToday < this.calendarPicker.minimumMonth || + this.disabled || + monthContainingToday < this.calendarPicker.minimumMonth || monthContainingToday > this.calendarPicker.maximumMonth); } }; @@ -3121,7 +3287,8 @@ this.element.classList.add(DayCell.ClassNameDayCell); this.element.style.width = DayCell.GetWidth() + 'px'; this.element.style.height = DayCell.GetHeight() + 'px'; - this.element.style.lineHeight = (DayCell.GetHeight() - DayCell.PaddingSize * 2) + 'px'; + this.element.style.lineHeight = + (DayCell.GetHeight() - DayCell.PaddingSize * 2) + 'px'; this.element.setAttribute('role', 'gridcell'); /** * @type {?Day} @@ -3138,7 +3305,7 @@ return DayCell._WidthRefresh; } return DayCell._Width; -} +}; DayCell._Height = hasInaccuratePointingDevice() ? 34 : 20; DayCell._HeightRefresh = 28; DayCell.GetHeight = function() { @@ -3146,7 +3313,7 @@ return DayCell._HeightRefresh; } return DayCell._Height; -} +}; DayCell.PaddingSize = 1; DayCell.ClassNameDayCell = 'day-cell'; DayCell.ClassNameHighlighted = 'highlighted'; @@ -3237,9 +3404,11 @@ function WeekNumberCell() { ListCell.call(this); this.element.classList.add(WeekNumberCell.ClassNameWeekNumberCell); - this.element.style.width = (WeekNumberCell.Width - WeekNumberCell.SeparatorWidth) + 'px'; + this.element.style.width = + (WeekNumberCell.Width - WeekNumberCell.SeparatorWidth) + 'px'; this.element.style.height = WeekNumberCell.GetHeight() + 'px'; - this.element.style.lineHeight = (WeekNumberCell.GetHeight() - WeekNumberCell.PaddingSize * 2) + 'px'; + this.element.style.lineHeight = + (WeekNumberCell.GetHeight() - WeekNumberCell.PaddingSize * 2) + 'px'; /** * @type {?Week} */ @@ -3256,7 +3425,7 @@ return WeekNumberCell._HeightRefresh; } return WeekNumberCell._Height; -} +}; WeekNumberCell.SeparatorWidth = 1; WeekNumberCell.PaddingSize = 1; WeekNumberCell.ClassNameWeekNumberCell = 'week-number-cell'; @@ -3288,7 +3457,9 @@ this.element.id = week.toString(); this.element.setAttribute('role', 'gridcell'); this.element.setAttribute( - 'aria-label', window.pagePopupController.formatWeek(week.year, week.week, week.firstDay().format())); + 'aria-label', + window.pagePopupController.formatWeek( + week.year, week.week, week.firstDay().format())); this.element.textContent = localizeNumber(this.week.week.toString()); this.show(); }; @@ -3326,13 +3497,15 @@ function CalendarTableHeaderView(hasWeekNumberColumn) { View.call(this, createElement('div', 'calendar-table-header-view')); if (hasWeekNumberColumn) { - var weekNumberLabelElement = createElement('div', 'week-number-label', global.params.weekLabel); + var weekNumberLabelElement = + createElement('div', 'week-number-label', global.params.weekLabel); weekNumberLabelElement.style.width = WeekNumberCell.Width + 'px'; this.element.appendChild(weekNumberLabelElement); } for (var i = 0; i < DaysPerWeek; ++i) { var weekDayNumber = (global.params.weekStartDay + i) % DaysPerWeek; - var labelElement = createElement('div', 'week-day-label', global.params.dayLabels[weekDayNumber]); + var labelElement = createElement( + 'div', 'week-day-label', global.params.dayLabels[weekDayNumber]); labelElement.style.width = DayCell.GetWidth() + 'px'; this.element.appendChild(labelElement); if (getLanguage() === 'ja') { @@ -3353,7 +3526,7 @@ return CalendarTableHeaderView._HeightRefresh; } return CalendarTableHeaderView._Height; -} +}; /** * @constructor @@ -3389,7 +3562,7 @@ return CalendarRowCell._HeightRefresh; } return CalendarRowCell._Height; -} +}; CalendarRowCell.ClassNameCalendarRowCell = 'calendar-row-cell'; CalendarRowCell._recycleBin = []; @@ -3432,7 +3605,8 @@ ListCell.prototype.throwAway.call(this); if (this.weekNumberCell) this.calendarTableView.throwAwayWeekNumberCell(this.weekNumberCell); - this._dayCells.forEach(this.calendarTableView.throwAwayDayCell, this.calendarTableView); + this._dayCells.forEach( + this.calendarTableView.throwAwayDayCell, this.calendarTableView); this._dayCells.length = 0; }; @@ -3471,9 +3645,11 @@ */ var todayButton = new CalendarNavigationButton(); todayButton.attachTo(this); - todayButton.on(CalendarNavigationButton.EventTypeButtonClick, this.onTodayButtonClick); + todayButton.on( + CalendarNavigationButton.EventTypeButtonClick, this.onTodayButtonClick); todayButton.element.textContent = global.params.todayLabel; - todayButton.element.classList.add(CalendarHeaderView.GetClassNameTodayButton()); + todayButton.element.classList.add( + CalendarHeaderView.GetClassNameTodayButton()); var monthContainingToday = Month.createFromToday(); todayButton.setDisabled( monthContainingToday < this.calendarPicker.minimumMonth || @@ -3504,9 +3680,11 @@ this.element.addEventListener('mouseout', this.onMouseOut, false); // You shouldn't be able to use the mouse wheel to scroll. - this.scrollView.element.removeEventListener('mousewheel', this.scrollView.onMouseWheel, false); + this.scrollView.element.removeEventListener( + 'mousewheel', this.scrollView.onMouseWheel, false); // You shouldn't be able to do gesture scroll. - this.scrollView.element.removeEventListener('touchstart', this.scrollView.onTouchStart, false); + this.scrollView.element.removeEventListener( + 'touchstart', this.scrollView.onTouchStart, false); } CalendarTableView.prototype = Object.create(ListView.prototype); @@ -3518,7 +3696,7 @@ return CalendarTableView._BorderWidthRefresh; } return CalendarTableView._BorderWidth; -} +}; CalendarTableView._TodayButtonHeight = 0; CalendarTableView._TodayButtonHeightRefresh = 28; CalendarTableView.GetTodayButtonHeight = function() { @@ -3526,7 +3704,7 @@ return CalendarTableView._TodayButtonHeightRefresh; } return CalendarTableView._TodayButtonHeight; -} +}; CalendarTableView.ClassNameCalendarTableView = 'calendar-table-view'; /** @@ -3550,14 +3728,17 @@ */ CalendarTableView.prototype.onClick = function(event) { if (this.hasWeekNumberColumn) { - var weekNumberCellElement = enclosingNodeOrSelfWithClass(event.target, WeekNumberCell.ClassNameWeekNumberCell); + var weekNumberCellElement = enclosingNodeOrSelfWithClass( + event.target, WeekNumberCell.ClassNameWeekNumberCell); if (weekNumberCellElement) { var weekNumberCell = weekNumberCellElement.$view; - this.calendarPicker.selectRangeContainingDay(weekNumberCell.week.firstDay()); + this.calendarPicker.selectRangeContainingDay( + weekNumberCell.week.firstDay()); return; } } - var dayCellElement = enclosingNodeOrSelfWithClass(event.target, DayCell.ClassNameDayCell); + var dayCellElement = + enclosingNodeOrSelfWithClass(event.target, DayCell.ClassNameDayCell); if (!dayCellElement) return; var dayCell = dayCellElement.$view; @@ -3566,22 +3747,25 @@ CalendarTableView.prototype.onTodayButtonClick = function(sender) { this.calendarPicker.selectRangeContainingDay(Day.createFromToday()); -} +}; /** * @param {?Event} event */ CalendarTableView.prototype.onMouseOver = function(event) { if (this.hasWeekNumberColumn) { - var weekNumberCellElement = enclosingNodeOrSelfWithClass(event.target, WeekNumberCell.ClassNameWeekNumberCell); + var weekNumberCellElement = enclosingNodeOrSelfWithClass( + event.target, WeekNumberCell.ClassNameWeekNumberCell); if (weekNumberCellElement) { var weekNumberCell = weekNumberCellElement.$view; - this.calendarPicker.highlightRangeContainingDay(weekNumberCell.week.firstDay()); + this.calendarPicker.highlightRangeContainingDay( + weekNumberCell.week.firstDay()); this._ignoreMouseOutUntillNextMouseOver = false; return; } } - var dayCellElement = enclosingNodeOrSelfWithClass(event.target, DayCell.ClassNameDayCell); + var dayCellElement = + enclosingNodeOrSelfWithClass(event.target, DayCell.ClassNameDayCell); if (!dayCellElement) return; var dayCell = dayCellElement.$view; @@ -3595,7 +3779,8 @@ CalendarTableView.prototype.onMouseOut = function(event) { if (this._ignoreMouseOutUntillNextMouseOver) return; - var dayCellElement = enclosingNodeOrSelfWithClass(event.target, DayCell.ClassNameDayCell); + var dayCellElement = + enclosingNodeOrSelfWithClass(event.target, DayCell.ClassNameDayCell); if (!dayCellElement) { this.calendarPicker.highlightRangeContainingDay(null); } @@ -3615,14 +3800,19 @@ * @return {!number} Height in pixels. */ CalendarTableView.prototype.height = function() { - return this.scrollView.height() + CalendarTableHeaderView.GetHeight() + CalendarTableView.GetBorderWidth() * 2 + CalendarTableView.GetTodayButtonHeight(); + return this.scrollView.height() + CalendarTableHeaderView.GetHeight() + + CalendarTableView.GetBorderWidth() * 2 + + CalendarTableView.GetTodayButtonHeight(); }; /** * @param {!number} height Height in pixels. */ CalendarTableView.prototype.setHeight = function(height) { - this.scrollView.setHeight(height - CalendarTableHeaderView.GetHeight() - CalendarTableView.GetBorderWidth() * 2 - CalendarTableView.GetTodayButtonHeight()); + this.scrollView.setHeight( + height - CalendarTableHeaderView.GetHeight() - + CalendarTableView.GetBorderWidth() * 2 - + CalendarTableView.GetTodayButtonHeight()); if (global.params.isFormControlsRefreshEnabled) { this.element.style.height = height + 'px'; } @@ -3634,7 +3824,8 @@ */ CalendarTableView.prototype.scrollToMonth = function(month, animate) { var rowForFirstDayInMonth = this.columnAndRowForDay(month.firstDay()).row; - this.scrollView.scrollTo(this.scrollOffsetForRow(rowForFirstDayInMonth), animate); + this.scrollView.scrollTo( + this.scrollOffsetForRow(rowForFirstDayInMonth), animate); }; /** @@ -3643,8 +3834,11 @@ * @return {!Day} */ CalendarTableView.prototype.dayAtColumnAndRow = function(column, row) { - var daysSinceMinimum = row * DaysPerWeek + column + global.params.weekStartDay - CalendarTableView._MinimumDayWeekDay; - return Day.createFromValue(daysSinceMinimum * MillisecondsPerDay + CalendarTableView._MinimumDayValue); + var daysSinceMinimum = row * DaysPerWeek + column + + global.params.weekStartDay - CalendarTableView._MinimumDayWeekDay; + return Day.createFromValue( + daysSinceMinimum * MillisecondsPerDay + + CalendarTableView._MinimumDayValue); }; CalendarTableView._MinimumDayValue = Day.Minimum.valueOf(); @@ -3655,8 +3849,10 @@ * @return {!Object} Object with properties column and row. */ CalendarTableView.prototype.columnAndRowForDay = function(day) { - var daysSinceMinimum = (day.valueOf() - CalendarTableView._MinimumDayValue) / MillisecondsPerDay; - var offset = daysSinceMinimum + CalendarTableView._MinimumDayWeekDay - global.params.weekStartDay; + var daysSinceMinimum = + (day.valueOf() - CalendarTableView._MinimumDayValue) / MillisecondsPerDay; + var offset = daysSinceMinimum + CalendarTableView._MinimumDayWeekDay - + global.params.weekStartDay; var row = Math.floor(offset / DaysPerWeek); var column = offset - row * DaysPerWeek; return {column: column, row: row}; @@ -3693,16 +3889,19 @@ var dayCell = this._dayCells[dayString]; var day = dayCell.day; dayCell.setIsToday(Day.createFromToday().equals(day)); - dayCell.setSelected(day >= firstDayInSelection && day <= lastDayInSelection); + dayCell.setSelected( + day >= firstDayInSelection && day <= lastDayInSelection); var isHighlighted = day >= firstDayInHighlight && day <= lastDayInHighlight; dayCell.setHighlighted(isHighlighted); if (isHighlighted) { if (firstDayInHighlight == lastDayInHighlight) activeCell = dayCell; - else if (this.calendarPicker.type == 'month' && day == firstDayInHighlight) + else if ( + this.calendarPicker.type == 'month' && day == firstDayInHighlight) activeCell = dayCell; } - dayCell.setIsInCurrentMonth(day >= firstDayInCurrentMonth && day <= lastDayInCurrentMonth); + dayCell.setIsInCurrentMonth( + day >= firstDayInCurrentMonth && day <= lastDayInCurrentMonth); dayCell.setDisabled(!this.calendarPicker.isValidDay(day)); } if (this.hasWeekNumberColumn) { @@ -3734,7 +3933,8 @@ var dayCell = DayCell.recycleOrCreate(); dayCell.reset(day); if (this.calendarPicker.type == 'month') - dayCell.element.setAttribute('aria-label', Month.createFromDay(day).toLocaleString()); + dayCell.element.setAttribute( + 'aria-label', Month.createFromDay(day).toLocaleString()); this._dayCells[dayCell.day.toString()] = dayCell; return dayCell; }; @@ -3815,15 +4015,19 @@ * @const */ this.calendarHeaderView = new CalendarHeaderView(this); - this.calendarHeaderView.monthPopupButton.on(MonthPopupButton.EventTypeButtonClick, this.onMonthPopupButtonClick); + this.calendarHeaderView.monthPopupButton.on( + MonthPopupButton.EventTypeButtonClick, this.onMonthPopupButtonClick); /** * @type {!MonthPopupView} * @const */ - this.monthPopupView = new MonthPopupView(this.minimumMonth, this.maximumMonth); + this.monthPopupView = + new MonthPopupView(this.minimumMonth, this.maximumMonth); this.monthPopupView.yearListView.on( - YearListView.EventTypeYearListViewDidSelectMonth, this.onYearListViewDidSelectMonth); - this.monthPopupView.yearListView.on(YearListView.EventTypeYearListViewDidHide, this.onYearListViewDidHide); + YearListView.EventTypeYearListViewDidSelectMonth, + this.onYearListViewDidSelectMonth); + this.monthPopupView.yearListView.on( + YearListView.EventTypeYearListViewDidHide, this.onYearListViewDidHide); this.calendarHeaderView.attachTo(this); this.calendarTableView.attachTo(this); /** @@ -3841,7 +4045,8 @@ * @protected */ this._highlight = null; - this.calendarTableView.element.addEventListener('keydown', this.onCalendarTableKeyDown, false); + this.calendarTableView.element.addEventListener( + 'keydown', this.onCalendarTableKeyDown, false); document.body.addEventListener('keydown', this.onBodyKeyDown, false); window.addEventListener('resize', this.onWindowResize, false); @@ -3854,10 +4059,13 @@ var initialSelection = parseDateString(config.currentValue); if (initialSelection) { - this.setCurrentMonth(Month.createFromDay(initialSelection.middleDay()), CalendarPicker.NavigationBehavior.None); + this.setCurrentMonth( + Month.createFromDay(initialSelection.middleDay()), + CalendarPicker.NavigationBehavior.None); this.setSelection(initialSelection); } else - this.setCurrentMonth(Month.createFromToday(), CalendarPicker.NavigationBehavior.None); + this.setCurrentMonth( + Month.createFromToday(), CalendarPicker.NavigationBehavior.None); } CalendarPicker.prototype = Object.create(View.prototype); @@ -3895,7 +4103,8 @@ * @param {!YearListView} sender * @param {!Month} month */ -CalendarPicker.prototype.onYearListViewDidSelectMonth = function(sender, month) { +CalendarPicker.prototype.onYearListViewDidSelectMonth = function( + sender, month) { this.setCurrentMonth(month, CalendarPicker.NavigationBehavior.None); }; @@ -3911,7 +4120,8 @@ CalendarPicker.prototype.cleanup = function() { window.removeEventListener('resize', this.onWindowResize, false); - this.calendarTableView.element.removeEventListener('keydown', this.onBodyKeyDown, false); + this.calendarTableView.element.removeEventListener( + 'keydown', this.onBodyKeyDown, false); // Month popup view might be attached to document.body. this.monthPopupView.hide(); }; @@ -3922,7 +4132,8 @@ CalendarPicker.prototype.onMonthPopupButtonClick = function(sender) { var clientRect = this.calendarTableView.element.getBoundingClientRect(); var calendarTableRect = new Rectangle( - clientRect.left + document.body.scrollLeft, clientRect.top + document.body.scrollTop, clientRect.width, + clientRect.left + document.body.scrollLeft, + clientRect.top + document.body.scrollTop, clientRect.width, clientRect.height); this.monthPopupView.show(this.currentMonth(), calendarTableRect); this.calendarHeaderView.setDisabled(true); @@ -3934,15 +4145,20 @@ }; CalendarPicker.prototype._setConfig = function(config) { - this.config.minimum = (typeof config.min !== 'undefined' && config.min) ? parseDateString(config.min) : - this._dateTypeConstructor.Minimum; - this.config.maximum = (typeof config.max !== 'undefined' && config.max) ? parseDateString(config.max) : - this._dateTypeConstructor.Maximum; + this.config.minimum = (typeof config.min !== 'undefined' && config.min) ? + parseDateString(config.min) : + this._dateTypeConstructor.Minimum; + this.config.maximum = (typeof config.max !== 'undefined' && config.max) ? + parseDateString(config.max) : + this._dateTypeConstructor.Maximum; this.config.minimumValue = this.config.minimum.valueOf(); this.config.maximumValue = this.config.maximum.valueOf(); - this.config.step = (typeof config.step !== undefined) ? Number(config.step) : this._dateTypeConstructor.DefaultStep; - this.config.stepBase = - (typeof config.stepBase !== 'undefined') ? Number(config.stepBase) : this._dateTypeConstructor.DefaultStepBase; + this.config.step = (typeof config.step !== undefined) ? + Number(config.step) : + this._dateTypeConstructor.DefaultStep; + this.config.stepBase = (typeof config.stepBase !== 'undefined') ? + Number(config.stepBase) : + this._dateTypeConstructor.DefaultStepBase; }; /** @@ -3973,21 +4189,34 @@ return; this._currentMonth = month; this.calendarTableView.scrollToMonth( - this._currentMonth, behavior === CalendarPicker.NavigationBehavior.WithAnimation); + this._currentMonth, + behavior === CalendarPicker.NavigationBehavior.WithAnimation); this.adjustHeight(); this.calendarTableView.setNeedsUpdateCells(true); - this.dispatchEvent(CalendarPicker.EventTypeCurrentMonthChanged, {target: this}); + this.dispatchEvent( + CalendarPicker.EventTypeCurrentMonthChanged, {target: this}); }; CalendarPicker.prototype.adjustHeight = function() { - var rowForFirstDayInMonth = this.calendarTableView.columnAndRowForDay(this._currentMonth.firstDay()).row; - var rowForLastDayInMonth = this.calendarTableView.columnAndRowForDay(this._currentMonth.lastDay()).row; - var numberOfRows = global.params.isFormControlsRefreshEnabled ? CalendarPicker.VisibleRowsRefresh : rowForLastDayInMonth - rowForFirstDayInMonth + 1; - var calendarTableViewHeight = - CalendarTableHeaderView.GetHeight() + numberOfRows * DayCell.GetHeight() + CalendarTableView.GetBorderWidth() * 2 + CalendarTableView.GetTodayButtonHeight(); - var height = (this.monthPopupView.isVisible && !global.params.isFormControlsRefreshEnabled ? YearListView.GetHeight() : calendarTableViewHeight) + - CalendarHeaderView.Height + CalendarHeaderView.BottomMargin + CalendarPicker.Padding * 2 + - CalendarPicker.BorderWidth * 2; + var rowForFirstDayInMonth = + this.calendarTableView.columnAndRowForDay(this._currentMonth.firstDay()) + .row; + var rowForLastDayInMonth = + this.calendarTableView.columnAndRowForDay(this._currentMonth.lastDay()) + .row; + var numberOfRows = global.params.isFormControlsRefreshEnabled ? + CalendarPicker.VisibleRowsRefresh : + rowForLastDayInMonth - rowForFirstDayInMonth + 1; + var calendarTableViewHeight = CalendarTableHeaderView.GetHeight() + + numberOfRows * DayCell.GetHeight() + + CalendarTableView.GetBorderWidth() * 2 + + CalendarTableView.GetTodayButtonHeight(); + var height = (this.monthPopupView.isVisible && + !global.params.isFormControlsRefreshEnabled ? + YearListView.GetHeight() : + calendarTableViewHeight) + + CalendarHeaderView.Height + CalendarHeaderView.BottomMargin + + CalendarPicker.Padding * 2 + CalendarPicker.BorderWidth * 2; this.setHeight(height); }; @@ -4003,8 +4232,11 @@ * @return {!Day} */ CalendarPicker.prototype.firstVisibleDay = function() { - var firstVisibleRow = this.calendarTableView.columnAndRowForDay(this.currentMonth().firstDay()).row; - var firstVisibleDay = this.calendarTableView.dayAtColumnAndRow(0, firstVisibleRow); + var firstVisibleRow = + this.calendarTableView.columnAndRowForDay(this.currentMonth().firstDay()) + .row; + var firstVisibleDay = + this.calendarTableView.dayAtColumnAndRow(0, firstVisibleRow); if (!firstVisibleDay) firstVisibleDay = Day.Minimum; return firstVisibleDay; @@ -4014,11 +4246,17 @@ * @return {!Day} */ CalendarPicker.prototype.lastVisibleDay = function() { - var lastVisibleRow = this.calendarTableView.columnAndRowForDay(this.currentMonth().lastDay()).row; + var lastVisibleRow = + this.calendarTableView.columnAndRowForDay(this.currentMonth().lastDay()) + .row; if (global.params.isFormControlsRefreshEnabled) { - lastVisibleRow = this.calendarTableView.columnAndRowForDay(this.currentMonth().firstDay()).row + CalendarPicker.VisibleRowsRefresh - 1; + lastVisibleRow = this.calendarTableView + .columnAndRowForDay(this.currentMonth().firstDay()) + .row + + CalendarPicker.VisibleRowsRefresh - 1; } - var lastVisibleDay = this.calendarTableView.dayAtColumnAndRow(DaysPerWeek - 1, lastVisibleRow); + var lastVisibleDay = + this.calendarTableView.dayAtColumnAndRow(DaysPerWeek - 1, lastVisibleRow); if (!lastVisibleDay) lastVisibleDay = Day.Maximum; return lastVisibleDay; @@ -4052,24 +4290,40 @@ var firstDayInSelection = dayOrWeekOrMonth.firstDay(); var lastDayInSelection = dayOrWeekOrMonth.lastDay(); var candidateCurrentMonth = Month.createFromDay(firstDayInSelection); - if (this.firstVisibleDay() > lastDayInSelection || this.lastVisibleDay() < firstDayInSelection) { + if (this.firstVisibleDay() > lastDayInSelection || + this.lastVisibleDay() < firstDayInSelection) { // Change current month if the selection is not visible at all. - this.setCurrentMonth(candidateCurrentMonth, CalendarPicker.NavigationBehavior.WithAnimation); - } else if (this.firstVisibleDay() < firstDayInSelection || this.lastVisibleDay() > lastDayInSelection) { + this.setCurrentMonth( + candidateCurrentMonth, CalendarPicker.NavigationBehavior.WithAnimation); + } else if ( + this.firstVisibleDay() < firstDayInSelection || + this.lastVisibleDay() > lastDayInSelection) { // If the selection is partly visible, only change the current month if // doing so will make the whole selection visible. - var firstVisibleRow = this.calendarTableView.columnAndRowForDay(candidateCurrentMonth.firstDay()).row; - var firstVisibleDay = this.calendarTableView.dayAtColumnAndRow(0, firstVisibleRow); - var lastVisibleRow = this.calendarTableView.columnAndRowForDay(candidateCurrentMonth.lastDay()).row; - var lastVisibleDay = this.calendarTableView.dayAtColumnAndRow(DaysPerWeek - 1, lastVisibleRow); - if (firstDayInSelection >= firstVisibleDay && lastDayInSelection <= lastVisibleDay) - this.setCurrentMonth(candidateCurrentMonth, CalendarPicker.NavigationBehavior.WithAnimation); + var firstVisibleRow = + this.calendarTableView + .columnAndRowForDay(candidateCurrentMonth.firstDay()) + .row; + var firstVisibleDay = + this.calendarTableView.dayAtColumnAndRow(0, firstVisibleRow); + var lastVisibleRow = + this.calendarTableView + .columnAndRowForDay(candidateCurrentMonth.lastDay()) + .row; + var lastVisibleDay = this.calendarTableView.dayAtColumnAndRow( + DaysPerWeek - 1, lastVisibleRow); + if (firstDayInSelection >= firstVisibleDay && + lastDayInSelection <= lastVisibleDay) + this.setCurrentMonth( + candidateCurrentMonth, + CalendarPicker.NavigationBehavior.WithAnimation); } this._setHighlight(dayOrWeekOrMonth); if (!this.isValid(dayOrWeekOrMonth)) return; this._selection = dayOrWeekOrMonth; - this.monthPopupView.yearListView.setSelectedMonth(Month.createFromDay(dayOrWeekOrMonth.middleDay())); + this.monthPopupView.yearListView.setSelectedMonth( + Month.createFromDay(dayOrWeekOrMonth.middleDay())); this.calendarTableView.setNeedsUpdateCells(true); }; @@ -4116,7 +4370,9 @@ */ CalendarPicker.prototype._stepMismatch = function(value) { var nextAllowedValue = - Math.ceil((value - this.config.stepBase) / this.config.step) * this.config.step + this.config.stepBase; + Math.ceil((value - this.config.stepBase) / this.config.step) * + this.config.step + + this.config.stepBase; return nextAllowedValue >= value + this._dateTypeConstructor.DefaultStep; }; @@ -4134,8 +4390,8 @@ */ CalendarPicker.prototype.isValid = function(dayOrWeekOrMonth) { var value = dayOrWeekOrMonth.valueOf(); - return dayOrWeekOrMonth instanceof this._dateTypeConstructor && !this._outOfRange(value) && - !this._stepMismatch(value); + return dayOrWeekOrMonth instanceof this._dateTypeConstructor && + !this._outOfRange(value) && !this._stepMismatch(value); }; /** @@ -4155,8 +4411,11 @@ return false; if (this._outOfRange(dateRange.valueOf())) return false; - if (this.firstVisibleDay() > dateRange.middleDay() || this.lastVisibleDay() < dateRange.middleDay()) - this.setCurrentMonth(Month.createFromDay(dateRange.middleDay()), CalendarPicker.NavigationBehavior.WithAnimation); + if (this.firstVisibleDay() > dateRange.middleDay() || + this.lastVisibleDay() < dateRange.middleDay()) + this.setCurrentMonth( + Month.createFromDay(dateRange.middleDay()), + CalendarPicker.NavigationBehavior.WithAnimation); this._setHighlight(dateRange); return true; }; @@ -4173,28 +4432,35 @@ } else if (key == 'PageUp') { var previousMonth = this.currentMonth().previous(); if (previousMonth && previousMonth >= this.config.minimumValue) { - this.setCurrentMonth(previousMonth, CalendarPicker.NavigationBehavior.WithAnimation); + this.setCurrentMonth( + previousMonth, CalendarPicker.NavigationBehavior.WithAnimation); eventHandled = true; } } else if (key == 'PageDown') { var nextMonth = this.currentMonth().next(); if (nextMonth && nextMonth >= this.config.minimumValue) { - this.setCurrentMonth(nextMonth, CalendarPicker.NavigationBehavior.WithAnimation); + this.setCurrentMonth( + nextMonth, CalendarPicker.NavigationBehavior.WithAnimation); eventHandled = true; } } else if (this._highlight) { if (global.params.isLocaleRTL ? key == 'ArrowRight' : key == 'ArrowLeft') { eventHandled = this._moveHighlight(this._highlight.previous()); } else if (key == 'ArrowUp') { - eventHandled = this._moveHighlight(this._highlight.previous(this.type === 'date' ? DaysPerWeek : 1)); - } else if (global.params.isLocaleRTL ? key == 'ArrowLeft' : key == 'ArrowRight') { + eventHandled = this._moveHighlight( + this._highlight.previous(this.type === 'date' ? DaysPerWeek : 1)); + } else if ( + global.params.isLocaleRTL ? key == 'ArrowLeft' : key == 'ArrowRight') { eventHandled = this._moveHighlight(this._highlight.next()); } else if (key == 'ArrowDown') { - eventHandled = this._moveHighlight(this._highlight.next(this.type === 'date' ? DaysPerWeek : 1)); + eventHandled = this._moveHighlight( + this._highlight.next(this.type === 'date' ? DaysPerWeek : 1)); } else if (key == 'Enter') { this.setSelectionAndCommit(this._highlight); } - } else if (key == 'ArrowLeft' || key == 'ArrowUp' || key == 'ArrowRight' || key == 'ArrowDown') { + } else if ( + key == 'ArrowLeft' || key == 'ArrowUp' || key == 'ArrowRight' || + key == 'ArrowDown') { // Highlight range near the middle. this.highlightRangeContainingDay(this.currentMonth().middleDay()); eventHandled = true; @@ -4211,7 +4477,9 @@ */ CalendarPicker.prototype.width = function() { return this.calendarTableView.width() + - (CalendarTableView.GetBorderWidth() + CalendarPicker.BorderWidth + CalendarPicker.Padding) * 2; + (CalendarTableView.GetBorderWidth() + CalendarPicker.BorderWidth + + CalendarPicker.Padding) * + 2; }; /** @@ -4230,7 +4498,8 @@ this._height = height; resizeWindow(this.width(), this._height); this.calendarTableView.setHeight( - this._height - CalendarHeaderView.Height - CalendarHeaderView.BottomMargin - CalendarPicker.Padding * 2 - + this._height - CalendarHeaderView.Height - + CalendarHeaderView.BottomMargin - CalendarPicker.Padding * 2 - CalendarPicker.BorderWidth * 2); }; @@ -4255,15 +4524,22 @@ case 'd': case 'D': offset = offset || MonthsPerYear * 10; - var oldFirstVisibleRow = this.calendarTableView.columnAndRowForDay(this.currentMonth().firstDay()).row; + var oldFirstVisibleRow = + this.calendarTableView + .columnAndRowForDay(this.currentMonth().firstDay()) + .row; this.setCurrentMonth( - event.shiftKey ? this.currentMonth().previous(offset) : this.currentMonth().next(offset), + event.shiftKey ? this.currentMonth().previous(offset) : + this.currentMonth().next(offset), CalendarPicker.NavigationBehavior.WithAnimation); - var newFirstVisibleRow = this.calendarTableView.columnAndRowForDay(this.currentMonth().firstDay()).row; + var newFirstVisibleRow = + this.calendarTableView + .columnAndRowForDay(this.currentMonth().firstDay()) + .row; if (this._highlight) { var highlightMiddleDay = this._highlight.middleDay(); - this.highlightRangeContainingDay( - highlightMiddleDay.next((newFirstVisibleRow - oldFirstVisibleRow) * DaysPerWeek)); + this.highlightRangeContainingDay(highlightMiddleDay.next( + (newFirstVisibleRow - oldFirstVisibleRow) * DaysPerWeek)); } eventHandled = true; break;
diff --git a/third_party/blink/renderer/core/html/forms/resources/colorSuggestionPicker.js b/third_party/blink/renderer/core/html/forms/resources/colorSuggestionPicker.js index 15c60eb0..43698c0 100644 --- a/third_party/blink/renderer/core/html/forms/resources/colorSuggestionPicker.js +++ b/third_party/blink/renderer/core/html/forms/resources/colorSuggestionPicker.js
@@ -35,7 +35,7 @@ */ function validateColorSuggestionPickerArguments(args) { if (!args.shouldShowColorSuggestionPicker) - return 'Should not be showing the color suggestion picker.' + return 'Should not be showing the color suggestion picker.'; if (!args.values) return 'No values.'; if (!args.otherColorLabel) @@ -70,7 +70,8 @@ ColorSuggestionPicker.prototype._layout = function() { var container = createElement('div', 'color-swatch-container'); - container.addEventListener('click', this._handleSwatchClick.bind(this), false); + container.addEventListener( + 'click', this._handleSwatchClick.bind(this), false); for (var i = 0; i < this._config.values.length; ++i) { var swatch = createElement('button', 'color-swatch'); swatch.dataset.index = i; @@ -85,8 +86,10 @@ container.style.width = containerWidth + 'px'; container.style.maxHeight = (SwatchBorderBoxHeight * SwatchesMaxRow) + 'px'; this._element.appendChild(container); - var otherButton = createElement('button', 'other-color', this._config.otherColorLabel); - otherButton.addEventListener('click', this._onOtherButtonClick.bind(this), false); + var otherButton = + createElement('button', 'other-color', this._config.otherColorLabel); + otherButton.addEventListener( + 'click', this._onOtherButtonClick.bind(this), false); this._element.appendChild(otherButton); this._container = container; this._otherButton = otherButton; @@ -109,7 +112,7 @@ } else { this.chooseOtherColor(); } -} +}; ColorSuggestionPicker.prototype.selectColorAtIndex = function(index) { index = Math.max(Math.min(this._container.childNodes.length - 1, index), 0); @@ -131,7 +134,9 @@ var key = event.key; if (key === 'Escape') this.handleCancel(); - else if (key == 'ArrowLeft' || key == 'ArrowUp' || key == 'ArrowRight' || key == 'ArrowDown') { + else if ( + key == 'ArrowLeft' || key == 'ArrowUp' || key == 'ArrowRight' || + key == 'ArrowDown') { var selectedElement = document.activeElement; var index = 0; if (selectedElement.classList.contains('other-color')) {
diff --git a/third_party/blink/renderer/core/html/forms/resources/color_picker.js b/third_party/blink/renderer/core/html/forms/resources/color_picker.js index 8b7ce346..c09fad5 100644 --- a/third_party/blink/renderer/core/html/forms/resources/color_picker.js +++ b/third_party/blink/renderer/core/html/forms/resources/color_picker.js
@@ -23,7 +23,7 @@ */ function validateColorPickerArguments(args) { if (args.shouldShowColorSuggestionPicker) - return 'Should be showing the color suggestion picker.' + return 'Should be showing the color suggestion picker.'; if (!args.selectedColor) return 'No selectedColor.'; return null; @@ -83,15 +83,17 @@ colorStringOrFormat = colorStringOrFormat.replace(/\s+/g, ''); [this.rValue_, this.gValue_, this.bValue_] = colorStringOrFormat.substring(4, colorStringOrFormat.length - 1) - .split(',').map(Number); + .split(',') + .map(Number); } else if (colorStringOrFormat.startsWith('hsl')) { colorStringOrFormat = colorStringOrFormat.replace(/%|\s+/g, ''); [this.hValue_, this.sValue_, this.lValue_] = colorStringOrFormat.substring(4, colorStringOrFormat.length - 1) - .split(',').map(Number); + .split(',') + .map(Number); } } else { - switch(colorStringOrFormat) { + switch (colorStringOrFormat) { case ColorFormat.HEX: this.hexValue_ = colorValues[0].toLowerCase(); break; @@ -124,11 +126,9 @@ if (this.hexValue_ !== undefined) { // Already computed. } else if (this.rValue_ !== undefined) { - this.hexValue_ = - Color.rgbToHex(this.rValue_, this.gValue_, this.bValue_); + this.hexValue_ = Color.rgbToHex(this.rValue_, this.gValue_, this.bValue_); } else if (this.hValue_ !== undefined) { - this.hexValue_ = - Color.hslToHex(this.hValue_, this.sValue_, this.lValue_); + this.hexValue_ = Color.hslToHex(this.hValue_, this.sValue_, this.lValue_); } } @@ -231,7 +231,9 @@ static hexToRGB(hexValue) { // Ex. 'ffffff' => '[255,255,255]' const colorValue = parseInt(hexValue, 16); - return [(colorValue >> 16) & 255, (colorValue >> 8) & 255, colorValue & 255]; + return [ + (colorValue >> 16) & 255, (colorValue >> 8) & 255, colorValue & 255 + ]; } /** @@ -242,7 +244,7 @@ // Ex. '[255,255,255]' => 'ffffff' return rgbValues.reduce((cumulativeHexValue, rgbValue) => { let hexValue = Number(rgbValue).toString(16); - if(hexValue.length == 1) { + if (hexValue.length == 1) { hexValue = '0' + hexValue; } return (cumulativeHexValue + hexValue); @@ -357,9 +359,10 @@ * Both color triples must be of the same color format. */ static distance(colorTripleA, colorTripleB) { - return Math.sqrt(Math.pow(colorTripleA[0] - colorTripleB[0], 2) - + Math.pow(colorTripleA[1] - colorTripleB[1], 2) - + Math.pow(colorTripleA[2] - colorTripleB[2], 2)); + return Math.sqrt( + Math.pow(colorTripleA[0] - colorTripleB[0], 2) + + Math.pow(colorTripleA[1] - colorTripleB[1], 2) + + Math.pow(colorTripleA[2] - colorTripleB[2], 2)); } } @@ -425,15 +428,14 @@ this.visualColorPicker_ = new VisualColorPicker(initialColor); this.manualColorPicker_ = new ManualColorPicker(initialColor); - this.submissionControls_ = - new SubmissionControls(this.onSubmitButtonClick_, - this.onCancelButtonClick_); - this.append(this.visualColorPicker_, - this.manualColorPicker_, - this.submissionControls_); + this.submissionControls_ = new SubmissionControls( + this.onSubmitButtonClick_, this.onCancelButtonClick_); + this.append( + this.visualColorPicker_, this.manualColorPicker_, + this.submissionControls_); - this.visualColorPicker_.addEventListener('visual-color-picker-initialized', - this.initializeListeners_); + this.visualColorPicker_.addEventListener( + 'visual-color-picker-initialized', this.initializeListeners_); } initializeListeners_ = () => { @@ -519,11 +521,11 @@ window.setTimeout(function() { window.pagePopupController.setValueAndClosePopup(0, selectedValue); }, ColorPicker.COMMIT_DELAY_MS); - } + }; onCancelButtonClick_ = () => { window.pagePopupController.closePopup(); - } + }; } window.customElements.define('color-picker', ColorPicker); @@ -543,9 +545,8 @@ this.eyeDropper_ = new EyeDropper(); this.colorViewer_ = new ColorViewer(initialColor); this.hueSlider_ = new HueSlider(initialColor); - visualColorPickerStrip.append(this.eyeDropper_, - this.colorViewer_, - this.hueSlider_); + visualColorPickerStrip.append( + this.eyeDropper_, this.colorViewer_, this.hueSlider_); this.append(visualColorPickerStrip); this.colorWell_ = new ColorWell(initialColor); @@ -671,7 +672,7 @@ * implementation.) * TODO(http://crbug.com/992297): Implement eye dropper */ -class EyeDropper extends HTMLElement { } +class EyeDropper extends HTMLElement {} window.customElements.define('eye-dropper', EyeDropper); /** @@ -716,8 +717,10 @@ this.append(this.colorPalette_, this.colorSelectionRing_); this.initialized_ = false; - this.colorSelectionRing_.addEventListener('focus', this.onColorSelectionRingFocus_); - this.colorSelectionRing_.addEventListener('blur', this.onColorSelectionRingBlur_); + this.colorSelectionRing_.addEventListener( + 'focus', this.onColorSelectionRingFocus_); + this.colorSelectionRing_.addEventListener( + 'blur', this.onColorSelectionRingBlur_); } get initialized() { @@ -726,11 +729,11 @@ onColorSelectionRingFocus_ = () => { this.focused_ = true; - } + }; onColorSelectionRingBlur_ = () => { this.focused_ = false; - } + }; /** * @param {!Point} point @@ -800,14 +803,15 @@ get hslImageData() { if (this.pendingColorChange_) { - const rgbaImageData = this.renderingContext - .getImageData(0, 0, this.width, this.height).data; - this.hslImageData_ = rgbaImageData - .reduce((hslArray, {}, currentIndex, rgbaArray) => { + const rgbaImageData = + this.renderingContext.getImageData(0, 0, this.width, this.height) + .data; + this.hslImageData_ = + rgbaImageData.reduce((hslArray, {}, currentIndex, rgbaArray) => { if ((currentIndex % 4) === 0) { - hslArray.push(...Color.rgbToHSL(rgbaArray[currentIndex], - rgbaArray[currentIndex + 1], - rgbaArray[currentIndex + 2])); + hslArray.push(...Color.rgbToHSL( + rgbaArray[currentIndex], rgbaArray[currentIndex + 1], + rgbaArray[currentIndex + 2])); } return hslArray; }, []); @@ -832,8 +836,9 @@ colorAtPoint(point) { const hslImageDataAtPoint = this.hslImageDataAtPoint_(point.x - this.left, point.y - this.top); - return new Color(ColorFormat.HSL, hslImageDataAtPoint[0], - hslImageDataAtPoint[1], hslImageDataAtPoint[2]); + return new Color( + ColorFormat.HSL, hslImageDataAtPoint[0], hslImageDataAtPoint[1], + hslImageDataAtPoint[2]); } /** @@ -866,8 +871,9 @@ * @param {!Color} color */ fillHue(color) { - this.fillColor_ = new Color(ColorFormat.HSL, color.hValue, - this.fillColor_.sValue, this.fillColor_.lValue); + this.fillColor_ = new Color( + ColorFormat.HSL, color.hValue, this.fillColor_.sValue, + this.fillColor_.lValue); this.fillColorAndGradients_(); this.pendingHueChange_ = true; } @@ -937,9 +943,8 @@ return Math.ceil(this.getBoundingClientRect().bottom - 1); } } -window.customElements.define('color-palette', - ColorPalette, - { extends: 'canvas' }); +window.customElements.define( + 'color-palette', ColorPalette, {extends: 'canvas'}); /** * ColorSelectionRing: Provides movement and color selection functionality to @@ -1023,20 +1028,20 @@ setElementPosition_() { if (this.height > this.backingColorPalette_.height) { - this.style.top = this.top - - (this.height - this.backingColorPalette_.height) / 2 - - this.backingColorPalette_.top + 'px'; + this.style.top = this.top - + (this.height - this.backingColorPalette_.height) / 2 - + this.backingColorPalette_.top + 'px'; } else { - this.style.top = this.top - this.radius - - this.backingColorPalette_.top + 'px'; + this.style.top = + this.top - this.radius - this.backingColorPalette_.top + 'px'; } if (this.width > this.backingColorPalette_.width) { - this.style.left = this.left - - (this.width - this.backingColorPalette_.width) / 2 - - this.backingColorPalette_.left + 'px'; + this.style.left = this.left - + (this.width - this.backingColorPalette_.width) / 2 - + this.backingColorPalette_.left + 'px'; } else { - this.style.left = this.left - this.radius - - this.backingColorPalette_.left + 'px'; + this.style.left = + this.left - this.radius - this.backingColorPalette_.left + 'px'; } } @@ -1072,9 +1077,9 @@ * @param {bool} accelerated */ move(direction, accelerated) { - let shiftFactor = accelerated - ? ColorSelectionRing.ACCELERATED_MOVE_DISTANCE - : ColorSelectionRing.MOVE_DISTANCE; + let shiftFactor = accelerated ? + ColorSelectionRing.ACCELERATED_MOVE_DISTANCE : + ColorSelectionRing.MOVE_DISTANCE; if ((direction === Direction.UP) || (direction === Direction.LEFT)) { shiftFactor *= -1; } @@ -1087,13 +1092,13 @@ } } else { // direction === Direction.RIGHT - if (this.position_.x + shiftFactor > - this.backingColorPalette_.right) { + if (this.position_.x + shiftFactor > this.backingColorPalette_.right) { newX = this.backingColorPalette_.right; } } this.setX(newX); - } else if (this.canMoveVertically_ && + } else if ( + this.canMoveVertically_ && ((direction === Direction.UP) || (direction === Direction.DOWN))) { let newY = this.position_.y + shiftFactor; if (direction === Direction.UP) { @@ -1102,8 +1107,7 @@ } } else { // direction === Direction.DOWN - if (this.position_.y + shiftFactor > - this.backingColorPalette_.bottom) { + if (this.position_.y + shiftFactor > this.backingColorPalette_.bottom) { newY = this.backingColorPalette_.bottom; } } @@ -1159,20 +1163,22 @@ this.selectedColor_ = initialColor; this.resizeObserver_ = new ResizeObserver(() => { - let whiteGradient = this.colorPalette_.renderingContext - .createLinearGradient(0, 0, this.colorPalette_.offsetWidth, 0); + let whiteGradient = + this.colorPalette_.renderingContext.createLinearGradient( + 0, 0, this.colorPalette_.offsetWidth, 0); whiteGradient.addColorStop(0.01, 'hsla(0, 0%, 100%, 1)'); whiteGradient.addColorStop(0.99, 'hsla(0, 0%, 100%, 0)'); - let blackGradient = this.colorPalette_.renderingContext - .createLinearGradient(0, this.colorPalette_.offsetHeight, 0, 0); + let blackGradient = + this.colorPalette_.renderingContext.createLinearGradient( + 0, this.colorPalette_.offsetHeight, 0, 0); blackGradient.addColorStop(0.01, 'hsla(0, 0%, 0%, 1)'); blackGradient.addColorStop(0.99, 'hsla(0, 0%, 0%, 0)'); this.colorPalette_.initialize(whiteGradient, blackGradient); this.colorPalette_.fillHue(this.fillColor_); this.colorSelectionRing_.initialize(); - this.colorSelectionRing_.addEventListener('color-selection-ring-update', - this.onColorSelectionRingUpdate_); + this.colorSelectionRing_.addEventListener( + 'color-selection-ring-update', this.onColorSelectionRingUpdate_); this.moveColorSelectionRingTo_(this.selectedColor_); @@ -1194,26 +1200,30 @@ this.colorPalette_.nearestPointOnColorPalette(newPositionOrColor); this.colorSelectionRing_.moveTo(point); } else { - const closestHSLValueIndex = this.colorPalette_.hslImageData - .reduce((closestSoFar, {}, index, array) => { + const closestHSLValueIndex = this.colorPalette_.hslImageData.reduce( + (closestSoFar, {}, index, array) => { if ((index % 3) === 0) { - const currentHSLValueDistance = Color.distance([array[index], - array[index + 1], array[index + 2]], - newPositionOrColor.hslValues()); - const closestHSLValueDistance = - Color.distance([array[closestSoFar], array[closestSoFar + 1], - array[closestSoFar + 2]], newPositionOrColor.hslValues()); + const currentHSLValueDistance = Color.distance( + [array[index], array[index + 1], array[index + 2]], + newPositionOrColor.hslValues()); + const closestHSLValueDistance = Color.distance( + [ + array[closestSoFar], array[closestSoFar + 1], + array[closestSoFar + 2] + ], + newPositionOrColor.hslValues()); if (currentHSLValueDistance < closestHSLValueDistance) { return index; } } return closestSoFar; - }, 0); + }, + 0); const offsetX = (closestHSLValueIndex / 3) % this.colorPalette_.width; const offsetY = Math.floor((closestHSLValueIndex / 3) / this.colorPalette_.width); - this.colorSelectionRing_.set(this.colorPalette_.left + offsetX, - this.colorPalette_.top + offsetY); + this.colorSelectionRing_.set( + this.colorPalette_.left + offsetX, this.colorPalette_.top + offsetY); } } @@ -1248,12 +1258,9 @@ onColorSelectionRingUpdate_ = () => { this.selectedColor_ = this.colorSelectionRing_.color; - this.dispatchEvent(new CustomEvent('visual-color-change', { - bubbles: true, - detail: { - color: this.selectedColor - } - })); + this.dispatchEvent(new CustomEvent( + 'visual-color-change', + {bubbles: true, detail: {color: this.selectedColor}})); } } window.customElements.define('color-well', ColorWell); @@ -1271,8 +1278,9 @@ this.color_ = new Color(ColorFormat.HSL, initialColor.hValue, 100, 50); this.resizeObserver_ = new ResizeObserver(() => { - let hueSliderPaletteGradient = this.colorPalette_.renderingContext - .createLinearGradient(0, 0, this.colorPalette_.offsetWidth, 0); + let hueSliderPaletteGradient = + this.colorPalette_.renderingContext.createLinearGradient( + 0, 0, this.colorPalette_.offsetWidth, 0); hueSliderPaletteGradient.addColorStop(0.01, 'hsl(0, 100%, 50%)'); hueSliderPaletteGradient.addColorStop(0.17, 'hsl(300, 100%, 50%)'); hueSliderPaletteGradient.addColorStop(0.33, 'hsl(240, 100%, 50%)'); @@ -1283,8 +1291,8 @@ this.colorPalette_.initialize(hueSliderPaletteGradient); this.colorSelectionRing_.initialize(); - this.colorSelectionRing_.addEventListener('color-selection-ring-update', - this.onColorSelectionRingUpdate_); + this.colorSelectionRing_.addEventListener( + 'color-selection-ring-update', this.onColorSelectionRingUpdate_); this.moveColorSelectionRingTo_(this.color_); @@ -1308,15 +1316,16 @@ } else { const targetHValue = newPositionOrColor.hValue; if (targetHValue !== this.colorSelectionRing_.color.hValue) { - const closestHValueIndex = this.colorPalette_.hslImageData - .reduce((closestHValueIndexSoFar, currentHValue, index, array) => { + const closestHValueIndex = this.colorPalette_.hslImageData.reduce( + (closestHValueIndexSoFar, currentHValue, index, array) => { if ((index % 3 === 0) && (Math.abs(currentHValue - targetHValue) < - Math.abs(array[closestHValueIndexSoFar] - targetHValue))) { + Math.abs(array[closestHValueIndexSoFar] - targetHValue))) { return index; } return closestHValueIndexSoFar; - }, 0); + }, + 0); const offsetX = (closestHValueIndex / 3) % this.colorPalette_.width; this.colorSelectionRing_.setX(this.colorPalette_.left + offsetX); } @@ -1339,9 +1348,7 @@ onColorSelectionRingUpdate_ = () => { this.color_ = this.colorSelectionRing_.color; - this.dispatchEvent(new CustomEvent('hue-slider-update', { - bubbles: true - })); + this.dispatchEvent(new CustomEvent('hue-slider-update', {bubbles: true})); } } window.customElements.define('hue-slider', HueSlider); @@ -1357,12 +1364,12 @@ constructor(initialColor) { super(); - this.hexValueContainer_ = new ColorValueContainer(ColorChannel.HEX, - initialColor); - this.rgbValueContainer_ = new ColorValueContainer(ColorFormat.RGB, - initialColor); - this.hslValueContainer_ = new ColorValueContainer(ColorFormat.HSL, - initialColor); + this.hexValueContainer_ = + new ColorValueContainer(ColorChannel.HEX, initialColor); + this.rgbValueContainer_ = + new ColorValueContainer(ColorFormat.RGB, initialColor); + this.hslValueContainer_ = + new ColorValueContainer(ColorFormat.HSL, initialColor); this.colorValueContainers_ = [ this.hexValueContainer_, this.rgbValueContainer_, @@ -1373,8 +1380,7 @@ this.formatToggler_ = new FormatToggler(this.currentColorFormat_); this.append(...this.colorValueContainers_, this.formatToggler_); - this.formatToggler_ - .addEventListener('format-change', this.onFormatChange_); + this.formatToggler_.addEventListener('format-change', this.onFormatChange_); this.addEventListener('manual-color-change', this.onManualColorChange_); } @@ -1408,8 +1414,8 @@ * @param {!Color} newColor */ set color(newColor) { - this.colorValueContainers_.forEach((colorValueContainer) => - colorValueContainer.color = newColor); + this.colorValueContainers_.forEach( + (colorValueContainer) => colorValueContainer.color = newColor); } } window.customElements.define('manual-color-picker', ManualColorPicker); @@ -1429,35 +1435,33 @@ this.colorFormat_ = colorFormat; this.channelValueContainers_ = []; if (this.colorFormat_ === ColorFormat.HEX) { - const hexValueContainer = new ChannelValueContainer(ColorChannel.HEX, - initialColor); + const hexValueContainer = + new ChannelValueContainer(ColorChannel.HEX, initialColor); this.channelValueContainers_.push(hexValueContainer); } else if (this.colorFormat_ === ColorFormat.RGB) { - const rValueContainer = new ChannelValueContainer(ColorChannel.R, - initialColor); - const gValueContainer = new ChannelValueContainer(ColorChannel.G, - initialColor); - const bValueContainer = new ChannelValueContainer(ColorChannel.B, - initialColor); - this.channelValueContainers_.push(rValueContainer, - gValueContainer, - bValueContainer); + const rValueContainer = + new ChannelValueContainer(ColorChannel.R, initialColor); + const gValueContainer = + new ChannelValueContainer(ColorChannel.G, initialColor); + const bValueContainer = + new ChannelValueContainer(ColorChannel.B, initialColor); + this.channelValueContainers_.push( + rValueContainer, gValueContainer, bValueContainer); } else if (this.colorFormat_ === ColorFormat.HSL) { - const hValueContainer = new ChannelValueContainer(ColorChannel.H, - initialColor); - const sValueContainer = new ChannelValueContainer(ColorChannel.S, - initialColor); - const lValueContainer = new ChannelValueContainer(ColorChannel.L, - initialColor); - this.channelValueContainers_.push(hValueContainer, - sValueContainer, - lValueContainer); + const hValueContainer = + new ChannelValueContainer(ColorChannel.H, initialColor); + const sValueContainer = + new ChannelValueContainer(ColorChannel.S, initialColor); + const lValueContainer = + new ChannelValueContainer(ColorChannel.L, initialColor); + this.channelValueContainers_.push( + hValueContainer, sValueContainer, lValueContainer); } this.append(...this.channelValueContainers_); - this.channelValueContainers_.forEach((channelValueContainer) => - channelValueContainer.addEventListener('input', - this.onChannelValueChange_)); + this.channelValueContainers_.forEach( + (channelValueContainer) => channelValueContainer.addEventListener( + 'input', this.onChannelValueChange_)); } get colorFormat() { @@ -1465,17 +1469,18 @@ } get color() { - return new Color(this.colorFormat_, - ...this.channelValueContainers_.map((channelValueContainer) => - channelValueContainer.channelValue)); + return new Color( + this.colorFormat_, + ...this.channelValueContainers_.map( + (channelValueContainer) => channelValueContainer.channelValue)); } /** * @param {!Color} color */ set color(color) { - this.channelValueContainers_.forEach((channelValueContainer) => - channelValueContainer.setValue(color)); + this.channelValueContainers_.forEach( + (channelValueContainer) => channelValueContainer.setValue(color)); } show() { @@ -1487,12 +1492,8 @@ } onChannelValueChange_ = () => { - this.dispatchEvent(new CustomEvent('manual-color-change', { - bubbles: true, - detail: { - color: this.color - } - })); + this.dispatchEvent(new CustomEvent( + 'manual-color-change', {bubbles: true, detail: {color: this.color}})); } } window.customElements.define('color-value-container', ColorValueContainer); @@ -1511,7 +1512,7 @@ this.setAttribute('type', 'text'); this.colorChannel_ = colorChannel; - switch(colorChannel) { + switch (colorChannel) { case ColorChannel.HEX: this.setAttribute('id', 'hexValueContainer'); this.setAttribute('maxlength', '7'); @@ -1556,7 +1557,7 @@ * @param {!Color} color */ setValue(color) { - switch(this.colorChannel_) { + switch (this.colorChannel_) { case ColorChannel.HEX: if (this.channelValue_ !== color.hexValue) { this.channelValue_ = color.hexValue; @@ -1606,7 +1607,7 @@ // Set this.channelValue_ based on the element's new value. let value = this.value; if (value) { - switch(this.colorChannel_) { + switch (this.colorChannel_) { case ColorChannel.HEX: if (value.startsWith('#')) { value = value.substr(1).toLowerCase(); @@ -1642,9 +1643,8 @@ } } } -window.customElements.define('channel-value-container', - ChannelValueContainer, - { extends: 'input' }); +window.customElements.define( + 'channel-value-container', ChannelValueContainer, {extends: 'input'}); /** * FormatToggler: Button that powers switching between different color formats. @@ -1690,9 +1690,8 @@ */ updateColorFormat_(choosePreviousFormat) { const numFormats = Object.keys(ColorFormat).length; - const newValue = choosePreviousFormat - ? this.currentColorFormat_ - 1 - : this.currentColorFormat_ + 1; + const newValue = choosePreviousFormat ? this.currentColorFormat_ - 1 : + this.currentColorFormat_ + 1; const newColorFormatKey = Object.keys(ColorFormat).filter((key) => { return ColorFormat[key] === (((newValue % numFormats) + numFormats) % numFormats); @@ -1701,11 +1700,8 @@ this.adjustFormatLabelVisibility_(); - this.dispatchEvent(new CustomEvent('format-change', { - detail: { - colorFormat: this.currentColorFormat_ - } - })); + this.dispatchEvent(new CustomEvent( + 'format-change', {detail: {colorFormat: this.currentColorFormat_}})); } adjustFormatLabelVisibility_() { @@ -1721,13 +1717,13 @@ onClick_ = () => { this.focus(); this.updateColorFormat_(false); - } + }; /** * @param {!Event} event */ onKeyDown_ = (event) => { - switch(event.key) { + switch (event.key) { case 'ArrowUp': this.updateColorFormat_(true); break; @@ -1758,16 +1754,14 @@ this.rChannelLabel_ = new ChannelLabel(ColorChannel.R); this.gChannelLabel_ = new ChannelLabel(ColorChannel.G); this.bChannelLabel_ = new ChannelLabel(ColorChannel.B); - this.append(this.rChannelLabel_, - this.gChannelLabel_, - this.bChannelLabel_); + this.append( + this.rChannelLabel_, this.gChannelLabel_, this.bChannelLabel_); } else if (colorFormat === ColorFormat.HSL) { this.hChannelLabel_ = new ChannelLabel(ColorChannel.H); this.sChannelLabel_ = new ChannelLabel(ColorChannel.S); this.lChannelLabel_ = new ChannelLabel(ColorChannel.L); - this.append(this.hChannelLabel_, - this.sChannelLabel_, - this.lChannelLabel_); + this.append( + this.hChannelLabel_, this.sChannelLabel_, this.lChannelLabel_); } } @@ -1829,20 +1823,20 @@ padding.setAttribute('id', 'submission-controls-padding'); this.append(padding); - this.submitButton_ = new SubmissionButton(submitCallback, + this.submitButton_ = new SubmissionButton( + submitCallback, '<svg width="14" height="10" viewBox="0 0 14 10" fill="none" ' + - 'xmlns="http://www.w3.org/2000/svg"><path d="M13.3516 ' + - '1.35156L5 9.71094L0.648438 5.35156L1.35156 4.64844L5 ' + - '8.28906L12.6484 0.648438L13.3516 1.35156Z" fill="WindowText"/></svg>' - ); - this.cancelButton_ = new SubmissionButton(cancelCallback, + 'xmlns="http://www.w3.org/2000/svg"><path d="M13.3516 ' + + '1.35156L5 9.71094L0.648438 5.35156L1.35156 4.64844L5 ' + + '8.28906L12.6484 0.648438L13.3516 1.35156Z" fill="WindowText"/></svg>'); + this.cancelButton_ = new SubmissionButton( + cancelCallback, '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" ' + - 'xmlns="http://www.w3.org/2000/svg"><path d="M7.71094 7L13.1016 ' + - '12.3984L12.3984 13.1016L7 7.71094L1.60156 13.1016L0.898438 ' + - '12.3984L6.28906 7L0.898438 1.60156L1.60156 0.898438L7 ' + - '6.28906L12.3984 0.898438L13.1016 1.60156L7.71094 7Z" ' + - 'fill="WindowText"/></svg>' - ); + 'xmlns="http://www.w3.org/2000/svg"><path d="M7.71094 7L13.1016 ' + + '12.3984L12.3984 13.1016L7 7.71094L1.60156 13.1016L0.898438 ' + + '12.3984L6.28906 7L0.898438 1.60156L1.60156 0.898438L7 ' + + '6.28906L12.3984 0.898438L13.1016 1.60156L7.71094 7Z" ' + + 'fill="WindowText"/></svg>'); this.append(this.submitButton_, this.cancelButton_); } @@ -1874,4 +1868,4 @@ this.addEventListener('click', clickCallback); } } -window.customElements.define('submission-button', SubmissionButton); \ No newline at end of file +window.customElements.define('submission-button', SubmissionButton);
diff --git a/third_party/blink/renderer/core/html/forms/resources/listPicker.js b/third_party/blink/renderer/core/html/forms/resources/listPicker.js index 59af8767..8294f0b 100644 --- a/third_party/blink/renderer/core/html/forms/resources/listPicker.js +++ b/third_party/blink/renderer/core/html/forms/resources/listPicker.js
@@ -44,16 +44,24 @@ this._delayedChildrenConfig = null; this._delayedChildrenConfigIndex = 0; this._layout(); - this._selectElement.addEventListener('mouseup', this._handleMouseUp.bind(this), false); - this._selectElement.addEventListener('touchstart', this._handleTouchStart.bind(this), false); - this._selectElement.addEventListener('keydown', this._handleKeyDown.bind(this), false); - this._selectElement.addEventListener('change', this._handleChange.bind(this), false); - window.addEventListener('message', this._handleWindowMessage.bind(this), false); - window.addEventListener('mousemove', this._handleWindowMouseMove.bind(this), false); - window.addEventListener('mouseover', this._handleWindowMouseOver.bind(this), false); + this._selectElement.addEventListener( + 'mouseup', this._handleMouseUp.bind(this), false); + this._selectElement.addEventListener( + 'touchstart', this._handleTouchStart.bind(this), false); + this._selectElement.addEventListener( + 'keydown', this._handleKeyDown.bind(this), false); + this._selectElement.addEventListener( + 'change', this._handleChange.bind(this), false); + window.addEventListener( + 'message', this._handleWindowMessage.bind(this), false); + window.addEventListener( + 'mousemove', this._handleWindowMouseMove.bind(this), false); + window.addEventListener( + 'mouseover', this._handleWindowMouseOver.bind(this), false); this._handleWindowTouchMoveBound = this._handleWindowTouchMove.bind(this); this._handleWindowTouchEndBound = this._handleWindowTouchEnd.bind(this); - this._handleTouchSelectModeScrollBound = this._handleTouchSelectModeScroll.bind(this); + this._handleTouchSelectModeScrollBound = + this._handleTouchSelectModeScroll.bind(this); this.lastMousePositionX = Infinity; this.lastMousePositionY = Infinity; this._selectionSetByMouseHover = false; @@ -68,7 +76,8 @@ ListPicker.prototype._handleWindowDidHide = function() { this._fixWindowSize(); - var selectedOption = this._selectElement.options[this._selectElement.selectedIndex]; + var selectedOption = + this._selectElement.options[this._selectElement.selectedIndex]; if (selectedOption) selectedOption.scrollIntoView(false); window.removeEventListener('didHide', this._handleWindowDidHideBound, false); @@ -80,10 +89,14 @@ this._config.baseStyle = window.updateData.baseStyle; this._config.children = window.updateData.children; this._update(); - if (this._config.anchorRectInScreen.x !== window.updateData.anchorRectInScreen.x || - this._config.anchorRectInScreen.y !== window.updateData.anchorRectInScreen.y || - this._config.anchorRectInScreen.width !== window.updateData.anchorRectInScreen.width || - this._config.anchorRectInScreen.height !== window.updateData.anchorRectInScreen.height) { + if (this._config.anchorRectInScreen.x !== + window.updateData.anchorRectInScreen.x || + this._config.anchorRectInScreen.y !== + window.updateData.anchorRectInScreen.y || + this._config.anchorRectInScreen.width !== + window.updateData.anchorRectInScreen.width || + this._config.anchorRectInScreen.height !== + window.updateData.anchorRectInScreen.height) { // TODO(tkent): Don't fix window size here due to a bug of Aura or // compositor. crbug.com/863770 if (!navigator.platform.startsWith('Win')) { @@ -101,7 +114,8 @@ ListPicker.prototype._handleWindowMouseMove = function(event) { var visibleTop = ListPicker.ListboxSelectBorder; - var visibleBottom = this._selectElement.offsetHeight - ListPicker.ListboxSelectBorder; + var visibleBottom = + this._selectElement.offsetHeight - ListPicker.ListboxSelectBorder; var optionBounds = event.target.getBoundingClientRect(); if (optionBounds.height >= 1.0) { // If the height of the visible part of event.target is less than 1px, @@ -128,7 +142,8 @@ ListPicker.prototype._handleMouseUp = function(event) { if (event.target.tagName !== 'OPTION') return; - window.pagePopupController.setValueAndClosePopup(0, this._selectElement.value); + window.pagePopupController.setValueAndClosePopup( + 0, this._selectElement.value); }; ListPicker.prototype._handleTouchStart = function(event) { @@ -140,7 +155,8 @@ this._trackingTouchId = touch.identifier; this._highlightOption(touch.target); this._selectionSetByMouseHover = false; - this._selectElement.addEventListener('scroll', this._handleTouchSelectModeScrollBound, false); + this._selectElement.addEventListener( + 'scroll', this._handleTouchSelectModeScrollBound, false); window.addEventListener('touchmove', this._handleWindowTouchMoveBound, false); window.addEventListener('touchend', this._handleWindowTouchEndBound, false); }; @@ -151,9 +167,12 @@ ListPicker.prototype._exitTouchSelectMode = function(event) { this._trackingTouchId = null; - this._selectElement.removeEventListener('scroll', this._handleTouchSelectModeScrollBound, false); - window.removeEventListener('touchmove', this._handleWindowTouchMoveBound, false); - window.removeEventListener('touchend', this._handleWindowTouchEndBound, false); + this._selectElement.removeEventListener( + 'scroll', this._handleTouchSelectModeScrollBound, false); + window.removeEventListener( + 'touchmove', this._handleWindowTouchMoveBound, false); + window.removeEventListener( + 'touchend', this._handleWindowTouchEndBound, false); }; ListPicker.prototype._handleWindowTouchMove = function(event) { @@ -162,7 +181,8 @@ var touch = this._getTouchForId(event.touches, this._trackingTouchId); if (!touch) return; - this._highlightOption(document.elementFromPoint(touch.clientX, touch.clientY)); + this._highlightOption( + document.elementFromPoint(touch.clientX, touch.clientY)); this._selectionSetByMouseHover = false; }; @@ -174,7 +194,8 @@ return; var target = document.elementFromPoint(touch.clientX, touch.clientY); if (target.tagName === 'OPTION' && !target.disabled) - window.pagePopupController.setValueAndClosePopup(0, this._selectElement.value); + window.pagePopupController.setValueAndClosePopup( + 0, this._selectElement.value); this._exitTouchSelectMode(); }; @@ -207,7 +228,8 @@ window.pagePopupController.closePopup(); event.preventDefault(); } else if (key === 'Tab' || key === 'Enter') { - window.pagePopupController.setValueAndClosePopup(0, this._selectElement.value); + window.pagePopupController.setValueAndClosePopup( + 0, this._selectElement.value); event.preventDefault(); } else if (event.altKey && (key === 'ArrowDown' || key === 'ArrowUp')) { // We need to add a delay here because, if we do it immediately the key @@ -224,7 +246,8 @@ this._selectElement.style.height = ''; var scale = this._config.scaleFactor; var maxHeight = this._selectElement.offsetHeight; - var noScrollHeight = (this._calculateScrollHeight() + ListPicker.ListboxSelectBorder * 2); + var noScrollHeight = + (this._calculateScrollHeight() + ListPicker.ListboxSelectBorder * 2); var scrollbarWidth = getScrollbarWidth(); var elementOffsetWidth = this._selectElement.offsetWidth; var desiredWindowHeight = noScrollHeight; @@ -241,13 +264,17 @@ expectingScrollbar = true; } // Screen coordinate for anchorRectInScreen and windowRect is DIP. - desiredWindowWidth = Math.max(this._config.anchorRectInScreen.width * scale, desiredWindowWidth); - var windowRect = - adjustWindowRect(desiredWindowWidth / scale, desiredWindowHeight / scale, elementOffsetWidth / scale, 0); + desiredWindowWidth = Math.max( + this._config.anchorRectInScreen.width * scale, desiredWindowWidth); + var windowRect = adjustWindowRect( + desiredWindowWidth / scale, desiredWindowHeight / scale, + elementOffsetWidth / scale, 0); // If the available screen space is smaller than maxHeight, we will get an unexpected scrollbar. if (!expectingScrollbar && windowRect.height < noScrollHeight / scale) { desiredWindowWidth = windowRect.width * scale + scrollbarWidth; - windowRect = adjustWindowRect(desiredWindowWidth / scale, windowRect.height, windowRect.width, windowRect.height); + windowRect = adjustWindowRect( + desiredWindowWidth / scale, windowRect.height, windowRect.width, + windowRect.height); } this._selectElement.style.width = (windowRect.width * scale) + 'px'; this._selectElement.style.height = (windowRect.height * scale) + 'px'; @@ -279,11 +306,14 @@ ListPicker.prototype._layout = function() { if (this._config.isRTL) this._element.classList.add('rtl'); - this._selectElement.style.backgroundColor = this._config.baseStyle.backgroundColor; + this._selectElement.style.backgroundColor = + this._config.baseStyle.backgroundColor; this._selectElement.style.color = this._config.baseStyle.color; - this._selectElement.style.textTransform = this._config.baseStyle.textTransform; + this._selectElement.style.textTransform = + this._config.baseStyle.textTransform; this._selectElement.style.fontSize = this._config.baseStyle.fontSize + 'px'; - this._selectElement.style.fontFamily = this._config.baseStyle.fontFamily.map(s => '"' + s + '"').join(','); + this._selectElement.style.fontFamily = + this._config.baseStyle.fontFamily.map(s => '"' + s + '"').join(','); this._selectElement.style.fontStyle = this._config.baseStyle.fontStyle; this._selectElement.style.fontVariant = this._config.baseStyle.fontVariant; this._updateChildren(this._selectElement, this._config); @@ -297,7 +327,8 @@ this._selectElement.scrollTop = scrollPosition; var optionUnderMouse = null; if (this._selectionSetByMouseHover) { - var elementUnderMouse = document.elementFromPoint(this.lastMousePositionX, this.lastMousePositionY); + var elementUnderMouse = document.elementFromPoint( + this.lastMousePositionX, this.lastMousePositionY); optionUnderMouse = elementUnderMouse && elementUnderMouse.closest('option'); } if (optionUnderMouse) @@ -319,13 +350,15 @@ var fragment = null; var inGroup = parent.tagName === 'OPTGROUP'; var lastListIndex = -1; - var limit = Math.max(this._config.selectedIndex, ListPicker.DelayedLayoutThreshold); + var limit = + Math.max(this._config.selectedIndex, ListPicker.DelayedLayoutThreshold); var i; for (i = 0; i < config.children.length; ++i) { if (!inGroup && lastListIndex >= limit) break; var childConfig = config.children[i]; - var item = this._findReusableItem(parent, childConfig, outOfDateIndex) || this._createItemElement(childConfig); + var item = this._findReusableItem(parent, childConfig, outOfDateIndex) || + this._createItemElement(childConfig); this._configureItem(item, childConfig, inGroup); lastListIndex = item.value ? Number(item.value) : -1; if (outOfDateIndex < parent.children.length) { @@ -361,8 +394,10 @@ return; var fragment = document.createDocumentFragment(); var startIndex = this._delayedChildrenConfigIndex; - for (; this._delayedChildrenConfigIndex < this._delayedChildrenConfig.length; ++this._delayedChildrenConfigIndex) { - var childConfig = this._delayedChildrenConfig[this._delayedChildrenConfigIndex]; + for (; this._delayedChildrenConfigIndex < this._delayedChildrenConfig.length; + ++this._delayedChildrenConfigIndex) { + var childConfig = + this._delayedChildrenConfig[this._delayedChildrenConfigIndex]; var item = this._createItemElement(childConfig); this._configureItem(item, childConfig, false); fragment.appendChild(item); @@ -409,13 +444,17 @@ style.direction = styleConfig.direction ? styleConfig.direction : ''; style.unicodeBidi = styleConfig.unicodeBidi ? styleConfig.unicodeBidi : ''; style.color = styleConfig.color ? styleConfig.color : ''; - style.backgroundColor = styleConfig.backgroundColor ? styleConfig.backgroundColor : ''; + style.backgroundColor = + styleConfig.backgroundColor ? styleConfig.backgroundColor : ''; style.fontSize = styleConfig.fontSize ? styleConfig.fontSize + 'px' : ''; style.fontWeight = styleConfig.fontWeight ? styleConfig.fontWeight : ''; - style.fontFamily = styleConfig.fontFamily ? styleConfig.fontFamily.map(s => '"' + s + '"').join(',') : ''; + style.fontFamily = styleConfig.fontFamily ? + styleConfig.fontFamily.map(s => '"' + s + '"').join(',') : + ''; style.fontStyle = styleConfig.fontStyle ? styleConfig.fontStyle : ''; style.fontVariant = styleConfig.fontVariant ? styleConfig.fontVariant : ''; - style.textTransform = styleConfig.textTransform ? styleConfig.textTransform : ''; + style.textTransform = + styleConfig.textTransform ? styleConfig.textTransform : ''; }; ListPicker.prototype._configureItem = function(element, config, inGroup) {
diff --git a/third_party/blink/renderer/core/html/forms/resources/month_picker.js b/third_party/blink/renderer/core/html/forms/resources/month_picker.js index bd001c8..47cf5ee 100644 --- a/third_party/blink/renderer/core/html/forms/resources/month_picker.js +++ b/third_party/blink/renderer/core/html/forms/resources/month_picker.js
@@ -28,7 +28,8 @@ this.initializeFromConfig_(config); - this.yearListView_ = new YearListView(this.minimumMonth_, this.maximumMonth_); + this.yearListView_ = + new YearListView(this.minimumMonth_, this.maximumMonth_); this.append(this.yearListView_.element); this.initializeYearListView_(); @@ -40,14 +41,19 @@ } initializeFromConfig_ = (config) => { - const minimum =(typeof config.min !== 'undefined' && config.min) ? parseDateString(config.min) : Month.Minimum; - const maximum = (typeof config.max !== 'undefined' && config.max) ? parseDateString(config.max) : Month.Maximum; + const minimum = (typeof config.min !== 'undefined' && config.min) ? + parseDateString(config.min) : + Month.Minimum; + const maximum = (typeof config.max !== 'undefined' && config.max) ? + parseDateString(config.max) : + Month.Maximum; this.minimumMonth_ = Month.createFromDay(minimum.firstDay()); this.maximumMonth_ = Month.createFromDay(maximum.lastDay()); const initialSelection = parseDateString(config.currentValue); - const initialSelectedMonth = initialSelection ? Month.createFromDay(initialSelection.middleDay()) - : Month.createFromToday(); + const initialSelectedMonth = initialSelection ? + Month.createFromDay(initialSelection.middleDay()) : + Month.createFromToday(); this.initialValidSelection_ = false; if (initialSelectedMonth < this.minimumMonth_) { this.selectedMonth_ = this.minimumMonth_; @@ -57,60 +63,68 @@ this.selectedMonth_ = initialSelectedMonth; this.initialValidSelection_ = initialSelection != null; } - } + }; initializeYearListView_ = () => { this.yearListView_.setWidth(MonthPicker.YearWidth); this.yearListView_.setHeight(MonthPicker.YearHeight); if (global.params.isLocaleRTL) { this.yearListView_.element.style.right = MonthPicker.YearPadding + 'px'; - this.yearListView_.scrubbyScrollBar.element.style.right = MonthPicker.YearWidth + 'px'; + this.yearListView_.scrubbyScrollBar.element.style.right = + MonthPicker.YearWidth + 'px'; } else { this.yearListView_.element.style.left = MonthPicker.YearPadding + 'px'; - this.yearListView_.scrubbyScrollBar.element.style.left = MonthPicker.YearWidth + 'px'; + this.yearListView_.scrubbyScrollBar.element.style.left = + MonthPicker.YearWidth + 'px'; } this.yearListView_.element.style.top = MonthPicker.YearPadding + 'px'; if (this.initialValidSelection_) { this.yearListView_.setSelectedMonth(this.selectedMonth_); } - this.yearListView_.show(this.selectedMonth_) - this.yearListView_.on(YearListView.EventTypeYearListViewDidSelectMonth, this.onYearListViewDidSelectMonth_); - this.yearListView_.on(YearListView.EventTypeYearListViewDidHide, this.onYearListViewDidHide_); - } + this.yearListView_.show(this.selectedMonth_); + this.yearListView_.on( + YearListView.EventTypeYearListViewDidSelectMonth, + this.onYearListViewDidSelectMonth_); + this.yearListView_.on( + YearListView.EventTypeYearListViewDidHide, this.onYearListViewDidHide_); + }; onYearListViewDidHide_ = (sender) => { const selectedValue = this.selectedMonth_.toString(); window.setTimeout(function() { window.pagePopupController.setValueAndClosePopup(0, selectedValue); }, 100); - } + }; onYearListViewDidSelectMonth_ = (sender, month) => { this.selectedMonth_ = month; - } + }; initializeTodayButton_ = () => { this.todayButton_.element.textContent = global.params.todayLabel; - this.todayButton_.element.setAttribute('aria-label', global.params.todayLabel) + this.todayButton_.element.setAttribute( + 'aria-label', global.params.todayLabel); this.todayButton_.element.classList.add(MonthPicker.ClassNameTodayButton); const monthContainingToday = Month.createFromToday(); this.todayButton_.setDisabled( monthContainingToday < this.minimumMonth_ || monthContainingToday > this.maximumMonth_); - this.todayButton_.on(CalendarNavigationButton.EventTypeButtonClick, this.onTodayButtonClick_); - } + this.todayButton_.on( + CalendarNavigationButton.EventTypeButtonClick, + this.onTodayButtonClick_); + }; onTodayButtonClick_ = (sender) => { const selectedValue = Month.createFromToday().toString(); window.setTimeout(function() { window.pagePopupController.setValueAndClosePopup(0, selectedValue); }, 100); - } + }; onWindowResize_ = (event) => { window.removeEventListener('resize', this.onWindowResize_); this.yearListView_.element.focus(); - } + }; } MonthPicker.Width = 232; MonthPicker.YearWidth = 194; @@ -118,4 +132,4 @@ MonthPicker.YearPadding = 12; MonthPicker.Height = 182; MonthPicker.ClassNameTodayButton = 'today-button-refresh'; -window.customElements.define('month-picker', MonthPicker); \ No newline at end of file +window.customElements.define('month-picker', MonthPicker);
diff --git a/third_party/blink/renderer/core/html/forms/resources/pickerCommon.js b/third_party/blink/renderer/core/html/forms/resources/pickerCommon.js index b5071055..ae3504d 100644 --- a/third_party/blink/renderer/core/html/forms/resources/pickerCommon.js +++ b/third_party/blink/renderer/core/html/forms/resources/pickerCommon.js
@@ -74,7 +74,8 @@ return this.y + this.height; }, toString: function() { - return 'Rectangle(' + this.x + ',' + this.y + ',' + this.width + ',' + this.height + ')'; + return 'Rectangle(' + this.x + ',' + this.y + ',' + this.width + ',' + + this.height + ')'; } }; @@ -101,7 +102,8 @@ */ function resizeWindow(width, height) { var zoom = global.params.zoomFactor ? global.params.zoomFactor : 1; - setWindowRect(adjustWindowRect(width * zoom, height * zoom, width * zoom, height * zoom)); + setWindowRect(adjustWindowRect( + width * zoom, height * zoom, width * zoom, height * zoom)); } /** @@ -124,7 +126,8 @@ var anchorRect = new Rectangle(global.params.anchorRectInScreen); var availRect = new Rectangle( - window.screen.availLeft, window.screen.availTop, window.screen.availWidth, window.screen.availHeight); + window.screen.availLeft, window.screen.availTop, window.screen.availWidth, + window.screen.availHeight); _adjustWindowRectVertically(windowRect, availRect, anchorRect, minHeight); _adjustWindowRectHorizontally(windowRect, availRect, anchorRect, minWidth); @@ -135,12 +138,15 @@ /** * Arguments are DIPs. */ -function _adjustWindowRectVertically(windowRect, availRect, anchorRect, minHeight) { +function _adjustWindowRectVertically( + windowRect, availRect, anchorRect, minHeight) { var availableSpaceAbove = anchorRect.y - availRect.y; - availableSpaceAbove = Math.max(0, Math.min(availRect.height, availableSpaceAbove)); + availableSpaceAbove = + Math.max(0, Math.min(availRect.height, availableSpaceAbove)); var availableSpaceBelow = availRect.maxY - anchorRect.maxY; - availableSpaceBelow = Math.max(0, Math.min(availRect.height, availableSpaceBelow)); + availableSpaceBelow = + Math.max(0, Math.min(availRect.height, availableSpaceBelow)); // In some situations, there may be no space available. This can happen on // Linux when using a buggy window manager (https://crbug.com/774232). When @@ -148,7 +154,9 @@ if (availableSpaceAbove == 0 && availableSpaceBelow == 0) { windowRect.height = Math.max(minHeight, windowRect.height); windowRect.y = anchorRect.maxY; - } else if (windowRect.height > availableSpaceBelow && availableSpaceBelow < availableSpaceAbove) { + } else if ( + windowRect.height > availableSpaceBelow && + availableSpaceBelow < availableSpaceAbove) { windowRect.height = Math.min(windowRect.height, availableSpaceAbove); windowRect.height = Math.max(windowRect.height, minHeight); windowRect.y = anchorRect.y - windowRect.height; @@ -162,7 +170,8 @@ /** * Arguments are DIPs. */ -function _adjustWindowRectHorizontally(windowRect, availRect, anchorRect, minWidth) { +function _adjustWindowRectHorizontally( + windowRect, availRect, anchorRect, minWidth) { if (anchorRect.maxX <= availRect.x || availRect.maxX <= anchorRect.x) { windowRect.width = Math.max(minWidth, windowRect.width); windowRect.x = anchorRect.x @@ -174,7 +183,8 @@ // If we are getting clipped, we want to switch alignment to the right side // of the anchor rect as long as doing so will make the popup not clipped. var rightAlignedX = windowRect.x + anchorRect.width - windowRect.width; - if (rightAlignedX >= availRect.x && (windowRect.maxX > availRect.maxX || global.params.isRTL)) + if (rightAlignedX >= availRect.x && + (windowRect.maxX > availRect.maxX || global.params.isRTL)) windowRect.x = rightAlignedX; } @@ -186,7 +196,8 @@ window.frameElement.style.width = rect.width + 'px'; window.frameElement.style.height = rect.height + 'px'; } else { - window.pagePopupController.setWindowRect(rect.x, rect.y, rect.width, rect.height); + window.pagePopupController.setWindowRect( + rect.x, rect.y, rect.width, rect.height); } } @@ -233,8 +244,10 @@ * @return {?Element} */ function enclosingNodeOrSelfWithClass(selfNode, className) { - for (var node = selfNode; node && node !== selfNode.ownerDocument; node = node.parentNode) { - if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains(className)) + for (var node = selfNode; node && node !== selfNode.ownerDocument; + node = node.parentNode) { + if (node.nodeType === Node.ELEMENT_NODE && + node.classList.contains(className)) return node; } return null; @@ -243,7 +256,8 @@ /** * @constructor */ -function EventEmitter(){}; +function EventEmitter() { +} /** * @param {!string} type @@ -333,7 +347,8 @@ }; Picker.prototype.chooseOtherColor = function() { - window.pagePopupController.setValueAndClosePopup(Picker.Actions.ChooseOtherColor, ''); + window.pagePopupController.setValueAndClosePopup( + Picker.Actions.ChooseOtherColor, ''); }; Picker.prototype.cleanup = function() {};
diff --git a/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.js b/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.js index e56b93ea..b6a85fd 100644 --- a/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.js +++ b/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.js
@@ -38,7 +38,8 @@ this._fixWindowSize(); this._handleBodyKeyDownBound = this._handleBodyKeyDown.bind(this); document.body.addEventListener('keydown', this._handleBodyKeyDownBound); - this._element.addEventListener('mouseout', this._handleMouseOut.bind(this), false); + this._element.addEventListener( + 'mouseout', this._handleMouseOut.bind(this), false); } SuggestionPicker.prototype = Object.create(Picker.prototype); @@ -58,9 +59,11 @@ return 'No otherDateLabel.'; if (config.suggestionHighlightColor && !config.suggestionHighlightColor) return 'No suggestionHighlightColor.'; - if (config.suggestionHighlightTextColor && !config.suggestionHighlightTextColor) + if (config.suggestionHighlightTextColor && + !config.suggestionHighlightTextColor) return 'No suggestionHighlightTextColor.'; - if (config.suggestionValues.length !== config.localizedSuggestionValues.length) + if (config.suggestionValues.length !== + config.localizedSuggestionValues.length) return 'localizedSuggestionValues.length must equal suggestionValues.length.'; if (config.suggestionValues.length !== config.suggestionLabels.length) return 'suggestionLabels.length must equal suggestionValues.length.'; @@ -76,12 +79,14 @@ color: ' + this._config.suggestionHighlightTextColor + '; }'; text += '.' + SuggestionPicker.ListEntryClass + - ':focus .label { color: ' + this._config.suggestionHighlightTextColor + '; }'; + ':focus .label { color: ' + this._config.suggestionHighlightTextColor + + '; }'; document.head.appendChild(createElement('style', null, text)); }; SuggestionPicker.prototype.cleanup = function() { - document.body.removeEventListener('keydown', this._handleBodyKeyDownBound, false); + document.body.removeEventListener( + 'keydown', this._handleBodyKeyDownBound, false); }; /** @@ -90,7 +95,8 @@ * @param {!string} value * @return {!Element} */ -SuggestionPicker.prototype._createSuggestionEntryElement = function(title, label, value) { +SuggestionPicker.prototype._createSuggestionEntryElement = function( + title, label, value) { var entryElement = createElement('li', SuggestionPicker.ListEntryClass); entryElement.tabIndex = 0; entryElement.dataset.value = value; @@ -102,7 +108,8 @@ var labelElement = createElement('span', 'label', label); content.appendChild(labelElement); } - entryElement.addEventListener('mouseover', this._handleEntryMouseOver.bind(this), false); + entryElement.addEventListener( + 'mouseover', this._handleEntryMouseOver.bind(this), false); return entryElement; }; @@ -111,7 +118,8 @@ * @param {!string} actionName * @return {!Element} */ -SuggestionPicker.prototype._createActionEntryElement = function(title, actionName) { +SuggestionPicker.prototype._createActionEntryElement = function( + title, actionName) { var entryElement = createElement('li', SuggestionPicker.ListEntryClass); entryElement.tabIndex = 0; entryElement.dataset.action = actionName; @@ -119,7 +127,8 @@ entryElement.appendChild(content); var titleElement = createElement('span', 'title', title); content.appendChild(titleElement); - entryElement.addEventListener('mouseover', this._handleEntryMouseOver.bind(this), false); + entryElement.addEventListener( + 'mouseover', this._handleEntryMouseOver.bind(this), false); return entryElement; }; @@ -131,9 +140,11 @@ // left aligns all the content including label. this._containerElement.classList.add('measuring-width'); var maxContentWidth = 0; - var contentElements = this._containerElement.getElementsByClassName('content'); + var contentElements = + this._containerElement.getElementsByClassName('content'); for (var i = 0; i < contentElements.length; ++i) { - maxContentWidth = Math.max(maxContentWidth, contentElements[i].getBoundingClientRect().width); + maxContentWidth = Math.max( + maxContentWidth, contentElements[i].getBoundingClientRect().width); } this._containerElement.classList.remove('measuring-width'); return maxContentWidth; @@ -153,7 +164,8 @@ if (node.classList.contains(SuggestionPicker.ListEntryClass)) entryCount++; totalHeight += node.offsetHeight; - if (maxHeight === 0 && entryCount == SuggestionPicker.NumberOfVisibleEntries) + if (maxHeight === 0 && + entryCount == SuggestionPicker.NumberOfVisibleEntries) maxHeight = totalHeight; } var desiredWindowHeight = totalHeight * zoom; @@ -163,8 +175,10 @@ desiredWindowHeight = maxHeight * zoom; this._containerElement.style.overflowY = 'scroll'; } - var windowRect = adjustWindowRect(desiredWindowWidth, desiredWindowHeight, desiredWindowWidth, 0); - this._containerElement.style.height = (windowRect.height / zoom - ListBorder) + 'px'; + var windowRect = adjustWindowRect( + desiredWindowWidth, desiredWindowHeight, desiredWindowWidth, 0); + this._containerElement.style.height = + (windowRect.height / zoom - ListBorder) + 'px'; setWindowRect(windowRect); }; @@ -174,10 +188,12 @@ if (this._config.isLocaleRTL) this._element.classList.add('locale-rtl'); this._containerElement = createElement('ul', 'suggestion-list'); - this._containerElement.addEventListener('click', this._handleEntryClick.bind(this), false); + this._containerElement.addEventListener( + 'click', this._handleEntryClick.bind(this), false); for (var i = 0; i < this._config.suggestionValues.length; ++i) { this._containerElement.appendChild(this._createSuggestionEntryElement( - this._config.localizedSuggestionValues[i], this._config.suggestionLabels[i], this._config.suggestionValues[i])); + this._config.localizedSuggestionValues[i], + this._config.suggestionLabels[i], this._config.suggestionValues[i])); } if (this._config.showOtherDateEntry) { // Add separator @@ -185,8 +201,9 @@ this._containerElement.appendChild(separator); // Add "Other..." entry - var otherEntry = - this._createActionEntryElement(this._config.otherDateLabel, SuggestionPicker.ActionNames.OpenCalendarPicker); + var otherEntry = this._createActionEntryElement( + this._config.otherDateLabel, + SuggestionPicker.ActionNames.OpenCalendarPicker); this._containerElement.appendChild(otherEntry); } this._element.appendChild(this._containerElement); @@ -198,8 +215,11 @@ SuggestionPicker.prototype.selectEntry = function(entry) { if (typeof entry.dataset.value !== 'undefined') { this.submitValue(entry.dataset.value); - } else if (entry.dataset.action === SuggestionPicker.ActionNames.OpenCalendarPicker) { - window.addEventListener('didHide', SuggestionPicker._handleWindowDidHide, false); + } else if ( + entry.dataset.action === + SuggestionPicker.ActionNames.OpenCalendarPicker) { + window.addEventListener( + 'didHide', SuggestionPicker._handleWindowDidHide, false); hideWindow(); } }; @@ -213,7 +233,8 @@ * @param {!Event} event */ SuggestionPicker.prototype._handleEntryClick = function(event) { - var entry = enclosingNodeOrSelfWithClass(event.target, SuggestionPicker.ListEntryClass); + var entry = enclosingNodeOrSelfWithClass( + event.target, SuggestionPicker.ListEntryClass); if (!entry) return; this.selectEntry(entry); @@ -228,9 +249,11 @@ var childNodes = this._containerElement.childNodes; for (var i = 0; i < childNodes.length; ++i) { var node = childNodes[i]; - if (node.nodeType !== Node.ELEMENT_NODE || !node.classList.contains(SuggestionPicker.ListEntryClass)) + if (node.nodeType !== Node.ELEMENT_NODE || + !node.classList.contains(SuggestionPicker.ListEntryClass)) continue; - if (node.offsetTop + node.offsetHeight - scrollTop > SuggestionPicker.VisibleEntryThresholdHeight) + if (node.offsetTop + node.offsetHeight - scrollTop > + SuggestionPicker.VisibleEntryThresholdHeight) return node; } return null; @@ -240,13 +263,16 @@ * @return {?Element} */ SuggestionPicker.prototype._findLastVisibleEntry = function() { - var scrollBottom = this._containerElement.scrollTop + this._containerElement.offsetHeight; + var scrollBottom = + this._containerElement.scrollTop + this._containerElement.offsetHeight; var childNodes = this._containerElement.childNodes; for (var i = childNodes.length - 1; i >= 0; --i) { var node = childNodes[i]; - if (node.nodeType !== Node.ELEMENT_NODE || !node.classList.contains(SuggestionPicker.ListEntryClass)) + if (node.nodeType !== Node.ELEMENT_NODE || + !node.classList.contains(SuggestionPicker.ListEntryClass)) continue; - if (scrollBottom - node.offsetTop > SuggestionPicker.VisibleEntryThresholdHeight) + if (scrollBottom - node.offsetTop > + SuggestionPicker.VisibleEntryThresholdHeight) return node; } return null; @@ -262,8 +288,11 @@ this.handleCancel(); eventHandled = true; } else if (key == 'ArrowUp') { - if (document.activeElement && document.activeElement.classList.contains(SuggestionPicker.ListEntryClass)) { - for (var node = document.activeElement.previousElementSibling; node; node = node.previousElementSibling) { + if (document.activeElement && + document.activeElement.classList.contains( + SuggestionPicker.ListEntryClass)) { + for (var node = document.activeElement.previousElementSibling; node; + node = node.previousElementSibling) { if (node.classList.contains(SuggestionPicker.ListEntryClass)) { this._isFocusByMouse = false; node.focus(); @@ -271,12 +300,17 @@ } } } else { - this._element.querySelector('.' + SuggestionPicker.ListEntryClass + ':last-child').focus(); + this._element + .querySelector('.' + SuggestionPicker.ListEntryClass + ':last-child') + .focus(); } eventHandled = true; } else if (key == 'ArrowDown') { - if (document.activeElement && document.activeElement.classList.contains(SuggestionPicker.ListEntryClass)) { - for (var node = document.activeElement.nextElementSibling; node; node = node.nextElementSibling) { + if (document.activeElement && + document.activeElement.classList.contains( + SuggestionPicker.ListEntryClass)) { + for (var node = document.activeElement.nextElementSibling; node; + node = node.nextElementSibling) { if (node.classList.contains(SuggestionPicker.ListEntryClass)) { this._isFocusByMouse = false; node.focus(); @@ -284,7 +318,9 @@ } } } else { - this._element.querySelector('.' + SuggestionPicker.ListEntryClass + ':first-child').focus(); + this._element + .querySelector('.' + SuggestionPicker.ListEntryClass + ':first-child') + .focus(); } eventHandled = true; } else if (key === 'Enter') { @@ -311,7 +347,8 @@ * @param {!Event} event */ SuggestionPicker.prototype._handleEntryMouseOver = function(event) { - var entry = enclosingNodeOrSelfWithClass(event.target, SuggestionPicker.ListEntryClass); + var entry = enclosingNodeOrSelfWithClass( + event.target, SuggestionPicker.ListEntryClass); if (!entry) return; this._isFocusByMouse = true; @@ -323,7 +360,8 @@ * @param {!Event} event */ SuggestionPicker.prototype._handleMouseOut = function(event) { - if (!document.activeElement.classList.contains(SuggestionPicker.ListEntryClass)) + if (!document.activeElement.classList.contains( + SuggestionPicker.ListEntryClass)) return; this._isFocusByMouse = false; document.activeElement.blur();
diff --git a/third_party/blink/renderer/core/html/forms/resources/time_picker.js b/third_party/blink/renderer/core/html/forms/resources/time_picker.js index b45bc86..625a1ce 100644 --- a/third_party/blink/renderer/core/html/forms/resources/time_picker.js +++ b/third_party/blink/renderer/core/html/forms/resources/time_picker.js
@@ -59,10 +59,11 @@ case TimeColumnType.MILLISECOND: // TODO(https://crbug.com/1008294): Use increments of 1 instead of 100 for milliseconds. // support 100, 200, 300... for milliseconds - this.millisecond_ = (Math.round(this.millisecond_ / 100) * 100 + 100) % 1000; + this.millisecond_ = + (Math.round(this.millisecond_ / 100) * 100 + 100) % 1000; break; } - } + }; value = (columnType) => { switch (columnType) { @@ -75,10 +76,11 @@ case TimeColumnType.MILLISECOND: return this.millisecond_.toString().padStart(3, '0'); } - } + }; toString = (hasSecond, hasMillisecond) => { - let value = `${this.value(TimeColumnType.HOUR)}:${this.value(TimeColumnType.MINUTE)}`; + let value = `${this.value(TimeColumnType.HOUR)}:${ + this.value(TimeColumnType.MINUTE)}`; if (hasSecond) { value += `:${this.value(TimeColumnType.SECOND)}`; } @@ -86,7 +88,7 @@ value += `.${this.value(TimeColumnType.MILLISECOND)}`; } return value; - } + }; static parse = (str) => { var match = Time.ISOStringRegExp.exec(str); @@ -101,13 +103,14 @@ if (match[4]) millisecond = parseInt(match[4], 10); return new Time(hour, minute, second, millisecond); - } + }; static currentTime = () => { var currentDate = new Date(); - return new Time(currentDate.getHours(), currentDate.getMinutes(), - currentDate.getSeconds(), currentDate.getMilliseconds()); - } + return new Time( + currentDate.getHours(), currentDate.getMinutes(), + currentDate.getSeconds(), currentDate.getMilliseconds()); + }; static numberOfValues = (columnType) => { switch (columnType) { @@ -120,7 +123,7 @@ case TimeColumnType.MILLISECOND: return Time.MILLISECOND_VALUES; } - } + }; } // See platform/date_components.h. Time.Minimum = new Time(0, 0, 0, 0); @@ -145,9 +148,8 @@ this.initializeFromConfig_(config); this.timeColumns_ = new TimeColumns(this); - this.submissionControls_ = - new SubmissionControls(this.onSubmitButtonClick_, - this.onCancelButtonClick_); + this.submissionControls_ = new SubmissionControls( + this.onSubmitButtonClick_, this.onCancelButtonClick_); this.append(this.timeColumns_, this.submissionControls_); } @@ -223,8 +225,8 @@ this.width_ += TimePicker.ColumnWidth; } if (timePicker.hasMillisecond) { - this.millisecondColumn_ = new TimeColumn(TimeColumnType.MILLISECOND, - timePicker); + this.millisecondColumn_ = + new TimeColumn(TimeColumnType.MILLISECOND, timePicker); this.append(this.millisecondColumn_); this.width_ += TimePicker.ColumnWidth; } @@ -237,10 +239,12 @@ selectedValue = () => { const hour = parseInt(this.hourColumn_.selectedTimeCell.value, 10); const minute = parseInt(this.minuteColumn_.selectedTimeCell.value, 10); - const second = this.secondColumn_ ? parseInt(this.secondColumn_.selectedTimeCell.value, 10) - : 0; - const millisecond = this.millisecondColumn_ ? parseInt(this.millisecondColumn_.selectedTimeCell.value, 10) - : 0; + const second = this.secondColumn_ ? + parseInt(this.secondColumn_.selectedTimeCell.value, 10) : + 0; + const millisecond = this.millisecondColumn_ ? + parseInt(this.millisecondColumn_.selectedTimeCell.value, 10) : + 0; return new Time(hour, minute, second, millisecond); } } @@ -291,7 +295,7 @@ } } TimeColumn.ClassName = 'time-column'; -window.customElements.define('time-column', TimeColumn, { extends: "ul" }); +window.customElements.define('time-column', TimeColumn, {extends: 'ul'}); /** * TimeCell: List item with a custom look that displays a time value. @@ -306,7 +310,7 @@ } } TimeCell.ClassName = 'time-cell'; -window.customElements.define('time-cell', TimeCell, { extends: "li" }); +window.customElements.define('time-cell', TimeCell, {extends: 'li'}); /** * SubmissionControls: Provides functionality to submit or discard a change. @@ -319,22 +323,22 @@ padding.setAttribute('id', 'submission-controls-padding'); this.append(padding); - this.className = SubmissionControls.ClassName + this.className = SubmissionControls.ClassName; - this.submitButton_ = new SubmissionButton(submitCallback, + this.submitButton_ = new SubmissionButton( + submitCallback, '<svg width="14" height="10" viewBox="0 0 14 10" fill="none" ' + - 'xmlns="http://www.w3.org/2000/svg"><path d="M13.3516 ' + - '1.35156L5 9.71094L0.648438 5.35156L1.35156 4.64844L5 ' + - '8.28906L12.6484 0.648438L13.3516 1.35156Z" fill="black"/></svg>' - ); - this.cancelButton_ = new SubmissionButton(cancelCallback, + 'xmlns="http://www.w3.org/2000/svg"><path d="M13.3516 ' + + '1.35156L5 9.71094L0.648438 5.35156L1.35156 4.64844L5 ' + + '8.28906L12.6484 0.648438L13.3516 1.35156Z" fill="black"/></svg>'); + this.cancelButton_ = new SubmissionButton( + cancelCallback, '<svg width="14" height="14" viewBox="0 0 14 14" fill="none" ' + - 'xmlns="http://www.w3.org/2000/svg"><path d="M7.71094 7L13.1016 ' + - '12.3984L12.3984 13.1016L7 7.71094L1.60156 13.1016L0.898438 ' + - '12.3984L6.28906 7L0.898438 1.60156L1.60156 0.898438L7 ' + - '6.28906L12.3984 0.898438L13.1016 1.60156L7.71094 7Z" ' + - 'fill="black"/></svg>' - ); + 'xmlns="http://www.w3.org/2000/svg"><path d="M7.71094 7L13.1016 ' + + '12.3984L12.3984 13.1016L7 7.71094L1.60156 13.1016L0.898438 ' + + '12.3984L6.28906 7L0.898438 1.60156L1.60156 0.898438L7 ' + + '6.28906L12.3984 0.898438L13.1016 1.60156L7.71094 7Z" ' + + 'fill="black"/></svg>'); this.append(this.submitButton_, this.cancelButton_); } @@ -357,10 +361,11 @@ constructor(clickCallback, htmlString) { super(); - this.className = SubmissionButton.ClassName + this.className = SubmissionButton.ClassName; this.innerHTML = htmlString; this.addEventListener('click', clickCallback); } } SubmissionButton.ClassName = 'submission-button'; -window.customElements.define('submission-button', SubmissionButton, { extends: 'button' }); \ No newline at end of file +window.customElements.define( + 'submission-button', SubmissionButton, {extends: 'button'});
diff --git a/third_party/blink/renderer/core/html/resources/forced_colors.css b/third_party/blink/renderer/core/html/resources/forced_colors.css index 6d3cdce0..4e83f4f 100644 --- a/third_party/blink/renderer/core/html/resources/forced_colors.css +++ b/third_party/blink/renderer/core/html/resources/forced_colors.css
@@ -120,6 +120,11 @@ color: GrayText; } + /* same color as hyperlinks */ + details summary { + color: LinkText; + } + select:-internal-list-box { background-color: Window !important; border-color: ButtonText;
diff --git a/third_party/blink/renderer/core/inspector/browser_protocol.pdl b/third_party/blink/renderer/core/inspector/browser_protocol.pdl index 898ec97c..7f49d8d 100644 --- a/third_party/blink/renderer/core/inspector/browser_protocol.pdl +++ b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
@@ -6803,6 +6803,9 @@ # Request a global memory dump. command requestMemoryDump + parameters + # Enables more deterministic results by forcing garbage collection + optional boolean deterministic returns # GUID of the resulting global memory dump. string dumpGuid
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc index 5cad314..13180f9 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
@@ -73,9 +73,10 @@ if (target_->isConnected() && !observer_data->IsTargetOfImplicitRootObserver() && !observer_data->IsRoot()) { - target_->GetDocument() - .EnsureIntersectionObserverController() - .RemoveTrackedElement(*target_); + IntersectionObserverController* controller = + target_->GetDocument().GetIntersectionObserverController(); + if (controller) + controller->RemoveTrackedElement(*target_); } } entries_.clear();
diff --git a/third_party/blink/renderer/core/layout/layout_shift_tracker.cc b/third_party/blink/renderer/core/layout/layout_shift_tracker.cc index 9d6b822e..b658a7a4c 100644 --- a/third_party/blink/renderer/core/layout/layout_shift_tracker.cc +++ b/third_party/blink/renderer/core/layout/layout_shift_tracker.cc
@@ -28,7 +28,7 @@ static constexpr base::TimeDelta kTimerDelay = base::TimeDelta::FromMilliseconds(500); -static const float kMovementThreshold = 3.0; // CSS pixels. +static const float kMovementThreshold = 1.0; // CSS pixels. static FloatPoint LogicalStart(const FloatRect& rect, const LayoutObject& object) {
diff --git a/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc b/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc index 4b9287b7..ec88c25b 100644 --- a/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc +++ b/third_party/blink/renderer/core/layout/layout_shift_tracker_test.cc
@@ -92,33 +92,6 @@ EXPECT_FLOAT_EQ(20.0, GetLayoutShiftTracker().OverallMaxDistance()); } -TEST_F(LayoutShiftTrackerTest, SmallMovementIgnored) { - SetBodyInnerHTML(R"HTML( - <style> - #j { position: relative; width: 300px; height: 100px; } - </style> - <div id='j'></div> - )HTML"); - GetDocument().getElementById("j")->setAttribute(html_names::kStyleAttr, - AtomicString("top: 2px")); - UpdateAllLifecyclePhases(); - EXPECT_EQ(0.0, GetLayoutShiftTracker().Score()); -} - -TEST_F(LayoutShiftTrackerTest, SmallMovementIgnoredWithZoom) { - GetDocument().GetFrame()->SetPageZoomFactor(2); - SetBodyInnerHTML(R"HTML( - <style> - #j { position: relative; width: 300px; height: 100px; } - </style> - <div id='j'></div> - )HTML"); - GetDocument().getElementById("j")->setAttribute(html_names::kStyleAttr, - AtomicString("top: 2px")); - UpdateAllLifecyclePhases(); - EXPECT_EQ(0.0, GetLayoutShiftTracker().Score()); -} - TEST_F(LayoutShiftTrackerTest, IgnoreAfterInput) { SetBodyInnerHTML(R"HTML( <style>
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h index 2af19ca..498e42e 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_box_fragment_builder.h
@@ -181,7 +181,7 @@ public: ChildList() = default; - void operator=(ChildList&& other) noexcept { + void operator=(ChildList&& other) { children_ = std::move(other.children_); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc index b12baeb..4333b4d 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -1156,12 +1156,12 @@ container_builder_.Size().inline_size, ConstraintSpace().Direction()); if (ConstraintSpace().HasBlockFragmentation()) { - bool is_pushed_by_floats = - child_margin_got_separated || + bool has_container_separation = + has_processed_first_child_ || child_margin_got_separated || child_bfc_offset.block_offset > child_bfc_offset_estimate || layout_result->IsPushedByFloats(); if (BreakBeforeChild(child, *layout_result, previous_inflow_position, - logical_offset.block_offset, is_pushed_by_floats)) + logical_offset.block_offset, has_container_separation)) return true; EBreakBetween break_after = JoinFragmentainerBreakValues( layout_result->FinalBreakAfter(), child.Style().BreakAfter()); @@ -1642,9 +1642,14 @@ fragment, layout_result->BfcLineOffset(), child_bfc_block_offset); if (ConstraintSpace().HasBlockFragmentation()) { + // Floats only cause container separation for the outermost block child that + // gets pushed down (the container and the child may have adjoining + // block-start margins). + bool has_container_separation = + has_processed_first_child_ || (layout_result->IsPushedByFloats() && + !container_builder_.IsPushedByFloats()); if (BreakBeforeChild(child, *layout_result, previous_inflow_position, - logical_offset.block_offset, - layout_result->IsPushedByFloats())) + logical_offset.block_offset, has_container_separation)) return true; EBreakBetween break_after = JoinFragmentainerBreakValues( layout_result->FinalBreakAfter(), child.Style().BreakAfter()); @@ -2002,10 +2007,10 @@ const NGLayoutResult& layout_result, NGPreviousInflowPosition* previous_inflow_position, LayoutUnit block_offset, - bool is_pushed_by_floats) { + bool has_container_separation) { DCHECK(ConstraintSpace().HasBlockFragmentation()); BreakType break_type = BreakTypeBeforeChild( - child, layout_result, block_offset, is_pushed_by_floats); + child, layout_result, block_offset, has_container_separation); if (break_type == NoBreak) return false; @@ -2091,14 +2096,10 @@ } } - if (!has_processed_first_child_ && - (container_builder_.IsPushedByFloats() || !is_pushed_by_floats)) { + if (!has_container_separation) { // We're breaking before the first piece of in-flow content inside this // block, even if it's not a valid class C break point [1] in this case. We - // really don't want to break here, if we can find something better. A class - // C break point occurs if a first child has been pushed by floats, but this - // only applies to the outermost block that gets pushed (in case this parent - // and the child have adjoining top margins). + // really don't want to break here, if we can find something better. // // [1] https://www.w3.org/TR/css-break-3/#possible-breaks container_builder_.SetHasLastResortBreak(); @@ -2133,7 +2134,7 @@ NGLayoutInputNode child, const NGLayoutResult& layout_result, LayoutUnit block_offset, - bool is_pushed_by_floats) const { + bool has_container_separation) const { if (!container_builder_.BfcBlockOffset().has_value()) return NoBreak; @@ -2157,9 +2158,11 @@ EBreakBetween break_between = container_builder_.JoinedBreakBetweenValue(break_before); if (IsForcedBreakValue(ConstraintSpace(), break_between)) { - // There should be a forced break before this child, and if we're not at the - // first in-flow child, just go ahead and break. - if (has_processed_first_child_) + // There should be a forced break before this child, and if we're at a valid + // breakpoint (class A or C), just go ahead and break. If we're not at a + // valid breakpoint, the forced break will be propagated upwards until we + // find a valid breakpoint. + if (has_container_separation) return ForcedBreak; } @@ -2186,7 +2189,7 @@ // content progression. // // [1] https://www.w3.org/TR/css-break-3/#possible-breaks - if (has_processed_first_child_ || is_pushed_by_floats) { + if (has_container_separation) { // This is a valid break point, and we can resolve the last-resort // situation. return SoftBreak;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h index 7e144a1..e6893cdd 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h +++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h
@@ -227,11 +227,21 @@ // Insert a fragmentainer break before the child if necessary. // Update previous in-flow position and return true if a break was inserted. // Otherwise return false. + // If |has_container_separation| is true, it means that we're at a valid + // breakpoint. We obviously prefer valid breakpoints, but sometimes we need to + // break at undesirable locations. Class A breakpoints occur between block + // siblings. Class B breakpoints between line boxes. Both these breakpoint + // classes imply that we're already past the first in-flow child in the + // container, but there's also another way of achieving container separation: + // class C breakpoints. Those occur if there's a positive gap between the + // block-start content edge of the container and the block-start margin edge + // of the first in-flow child. This can happen when in-flow content is pushed + // down by floats. https://www.w3.org/TR/css-break-3/#possible-breaks bool BreakBeforeChild(NGLayoutInputNode child, const NGLayoutResult&, NGPreviousInflowPosition*, LayoutUnit block_offset, - bool is_pushed_by_floats); + bool has_container_separation); enum BreakType { NoBreak, SoftBreak, ForcedBreak }; @@ -240,7 +250,7 @@ BreakType BreakTypeBeforeChild(NGLayoutInputNode child, const NGLayoutResult&, LayoutUnit block_offset, - bool is_pushed_by_floats) const; + bool has_container_separation) const; // Final adjustments before fragment creation. We need to prevent the fragment // from crossing fragmentainer boundaries, and rather create a break token if
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc index 310a86f..91d8a52 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc
@@ -3228,6 +3228,43 @@ EXPECT_EQ(expectation, dump); } +TEST_F(NGColumnLayoutAlgorithmTest, ForcedBreakAtClassCBreakPoint) { + SetBodyInnerHTML(R"HTML( + <style> + #parent { + columns: 3; + column-gap: 10px; + column-fill: auto; + width: 320px; + height:100px; + } + </style> + <div id="container"> + <div id="parent"> + <div style="width:50px; height:50px;"></div> + <div style="float:left; width:100%; height:40px;"></div> + <div style="width:55px;"> + <div style="display:flow-root; break-before:column; width:44px; height:20px;"></div> + </div> + </div> + </div> + )HTML"); + + String dump = DumpFragmentTree(GetElementById("container")); + String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. + offset:unplaced size:1000x100 + offset:0,0 size:320x100 + offset:0,0 size:100x100 + offset:0,0 size:50x50 + offset:0,50 size:100x40 + offset:0,50 size:55x50 + offset:110,0 size:100x20 + offset:0,0 size:55x20 + offset:0,0 size:44x20 +)DUMP"; + EXPECT_EQ(expectation, dump); +} + TEST_F(NGColumnLayoutAlgorithmTest, Nested) { SetBodyInnerHTML(R"HTML( <style>
diff --git a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h index 8f77b90..833b0d23 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h +++ b/third_party/blink/renderer/core/layout/ng/ng_constraint_space.h
@@ -86,7 +86,7 @@ else bfc_offset_ = other.bfc_offset_; } - NGConstraintSpace(NGConstraintSpace&& other) noexcept + NGConstraintSpace(NGConstraintSpace&& other) : available_size_(other.available_size_), exclusion_space_(std::move(other.exclusion_space_)), bitfields_(other.bitfields_) { @@ -110,7 +110,7 @@ bitfields_ = other.bitfields_; return *this; } - NGConstraintSpace& operator=(NGConstraintSpace&& other) noexcept { + NGConstraintSpace& operator=(NGConstraintSpace&& other) { available_size_ = other.available_size_; if (HasRareData()) delete rare_data_;
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h index 22c752ec..7fe4716c 100644 --- a/third_party/blink/renderer/core/loader/empty_clients.h +++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -318,7 +318,6 @@ void DownloadURL(const ResourceRequest&, DownloadCrossOriginRedirects) override {} - void LoadErrorPage(int reason) override {} DocumentLoader* CreateDocumentLoader( LocalFrame*,
diff --git a/third_party/blink/renderer/core/messaging/blink_cloneable_message.cc b/third_party/blink/renderer/core/messaging/blink_cloneable_message.cc index b6c8768..74239307 100644 --- a/third_party/blink/renderer/core/messaging/blink_cloneable_message.cc +++ b/third_party/blink/renderer/core/messaging/blink_cloneable_message.cc
@@ -9,9 +9,8 @@ BlinkCloneableMessage::BlinkCloneableMessage() = default; BlinkCloneableMessage::~BlinkCloneableMessage() = default; -BlinkCloneableMessage::BlinkCloneableMessage(BlinkCloneableMessage&&) noexcept = - default; +BlinkCloneableMessage::BlinkCloneableMessage(BlinkCloneableMessage&&) = default; BlinkCloneableMessage& BlinkCloneableMessage::operator=( - BlinkCloneableMessage&&) noexcept = default; + BlinkCloneableMessage&&) = default; } // namespace blink
diff --git a/third_party/blink/renderer/core/messaging/blink_cloneable_message.h b/third_party/blink/renderer/core/messaging/blink_cloneable_message.h index 337b0f8..a51e888 100644 --- a/third_party/blink/renderer/core/messaging/blink_cloneable_message.h +++ b/third_party/blink/renderer/core/messaging/blink_cloneable_message.h
@@ -21,8 +21,8 @@ BlinkCloneableMessage(); ~BlinkCloneableMessage(); - BlinkCloneableMessage(BlinkCloneableMessage&&) noexcept; - BlinkCloneableMessage& operator=(BlinkCloneableMessage&&) noexcept; + BlinkCloneableMessage(BlinkCloneableMessage&&); + BlinkCloneableMessage& operator=(BlinkCloneableMessage&&); scoped_refptr<blink::SerializedScriptValue> message; v8_inspector::V8StackTraceId sender_stack_trace_id;
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc index 909ddb0..b5cdfda 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
@@ -16,10 +16,10 @@ BlinkTransferableMessage::BlinkTransferableMessage() = default; BlinkTransferableMessage::~BlinkTransferableMessage() = default; -BlinkTransferableMessage::BlinkTransferableMessage( - BlinkTransferableMessage&&) noexcept = default; +BlinkTransferableMessage::BlinkTransferableMessage(BlinkTransferableMessage&&) = + default; BlinkTransferableMessage& BlinkTransferableMessage::operator=( - BlinkTransferableMessage&&) noexcept = default; + BlinkTransferableMessage&&) = default; scoped_refptr<blink::StaticBitmapImage> ToStaticBitmapImage( const SkBitmap& sk_bitmap) {
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message.h b/third_party/blink/renderer/core/messaging/blink_transferable_message.h index edf4fab..3957bed 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message.h +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message.h
@@ -24,8 +24,8 @@ BlinkTransferableMessage(); ~BlinkTransferableMessage(); - BlinkTransferableMessage(BlinkTransferableMessage&&) noexcept; - BlinkTransferableMessage& operator=(BlinkTransferableMessage&&) noexcept; + BlinkTransferableMessage(BlinkTransferableMessage&&); + BlinkTransferableMessage& operator=(BlinkTransferableMessage&&); Vector<MessagePortChannel> ports;
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc index 8c7ec85a..64c67d12 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -217,7 +217,6 @@ } UpdateOverflowControlsLayers(false, false, false); - UpdateChildTransformLayer(false); UpdateForegroundLayer(false); UpdateMaskLayer(false); UpdateScrollingLayers(false); @@ -257,7 +256,6 @@ graphics_layer_ = nullptr; foreground_layer_ = nullptr; - child_transform_layer_ = nullptr; mask_layer_ = nullptr; scrolling_layer_ = nullptr; @@ -504,11 +502,6 @@ RequiresScrollCornerLayer())) layer_config_changed = true; - bool has_perspective = style.HasPerspective(); - bool needs_child_transform_layer = has_perspective && layout_object.IsBox(); - if (UpdateChildTransformLayer(needs_child_transform_layer)) - layer_config_changed = true; - if (UpdateSquashingLayers(!squashed_layers_.IsEmpty())) layer_config_changed = true; @@ -870,8 +863,6 @@ snapped_offset_from_composited_ancestor, squashed_layers_, layers_needing_paint_invalidation); - UpdateChildTransformLayerGeometry(); - UpdateMaskLayerGeometry(); UpdateTransformGeometry(snapped_offset_from_composited_ancestor, relative_compositing_bounds); @@ -1033,18 +1024,6 @@ overflow_controls_host_layer_->SetMasksToBounds(true); } -void CompositedLayerMapping::UpdateChildTransformLayerGeometry() { - if (!child_transform_layer_) - return; - - PhysicalRect border_box = - ToLayoutBox(owning_layer_.GetLayoutObject()).PhysicalBorderBoxRect(); - border_box.Move(ContentOffsetInCompositingLayer()); - child_transform_layer_->SetSize(gfx::Size(border_box.PixelSnappedSize())); - child_transform_layer_->SetOffsetFromLayoutObject(IntSize()); - child_transform_layer_->SetPosition(FloatPoint(border_box.offset)); -} - void CompositedLayerMapping::UpdateMaskLayerGeometry() { if (!mask_layer_) return; @@ -1102,11 +1081,8 @@ // When a m_childTransformLayer exists, local content offsets for the // m_scrollingLayer have already been applied. Otherwise, we apply them here. IntSize local_content_offset(0, 0); - if (!child_transform_layer_) { - local_content_offset = - RoundedIntPoint(owning_layer_.SubpixelAccumulation()) - - local_compositing_bounds.Location(); - } + local_content_offset = RoundedIntPoint(owning_layer_.SubpixelAccumulation()) - + local_compositing_bounds.Location(); scrolling_layer_->SetPosition( FloatPoint(overflow_clip_rect.Location() + local_content_offset)); @@ -1215,7 +1191,6 @@ } }; - update_bottom_layer(child_transform_layer_.get()); update_bottom_layer(scrolling_layer_.get()); // Now constructing the subtree for the overflow controls. @@ -1348,35 +1323,9 @@ } void CompositedLayerMapping::UpdateChildrenTransform() { - if (GraphicsLayer* child_transform_layer = ChildTransformLayer()) { - child_transform_layer->SetTransform(OwningLayer().PerspectiveTransform()); - child_transform_layer->SetTransformOrigin( - OwningLayer().PerspectiveOrigin()); - } - UpdateShouldFlattenTransform(); } -bool CompositedLayerMapping::UpdateChildTransformLayer( - bool needs_child_transform_layer) { - bool layers_changed = false; - - if (needs_child_transform_layer) { - if (!child_transform_layer_) { - child_transform_layer_ = - CreateGraphicsLayer(CompositingReason::kLayerForPerspective); - child_transform_layer_->SetDrawsContent(false); - layers_changed = true; - } - } else if (child_transform_layer_) { - child_transform_layer_->RemoveFromParent(); - child_transform_layer_ = nullptr; - layers_changed = true; - } - - return layers_changed; -} - bool CompositedLayerMapping::ToggleScrollbarLayerIfNeeded( std::unique_ptr<GraphicsLayer>& layer, bool needs_layer, @@ -1546,10 +1495,6 @@ DCHECK(mode); if (((mode & kApplyToLayersAffectedByPreserve3D) || - (mode & kApplyToChildContainingLayers)) && - mapping->ChildTransformLayer()) - f(mapping->ChildTransformLayer()); - if (((mode & kApplyToLayersAffectedByPreserve3D) || (mode & kApplyToContentLayers) || (mode & kApplyToNonScrollingContentLayers)) && mapping->MainGraphicsLayer()) @@ -1606,13 +1551,11 @@ // invalidation for this flag. See crbug.com/783614. bool is_flat = !owning_layer_.ShouldPreserve3D(); - if (GraphicsLayer* layer = ChildTransformLayer()) - layer->SetShouldFlattenTransform(false); if (GraphicsLayer* layer = ScrollingLayer()) layer->SetShouldFlattenTransform(false); graphics_layer_->SetShouldFlattenTransform(is_flat && !HasScrollingLayer()); if (GraphicsLayer* layer = ScrollingContentsLayer()) - layer->SetShouldFlattenTransform(is_flat && !HasChildTransformLayer()); + layer->SetShouldFlattenTransform(is_flat); if (GraphicsLayer* layer = ForegroundLayer()) layer->SetShouldFlattenTransform(is_flat); } @@ -2077,9 +2020,6 @@ if (scrolling_contents_layer_) return scrolling_contents_layer_.get(); - if (child_transform_layer_) - return child_transform_layer_.get(); - return graphics_layer_.get(); } @@ -2797,8 +2737,6 @@ ")"; } else if (graphics_layer == foreground_layer_.get()) { name = owning_layer_.DebugName() + " (foreground) Layer"; - } else if (graphics_layer == child_transform_layer_.get()) { - name = "Child Transform Layer"; } else if (graphics_layer == mask_layer_.get()) { name = "Mask Layer"; } else if (graphics_layer == layer_for_horizontal_scrollbar_.get()) {
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h index 40dd6e3a..dc151f2 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
@@ -134,11 +134,6 @@ GraphicsLayer* ChildForSuperlayers() const; void SetSublayers(const GraphicsLayerVector&); - bool HasChildTransformLayer() const { return child_transform_layer_.get(); } - GraphicsLayer* ChildTransformLayer() const { - return child_transform_layer_.get(); - } - GraphicsLayer* SquashingContainmentLayer() const { return squashing_containment_layer_.get(); } @@ -360,7 +355,6 @@ void UpdateInternalHierarchy(); void UpdatePaintingPhases(); - bool UpdateChildTransformLayer(bool needs_child_transform_layer); bool UpdateOverflowControlsLayers(bool needs_horizontal_scrollbar_layer, bool needs_vertical_scrollbar_layer, bool needs_scroll_corner_layer); @@ -446,8 +440,7 @@ // looks like this: // // + graphics_layer_ - // + child_transform_layer_ [OPTIONAL] - // | (scrolling_layer_ + scrolling_contents_layer_) [OPTIONAL] + // + (scrolling_layer_ + scrolling_contents_layer_) [OPTIONAL] // | + overflow_controls_host_layer_ [OPTIONAL] // | + layer_for_vertical_scrollbar_ [OPTIONAL] // | + layer_for_horizontal_scrollbar_ [OPTIONAL] @@ -458,9 +451,6 @@ std::unique_ptr<GraphicsLayer> graphics_layer_; - // Only used if we have perspective. - std::unique_ptr<GraphicsLayer> child_transform_layer_; - // Only used if the layer is using composited scrolling. std::unique_ptr<GraphicsLayer> scrolling_layer_;
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc index 785130b..daddc94 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc
@@ -1178,89 +1178,6 @@ EXPECT_FALSE(mapping->BackgroundPaintsOntoScrollingContentsLayer()); } -TEST_F(CompositedLayerMappingTest, - ScrollingLayerWithPerspectivePositionedCorrectly) { - // Test positioning of a scrolling layer within an offset parent, both with - // and without perspective. - // - // When a box shadow is used, the main graphics layer position is offset by - // the shadow. The scrolling contents then need to be offset in the other - // direction to compensate. To make this a little clearer, for the first - // example here the layer positions are calculated as: - // - // graphics_layer_ x = left_pos - shadow_spread + shadow_x_offset - // = 50 - 10 - 10 - // = 30 - // - // graphics_layer_ y = top_pos - shadow_spread + shadow_y_offset - // = 50 - 10 + 0 - // = 40 - // - // contents x = 50 - graphics_layer_ x = 50 - 30 = 20 - // contents y = 50 - graphics_layer_ y = 50 - 40 = 10 - // - // The reason that perspective matters is that it affects which 'contents' - // layer is offset; child_transform_layer_ when using perspective, or - // scrolling_layer_ when there is no perspective. - - SetBodyInnerHTML(R"HTML( - <div id='scroller' style='position: absolute; top: 50px; left: 50px; - width: 400px; height: 245px; overflow: auto; will-change: transform; - box-shadow: -10px 0 0 10px; perspective: 1px;'> - <div style='position: absolute; top: 50px; bottom: 0; width: 200px; - height: 200px;'></div> - </div> - <div id='scroller2' style='position: absolute; top: 400px; left: 50px; - width: 400px; height: 245px; overflow: auto; will-change: transform; - box-shadow: -10px 0 0 10px;'> - <div style='position: absolute; top: 50px; bottom: 0; width: 200px; - height: 200px;'></div> - </div> - )HTML"); - - auto* mapping = To<LayoutBlock>(GetLayoutObjectByElementId("scroller")) - ->Layer() - ->GetCompositedLayerMapping(); - - auto* mapping2 = To<LayoutBlock>(GetLayoutObjectByElementId("scroller2")) - ->Layer() - ->GetCompositedLayerMapping(); - - ASSERT_TRUE(mapping); - ASSERT_TRUE(mapping2); - - // The perspective scroller should have a child transform containing the - // positional offset, and a scrolling layer that has no offset. - - GraphicsLayer* scrolling_layer = mapping->ScrollingLayer(); - GraphicsLayer* child_transform_layer = mapping->ChildTransformLayer(); - GraphicsLayer* main_graphics_layer = mapping->MainGraphicsLayer(); - - ASSERT_TRUE(scrolling_layer); - ASSERT_TRUE(child_transform_layer); - - EXPECT_FLOAT_EQ(30, main_graphics_layer->GetPosition().x()); - EXPECT_FLOAT_EQ(40, main_graphics_layer->GetPosition().y()); - EXPECT_FLOAT_EQ(0, scrolling_layer->GetPosition().x()); - EXPECT_FLOAT_EQ(0, scrolling_layer->GetPosition().y()); - EXPECT_FLOAT_EQ(20, child_transform_layer->GetPosition().x()); - EXPECT_FLOAT_EQ(10, child_transform_layer->GetPosition().y()); - - // The non-perspective scroller should have no child transform and the - // offset on the scroller layer directly. - - GraphicsLayer* scrolling_layer2 = mapping2->ScrollingLayer(); - GraphicsLayer* main_graphics_layer2 = mapping2->MainGraphicsLayer(); - - ASSERT_TRUE(scrolling_layer2); - ASSERT_FALSE(mapping2->ChildTransformLayer()); - - EXPECT_FLOAT_EQ(30, main_graphics_layer2->GetPosition().x()); - EXPECT_FLOAT_EQ(390, main_graphics_layer2->GetPosition().y()); - EXPECT_FLOAT_EQ(20, scrolling_layer2->GetPosition().x()); - EXPECT_FLOAT_EQ(10, scrolling_layer2->GetPosition().y()); -} - TEST_F(CompositedLayerMappingTest, StickyPositionMainThreadOffset) { SetBodyInnerHTML(R"HTML( <style>.composited { backface-visibility: hidden; } @@ -1349,10 +1266,8 @@ sticky->Layer()->GetCompositedLayerMapping(); ASSERT_TRUE(mapping); GraphicsLayer* main_graphics_layer = mapping->MainGraphicsLayer(); - GraphicsLayer* child_transform_layer = mapping->ChildTransformLayer(); ASSERT_TRUE(main_graphics_layer); - ASSERT_TRUE(child_transform_layer); auto* scroller = To<LayoutBlock>(GetLayoutObjectByElementId("scroller"))->Layer(); @@ -1369,11 +1284,6 @@ // removed so that the compositor can take care of it. EXPECT_FLOAT_EQ(0, main_graphics_layer->GetPosition().x()); EXPECT_FLOAT_EQ(0, main_graphics_layer->GetPosition().y()); - - // The child transform layer for the perspective shifting should also not be - // moved by the sticky offset. - EXPECT_FLOAT_EQ(0, child_transform_layer->GetPosition().x()); - EXPECT_FLOAT_EQ(0, child_transform_layer->GetPosition().y()); } TEST_F(CompositedLayerMappingTest,
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc index af5e46ce..82f5f20 100644 --- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc +++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
@@ -515,7 +515,7 @@ ParseBeginOrEnd(value.GetString(), kBegin); if (isConnected()) { ConnectConditions(); - InstanceListChanged(kBegin, Elapsed()); + InstanceListChanged(kBegin); if (time_container_) time_container_->NotifyIntervalsChanged(); } @@ -528,7 +528,7 @@ ParseBeginOrEnd(value.GetString(), kEnd); if (isConnected()) { ConnectConditions(); - InstanceListChanged(kEnd, Elapsed()); + InstanceListChanged(kEnd); if (time_container_) time_container_->NotifyIntervalsChanged(); } @@ -724,9 +724,6 @@ void SVGSMILElement::AddInstanceTime(BeginOrEnd begin_or_end, SMILTime time, SMILTimeOrigin origin) { - SMILTime current_presentation_time = - time_container_ ? time_container_->CurrentDocumentTime() : SMILTime(); - DCHECK(!current_presentation_time.IsUnresolved()); // Ignore new instance times for 'end' if the element is not active // and the origin is script. if (begin_or_end == kEnd && GetActiveState() == kInactive && @@ -736,7 +733,7 @@ begin_or_end == kBegin ? begin_times_ : end_times_; InsertSortedAndUnique(list, SMILTimeWithOrigin(time, origin)); - InstanceListChanged(begin_or_end, current_presentation_time); + InstanceListChanged(begin_or_end); if (time_container_) time_container_->NotifyIntervalsChanged(); } @@ -870,16 +867,19 @@ FindInstanceTime(kBegin, presentation_time, false)); } -void SVGSMILElement::InstanceListChanged(BeginOrEnd begin_or_end, - SMILTime event_time) { +void SVGSMILElement::InstanceListChanged(BeginOrEnd begin_or_end) { if (is_waiting_for_first_interval_) { ResolveFirstInterval(); return; } + SMILTime current_presentation_time = + time_container_ ? time_container_->CurrentDocumentTime() : SMILTime(); + DCHECK(!current_presentation_time.IsUnresolved()); if (begin_or_end == kEnd) { // If we have no current interval, or the current interval ends before the // indicated time, then a new 'end' instance time will have no effect. - if (!interval_.IsResolved() || interval_.EndsBefore(event_time)) + if (!interval_.IsResolved() || + interval_.EndsBefore(current_presentation_time)) return; SMILTime new_end = FindInstanceTime(kEnd, interval_.begin, false); if (interval_.EndsBefore(new_end)) @@ -894,21 +894,25 @@ // Never resolve more than one interval when restart is 'never'. if (GetRestart() == kRestartNever) return; - SMILTime new_begin = FindInstanceTime(kBegin, event_time, true); + SMILTime new_begin = + FindInstanceTime(kBegin, current_presentation_time, true); if (!new_begin.IsFinite()) return; // If the current interval is active and contains the new begin time, then we // will pick up a potentially new interval during the regular interval // update. - if (interval_.BeginsBefore(new_begin) && interval_.EndsAfter(event_time)) + if (interval_.BeginsBefore(new_begin) && + interval_.EndsAfter(current_presentation_time)) return; // Begin time changed, re-resolve the interval. SMILTime old_begin = interval_.begin; - interval_ = ResolveInterval(event_time, event_time); + interval_ = + ResolveInterval(current_presentation_time, current_presentation_time); DCHECK(interval_.IsResolved()); if (interval_.begin != old_begin) { - if (GetActiveState() == kActive && interval_.BeginsAfter(event_time)) { - active_state_ = DetermineActiveState(event_time); + if (GetActiveState() == kActive && + interval_.BeginsAfter(current_presentation_time)) { + active_state_ = DetermineActiveState(current_presentation_time); if (GetActiveState() != kActive) EndedActiveInterval(); }
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h index 132a30ca..5dc47929 100644 --- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h +++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
@@ -183,7 +183,7 @@ SMILTime RepeatingDuration() const; const SMILInterval& GetActiveInterval(SMILTime elapsed) const; - void InstanceListChanged(BeginOrEnd, SMILTime event_time); + void InstanceListChanged(BeginOrEnd); // This represents conditions on elements begin or end list that need to be // resolved on runtime, for example
diff --git a/third_party/blink/renderer/devtools/BUILD.gn b/third_party/blink/renderer/devtools/BUILD.gn index f95ebbf..734379d9 100644 --- a/third_party/blink/renderer/devtools/BUILD.gn +++ b/third_party/blink/renderer/devtools/BUILD.gn
@@ -95,6 +95,19 @@ "front_end/browser_debugger/xhrBreakpointsSidebarPane.css", "front_end/browser_sdk/LogManager.js", "front_end/browser_sdk/module.json", + "front_end/css_overview/cssOverview.css", + "front_end/css_overview/cssOverviewStartView.css", + "front_end/css_overview/cssOverviewProcessingView.css", + "front_end/css_overview/cssOverviewCompletedView.css", + "front_end/css_overview/CSSOverviewController.js", + "front_end/css_overview/CSSOverviewStartView.js", + "front_end/css_overview/CSSOverviewProcessingView.js", + "front_end/css_overview/CSSOverviewCompletedView.js", + "front_end/css_overview/CSSOverviewModel.js", + "front_end/css_overview/CSSOverviewSidebarPanel.js", + "front_end/css_overview/cssOverviewSidebarPanel.css", + "front_end/css_overview/CSSOverviewPanel.js", + "front_end/css_overview/module.json", "front_end/changes/ChangesHighlighter.js", "front_end/changes/changesView.css", "front_end/changes/ChangesView.js", @@ -538,6 +551,7 @@ "front_end/resources/clearStorageView.css", "front_end/resources/ClearStorageView.js", "front_end/resources/CookieItemsView.js", + "front_end/resources/cookieItemsView.css", "front_end/resources/DatabaseModel.js", "front_end/resources/DatabaseQueryView.js", "front_end/resources/DatabaseTableView.js", @@ -1219,6 +1233,7 @@ "$resources_out_dir/browser_debugger/browser_debugger_module.js", "$resources_out_dir/changes/changes_module.js", "$resources_out_dir/protocol_monitor/protocol_monitor_module.js", + "$resources_out_dir/css_overview/css_overview_module.js", "$resources_out_dir/cm/cm_module.js", "$resources_out_dir/color_picker/color_picker_module.js", "$resources_out_dir/console/console_module.js",
diff --git a/third_party/blink/renderer/devtools/front_end/Tests.js b/third_party/blink/renderer/devtools/front_end/Tests.js index 33dc3a0..f61b3bf 100644 --- a/third_party/blink/renderer/devtools/front_end/Tests.js +++ b/third_party/blink/renderer/devtools/front_end/Tests.js
@@ -735,9 +735,9 @@ this.assertEquals(0, event.data.modifiers); this.assertEquals('', event.data.code); InspectorFrontendHost.events.removeEventListener( - InspectorFrontendHostAPI.Events.KeyEventUnhandled, onKeyEventUnhandledKeyDown, this); + Host.InspectorFrontendHostAPI.Events.KeyEventUnhandled, onKeyEventUnhandledKeyDown, this); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.KeyEventUnhandled, onKeyEventUnhandledKeyUp, this); + Host.InspectorFrontendHostAPI.Events.KeyEventUnhandled, onKeyEventUnhandledKeyUp, this); SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent( {type: 'keyUp', key: 'F8', code: 'F8', windowsVirtualKeyCode: 119, nativeVirtualKeyCode: 119}); } @@ -751,7 +751,7 @@ } this.takeControl(); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.KeyEventUnhandled, onKeyEventUnhandledKeyDown, this); + Host.InspectorFrontendHostAPI.Events.KeyEventUnhandled, onKeyEventUnhandledKeyDown, this); SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent( {type: 'rawKeyDown', key: 'F8', windowsVirtualKeyCode: 119, nativeVirtualKeyCode: 119}); };
diff --git a/third_party/blink/renderer/devtools/front_end/audits/audits_strings.grdp b/third_party/blink/renderer/devtools/front_end/audits/audits_strings.grdp index 488ce52..132daa2b 100644 --- a/third_party/blink/renderer/devtools/front_end/audits/audits_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/audits/audits_strings.grdp
@@ -13,7 +13,7 @@ 💡 <ph name="THIS__FASTFACTSQUEUED_FASTFACTINDEX_">$1s<ex>75% of global mobile users in 2016 were on 2G or 3G [Source: GSMA Mobile]</ex></ph> </message> <message name="IDS_DEVTOOLS_1076f1bac69647c846ac3b822b133518" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - The average user device costs less than 200 USD. [Source: International Data Corporation] + The average user device costs less than 200 USD. [Source: <ph name="LOCKED_1">International Data Corporation</ph>] </message> <message name="IDS_DEVTOOLS_1421c82f3616812789ac346b1638e39d" desc="Text of audits start button in Audits Start View"> Run audits @@ -25,25 +25,25 @@ View Trace </message> <message name="IDS_DEVTOOLS_169ece87d3c6b79c2c8d69892927857c" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - 19 seconds is the average time a mobile web page takes to load on a 3G connection [Source: Google DoubleClick blog] + 19 seconds is the average time a mobile web page takes to load on a 3G connection [Source: <ph name="LOCKED_1">Google DoubleClick blog</ph>] </message> <message name="IDS_DEVTOOLS_17de62900ceac9101c8814b4c4874328" desc="Text in Audits Controller"> Apply mobile emulation during auditing </message> <message name="IDS_DEVTOOLS_193c4edb3ab576449959f6710e017a49" desc="Text in Audits Controller"> - Typical DevTools throttling, with actual traffic shaping and CPU slowdown applied + Typical <ph name="LOCKED_1">DevTools</ph> throttling, with actual traffic shaping and CPU slowdown applied </message> <message name="IDS_DEVTOOLS_2046d43f4cc1f59c06f764da2ca2355a" desc="Status text in the Audits panel"> The print popup window is open. Please close it to continue. </message> <message name="IDS_DEVTOOLS_24e8ca2483129261096ba8ba0fbcd247" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - 70% of mobile pages take nearly 7 seconds for the visual content above the fold to display on the screen. [Source: Think with Google] + 70% of mobile pages take nearly 7 seconds for the visual content above the fold to display on the screen. [Source: <ph name="LOCKED_1">Think with Google</ph>] </message> <message name="IDS_DEVTOOLS_2a96c07a6c11ca7add2b1ffde86efe25" desc="Text in Audits Controller"> - Can only audit HTTP/HTTPS pages and Chrome extensions. Navigate to a different page to start an audit. + Can only audit HTTP/HTTPS pages and <ph name="LOCKED_1">Chrome</ph> extensions. Navigate to a different page to start an audit. </message> <message name="IDS_DEVTOOLS_39680b3025b1f8d881f9d983623bf071" desc="Text in Audits Status View"> - Lighthouse is loading your page + <ph name="LOCKED_1">Lighthouse</ph> is loading your page </message> <message name="IDS_DEVTOOLS_3b7e043f46813f1d8ffbd462eb77fb6c" desc="Text in Audits Controller"> How long does this app take to show content and become usable @@ -52,13 +52,13 @@ Applied Slow 4G, 4x CPU Slowdown </message> <message name="IDS_DEVTOOLS_47e2dbd37d8d524f5c4105a96db27b59" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - 75% of global mobile users in 2016 were on 2G or 3G [Source: GSMA Mobile] + 75% of global mobile users in 2016 were on 2G or 3G [Source: <ph name="LOCKED_1">GSMA Mobile</ph>] </message> <message name="IDS_DEVTOOLS_48d24d11c7c71282366fe2007d4cee3b" desc="Text in Audits Controller"> Throttling is simulated, resulting in faster audit runs with similar measurement accuracy </message> <message name="IDS_DEVTOOLS_4ab5093468559edd5940ac59f1c6ac02" desc="Text in Audits Status View"> - Try to navigate to the URL in a fresh Chrome profile without any other tabs or extensions open and try again. + Try to navigate to the URL in a fresh <ph name="LOCKED_1">Chrome</ph> profile without any other tabs or extensions open and try again. </message> <message name="IDS_DEVTOOLS_55f562701dc2cc775f9adc0478644b2a" desc="Tooltip text that appears when hovering over the largeicon add button in the Audits Panel"> Perform an audit… @@ -67,13 +67,13 @@ Cancelling </message> <message name="IDS_DEVTOOLS_56846b99d193dbbd252ddca10d29aff4" desc="Text when lighthouse is loading the page in the Audits panel"> - Lighthouse is loading your page with throttling to measure performance on a mobile device on 3G. + <ph name="LOCKED_1">Lighthouse</ph> is loading your page with throttling to measure performance on a mobile device on 3G. </message> <message name="IDS_DEVTOOLS_5a73519018eaaacb7882caf8f0971ac1" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - 1MB takes a minimum of 5 seconds to download on a typical 3G connection [Source: WebPageTest and DevTools 3G definition]. + 1MB takes a minimum of 5 seconds to download on a typical 3G connection [Source: <ph name="LOCKED_1">WebPageTest</ph> and <ph name="LOCKED_2">DevTools</ph> 3G definition]. </message> <message name="IDS_DEVTOOLS_5f0c08bc61549e7455c9e8b46bfe9aa9" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - 70% of mobile pages weigh over 1MB, 36% over 2MB, and 12% over 4MB. [Source: Think with Google] + 70% of mobile pages weigh over 1MB, 36% over 2MB, and 12% over 4MB. [Source: <ph name="LOCKED_1">Think with Google</ph>] </message> <message name="IDS_DEVTOOLS_64a64ca70e7a909a5a96c07082070bfc" desc="Text of a DOM element in Audits Status View"> Ah, sorry! We ran into an error. @@ -91,22 +91,22 @@ Multiple tabs are being controlled by the same service worker. Close your other tabs on the same origin to audit this page. </message> <message name="IDS_DEVTOOLS_6e394d18cb68d551f58fa35f4dfc70bb" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - As page load time increases from one second to seven seconds, the probability of a mobile site visitor bouncing increases 113%. [Source: Think with Google] + As page load time increases from one second to seven seconds, the probability of a mobile site visitor bouncing increases 113%. [Source: <ph name="LOCKED_1">Think with Google</ph>] </message> <message name="IDS_DEVTOOLS_72c4a2e545d220fd8c9ead876a59a89d" desc="Text in Audits Controller"> Is this page optimized for search engine results ranking </message> <message name="IDS_DEVTOOLS_73351c316c7866b1c5730af9c82b5ab3" desc="Text when lighthouse is loading the page in the Audits panel"> - Lighthouse is loading your page with throttling to measure performance on a slow desktop on 3G. + <ph name="LOCKED_1">Lighthouse</ph> is loading your page with throttling to measure performance on a slow desktop on 3G. </message> <message name="IDS_DEVTOOLS_7387b82b5b5cbc317147961ff45142c5" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - Walmart saw a 1% increase in revenue for every 100ms improvement in page load [Source: WPO Stats] + Walmart saw a 1% increase in revenue for every 100ms improvement in page load [Source: <ph name="LOCKED_1">WPO Stats</ph>] </message> <message name="IDS_DEVTOOLS_77d52e376f0c781e4f0d908f6d0b7ff2" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - Lighthouse only simulates mobile performance; to measure performance on a real device, try WebPageTest.org [Source: Lighthouse team] + <ph name="LOCKED_1">Lighthouse</ph> only simulates mobile performance; to measure performance on a real device, try WebPageTest.org [Source: <ph name="LOCKED_2">Lighthouse</ph> team] </message> <message name="IDS_DEVTOOLS_78b8123c78d60b80d6a09618ad56c2cb" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - Rebuilding Pinterest pages for performance increased conversion rates by 15% [Source: WPO Stats] + Rebuilding Pinterest pages for performance increased conversion rates by 15% [Source: <ph name="LOCKED_1">WPO Stats</ph>] </message> <message name="IDS_DEVTOOLS_7bd1e4f7363173e2c8329551ca4d38cc" desc="New audit item label in Audits Report Selector"> (new audit) @@ -115,22 +115,22 @@ Auditing <ph name="PAGEHOST">$1s<ex>github.com</ex></ph> </message> <message name="IDS_DEVTOOLS_8eb7115e5b4ba55f56931ec24c789f9e" desc="Text in Audits Status View"> - Lighthouse is warming up… + <ph name="LOCKED_1">Lighthouse</ph> is warming up… </message> <message name="IDS_DEVTOOLS_8fe967af0fb77d0261a6ead91bcd607f" desc="Text in Audits Controller"> Reset storage (localStorage, IndexedDB, etc) before auditing. (Good for performance & PWA testing) </message> <message name="IDS_DEVTOOLS_9103edac10b1749db57ca27386ff29dc" desc="Text when lighthouse is loading the page in the Audits panel"> - Lighthouse is loading your page. + <ph name="LOCKED_1">Lighthouse</ph> is loading your page. </message> <message name="IDS_DEVTOOLS_93c09fb3e06297a9b9504113fa5915ea" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - BBC has seen a loss of 10% of their users for every extra second of page load [Source: WPO Stats] + BBC has seen a loss of 10% of their users for every extra second of page load [Source: <ph name="LOCKED_1">WPO Stats</ph>] </message> <message name="IDS_DEVTOOLS_a3456af9cc3d7cf0c2e288f889f050b7" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - If a site takes >1 second to become interactive, users lose attention, and their perception of completing the page task is broken [Source: Google Developers Blog] + If a site takes >1 second to become interactive, users lose attention, and their perception of completing the page task is broken [Source: <ph name="LOCKED_1">Google Developers Blog</ph>] </message> <message name="IDS_DEVTOOLS_a99169b94755be554b65f8dcc2c2b842" desc="Text in the pop-up dialog when lighthouse is gathering information in the Audits panel"> - Lighthouse is gathering information about the page to compute your score. + <ph name="LOCKED_1">Lighthouse</ph> is gathering information about the page to compute your score. </message> <message name="IDS_DEVTOOLS_b002a564ceda05dbdf012a48a145d0d3" desc="Status header in the Audits panel"> Printing @@ -142,7 +142,7 @@ Does this page meet the standard of a Progressive Web App </message> <message name="IDS_DEVTOOLS_b29bb7427a05d89f1dae6ab5459e2d5c" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - By reducing the response size of JSON needed for displaying comments, Instagram saw increased impressions [Source: WPO Stats] + By reducing the response size of JSON needed for displaying comments, Instagram saw increased impressions [Source: <ph name="LOCKED_1">WPO Stats</ph>] </message> <message name="IDS_DEVTOOLS_bcf2457dd80557dd7ebdc1504b6149e6" desc="Text in Audits Controller"> Does this page follow best practices for modern web development @@ -154,7 +154,7 @@ Reports </message> <message name="IDS_DEVTOOLS_d2f618fd63c7c2028cd527f60e761bc6" desc="Text when lighthouse is loading the page in the Audits panel"> - Lighthouse is loading your page with mobile emulation. + <ph name="LOCKED_1">Lighthouse</ph> is loading your page with mobile emulation. </message> <message name="IDS_DEVTOOLS_d88946b678e4c2f251d4e292e8142291" desc="Text in Audits Controller"> SEO @@ -163,22 +163,22 @@ Identify and fix common problems that affect your site's performance, accessibility, and user experience. </message> <message name="IDS_DEVTOOLS_e339ef3bcd3e92466fa83dc21e690a5b" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - As the number of elements on a page increases from 400 to 6,000, the probability of conversion drops 95%. [Source: Think with Google] + As the number of elements on a page increases from 400 to 6,000, the probability of conversion drops 95%. [Source: <ph name="LOCKED_1">Think with Google</ph>] </message> <message name="IDS_DEVTOOLS_e499f5109f685235e6280179fe22beec" desc="Text that appears when user drag and drop something (for example, a file) in Audits Panel"> Drop audit file here </message> <message name="IDS_DEVTOOLS_e8e1638b0449b103a9fdcee6c12d700c" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - 14 seconds is the average time a mobile web page takes to load on a 4G connection [Source: Google DoubleClick blog] + 14 seconds is the average time a mobile web page takes to load on a 4G connection [Source: <ph name="LOCKED_1">Google DoubleClick blog</ph>] </message> <message name="IDS_DEVTOOLS_e9fe69c2de7c38bbe442e38780d20081" desc="Fast fact in the pop-up dialog when lighthouse is running in the Audits panel"> - 53% of all site visits are abandoned if page load takes more than 3 seconds [Source: Google DoubleClick blog] + 53% of all site visits are abandoned if page load takes more than 3 seconds [Source: <ph name="LOCKED_1">Google DoubleClick blog</ph>] </message> <message name="IDS_DEVTOOLS_ea60ba1496b05c6a5816fb75d0665c8d" desc="Text of a DOM element in Audits Status View"> - If this issue is reproducible, please report it at the Lighthouse GitHub repo. + If this issue is reproducible, please report it at the <ph name="LOCKED_1">Lighthouse</ph> <ph name="LOCKED_2">GitHub</ph> repo. </message> <message name="IDS_DEVTOOLS_f3ddea8173e7a06f7a6a5dadc234fd3d" desc="Text in the pop-up dialog when lighthouse is auditing in the Audits panel"> - Almost there! Lighthouse is now generating your report. + Almost there! <ph name="LOCKED_1">Lighthouse</ph> is now generating your report. </message> <message name="IDS_DEVTOOLS_fad0ce221c826eede253cb0956ca0700" desc="A search term referring to the linting application named Lighthouse that can be entered in the command menu"> <ph name="LOCKED_1">lighthouse</ph>
diff --git a/third_party/blink/renderer/devtools/front_end/bindings_test_runner/IsolatedFilesystemTestRunner.js b/third_party/blink/renderer/devtools/front_end/bindings_test_runner/IsolatedFilesystemTestRunner.js index a6e75d1..6910f2a 100644 --- a/third_party/blink/renderer/devtools/front_end/bindings_test_runner/IsolatedFilesystemTestRunner.js +++ b/third_party/blink/renderer/devtools/front_end/bindings_test_runner/IsolatedFilesystemTestRunner.js
@@ -43,7 +43,7 @@ BindingsTestRunner.TestFileSystem._instances[this.fileSystemPath] = this; InspectorFrontendHost.events.dispatchEventToListeners( - InspectorFrontendHostAPI.Events.FileSystemAdded, + Host.InspectorFrontendHostAPI.Events.FileSystemAdded, {fileSystem: {fileSystemPath: this.fileSystemPath, fileSystemName: this.fileSystemPath, type}}); Persistence.isolatedFileSystemManager.addEventListener( @@ -64,7 +64,7 @@ reportRemoved: function() { delete BindingsTestRunner.TestFileSystem._instances[this.fileSystemPath]; InspectorFrontendHost.events.dispatchEventToListeners( - InspectorFrontendHostAPI.Events.FileSystemRemoved, this.fileSystemPath); + Host.InspectorFrontendHostAPI.Events.FileSystemRemoved, this.fileSystemPath); }, addFile: function(path, content, lastModified) { @@ -124,7 +124,7 @@ child.parent = null; InspectorFrontendHost.events.dispatchEventToListeners( - InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, + Host.InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, {changed: [], added: [], removed: [fullPath]}); success(); @@ -149,7 +149,7 @@ const fullPath = this._fileSystem.fileSystemPath + child.fullPath; InspectorFrontendHost.events.dispatchEventToListeners( - InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, + Host.InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, {changed: [], added: [fullPath], removed: []}); return child; @@ -162,7 +162,7 @@ const fullPath = this._fileSystem.fileSystemPath + this.fullPath; InspectorFrontendHost.events.dispatchEventToListeners( - InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, + Host.InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, {changed: [fullPath], added: [], removed: []}); },
diff --git a/third_party/blink/renderer/devtools/front_end/color_picker/ContrastDetails.js b/third_party/blink/renderer/devtools/front_end/color_picker/ContrastDetails.js index 18cd246..5cd8415 100644 --- a/third_party/blink/renderer/devtools/front_end/color_picker/ContrastDetails.js +++ b/third_party/blink/renderer/devtools/front_end/color_picker/ContrastDetails.js
@@ -252,10 +252,10 @@ InspectorFrontendHost.setEyeDropperActive(enabled); if (enabled) { InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.EyeDropperPickedColor, this._bgColorPickedBound); + Host.InspectorFrontendHostAPI.Events.EyeDropperPickedColor, this._bgColorPickedBound); } else { InspectorFrontendHost.events.removeEventListener( - InspectorFrontendHostAPI.Events.EyeDropperPickedColor, this._bgColorPickedBound); + Host.InspectorFrontendHostAPI.Events.EyeDropperPickedColor, this._bgColorPickedBound); } }
diff --git a/third_party/blink/renderer/devtools/front_end/color_picker/Spectrum.js b/third_party/blink/renderer/devtools/front_end/color_picker/Spectrum.js index 098433e..65b86456 100644 --- a/third_party/blink/renderer/devtools/front_end/color_picker/Spectrum.js +++ b/third_party/blink/renderer/devtools/front_end/color_picker/Spectrum.js
@@ -889,10 +889,10 @@ InspectorFrontendHost.setEyeDropperActive(enabled); if (enabled) { InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.EyeDropperPickedColor, this._colorPickedBound); + Host.InspectorFrontendHostAPI.Events.EyeDropperPickedColor, this._colorPickedBound); } else { InspectorFrontendHost.events.removeEventListener( - InspectorFrontendHostAPI.Events.EyeDropperPickedColor, this._colorPickedBound); + Host.InspectorFrontendHostAPI.Events.EyeDropperPickedColor, this._colorPickedBound); } }
diff --git a/third_party/blink/renderer/devtools/front_end/console/console_strings.grdp b/third_party/blink/renderer/devtools/front_end/console/console_strings.grdp index 320cd87..be696a7 100644 --- a/third_party/blink/renderer/devtools/front_end/console/console_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/console/console_strings.grdp
@@ -61,7 +61,7 @@ [Violation] <ph name="MESSAGETEXT">$1s<ex>console.log(1)</ex></ph> </message> <message name="IDS_DEVTOOLS_375855385115b292f160b5131495003d" desc="Message element text content in Console View Message of the Console panel"> - console.clear() was prevented due to 'Preserve log' + <ph name="LOCKED_1">console.clear()</ph> was prevented due to 'Preserve log' </message> <message name="IDS_DEVTOOLS_383b1deb90603a79d86f3ae82e55a9e2" desc="Text in Console View of the Console panel"> <ph name="THIS__HIDDENBYFILTERCOUNT">$1s<ex>3</ex></ph> hidden @@ -235,7 +235,7 @@ JavaScript context: <ph name="THIS_TITLEFOR_ITEM_">$1s<ex>top</ex></ph> </message> <message name="IDS_DEVTOOLS_eacaf2bd1c1414e5086cf04573e154ef" desc="Text in Console View of the Console panel"> - e.g. /event\d/ -cdn url:a.com + e.g. <ph name="LOCKED_1">/event\d/ -cdn url:a.com</ph> </message> <message name="IDS_DEVTOOLS_ebfab4df1bb91688c62d4523eba870a5" desc="Title of a setting under the Console category in Settings"> Evaluate triggers user activation
diff --git a/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewCompletedView.js b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewCompletedView.js new file mode 100644 index 0000000..60e9a35 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewCompletedView.js
@@ -0,0 +1,167 @@ +// 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. + +/** + * @unrestricted + */ +CssOverview.CSSOverviewCompletedView = class extends UI.PanelWithSidebar { + constructor(controller) { + super('css_overview_completed_view'); + this.registerRequiredCSS('css_overview/cssOverviewCompletedView.css'); + + this._controller = controller; + this._formatter = new Intl.NumberFormat('en-US'); + this._mainContainer = new UI.VBox(); + + this._sideBar = new CssOverview.CSSOverviewSidebarPanel(); + this.splitWidget().setSidebarWidget(this._sideBar); + this.splitWidget().setMainWidget(this._mainContainer); + + this._sideBar.addItem(ls`Overview summary`, 'summary'); + this._sideBar.addItem(ls`Colors`, 'colors'); + this._sideBar.select('summary'); + + this._sideBar.addEventListener(CssOverview.SidebarEvents.ItemSelected, this._sideBarItemSelected, this); + this._sideBar.addEventListener(CssOverview.SidebarEvents.Reset, this._sideBarReset, this); + this._controller.addEventListener(CssOverview.Events.Reset, this._reset, this); + this._render({}); + } + + _sideBarItemSelected(event) { + const section = this._fragment.$(event.data); + if (!section) + return; + + section.scrollIntoView(); + } + + _sideBarReset() { + this._controller.dispatchEventToListeners(CssOverview.Events.Reset); + } + + _reset() { + this._mainContainer.element.removeChildren(); + } + + _render(data) { + if (!(data && ('textColors' in data) && ('backgroundColors' in data))) + return; + + const {elementStyleStats, elementCount, backgroundColors, textColors, globalStyleStats} = data; + + // Convert rgb values from the computed styles to either undefined or HEX(A) strings. + const nonTransparentBackgroundColors = this._getNonTransparentColorStrings(backgroundColors); + const nonTransparentTextColors = this._getNonTransparentColorStrings(textColors); + + this._fragment = UI.Fragment.build` + <div class="vbox overview-completed-view"> + <div $="summary" class="results-section summary"> + <h1>${ls`Overview summary`}</h1> + + <ul> + <li> + <div class="label">${ls`Elements processed`}</div> + <div class="value">${this._formatter.format(elementCount)}</div> + </li> + <li> + <div class="label">${ls`External stylesheets`}</div> + <div class="value">${this._formatter.format(globalStyleStats.externalSheets)}</div> + </li> + <li> + <div class="label">${ls`Inline style elements`}</div> + <div class="value">${this._formatter.format(globalStyleStats.inlineStyles)}</div> + </li> + <li> + <div class="label">${ls`Style rules`}</div> + <div class="value">${this._formatter.format(globalStyleStats.styleRules)}</div> + </li> + <li> + <div class="label">${ls`Media rules`}</div> + <div class="value">${this._formatter.format(globalStyleStats.mediaRules)}</div> + </li> + <li> + <div class="label">${ls`Type selectors`}</div> + <div class="value">${this._formatter.format(elementStyleStats.type.size)}</div> + </li> + <li> + <div class="label">${ls`ID selectors`}</div> + <div class="value">${this._formatter.format(elementStyleStats.id.size)}</div> + </li> + <li> + <div class="label">${ls`Class selectors`}</div> + <div class="value">${this._formatter.format(elementStyleStats.class.size)}</div> + </li> + <li> + <div class="label">${ls`Universal selectors`}</div> + <div class="value">${this._formatter.format(elementStyleStats.universal.size)}</div> + </li> + <li> + <div class="label">${ls`Attribute selectors`}</div> + <div class="value">${this._formatter.format(elementStyleStats.attribute.size)}</div> + </li> + <li> + <div class="label">${ls`Non-simple selectors`}</div> + <div class="value">${this._formatter.format(elementStyleStats.nonSimple.size)}</div> + </li> + </ul> + </div> + + <div $="colors" class="results-section colors"> + <h1>${ls`Colors`}</h1> + <h2>${ls`Unique background colors: ${nonTransparentBackgroundColors.length}`}</h2> + <ul> + ${nonTransparentBackgroundColors.map(this._colorsToFragment)} + </ul> + + <h2>${ls`Unique text colors: ${nonTransparentTextColors.length}`}</h2> + <ul> + ${nonTransparentTextColors.map(this._colorsToFragment)} + </ul> + </div> + </div>`; + + this._mainContainer.element.appendChild(this._fragment.element()); + } + + _colorsToFragment(color) { + const colorFormatted = + color.hasAlpha() ? color.asString(Common.Color.Format.HEXA) : color.asString(Common.Color.Format.HEX); + const blockFragment = UI.Fragment.build`<li> + <div class="block" $="color"></div> + <div class="block-title">${colorFormatted}</div> + </li>`; + + const block = blockFragment.$('color'); + block.style.backgroundColor = colorFormatted; + + let [h, s, l] = color.hsla(); + h = Math.round(h * 360); + s = Math.round(s * 100); + l = Math.round(l * 100); + + // Reduce the lightness of the border to make sure that there's always a visible outline. + l = Math.max(0, l - 15); + + const borderString = `1px solid hsl(${h}, ${s}%, ${l}%)`; + block.style.border = borderString; + + return blockFragment; + } + + _getNonTransparentColorStrings(colors) { + return Array.from(colors) + .map(colorText => { + const color = Common.Color.parse(colorText); + if (color.rgba()[3] === 0) + return; + + return color; + }) + .filter(color => !!color); + } + + setOverviewData(data) { + this._render(data); + } +};
diff --git a/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewController.js b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewController.js new file mode 100644 index 0000000..3ff6f29 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewController.js
@@ -0,0 +1,25 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @unrestricted + */ +CssOverview.OverviewController = class extends Common.Object { + constructor() { + super(); + + SDK.targetManager.addEventListener(SDK.TargetManager.Events.InspectedURLChanged, this._reset, this); + } + + _reset() { + this.dispatchEventToListeners(CssOverview.Events.Reset); + } +}; + +CssOverview.Events = { + RequestOverviewStart: Symbol('RequestOverviewStart'), + RequestOverviewCancel: Symbol('RequestOverviewCancel'), + OverviewCompleted: Symbol('OverviewCompleted'), + Reset: Symbol('Reset'), +};
diff --git a/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewModel.js b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewModel.js new file mode 100644 index 0000000..6f64b33 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewModel.js
@@ -0,0 +1,130 @@ +// 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. + +/** + * @unrestricted + */ +CssOverview.CSSOverviewModel = class extends SDK.SDKModel { + /** + * @param {!SDK.Target} target + */ + constructor(target) { + super(target); + + this._runtimeAgent = target.runtimeAgent(); + this._cssAgent = target.cssAgent(); + this._domAgent = target.domAgent(); + } + + getFlattenedDocument() { + return this._domAgent.getFlattenedDocument(-1, true); + } + + getComputedStyleForNode(nodeId) { + return this._cssAgent.getComputedStyleForNode(nodeId); + } + + async getGlobalStylesheetStats() { + // There are no ways to pull CSSOM values directly today, due to its unserializable format, + // so instead we execute some JS within the page that extracts the relevant data and send that instead. + const expression = `(function() { + let styleRules = 0; + let mediaRules = 0; + let inlineStyles = 0; + let externalSheets = 0; + for (const { rules, href } of document.styleSheets) { + if (href) { + externalSheets++; + } else { + inlineStyles++; + } + + for (const rule of rules) { + if ('selectorText' in rule) { + styleRules++; + } else if ('conditionText' in rule) { + mediaRules++; + } + } + } + + return { + styleRules, + mediaRules, + inlineStyles, + externalSheets + } + })()`; + const {result} = await this._runtimeAgent.invoke_evaluate({expression, returnByValue: true}); + + // TODO(paullewis): Handle errors properly. + if (result.type !== 'object') + return; + + return result.value; + } + + async getStylesStatsForNode(nodeId) { + const stats = { + // Simple. + type: new Set(), + class: new Set(), + id: new Set(), + universal: new Set(), + attribute: new Set(), + + // Non-simple. + nonSimple: new Set() + }; + + const matches = await this._cssAgent.invoke_getMatchedStylesForNode({nodeId}); + if (!matches || !matches.matchedCSSRules || !matches.matchedCSSRules.length) + return; + + matches.matchedCSSRules.forEach(cssRule => { + const {matchingSelectors} = cssRule; + const {origin, selectorList} = cssRule.rule; + const isExternalSheet = origin === 'regular'; + if (!isExternalSheet || !selectorList) + return; + + + const selectors = matchingSelectors.map(idx => selectorList.selectors[idx]); + + // Each group of selectors, e.g. foo.baz, foo .bar, foo { ... } + for (const {text} of selectors) { + // Each group that was used. + for (const selectorGroup of text.split(',')) { + // Each selector in the group. + for (const selector of selectorGroup.split(/[\t\n\f\r ]+/g)) { + if (selector.startsWith('.')) { + // Class. + stats.class.add(selector); + } else if (selector.startsWith('#')) { + // Id. + stats.id.add(selector); + } else if (selector.startsWith('*')) { + // Universal. + stats.universal.add(selector); + } else if (selector.startsWith('[')) { + // Attribute. + stats.attribute.add(selector); + } else { + // Type or non-simple selector. + const specialChars = /[#\.:\[\]|\+>~]/; + if (specialChars.test(selector)) + stats.nonSimple.add(selector); + else + stats.type.add(selector); + } + } + } + } + }); + + return stats; + } +}; + +SDK.SDKModel.register(CssOverview.CSSOverviewModel, SDK.Target.Capability.DOM, false);
diff --git a/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewPanel.js b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewPanel.js new file mode 100644 index 0000000..0520b58 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewPanel.js
@@ -0,0 +1,159 @@ +// 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. + +/** + * @unrestricted + */ +CssOverview.CSSOverviewPanel = class extends UI.Panel { + constructor() { + super('css_overview'); + this.registerRequiredCSS('css_overview/cssOverview.css'); + this.element.classList.add('css-overview-panel'); + + this._controller = new CssOverview.OverviewController(); + this._startView = new CssOverview.CSSOverviewStartView(this._controller); + this._processingView = new CssOverview.CSSOverviewProcessingView(this._controller); + this._completedView = new CssOverview.CSSOverviewCompletedView(this._controller); + + const [model] = SDK.targetManager.models(CssOverview.CSSOverviewModel); + this._model = model; + this._controller.addEventListener(CssOverview.Events.RequestOverviewStart, this._startOverview, this); + this._controller.addEventListener(CssOverview.Events.RequestOverviewCancel, this._cancelOverview, this); + this._controller.addEventListener(CssOverview.Events.OverviewCompleted, this._overviewCompleted, this); + this._controller.addEventListener(CssOverview.Events.Reset, this._reset, this); + + this._reset(); + } + + _reset() { + this._backgroundColors = new Set(); + this._textColors = new Set(); + this._fontSizes = new Map(); + this._elementCount = 0; + this._elementStyleStats = { + // Simple. + type: new Set(), + class: new Set(), + id: new Set(), + universal: new Set(), + attribute: new Set(), + + // Non-simple. + nonSimple: new Set() + }; + this._cancelled = false; + this._globalStyleStats = {styleRules: 0, mediaRules: 0, inlineStyles: 0, externalSheets: 0}; + this._renderInitialView(); + } + + _renderInitialView() { + this._processingView.hideWidget(); + this._completedView.hideWidget(); + + this._startView.show(this.contentElement); + } + + _renderOverviewStartedView(elementsHandled = 0, total = 0) { + this._startView.hideWidget(); + this._completedView.hideWidget(); + + this._processingView.show(this.contentElement); + this._processingView.setElementsHandled(elementsHandled, total); + } + + _renderOverviewCompletedView() { + this._startView.hideWidget(); + this._processingView.hideWidget(); + + this._completedView.show(this.contentElement); + this._completedView.setOverviewData({ + backgroundColors: this._backgroundColors, + textColors: this._textColors, + globalStyleStats: this._globalStyleStats, + elementStyleStats: this._elementStyleStats, + fontSizes: this._fontSizes, + elementCount: this._elementCount + }); + } + + async _startOverview() { + this._renderOverviewStartedView(); + + const document = await this._model.getFlattenedDocument(); + if (this._cancelled) { + this._reset(); + return; + } + + // 1. Get the global style stats. + const globalStyleStats = await this._model.getGlobalStylesheetStats(); + if (globalStyleStats) + this._globalStyleStats = globalStyleStats; + + // 2. Get the total element count. + this._elementCount = document.length; + + // 3. Process every element in the doc. + for (let idx = 0; idx < document.length; idx++) { + if (this._cancelled) { + this._reset(); + return; + } + + const node = document[idx]; + const [computedStyles, styleStats] = await Promise.all( + [this._model.getComputedStyleForNode(node.nodeId), this._model.getStylesStatsForNode(node.nodeId)]); + + // 3a. Capture any colors from the computed styles. + if (computedStyles) { + const backgroundColor = this._getStyleValue(computedStyles, 'background-color'); + if (backgroundColor) + this._backgroundColors.add(backgroundColor); + + if (node.nodeType === Node.TEXT_NODE) { + const textColor = this._getStyleValue(computedStyles, 'color'); + this._textColors.add(textColor); + + const fontSize = this._getStyleValue(computedStyles, 'font-size'); + if (!this._fontSizes.has(fontSize)) + this._fontSizes.set(fontSize, 0); + + this._fontSizes.set(fontSize, this._fontSizes.get(fontSize) + 1); + } + } + + // 3b. Tally the selector stats. + if (styleStats) { + for (const section of Object.keys(this._elementStyleStats)) { + if (!styleStats[section]) + continue; + + for (const value of styleStats[section]) + this._elementStyleStats[section].add(value); + } + } + + this._renderOverviewStartedView(idx + 1, document.length); + } + + // 4. Finish. + this._controller.dispatchEventToListeners(CssOverview.Events.OverviewCompleted); + } + + _getStyleValue(styles, name) { + const item = styles.filter(style => style.name === name); + if (!item.length) + return; + + return item[0].value; + } + + _cancelOverview() { + this._cancelled = true; + } + + _overviewCompleted() { + this._renderOverviewCompletedView(); + } +};
diff --git a/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewProcessingView.js b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewProcessingView.js new file mode 100644 index 0000000..169c363 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewProcessingView.js
@@ -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. + +/** + * @unrestricted + */ +CssOverview.CSSOverviewProcessingView = class extends UI.Widget { + constructor(controller) { + super(); + this.registerRequiredCSS('css_overview/cssOverviewProcessingView.css'); + + this._formatter = new Intl.NumberFormat('en-US'); + this._controller = controller; + this._render(); + } + + _render() { + const cancelButton = UI.createTextButton( + ls`Cancel`, () => this._controller.dispatchEventToListeners(CssOverview.Events.RequestOverviewCancel), '', + true /* primary */); + this.setDefaultFocusedElement(cancelButton); + + this.fragment = UI.Fragment.build` + <div class="vbox overview-processing-view"> + <h1>Processing page</h1> + <div>${cancelButton}</div> + + <h2 $="processed"></h2> + </div> + `; + + this.contentElement.appendChild(this.fragment.element()); + this.contentElement.style.overflow = 'auto'; + } + + setElementsHandled(handled = 0, total = 0) { + // TODO(aerotwist): We might want to switch this to using Intl.PluralRules in the future + // @see https://v8.dev/features/intl-pluralrules + const elementsTotal = total > 0 ? ls`document elements` : ls`document element`; + this.fragment.$('processed').textContent = + ls`Processed ${this._formatter.format(handled)} of ${this._formatter.format(total)} ${elementsTotal}.`; + } +};
diff --git a/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewSidebarPanel.js b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewSidebarPanel.js new file mode 100644 index 0000000..3955421 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewSidebarPanel.js
@@ -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. + +CssOverview.CSSOverviewSidebarPanel = class extends UI.VBox { + static get ITEM_CLASS_NAME() { + return 'overview-sidebar-panel-item'; + } + + static get SELECTED() { + return 'selected'; + } + + constructor() { + super(true); + + this.registerRequiredCSS('css_overview/cssOverviewSidebarPanel.css'); + this.contentElement.classList.add('overview-sidebar-panel'); + this.contentElement.addEventListener('click', this._onItemClick.bind(this)); + + // Clear overview. + const clearResultsButton = new UI.ToolbarButton(ls`Clear overview`, 'largeicon-clear'); + clearResultsButton.addEventListener(UI.ToolbarButton.Events.Click, this._reset, this); + + // Toolbar. + const toolbarElement = this.contentElement.createChild('div', 'overview-toolbar'); + const toolbar = new UI.Toolbar('', toolbarElement); + toolbar.appendToolbarItem(clearResultsButton); + } + + addItem(name, id) { + const item = this.contentElement.createChild('div', CssOverview.CSSOverviewSidebarPanel.ITEM_CLASS_NAME); + item.textContent = name; + item.dataset.id = id; + } + + _reset() { + this.dispatchEventToListeners(CssOverview.SidebarEvents.Reset); + } + + _deselectAllItems() { + const items = this.contentElement.querySelectorAll(`.${CssOverview.CSSOverviewSidebarPanel.ITEM_CLASS_NAME}`); + for (const item of items) + item.classList.remove(CssOverview.CSSOverviewSidebarPanel.SELECTED); + } + + _onItemClick(event) { + const target = event.path[0]; + if (!target.classList.contains(CssOverview.CSSOverviewSidebarPanel.ITEM_CLASS_NAME)) + return; + + const {id} = target.dataset; + this.select(id); + this.dispatchEventToListeners(CssOverview.SidebarEvents.ItemSelected, id); + } + + select(id) { + const target = this.contentElement.querySelector(`[data-id=${CSS.escape(id)}]`); + if (!target) + return; + + if (target.classList.contains(CssOverview.CSSOverviewSidebarPanel.SELECTED)) + return; + + this._deselectAllItems(); + target.classList.add(CssOverview.CSSOverviewSidebarPanel.SELECTED); + } +}; + +CssOverview.SidebarEvents = { + ItemSelected: Symbol('ItemSelected'), + Reset: Symbol('Reset') +};
diff --git a/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewStartView.js b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewStartView.js new file mode 100644 index 0000000..d19cc9e --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewStartView.js
@@ -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. + +/** + * @unrestricted + */ +CssOverview.CSSOverviewStartView = class extends UI.Widget { + constructor(controller) { + super(); + this.registerRequiredCSS('css_overview/cssOverviewStartView.css'); + + this._controller = controller; + this._render(); + } + + _render() { + const startButton = UI.createTextButton( + ls`Capture overview`, () => this._controller.dispatchEventToListeners(CssOverview.Events.RequestOverviewStart), + '', true /* primary */); + + this.setDefaultFocusedElement(startButton); + + const fragment = UI.Fragment.build` + <div class="vbox overview-start-view"> + <h1>${ls`CSS Overview`}</h1> + <div>${startButton}</div> + </div> + `; + + this.contentElement.appendChild(fragment.element()); + this.contentElement.style.overflow = 'auto'; + } +};
diff --git a/third_party/blink/renderer/devtools/front_end/css_overview/cssOverview.css b/third_party/blink/renderer/devtools/front_end/css_overview/cssOverview.css new file mode 100644 index 0000000..944bafacf --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/css_overview/cssOverview.css
@@ -0,0 +1,9 @@ +/** + * 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. + */ + +.css-overview-panel { + overflow: hidden; +}
diff --git a/third_party/blink/renderer/devtools/front_end/css_overview/cssOverviewCompletedView.css b/third_party/blink/renderer/devtools/front_end/css_overview/cssOverviewCompletedView.css new file mode 100644 index 0000000..fa6f0d4 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/css_overview/cssOverviewCompletedView.css
@@ -0,0 +1,81 @@ +/** + * 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. + */ + +.overview-completed-view { + overflow: auto; +} + +.overview-completed-view .summary ul, +.overview-completed-view .colors ul { + list-style: none; + padding: 0; + margin: 0; +} + +.overview-completed-view .summary ul { + display: grid; + grid-template-columns: repeat(auto-fill, 140px); + grid-gap: 16px; +} + +.overview-completed-view .colors ul li { + display: inline-block; + padding: 0; + margin: 0 0 16px 0; +} + +.overview-completed-view .summary ul li { + display: flex; + flex-direction: column; + grid-column-start: auto; +} + +.overview-completed-view li .label { + font-size: 12px; + padding-bottom: 2px; +} + +.overview-completed-view li .value { + font-size: 17px; +} + +.overview-completed-view ul li span { + font-weight: bold; +} + +.block { + width: 65px; + height: 25px; + border-radius: 3px; + margin-right: 16px; +} + +.block-title { + padding-top: 4px; + font-size: 12px; + color: #303942; + text-transform: uppercase; + letter-spacing: 0; +} + +.results-section { + flex-shrink: 0; + padding: 28px; + border-bottom: 1px solid #E6E6E6; +} + +.results-section h1 { + font-size: 15px; + font-weight: normal; + padding: 0; + margin: 0 0 20px 0; +} + +.results-section.colors h2 { + margin-top: 20px; + font-size: 13px; + font-weight: normal; +}
diff --git a/third_party/blink/renderer/devtools/front_end/css_overview/cssOverviewProcessingView.css b/third_party/blink/renderer/devtools/front_end/css_overview/cssOverviewProcessingView.css new file mode 100644 index 0000000..a91165b1 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/css_overview/cssOverviewProcessingView.css
@@ -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. + */ + +.overview-processing-view { + overflow: hidden; +} + +.overview-processing-view { + overflow: hidden; + padding: 16px; + justify-content: center; + align-items: center; + height: 100%; +} + +.overview-processing-view h1 { + font-size: 16px; + text-align: center; + font-weight: normal; + margin: 0; + padding: 8px; +} + +.overview-processing-view h2 { + font-size: 12px; + text-align: center; + font-weight: normal; + margin: 0; + padding-top: 32px; +}
diff --git a/third_party/blink/renderer/devtools/front_end/css_overview/cssOverviewSidebarPanel.css b/third_party/blink/renderer/devtools/front_end/css_overview/cssOverviewSidebarPanel.css new file mode 100644 index 0000000..45025dc --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/css_overview/cssOverviewSidebarPanel.css
@@ -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. + */ + +.overview-sidebar-panel { + overflow: auto; + display: flex; + background: #F3F3F3; +} + +.overview-sidebar-panel-item { + height: 30px; + padding-left: 30px; + display: flex; + align-items: center; + cursor: pointer; +} + +.overview-sidebar-panel-item:hover, +.overview-sidebar-panel-item:focus { + background: rgb(234, 234, 234); +} + +.overview-sidebar-panel-item.selected { + background: #1A73E8; + color: #FFFFFF; +} + +.overview-toolbar { + border-bottom: 1px solid rgb(204, 204, 204); +}
diff --git a/third_party/blink/renderer/devtools/front_end/css_overview/cssOverviewStartView.css b/third_party/blink/renderer/devtools/front_end/css_overview/cssOverviewStartView.css new file mode 100644 index 0000000..1c3d870 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/css_overview/cssOverviewStartView.css
@@ -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. + */ + +.overview-start-view { + overflow: hidden; + padding: 16px; + justify-content: center; + align-items: center; + height: 100%; +} + +.overview-start-view h1 { + font-size: 16px; + text-align: center; + font-weight: normal; + margin: 0; + padding: 8px; +} + +.overview-start-view div { + font-size: 12px; + text-align: center; + font-weight: normal; + margin: 0; + padding-bottom: 44px; +}
diff --git a/third_party/blink/renderer/devtools/front_end/css_overview/css_overview_strings.grdp b/third_party/blink/renderer/devtools/front_end/css_overview/css_overview_strings.grdp new file mode 100644 index 0000000..87042a3 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/css_overview/css_overview_strings.grdp
@@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="utf-8"?> +<grit-part> + <message name="IDS_DEVTOOLS_01ac702a8b31775d1cdbc30ec453e611" desc="Label for the number of non-simple selectors in the CSS Overview report"> + Non-simple selectors + </message> + <message name="IDS_DEVTOOLS_1049ae5279b7a1b50dddec905ed992df" desc="Label for the number ofstyle rules in CSS Overview report"> + Style rules + </message> + <message name="IDS_DEVTOOLS_196c5897880c864a303527f5d8e7cb77" desc="Label for unique background colors in the CSS Overview report"> + Unique background colors: <ph name="BACKGROUNDCOLORS_LENGTH">$1s<ex>17</ex></ph> + </message> + <message name="IDS_DEVTOOLS_1f1621cad66c8f661842bf9392d8559b" desc="Label for the summary in the CSS Overview report"> + Overview summary + </message> + <message name="IDS_DEVTOOLS_23717568804f63f75e7596dcced3119e" desc="Label for the number of universal selectors in the CSS Overview report"> + Universal selectors + </message> + <message name="IDS_DEVTOOLS_396ea220fc4d34d57a5a505de918bdde" desc="Singular of 'document element' in the processing update message"> + document element + </message> + <message name="IDS_DEVTOOLS_4b3e6e4359cfb882a3b8b551f38a92c7" desc="Label for unique text colors in the CSS Overview Panel"> + Unique text colors: <ph name="TEXTCOLORS_LENGTH">$1s<ex>32</ex></ph> + </message> + <message name="IDS_DEVTOOLS_52798275481d47b10f5b8e31310b155e" desc="Label for the update message in the processing stage of CSS Overview"> + Processed <ph name="THIS__FORMATTER_FORMAT_HANDLED_">$1s<ex>23</ex></ph> of <ph name="THIS__FORMATTER_FORMAT_TOTAL_">$2s<ex>1,223</ex></ph> <ph name="ELEMENTSTOTAL">$3s<ex>document elements</ex></ph>. + </message> + <message name="IDS_DEVTOOLS_5d50889672f6f860d14f502de3de1957" desc="Title of colors subsection in the CSS Overview Panel"> + Colors + </message> + <message name="IDS_DEVTOOLS_62d79b9db9edfb64bd8c538cb9ed0190" desc="Label for the number of media rules in the CSS Overview report"> + Media rules + </message> + <message name="IDS_DEVTOOLS_6ad170a0581c9c116ca254758bd0c5b9" desc="Label for the number of ID selectors in the CSS Overview report"> + ID selectors + </message> + <message name="IDS_DEVTOOLS_811b0dc0576a9743353448d08b400f45" desc="Label for the number of Attribute selectors in the CSS Overview report"> + Attribute selectors + </message> + <message name="IDS_DEVTOOLS_8781fdba66e6cf7177ce03ea3db8a35a" desc="Label for the number of class selectors in the CSS Overview report"> + Class selectors + </message> + <message name="IDS_DEVTOOLS_8a2d39bc733e82310760e2767889673a" desc="Title of the CSS Overview Panel"> + CSS Overview + </message> + <message name="IDS_DEVTOOLS_95d366a44bd7bad09d9916e05b512cc6" desc="Label for the number of External stylesheets in the CSS Overview report"> + External stylesheets + </message> + <message name="IDS_DEVTOOLS_a9427e421abd9fd7ba45212c25ba55a5" desc="Plural of 'document element' in the processing update message"> + document elements + </message> + <message name="IDS_DEVTOOLS_aff1062318f6d07520a0feba60f3f253" desc="Label for the number of type selectors in the CSS Overview report"> + Type selectors + </message> + <message name="IDS_DEVTOOLS_cd9c2b5232bcbda828c542a9f5306f8e" desc="Label for the 'Elements processed' button in the CSS Overview report"> + Elements processed + </message> + <message name="IDS_DEVTOOLS_d4a993a4b0d13c2cc4ce9387af1604ce" desc="Label for the 'Clear overview' button in the CSS Overview report"> + Clear overview + </message> + <message name="IDS_DEVTOOLS_e9c6934e961dad71d311f68c679dfd3b" desc="Label for the capture button in the CSS Overview Panel"> + Capture overview + </message> + <message name="IDS_DEVTOOLS_f1637e0528f8c9d37be5de8b50fd2926" desc="Label for the number of inline style elements in the CSS Overview report"> + Inline style elements + </message> +</grit-part>
diff --git a/third_party/blink/renderer/devtools/front_end/css_overview/module.json b/third_party/blink/renderer/devtools/front_end/css_overview/module.json new file mode 100644 index 0000000..4e447cd --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/css_overview/module.json
@@ -0,0 +1,34 @@ +{ + "extensions": [ + { + "type": "view", + "location": "panel", + "id": "cssoverview", + "title": "CSS Overview", + "className": "CssOverview.CSSOverviewPanel", + "order": 95, + "experiment": "cssOverview" + } + ], + "dependencies": [ + "elements", + "ui", + "sdk" + ], + "scripts": [ + "CSSOverviewController.js", + "CSSOverviewModel.js", + "CSSOverviewStartView.js", + "CSSOverviewProcessingView.js", + "CSSOverviewCompletedView.js", + "CSSOverviewSidebarPanel.js", + "CSSOverviewPanel.js" + ], + "resources": [ + "cssOverview.css", + "cssOverviewStartView.css", + "cssOverviewProcessingView.css", + "cssOverviewCompletedView.css", + "cssOverviewSidebarPanel.css" + ] +}
diff --git a/third_party/blink/renderer/devtools/front_end/devices/DevicesView.js b/third_party/blink/renderer/devtools/front_end/devices/DevicesView.js index 3b8e4808..59f72dda 100644 --- a/third_party/blink/renderer/devtools/front_end/devices/DevicesView.js +++ b/third_party/blink/renderer/devtools/front_end/devices/DevicesView.js
@@ -44,13 +44,12 @@ this._selectSidebarListItem(this._discoveryListItem, this._discoveryView); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.DevicesUpdated, this._devicesUpdated, this); + Host.InspectorFrontendHostAPI.Events.DevicesUpdated, this._devicesUpdated, this); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this); + Host.InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.DevicesPortForwardingStatusChanged, this._devicesPortForwardingStatusChanged, - this); - + Host.InspectorFrontendHostAPI.Events.DevicesPortForwardingStatusChanged, + this._devicesPortForwardingStatusChanged, this); } /**
diff --git a/third_party/blink/renderer/devtools/front_end/devices/devices_strings.grdp b/third_party/blink/renderer/devtools/front_end/devices/devices_strings.grdp index 8ca703dd..1a3c208 100644 --- a/third_party/blink/renderer/devtools/front_end/devices/devices_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/devices/devices_strings.grdp
@@ -4,7 +4,7 @@ Port Forwarding: </message> <message name="IDS_DEVTOOLS_034fd013261994214d1e8cb42571d191" desc="Text in Devices View of the Remote Devices tab"> - Need help? Read Chrome <ph name="DOCUMENTATIONLINK">$1s<ex>documentation link</ex></ph>. + Need help? Read <ph name="LOCKED_1">Chrome</ph> <ph name="DOCUMENTATIONLINK">$1s<ex>documentation link</ex></ph>. </message> <message name="IDS_DEVTOOLS_03fc5c0bd59679c442b86074c7a7cc3a" desc="Text in Devices View of the Remote Devices tab"> Port forwarding
diff --git a/third_party/blink/renderer/devtools/front_end/devtools_app.json b/third_party/blink/renderer/devtools/front_end/devtools_app.json index 79074d56..f50defe 100644 --- a/third_party/blink/renderer/devtools/front_end/devtools_app.json +++ b/third_party/blink/renderer/devtools/front_end/devtools_app.json
@@ -8,6 +8,7 @@ { "name": "animation" }, { "name": "audits" }, { "name": "browser_debugger" }, + { "name": "css_overview" }, { "name": "cookie_table" }, { "name": "devices" }, { "name": "elements" },
diff --git a/third_party/blink/renderer/devtools/front_end/emulated_devices/emulated_devices_strings.grdp b/third_party/blink/renderer/devtools/front_end/emulated_devices/emulated_devices_strings.grdp index 053c7c38e..2a2c2260 100644 --- a/third_party/blink/renderer/devtools/front_end/emulated_devices/emulated_devices_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/emulated_devices/emulated_devices_strings.grdp
@@ -4,99 +4,99 @@ Laptop with MDPI screen </message> <message name="IDS_DEVTOOLS_079a3d134d2387adc52b2b3895f85e55" desc="Title of the iPhone X device"> - iPhone X + <ph name="LOCKED_1">iPhone X</ph> </message> <message name="IDS_DEVTOOLS_0d1160fe394d87ddbc2ca8e7cc25379d" desc="Title of the Laptop with touch device"> Laptop with touch </message> <message name="IDS_DEVTOOLS_0e5aeadd53726e96d7d9faa671b423ae" desc="Title of the Kindle Fire HDX device"> - Kindle Fire HDX + <ph name="LOCKED_1">Kindle Fire HDX</ph> </message> <message name="IDS_DEVTOOLS_1b9018182a49e16ba85bb095f224867c" desc="Title of the iPad device"> - iPad + <ph name="LOCKED_1">iPad</ph> </message> <message name="IDS_DEVTOOLS_2235bd527cc1684230b1db146c570a9d" desc="Title of the Pixel 2 device"> - Pixel 2 + <ph name="LOCKED_1">Pixel 2</ph> </message> <message name="IDS_DEVTOOLS_2c17ed2506add59c15ea763801cfafb1" desc="Title of the Nexus 6 device"> - Nexus 6 + <ph name="LOCKED_1">Nexus 6</ph> </message> <message name="IDS_DEVTOOLS_2d1fbe61c136940101281ec1df805c01" desc="Title of the Nexus 5 device"> - Nexus 5 + <ph name="LOCKED_1">Nexus 5</ph> </message> <message name="IDS_DEVTOOLS_2d9a25096b47a022c95787ab90308d6b" desc="Title of the LG Optimus L70 device"> - LG Optimus L70 + <ph name="LOCKED_1">LG Optimus L70</ph> </message> <message name="IDS_DEVTOOLS_4a321c67ad4bac0f3386f5e257b1fba3" desc="Title of the Laptop with HiDPI screen device"> Laptop with HiDPI screen </message> <message name="IDS_DEVTOOLS_6247fa438881677e5f910b89db1974a7" desc="Title of the Nokia N9 device"> - Nokia N9 + <ph name="LOCKED_1">Nokia N9</ph> </message> <message name="IDS_DEVTOOLS_659810deafc0279869114daf8446ef4a" desc="Title of the Nexus 10 device"> - Nexus 10 + <ph name="LOCKED_1">Nexus 10</ph> </message> <message name="IDS_DEVTOOLS_6d9131a4a569108e7d19038b27111c86" desc="Title of the Nexus 5X device"> - Nexus 5X + <ph name="LOCKED_1">Nexus 5X</ph> </message> <message name="IDS_DEVTOOLS_71e3580e3c3a03f17798ebccaad9e6cb" desc="Title of the Nexus 7 device"> - Nexus 7 + <ph name="LOCKED_1">Nexus 7</ph> </message> <message name="IDS_DEVTOOLS_71f859515e31ad9bb417977247315f0a" desc="Title of the iPad Pro device"> - iPad Pro + <ph name="LOCKED_1">iPad Pro</ph> </message> <message name="IDS_DEVTOOLS_76c4064f51952f873baa0f9a201b49a3" desc="Title of the Nokia Lumia 520 device"> - Nokia Lumia 520 + <ph name="LOCKED_1">Nokia Lumia 520</ph> </message> <message name="IDS_DEVTOOLS_8be08fbcf1f787159e451a97a7c1cc90" desc="Title of the iPhone 6/7/8 Plus device"> - iPhone 6/7/8 Plus + <ph name="LOCKED_1">iPhone 6/7/8 Plus</ph> </message> <message name="IDS_DEVTOOLS_8d0c6a99bcfbb75724c123476d683d3f" desc="Title of the iPhone 4 device"> - iPhone 4 + <ph name="LOCKED_1">iPhone 4</ph> </message> <message name="IDS_DEVTOOLS_99d1a0f994cdce14eea8b6ae823d5a76" desc="Title of the Galaxy S III device"> - Galaxy S III + <ph name="LOCKED_1">Galaxy S III</ph> </message> <message name="IDS_DEVTOOLS_a75624548994321c1cc7173b9933438b" desc="Title of the Microsoft Lumia 550 device"> - Microsoft Lumia 550 + <ph name="LOCKED_1">Microsoft Lumia 550</ph> </message> <message name="IDS_DEVTOOLS_aa5fa1bdadb078da054c34752031a5e9" desc="Title of the iPhone 6/7/8 device"> - iPhone 6/7/8 + <ph name="LOCKED_1">iPhone 6/7/8</ph> </message> <message name="IDS_DEVTOOLS_b9e5554cdd9d9f2d3df1f30914b617c2" desc="Title of the Galaxy Note 3 device"> - Galaxy Note 3 + <ph name="LOCKED_1">Galaxy Note 3</ph> </message> <message name="IDS_DEVTOOLS_be6a9d69eff86af39e5a73345c585da6" desc="Title of the iPad Mini device"> - iPad Mini + <ph name="LOCKED_1">iPad Mini</ph> </message> <message name="IDS_DEVTOOLS_c99b8431589c0273278e87ebf44a7fd6" desc="Title of the iPhone 5/SE device"> - iPhone 5/SE + <ph name="LOCKED_1">iPhone 5/SE</ph> </message> <message name="IDS_DEVTOOLS_cc810fb8b8bc7c7d6a8327f0e7b2aead" desc="Title of the Nexus 6P device"> - Nexus 6P + <ph name="LOCKED_1">Nexus 6P</ph> </message> <message name="IDS_DEVTOOLS_d4f2f5453f28c5fd35c68f52e4da07cd" desc="Title of the BlackBerry Z30 device"> - BlackBerry Z30 + <ph name="LOCKED_1">BlackBerry Z30</ph> </message> <message name="IDS_DEVTOOLS_d6162eb3dd4dc5a9bc67222e24f19b25" desc="Title of the Nexus 4 device"> - Nexus 4 + <ph name="LOCKED_1">Nexus 4</ph> </message> <message name="IDS_DEVTOOLS_d8860bf736e83cfb5c13ee82a8f61a43" desc="Title of the Microsoft Lumia 950 device"> - Microsoft Lumia 950 + <ph name="LOCKED_1">Microsoft Lumia 950</ph> </message> <message name="IDS_DEVTOOLS_dfd6e576e036db4f857c8c03c977d975" desc="Title of the Galaxy Note II device"> - Galaxy Note II + <ph name="LOCKED_1">Galaxy Note II</ph> </message> <message name="IDS_DEVTOOLS_e0261d2f1730ebff89bbde9a4bc74ac5" desc="Title of the JioPhone 2 device"> - JioPhone 2 + <ph name="LOCKED_1">JioPhone 2</ph> </message> <message name="IDS_DEVTOOLS_e770076f957c87605ff906d0ed2c4b52" desc="Title of the Blackberry PlayBook device"> - Blackberry PlayBook + <ph name="LOCKED_1">Blackberry PlayBook</ph> </message> <message name="IDS_DEVTOOLS_eb850446088fbc75e974788cc2b39caa" desc="Title of the Pixel 2 XL device"> - Pixel 2 XL + <ph name="LOCKED_1">Pixel 2 XL</ph> </message> <message name="IDS_DEVTOOLS_f8896f769d62b6102e48039154c4ca5e" desc="Title of the Galaxy S5 device"> - Galaxy S5 + <ph name="LOCKED_1">Galaxy S5</ph> </message> </grit-part> \ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/emulation/emulation_strings.grdp b/third_party/blink/renderer/devtools/front_end/emulation/emulation_strings.grdp index 4eaa21f..ee369b04 100644 --- a/third_party/blink/renderer/devtools/front_end/emulation/emulation_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/emulation/emulation_strings.grdp
@@ -100,7 +100,7 @@ Latitude </message> <message name="IDS_DEVTOOLS_414b730ab2cf9123d9230740864ffeec" desc="A context menu item in the Device Mode Toolbar of the Device Toolbar"> - Close DevTools + Close <ph name="LOCKED_1">DevTools</ph> </message> <message name="IDS_DEVTOOLS_45f80006d304f294d6c1de50c244856e" desc="Text of add geolocations button in Geolocations Settings Tab of the Device Toolbar"> Add location...
diff --git a/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js b/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js index 5953633..c1a2a097 100644 --- a/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js +++ b/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js
@@ -83,7 +83,7 @@ window.addEventListener('message', this._onWindowMessage.bind(this), false); // Only for main window. InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.SetInspectedTabId, this._setInspectedTabId, this); + Host.InspectorFrontendHostAPI.Events.SetInspectedTabId, this._setInspectedTabId, this); this._initExtensions(); }
diff --git a/third_party/blink/renderer/devtools/front_end/externs.js b/third_party/blink/renderer/devtools/front_end/externs.js index 48017b8..eaaf2a7 100644 --- a/third_party/blink/renderer/devtools/front_end/externs.js +++ b/third_party/blink/renderer/devtools/front_end/externs.js
@@ -1164,3 +1164,315 @@ * @return {string} */ Lighthouse.ReportGenerator.replaceStrings; + +/** @interface */ +class InspectorFrontendHostAPI { + /** + * @param {string=} type + */ + addFileSystem(type) { + } + + loadCompleted() { + } + + /** + * @param {number} requestId + * @param {string} fileSystemPath + * @param {string} excludedFolders + */ + indexPath(requestId, fileSystemPath, excludedFolders) { + } + + /** + * Requests inspected page to be placed atop of the inspector frontend with specified bounds. + * @param {{x: number, y: number, width: number, height: number}} bounds + */ + setInspectedPageBounds(bounds) { + } + + /** + * @param {!Array<string>} certChain + */ + showCertificateViewer(certChain) { + } + + /** + * @param {string} shortcuts + */ + setWhitelistedShortcuts(shortcuts) { + } + + /** + * @param {boolean} active + */ + setEyeDropperActive(active) { + } + + inspectElementCompleted() { + } + + /** + * @param {string} url + */ + openInNewTab(url) { + } + + /** + * @param {string} fileSystemPath + */ + showItemInFolder(fileSystemPath) { + } + + /** + * @param {string} fileSystemPath + */ + removeFileSystem(fileSystemPath) { + } + + requestFileSystems() { + } + + /** + * @param {string} url + * @param {string} content + * @param {boolean} forceSaveAs + */ + save(url, content, forceSaveAs) { + } + + /** + * @param {string} url + * @param {string} content + */ + append(url, content) { + } + + /** + * @param {string} url + */ + close(url) { + } + + /** + * @param {number} requestId + * @param {string} fileSystemPath + * @param {string} query + */ + searchInPath(requestId, fileSystemPath, query) { + } + + /** + * @param {number} requestId + */ + stopIndexing(requestId) { + } + + bringToFront() { + } + + closeWindow() { + } + + copyText(text) { + } + + /** + * @param {string} url + */ + inspectedURLChanged(url) { + } + + /** + * @param {string} fileSystemId + * @param {string} registeredName + * @return {?DOMFileSystem} + */ + isolatedFileSystem(fileSystemId, registeredName) { + } + + /** + * @param {string} url + * @param {string} headers + * @param {number} streamId + * @param {function(!InspectorFrontendHostAPI.LoadNetworkResourceResult)} callback + */ + loadNetworkResource(url, headers, streamId, callback) { + } + + /** + * @param {function(!Object<string, string>)} callback + */ + getPreferences(callback) { + } + + /** + * @param {string} name + * @param {string} value + */ + setPreference(name, value) { + } + + /** + * @param {string} name + */ + removePreference(name) { + } + + clearPreferences() { + } + + /** + * @param {!FileSystem} fileSystem + */ + upgradeDraggedFileSystemPermissions(fileSystem) { + } + + /** + * @return {string} + */ + platform() { + } + + /** + * @param {string} actionName + * @param {number} actionCode + * @param {number} bucketSize + */ + recordEnumeratedHistogram(actionName, actionCode, bucketSize) { + } + + /** + * @param {string} histogramName + * @param {number} duration + */ + recordPerformanceHistogram(histogramName, duration) { + } + + /** + * @param {string} umaName + */ + recordUserMetricsAction(umaName) { + } + + /** + * @param {string} message + */ + sendMessageToBackend(message) { + } + + /** + * @param {!Adb.Config} config + */ + setDevicesDiscoveryConfig(config) { + } + + /** + * @param {boolean} enabled + */ + setDevicesUpdatesEnabled(enabled) { + } + + /** + * @param {string} pageId + * @param {string} action + */ + performActionOnRemotePage(pageId, action) { + } + + /** + * @param {string} browserId + * @param {string} url + */ + openRemotePage(browserId, url) { + } + + openNodeFrontend() { + } + + /** + * @param {string} origin + * @param {string} script + */ + setInjectedScriptForOrigin(origin, script) { + } + + /** + * @param {boolean} isDocked + * @param {function()} callback + */ + setIsDocked(isDocked, callback) { + } + + /** + * @return {number} + */ + zoomFactor() { + } + + zoomIn() { + } + + zoomOut() { + } + + resetZoom() { + } + + /** + * @param {number} x + * @param {number} y + * @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items + * @param {!Document} document + */ + showContextMenuAtPoint(x, y, items, document) { + } + + /** + * @param {function()} callback + */ + reattach(callback) { + } + + readyForTest() { + } + + connectionReady() { + } + + /** + * @param {boolean} value + */ + setOpenNewWindowForPopups(value) { + } + + /** + * @return {boolean} + */ + isHostedMode() { + } + + /** + * @param {function(!ExtensionDescriptor)} callback + */ + setAddExtensionCallback(callback) { + } +} + +/** @typedef +{{ + type: string, + id: (number|undefined), + label: (string|undefined), + enabled: (boolean|undefined), + checked: (boolean|undefined), + subItems: (!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>|undefined) +}} */ +InspectorFrontendHostAPI.ContextMenuDescriptor; + +/** @typedef +{{ + statusCode: number, + headers: (!Object.<string, string>|undefined) +}} */ +InspectorFrontendHostAPI.LoadNetworkResourceResult; \ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/help/help_strings.grdp b/third_party/blink/renderer/devtools/front_end/help/help_strings.grdp index e71d504..ad49d79 100644 --- a/third_party/blink/renderer/devtools/front_end/help/help_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/help/help_strings.grdp
@@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <grit-part> <message name="IDS_DEVTOOLS_8381815d48c2d49f31dce1807ae0507c" desc="Title of an action in the help tool to file an issue"> - Report a DevTools issue + Report a <ph name="LOCKED_1">DevTools</ph> issue </message> <message name="IDS_DEVTOOLS_7d0ee6fed10d3d4e5c9ee496729ab519" desc="Title of an action in the help tool to release notes"> Release notes
diff --git a/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js b/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js index af2b1633..6249a30 100644 --- a/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js +++ b/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js
@@ -50,6 +50,11 @@ * @type {!Map<string, !Array<string>>} */ this._urlsBeingSaved = new Map(); + + /** + * @type {!Common.EventTarget} + */ + this.events; } /** @@ -128,10 +133,12 @@ /** * @override - * @param {string} text + * @param {?(string|undefined)} text * @suppressGlobalPropertiesCheck */ copyText(text) { + if (text === undefined || text === null) + return; if (navigator.clipboard) { navigator.clipboard.writeText(text); } else if (document.queryCommandSupported('copy')) { @@ -175,7 +182,7 @@ this._urlsBeingSaved.set(url, buffer); } buffer.push(content); - this.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.SavedURL, {url, fileSystemPath: url}); + this.events.dispatchEventToListeners(Host.InspectorFrontendHostAPI.Events.SavedURL, {url, fileSystemPath: url}); } /** @@ -186,7 +193,7 @@ append(url, content) { const buffer = this._urlsBeingSaved.get(url); buffer.push(content); - this.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.AppendedToURL, url); + this.events.dispatchEventToListeners(Host.InspectorFrontendHostAPI.Events.AppendedToURL, url); } /** @@ -239,7 +246,7 @@ * @override */ requestFileSystems() { - this.events.dispatchEventToListeners(InspectorFrontendHostAPI.Events.FileSystemsLoaded, []); + this.events.dispatchEventToListeners(Host.InspectorFrontendHostAPI.Events.FileSystemsLoaded, []); } /** @@ -496,7 +503,7 @@ this._debugFrontend = !!Runtime.queryParam('debugFrontend') || (window['InspectorTest'] && window['InspectorTest']['debugTest']); - const descriptors = InspectorFrontendHostAPI.EventDescriptors; + const descriptors = Host.InspectorFrontendAPIImpl.EventDescriptors; for (let i = 0; i < descriptors.length; ++i) this[descriptors[i][1]] = this._dispatch.bind(this, descriptors[i][0], descriptors[i][2], descriptors[i][3]); } @@ -544,8 +551,47 @@ } }; +Host.InspectorFrontendAPIImpl.EventDescriptors = [ + [Host.InspectorFrontendHostAPI.Events.AppendedToURL, 'appendedToURL', ['url']], + [Host.InspectorFrontendHostAPI.Events.CanceledSaveURL, 'canceledSaveURL', ['url']], + [Host.InspectorFrontendHostAPI.Events.ContextMenuCleared, 'contextMenuCleared', []], + [Host.InspectorFrontendHostAPI.Events.ContextMenuItemSelected, 'contextMenuItemSelected', ['id']], + [Host.InspectorFrontendHostAPI.Events.DeviceCountUpdated, 'deviceCountUpdated', ['count']], + [Host.InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, 'devicesDiscoveryConfigChanged', ['config']], + [ + Host.InspectorFrontendHostAPI.Events.DevicesPortForwardingStatusChanged, 'devicesPortForwardingStatusChanged', + ['status'] + ], + [Host.InspectorFrontendHostAPI.Events.DevicesUpdated, 'devicesUpdated', ['devices']], + [Host.InspectorFrontendHostAPI.Events.DispatchMessage, 'dispatchMessage', ['messageObject']], + [Host.InspectorFrontendHostAPI.Events.DispatchMessageChunk, 'dispatchMessageChunk', ['messageChunk', 'messageSize']], + [Host.InspectorFrontendHostAPI.Events.EnterInspectElementMode, 'enterInspectElementMode', []], + [Host.InspectorFrontendHostAPI.Events.EyeDropperPickedColor, 'eyeDropperPickedColor', ['color']], + [Host.InspectorFrontendHostAPI.Events.FileSystemsLoaded, 'fileSystemsLoaded', ['fileSystems']], + [Host.InspectorFrontendHostAPI.Events.FileSystemRemoved, 'fileSystemRemoved', ['fileSystemPath']], + [Host.InspectorFrontendHostAPI.Events.FileSystemAdded, 'fileSystemAdded', ['errorMessage', 'fileSystem']], + [ + Host.InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, 'fileSystemFilesChangedAddedRemoved', + ['changed', 'added', 'removed'] + ], + [ + Host.InspectorFrontendHostAPI.Events.IndexingTotalWorkCalculated, 'indexingTotalWorkCalculated', + ['requestId', 'fileSystemPath', 'totalWork'] + ], + [Host.InspectorFrontendHostAPI.Events.IndexingWorked, 'indexingWorked', ['requestId', 'fileSystemPath', 'worked']], + [Host.InspectorFrontendHostAPI.Events.IndexingDone, 'indexingDone', ['requestId', 'fileSystemPath']], + [Host.InspectorFrontendHostAPI.Events.KeyEventUnhandled, 'keyEventUnhandled', ['event']], + [Host.InspectorFrontendHostAPI.Events.ReloadInspectedPage, 'reloadInspectedPage', ['hard']], + [Host.InspectorFrontendHostAPI.Events.RevealSourceLine, 'revealSourceLine', ['url', 'lineNumber', 'columnNumber']], + [Host.InspectorFrontendHostAPI.Events.SavedURL, 'savedURL', ['url', 'fileSystemPath']], + [Host.InspectorFrontendHostAPI.Events.SearchCompleted, 'searchCompleted', ['requestId', 'fileSystemPath', 'files']], + [Host.InspectorFrontendHostAPI.Events.SetInspectedTabId, 'setInspectedTabId', ['tabId']], + [Host.InspectorFrontendHostAPI.Events.SetUseSoftMenu, 'setUseSoftMenu', ['useSoftMenu']], + [Host.InspectorFrontendHostAPI.Events.ShowPanel, 'showPanel', ['panelName']] +]; + /** - * @type {!InspectorFrontendHostAPI} + * @type {!Host.InspectorFrontendHostStub} */ let InspectorFrontendHost = window.InspectorFrontendHost; (function() { @@ -580,11 +626,6 @@ })(); /** - * @type {!Common.EventTarget} - */ -InspectorFrontendHost.events; - -/** * @param {!Object<string, string>=} prefs * @return {boolean} */
diff --git a/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js b/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js index f148630..e017314 100644 --- a/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js +++ b/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js
@@ -1,30 +1,11 @@ // Copyright (c) 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/** @interface */ -function InspectorFrontendHostAPI() { -} -window.InspectorFrontendHostAPI = InspectorFrontendHostAPI; -/** @typedef -{{ - type: string, - id: (number|undefined), - label: (string|undefined), - enabled: (boolean|undefined), - checked: (boolean|undefined), - subItems: (!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>|undefined) -}} */ -InspectorFrontendHostAPI.ContextMenuDescriptor; -/** @typedef -{{ - statusCode: number, - headers: (!Object.<string, string>|undefined) -}} */ -InspectorFrontendHostAPI.LoadNetworkResourceResult; +Host.InspectorFrontendHostAPI = {}; /** @enum {symbol} */ -InspectorFrontendHostAPI.Events = { +Host.InspectorFrontendHostAPI.Events = { AppendedToURL: Symbol('appendedToURL'), CanceledSaveURL: Symbol('canceledSaveURL'), ContextMenuCleared: Symbol('contextMenuCleared'), @@ -53,283 +34,3 @@ SetUseSoftMenu: Symbol('setUseSoftMenu'), ShowPanel: Symbol('showPanel') }; - -InspectorFrontendHostAPI.EventDescriptors = [ - [InspectorFrontendHostAPI.Events.AppendedToURL, 'appendedToURL', ['url']], - [InspectorFrontendHostAPI.Events.CanceledSaveURL, 'canceledSaveURL', ['url']], - [InspectorFrontendHostAPI.Events.ContextMenuCleared, 'contextMenuCleared', []], - [InspectorFrontendHostAPI.Events.ContextMenuItemSelected, 'contextMenuItemSelected', ['id']], - [InspectorFrontendHostAPI.Events.DeviceCountUpdated, 'deviceCountUpdated', ['count']], - [InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, 'devicesDiscoveryConfigChanged', ['config']], - [ - InspectorFrontendHostAPI.Events.DevicesPortForwardingStatusChanged, 'devicesPortForwardingStatusChanged', ['status'] - ], - [InspectorFrontendHostAPI.Events.DevicesUpdated, 'devicesUpdated', ['devices']], - [InspectorFrontendHostAPI.Events.DispatchMessage, 'dispatchMessage', ['messageObject']], - [InspectorFrontendHostAPI.Events.DispatchMessageChunk, 'dispatchMessageChunk', ['messageChunk', 'messageSize']], - [InspectorFrontendHostAPI.Events.EnterInspectElementMode, 'enterInspectElementMode', []], - [InspectorFrontendHostAPI.Events.EyeDropperPickedColor, 'eyeDropperPickedColor', ['color']], - [InspectorFrontendHostAPI.Events.FileSystemsLoaded, 'fileSystemsLoaded', ['fileSystems']], - [InspectorFrontendHostAPI.Events.FileSystemRemoved, 'fileSystemRemoved', ['fileSystemPath']], - [InspectorFrontendHostAPI.Events.FileSystemAdded, 'fileSystemAdded', ['errorMessage', 'fileSystem']], - [ - InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, 'fileSystemFilesChangedAddedRemoved', - ['changed', 'added', 'removed'] - ], - [ - InspectorFrontendHostAPI.Events.IndexingTotalWorkCalculated, 'indexingTotalWorkCalculated', - ['requestId', 'fileSystemPath', 'totalWork'] - ], - [InspectorFrontendHostAPI.Events.IndexingWorked, 'indexingWorked', ['requestId', 'fileSystemPath', 'worked']], - [InspectorFrontendHostAPI.Events.IndexingDone, 'indexingDone', ['requestId', 'fileSystemPath']], - [InspectorFrontendHostAPI.Events.KeyEventUnhandled, 'keyEventUnhandled', ['event']], - [InspectorFrontendHostAPI.Events.ReloadInspectedPage, 'reloadInspectedPage', ['hard']], - [InspectorFrontendHostAPI.Events.RevealSourceLine, 'revealSourceLine', ['url', 'lineNumber', 'columnNumber']], - [InspectorFrontendHostAPI.Events.SavedURL, 'savedURL', ['url', 'fileSystemPath']], - [InspectorFrontendHostAPI.Events.SearchCompleted, 'searchCompleted', ['requestId', 'fileSystemPath', 'files']], - [InspectorFrontendHostAPI.Events.SetInspectedTabId, 'setInspectedTabId', ['tabId']], - [InspectorFrontendHostAPI.Events.SetUseSoftMenu, 'setUseSoftMenu', ['useSoftMenu']], - [InspectorFrontendHostAPI.Events.ShowPanel, 'showPanel', ['panelName']] -]; - -InspectorFrontendHostAPI.prototype = { - /** - * @param {string=} type - */ - addFileSystem(type) {}, - - loadCompleted() {}, - - /** - * @param {number} requestId - * @param {string} fileSystemPath - * @param {string} excludedFolders - */ - indexPath(requestId, fileSystemPath, excludedFolders) {}, - - /** - * Requests inspected page to be placed atop of the inspector frontend with specified bounds. - * @param {{x: number, y: number, width: number, height: number}} bounds - */ - setInspectedPageBounds(bounds) {}, - - /** - * @param {!Array<string>} certChain - */ - showCertificateViewer(certChain) {}, - - /** - * @param {string} shortcuts - */ - setWhitelistedShortcuts(shortcuts) {}, - - /** - * @param {boolean} active - */ - setEyeDropperActive(active) {}, - - inspectElementCompleted() {}, - - /** - * @param {string} url - */ - openInNewTab(url) {}, - - /** - * @param {string} fileSystemPath - */ - showItemInFolder(fileSystemPath) {}, - - /** - * @param {string} fileSystemPath - */ - removeFileSystem(fileSystemPath) {}, - - requestFileSystems() {}, - - /** - * @param {string} url - * @param {string} content - * @param {boolean} forceSaveAs - */ - save(url, content, forceSaveAs) {}, - - /** - * @param {string} url - * @param {string} content - */ - append(url, content) {}, - - /** - * @param {string} url - */ - close(url) {}, - - /** - * @param {number} requestId - * @param {string} fileSystemPath - * @param {string} query - */ - searchInPath(requestId, fileSystemPath, query) {}, - - /** - * @param {number} requestId - */ - stopIndexing(requestId) {}, - - bringToFront() {}, - - closeWindow() {}, - - copyText(text) {}, - - /** - * @param {string} url - */ - inspectedURLChanged(url) {}, - - /** - * @param {string} fileSystemId - * @param {string} registeredName - * @return {?DOMFileSystem} - */ - isolatedFileSystem(fileSystemId, registeredName) {}, - - /** - * @param {string} url - * @param {string} headers - * @param {number} streamId - * @param {function(!InspectorFrontendHostAPI.LoadNetworkResourceResult)} callback - */ - loadNetworkResource(url, headers, streamId, callback) {}, - - /** - * @param {function(!Object<string, string>)} callback - */ - getPreferences(callback) {}, - - /** - * @param {string} name - * @param {string} value - */ - setPreference(name, value) {}, - - /** - * @param {string} name - */ - removePreference(name) {}, - - clearPreferences() {}, - - /** - * @param {!FileSystem} fileSystem - */ - upgradeDraggedFileSystemPermissions(fileSystem) {}, - - /** - * @return {string} - */ - platform() {}, - - /** - * @param {string} actionName - * @param {number} actionCode - * @param {number} bucketSize - */ - recordEnumeratedHistogram(actionName, actionCode, bucketSize) {}, - - /** - * @param {string} histogramName - * @param {number} duration - */ - recordPerformanceHistogram(histogramName, duration) {}, - - /** - * @param {string} umaName - */ - recordUserMetricsAction(umaName) {}, - - /** - * @param {string} message - */ - sendMessageToBackend(message) {}, - - /** - * @param {!Adb.Config} config - */ - setDevicesDiscoveryConfig(config) {}, - - /** - * @param {boolean} enabled - */ - setDevicesUpdatesEnabled(enabled) {}, - - /** - * @param {string} pageId - * @param {string} action - */ - performActionOnRemotePage(pageId, action) {}, - - /** - * @param {string} browserId - * @param {string} url - */ - openRemotePage(browserId, url) {}, - - openNodeFrontend() {}, - - /** - * @param {string} origin - * @param {string} script - */ - setInjectedScriptForOrigin(origin, script) {}, - - /** - * @param {boolean} isDocked - * @param {function()} callback - */ - setIsDocked(isDocked, callback) {}, - - /** - * @return {number} - */ - zoomFactor() {}, - - zoomIn() {}, - - zoomOut() {}, - - resetZoom() {}, - - /** - * @param {number} x - * @param {number} y - * @param {!Array.<!InspectorFrontendHostAPI.ContextMenuDescriptor>} items - * @param {!Document} document - */ - showContextMenuAtPoint(x, y, items, document) {}, - - /** - * @param {function()} callback - */ - reattach(callback) {}, - - readyForTest() {}, - - connectionReady() {}, - - /** - * @param {boolean} value - */ - setOpenNewWindowForPopups(value) {}, - - /** - * @return {boolean} - */ - isHostedMode() {}, - - /** - * @param {function(!ExtensionDescriptor)} callback - */ - setAddExtensionCallback(callback) {} -};
diff --git a/third_party/blink/renderer/devtools/front_end/host/host_strings.grdp b/third_party/blink/renderer/devtools/front_end/host/host_strings.grdp index a88edbb..020a2ff 100644 --- a/third_party/blink/renderer/devtools/front_end/host/host_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/host/host_strings.grdp
@@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <grit-part> <message name="IDS_DEVTOOLS_92bb7e733a12d24684262f046afcc2fd" desc="Document title in Inspector Frontend Host of the DevTools window"> - DevTools - <ph name="URL_REPLACE___HTTPS____________">$1s<ex>example.com</ex></ph> + <ph name="LOCKED_1">DevTools</ph> - <ph name="URL_REPLACE___HTTPS____________">$1s<ex>example.com</ex></ph> </message> </grit-part> \ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/inspector_main/InspectorMain.js b/third_party/blink/renderer/devtools/front_end/inspector_main/InspectorMain.js index 6808e0b..079b4e5 100644 --- a/third_party/blink/renderer/devtools/front_end/inspector_main/InspectorMain.js +++ b/third_party/blink/renderer/devtools/front_end/inspector_main/InspectorMain.js
@@ -38,7 +38,7 @@ new InspectorMain.BackendSettingsSync(); new MobileThrottling.NetworkPanelIndicator(); - InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.ReloadInspectedPage, event => { + InspectorFrontendHost.events.addEventListener(Host.InspectorFrontendHostAPI.Events.ReloadInspectedPage, event => { const hard = /** @type {boolean} */ (event.data); SDK.ResourceTreeModel.reloadAllPages(hard); });
diff --git a/third_party/blink/renderer/devtools/front_end/inspector_main/inspector_main_strings.grdp b/third_party/blink/renderer/devtools/front_end/inspector_main/inspector_main_strings.grdp index b073284..4f9582c 100644 --- a/third_party/blink/renderer/devtools/front_end/inspector_main/inspector_main_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/inspector_main/inspector_main_strings.grdp
@@ -13,7 +13,7 @@ Paint flashing </message> <message name="IDS_DEVTOOLS_0ef16a6645018dec4609e392c7e9bda1" desc="Title of a setting under the DevTools category that can be invoked through the Command Menu"> - Do not auto-open DevTools for popups + Do not auto-open <ph name="LOCKED_1">DevTools</ph> for popups </message> <message name="IDS_DEVTOOLS_1808fb32cf4e8a03daa326b48d4246eb" desc="Title of a setting under the Appearance category in Settings"> Disable paused state overlay @@ -46,7 +46,7 @@ Hit-test borders </message> <message name="IDS_DEVTOOLS_7e9495c56e55fa2c5236512bf80e5d2b" desc="Title of a setting under the Appearance category in Settings"> - Don't show Chrome Data Saver warning + Don't show <ph name="LOCKED_1">Chrome Data Saver</ph> warning </message> <message name="IDS_DEVTOOLS_8339f28e0c74e2c821b05332280c754b" desc="Title of a setting under the Network category in Settings"> Force ad blocking on this site @@ -55,7 +55,7 @@ Navigation </message> <message name="IDS_DEVTOOLS_8634af2a16e41305fc8dca2d67360810" desc="Title of button in inspector main"> - Open dedicated DevTools for Node.js + Open dedicated <ph name="LOCKED_1">DevTools</ph> for Node.js </message> <message name="IDS_DEVTOOLS_86f849e1a655c2df19f28cb3dfe07bc9" desc="Title of a setting under the Network category that can be invoked through the Command Menu"> Block ads on this site @@ -82,6 +82,6 @@ Hard reload page </message> <message name="IDS_DEVTOOLS_f23c9ba06e7123f0b4c906de90fbcc9f" desc="Title of a setting under the DevTools category that can be invoked through the Command Menu"> - Auto-open DevTools for popups + Auto-open <ph name="LOCKED_1">DevTools</ph> for popups </message> </grit-part> \ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/langpacks/devtools_ui_strings.grd b/third_party/blink/renderer/devtools/front_end/langpacks/devtools_ui_strings.grd index af6a9228..340e2c6 100644 --- a/third_party/blink/renderer/devtools/front_end/langpacks/devtools_ui_strings.grd +++ b/third_party/blink/renderer/devtools/front_end/langpacks/devtools_ui_strings.grd
@@ -24,6 +24,7 @@ <part file="../console_counters/console_counters_strings.grdp" /> <part file="../cookie_table/cookie_table_strings.grdp" /> <part file="../coverage/coverage_strings.grdp" /> + <part file="../css_overview/css_overview_strings.grdp" /> <part file="../data_grid/data_grid_strings.grdp" /> <part file="../devices/devices_strings.grdp" /> <part file="../elements/elements_strings.grdp" />
diff --git a/third_party/blink/renderer/devtools/front_end/langpacks/shared_strings.grdp b/third_party/blink/renderer/devtools/front_end/langpacks/shared_strings.grdp index 0fc5d67..887a1cd 100644 --- a/third_party/blink/renderer/devtools/front_end/langpacks/shared_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/langpacks/shared_strings.grdp
@@ -49,6 +49,9 @@ <message name="IDS_DEVTOOLS_193cfc9be3b995831c6af2fea6650e60" desc="Text that refers to one or a group of webpages"> Page </message> + <message name="IDS_DEVTOOLS_1c481aa99d081c32182011a758f73d33" desc="Text that only contain a placeholder"> + <ph name="DURATIONTEXT">$1s<ex>100ms (at 200ms)</ex></ph> + </message> <message name="IDS_DEVTOOLS_1eaeeaeb638fdf7f6eeb047abbfd0f1a" desc="Time of a single activity, as opposed to the total time"> Self Time </message> @@ -152,7 +155,7 @@ No breakpoints </message> <message name="IDS_DEVTOOLS_482a4dca0bbd8fcdda5acc6f95f3c279" desc="Title of the DevTools"> - DevTools + <ph name="LOCKED_1">DevTools</ph> </message> <message name="IDS_DEVTOOLS_49ee3087348e8d44e1feda1917443987" desc="Text for the name of something"> Name @@ -215,7 +218,7 @@ Errors </message> <message name="IDS_DEVTOOLS_5f0ea62e5bc9f795512ef292ff162a2a" desc="Text to disable cache while DevTools is open"> - Disable cache (while DevTools is open) + Disable cache (while <ph name="LOCKED_1">DevTools</ph> is open) </message> <message name="IDS_DEVTOOLS_5f8442a46861496e9d2a3d11be13692b" desc="Text to indicate DevTools is writing to a file"> Writing file… @@ -284,7 +287,7 @@ (index) </message> <message name="IDS_DEVTOOLS_850985cd851d0fe440f03f77762e2590" desc="Text for the network request Content-Length header"> - Content-Length + <ph name="LOCKED_1">Content-Length</ph> </message> <message name="IDS_DEVTOOLS_86408593c34af77fdd90df932f8b5261" desc="Text for a programming function"> Function
diff --git a/third_party/blink/renderer/devtools/front_end/main/Main.js b/third_party/blink/renderer/devtools/front_end/main/Main.js index 787c31a..043cf09 100644 --- a/third_party/blink/renderer/devtools/front_end/main/Main.js +++ b/third_party/blink/renderer/devtools/front_end/main/Main.js
@@ -116,6 +116,7 @@ Runtime.experiments.register( 'backgroundServicesPeriodicBackgroundSync', 'Background services section for Periodic Background Sync'); Runtime.experiments.register('blackboxJSFramesOnTimeline', 'Blackbox JavaScript frames on Timeline', true); + Runtime.experiments.register('cssOverview', 'CSS Overview'); Runtime.experiments.register('emptySourceMapAutoStepping', 'Empty sourcemap auto-stepping'); Runtime.experiments.register('inputEventsOnTimelineOverview', 'Input events on Timeline overview', true); Runtime.experiments.register('liveHeapProfile', 'Live heap profile', true); @@ -236,11 +237,11 @@ // TODO: we should not access actions from other modules. if (toggleSearchNodeAction) { InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.EnterInspectElementMode, + Host.InspectorFrontendHostAPI.Events.EnterInspectElementMode, toggleSearchNodeAction.execute.bind(toggleSearchNodeAction), this); } InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.RevealSourceLine, this._revealSourceLine, this); + Host.InspectorFrontendHostAPI.Events.RevealSourceLine, this._revealSourceLine, this); UI.inspectorView.createToolbars(); InspectorFrontendHost.loadCompleted();
diff --git a/third_party/blink/renderer/devtools/front_end/main/main_strings.grdp b/third_party/blink/renderer/devtools/front_end/main/main_strings.grdp index 41c43d0..808c2cd 100644 --- a/third_party/blink/renderer/devtools/front_end/main/main_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/main/main_strings.grdp
@@ -49,7 +49,7 @@ Go to the panel to the left/right </message> <message name="IDS_DEVTOOLS_586740a88e6502850bc64f9f2d04d380" desc="Title element title in Main"> - Placement of DevTools relative to the page. (<ph name="TOGGLEDOCKSIDESHORCUTS____NAME">$1s<ex>Ctrl+Shift+D</ex></ph> to restore last position) + Placement of <ph name="LOCKED_1">DevTools</ph> relative to the page. (<ph name="TOGGLEDOCKSIDESHORCUTS____NAME">$1s<ex>Ctrl+Shift+D</ex></ph> to restore last position) </message> <message name="IDS_DEVTOOLS_5bf4a92da989a6943e3fed84f18c3f0f" desc="Text in the Shortcuts page in settings to explain a keyboard shortcut"> Search across all sources
diff --git a/third_party/blink/renderer/devtools/front_end/network/NetworkLogViewColumns.js b/third_party/blink/renderer/devtools/front_end/network/NetworkLogViewColumns.js index 938940e4..daefa7c 100644 --- a/third_party/blink/renderer/devtools/front_end/network/NetworkLogViewColumns.js +++ b/third_party/blink/renderer/devtools/front_end/network/NetworkLogViewColumns.js
@@ -749,7 +749,9 @@ { id: 'connection', isResponseHeader: true, - title: Common.UIString('Connection'), + // until IDs are supported for strings, the placeholder is used to workaround the limitation that + // having multiple translations for a string is not supported + title: ls`${'Connection'}`, sortingFunction: Network.NetworkRequestNode.ResponseHeaderStringComparator.bind(null, 'connection') }, {
diff --git a/third_party/blink/renderer/devtools/front_end/network/network_strings.grdp b/third_party/blink/renderer/devtools/front_end/network/network_strings.grdp index 4234efe..98b9eec 100644 --- a/third_party/blink/renderer/devtools/front_end/network/network_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/network/network_strings.grdp
@@ -301,7 +301,7 @@ Stop recording network log </message> <message name="IDS_DEVTOOLS_611a2b5dcde004cf68ffd56345584d40" desc="Text in Network Log View Columns of the Network panel"> - ETag + <ph name="LOCKED_1">ETag</ph> </message> <message name="IDS_DEVTOOLS_619d32de7168c6e770464dfc43e374d1" desc="Text in Request Headers View of the Network panel"> Request Headers @@ -322,7 +322,7 @@ Header Name </message> <message name="IDS_DEVTOOLS_6a98894cd6b4628f0b5117412aab083e" desc="Text in Network Log View Columns of the Network panel"> - Cache-Control + <ph name="LOCKED_1">Cache-Control</ph> </message> <message name="IDS_DEVTOOLS_6b41d86d21d49c95f5b106fb2ed95762" desc="An option in the user agent dropdown menu in the Network conditions tool"> <ph name="LOCKED_1">Internet Explorer 10</ph> @@ -439,7 +439,7 @@ Set Cookies </message> <message name="IDS_DEVTOOLS_8c074f405ad9737b1b59d35d6aab7cab" desc="Text in Network Log View Columns of the Network panel"> - Last-Modified + <ph name="LOCKED_1">Last-Modified</ph> </message> <message name="IDS_DEVTOOLS_8c09001c99ecb6fdd8d6023fcf039054" desc="Text in Signed Exchange Info View of the Network panel"> Signature @@ -529,7 +529,7 @@ Parser </message> <message name="IDS_DEVTOOLS_9aa1b03934893d7134a660af4204f2a9" desc="Text in Network Log View Columns of the Network panel"> - Server + <ph name="LOCKED_1">Server</ph> </message> <message name="IDS_DEVTOOLS_9c1ab57e621c2bb257798752dbbe6f14" desc="Text in Request Headers View of the Network panel"> view source @@ -658,7 +658,7 @@ mixed-content </message> <message name="IDS_DEVTOOLS_bd9176ee57c46268a853e038b133966a" desc="Text in Network Log View Columns of the Network panel"> - Keep-Alive + <ph name="LOCKED_1">Keep-Alive</ph> </message> <message name="IDS_DEVTOOLS_bdaacef16991cfa4cf17a388579e7c06" desc="Text in Network Item View of the Network panel"> EventStream @@ -670,7 +670,7 @@ Cookies that were sent to the server in the 'cookie' header of the request </message> <message name="IDS_DEVTOOLS_c0635a52980f98eff8adf2279c8ad8e0" desc="A tag of Network Conditions tool that can be searched in the command menu"> - <ph name="LOCKED_1">useragent</ph> + useragent </message> <message name="IDS_DEVTOOLS_c14108bc627e61f0e445dda0ff029f58" desc="An option in the user agent dropdown menu in the Network conditions tool"> <ph name="LOCKED_1">Chrome — iPhone</ph> @@ -742,7 +742,7 @@ Record (<ph name="RECORDNODE">$1s<ex>Ctrl + E</ex></ph>) to display network activity. </message> <message name="IDS_DEVTOOLS_d82a834165b99c4ea0969316296a2bc2" desc="Text in Network Log View Columns of the Network panel"> - Vary + <ph name="LOCKED_1">Vary</ph> </message> <message name="IDS_DEVTOOLS_d8e381f360a750d29368d3ec51346006" desc="Label for response cookies with invalid syntax"> Malformed Response Cookies @@ -760,7 +760,7 @@ Request/Response </message> <message name="IDS_DEVTOOLS_dcf3e36ee8115282aad46485cab6a4be" desc="A tag of Group Network by frame setting that can be searched in the command menu"> - <ph name="LOCKED_1">frame</ph> + frame </message> <message name="IDS_DEVTOOLS_dd47445f60115097d07d4cf2e61d933b" desc="Text of a DOM element in Request Timing View of the Network panel"> CAUTION: request is not finished yet! @@ -826,7 +826,7 @@ Started at <ph name="CALCULATOR_FORMATVALUE_REQUEST_STARTTIME____">$1s<ex>120.39ms</ex></ph> </message> <message name="IDS_DEVTOOLS_edfffa5a1ffba7492b25869813e7e15e" desc="Text in Network Log View Columns of the Network panel"> - Content-Encoding + <ph name="LOCKED_1">Content-Encoding</ph> </message> <message name="IDS_DEVTOOLS_ef110dd7355d7315c73995a47fe77dfd" desc="Text in Request Timing View of the Network panel"> DNS Lookup @@ -841,7 +841,7 @@ Content </message> <message name="IDS_DEVTOOLS_f2a4bb0e0bae2587046fb2bd377f3922" desc="A tag of Network Conditions tool that can be searched in the command menu"> - <ph name="LOCKED_1">user agent</ph> + user agent </message> <message name="IDS_DEVTOOLS_f312b3f268931a1367de22756237b197" desc="Text in Network Item View of the Network panel"> Headers and request body
diff --git a/third_party/blink/renderer/devtools/front_end/node_main/NodeConnectionsPanel.js b/third_party/blink/renderer/devtools/front_end/node_main/NodeConnectionsPanel.js index 7c49dbb..25e7259 100644 --- a/third_party/blink/renderer/devtools/front_end/node_main/NodeConnectionsPanel.js +++ b/third_party/blink/renderer/devtools/front_end/node_main/NodeConnectionsPanel.js
@@ -14,7 +14,7 @@ image.src = 'https://nodejs.org/static/images/logos/nodejs-new-pantone-black.png'; InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this); + Host.InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this); /** @type {!Adb.Config} */ this._config;
diff --git a/third_party/blink/renderer/devtools/front_end/node_main/NodeMain.js b/third_party/blink/renderer/devtools/front_end/node_main/NodeMain.js index 1b515281..10afb889 100644 --- a/third_party/blink/renderer/devtools/front_end/node_main/NodeMain.js +++ b/third_party/blink/renderer/devtools/front_end/node_main/NodeMain.js
@@ -39,7 +39,7 @@ this._targetAgent.setDiscoverTargets(true); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this); + Host.InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this); InspectorFrontendHost.setDevicesUpdatesEnabled(false); InspectorFrontendHost.setDevicesUpdatesEnabled(true); } @@ -64,7 +64,7 @@ */ dispose() { InspectorFrontendHost.events.removeEventListener( - InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this); + Host.InspectorFrontendHostAPI.Events.DevicesDiscoveryConfigChanged, this._devicesDiscoveryConfigChanged, this); for (const sessionId of this._childTargets.keys()) this.detachedFromTarget(sessionId, undefined);
diff --git a/third_party/blink/renderer/devtools/front_end/node_main/node_main_strings.grdp b/third_party/blink/renderer/devtools/front_end/node_main/node_main_strings.grdp index 0323906d..d7b6a6a 100644 --- a/third_party/blink/renderer/devtools/front_end/node_main/node_main_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/node_main/node_main_strings.grdp
@@ -4,7 +4,7 @@ Add connection </message> <message name="IDS_DEVTOOLS_3fd49f986cbd5dd3148c27c9aaaaa700" desc="Text in Node Connections Panel of the Sources panel when debugging a Node.js app"> - Network address (e.g. localhost:9229) + Network address (e.g. <ph name="LOCKED_1">localhost:9229</ph>) </message> <message name="IDS_DEVTOOLS_43d755260901476a60e28982f36b2913" desc="Text in Node Connections Panel of the Sources panel when debugging a Node.js app"> Node.js debugging guide @@ -16,9 +16,9 @@ Node.js: <ph name="TARGETINFO_URL">$1s<ex>example.com</ex></ph> </message> <message name="IDS_DEVTOOLS_ed6b1cccfa7455e9506ff7e5127e1df4" desc="Text in Node Connections Panel of the Sources panel when debugging a Node.js app"> - Specify network endpoint and DevTools will connect to it automatically. Read <ph name="DOCUMENTATIONLINK">$1s<ex>Node.js debugging guide</ex></ph> to learn more. + Specify network endpoint and <ph name="LOCKED_1">DevTools</ph> will connect to it automatically. Read <ph name="DOCUMENTATIONLINK">$1s<ex>Node.js debugging guide</ex></ph> to learn more. </message> <message name="IDS_DEVTOOLS_36c4536996ca5615dcf9911f068786dc" desc="A tag of Node.js Connection Panel that can be searched in the command menu"> - <ph name="LOCKED_1">node</ph> + node </message> </grit-part> \ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/object_ui/objectValue.css b/third_party/blink/renderer/devtools/front_end/object_ui/objectValue.css index bfaf983..e2dae873 100644 --- a/third_party/blink/renderer/devtools/front_end/object_ui/objectValue.css +++ b/third_party/blink/renderer/devtools/front_end/object_ui/objectValue.css
@@ -48,7 +48,7 @@ .object-value-string, .object-value-regexp, .object-value-symbol { - white-space: pre; + white-space: pre !important; unicode-bidi: -webkit-isolate; color: rgb(196, 26, 22); }
diff --git a/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystemManager.js b/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystemManager.js index 3ea1dc8..2c3604bd 100644 --- a/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystemManager.js +++ b/third_party/blink/renderer/devtools/front_end/persistence/IsolatedFileSystemManager.js
@@ -43,19 +43,19 @@ this._progresses = new Map(); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.FileSystemRemoved, this._onFileSystemRemoved, this); + Host.InspectorFrontendHostAPI.Events.FileSystemRemoved, this._onFileSystemRemoved, this); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.FileSystemAdded, this._onFileSystemAdded, this); + Host.InspectorFrontendHostAPI.Events.FileSystemAdded, this._onFileSystemAdded, this); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, this._onFileSystemFilesChanged, this); + Host.InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, this._onFileSystemFilesChanged, this); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.IndexingTotalWorkCalculated, this._onIndexingTotalWorkCalculated, this); + Host.InspectorFrontendHostAPI.Events.IndexingTotalWorkCalculated, this._onIndexingTotalWorkCalculated, this); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.IndexingWorked, this._onIndexingWorked, this); + Host.InspectorFrontendHostAPI.Events.IndexingWorked, this._onIndexingWorked, this); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.IndexingDone, this._onIndexingDone, this); + Host.InspectorFrontendHostAPI.Events.IndexingDone, this._onIndexingDone, this); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.SearchCompleted, this._onSearchCompleted, this); + Host.InspectorFrontendHostAPI.Events.SearchCompleted, this._onSearchCompleted, this); this._initExcludePatterSetting(); @@ -71,7 +71,7 @@ let fulfill; const promise = new Promise(f => fulfill = f); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.FileSystemsLoaded, onFileSystemsLoaded, this); + Host.InspectorFrontendHostAPI.Events.FileSystemsLoaded, onFileSystemsLoaded, this); InspectorFrontendHost.requestFileSystems(); return promise;
diff --git a/third_party/blink/renderer/devtools/front_end/profiler/profiler_strings.grdp b/third_party/blink/renderer/devtools/front_end/profiler/profiler_strings.grdp index bf670e1..bd0f64aa 100644 --- a/third_party/blink/renderer/devtools/front_end/profiler/profiler_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/profiler/profiler_strings.grdp
@@ -176,7 +176,7 @@ </message> <message name="IDS_DEVTOOLS_6b59ba1fcfd868474cae169876f9cbfa" desc="Text in Heap Profile View of a profiler tool"> Native memory snapshots show sampled native allocations in the renderer process since start up. - Chrome has to be started with --memlog=all flag. Check flags at chrome://flags + <ph name="LOCKED_1">Chrome</ph> has to be started with <ph name="LOCKED_2">--memlog=all</ph> flag. Check flags at <ph name="LOCKED_1">chrome://flags</ph> </message> <message name="IDS_DEVTOOLS_6d27e30b2f09c2a451a6d123c1a35805" desc="Text in Profiles Panel of a profiler tool"> Run <ph name="_">$1d<ex>2</ex></ph>
diff --git a/third_party/blink/renderer/devtools/front_end/resources/ApplicationPanelSidebar.js b/third_party/blink/renderer/devtools/front_end/resources/ApplicationPanelSidebar.js index 53ee664..4b8bb66a 100644 --- a/third_party/blink/renderer/devtools/front_end/resources/ApplicationPanelSidebar.js +++ b/third_party/blink/renderer/devtools/front_end/resources/ApplicationPanelSidebar.js
@@ -495,8 +495,11 @@ this._panel.showView(view); } - _updateDatabaseTables(event) { - const database = event.data; + /** + * @param {!Common.Event} event + */ + async _updateDatabaseTables(event) { + const database = /** @type {!Resources.Database} */ (event.data); if (!database) return; @@ -513,20 +516,21 @@ const tableNamesHash = {}; const panel = this._panel; - function tableNamesCallback(tableNames) { - const tableNamesLength = tableNames.length; - for (let i = 0; i < tableNamesLength; ++i) - tableNamesHash[tableNames[i]] = true; + const tableNames = await database.tableNames(); + const tableNamesLength = tableNames.length; - for (const tableName in tableViews) { - if (!(tableName in tableNamesHash)) { - if (panel.visibleView === tableViews[tableName]) - panel.showView(null); - delete tableViews[tableName]; - } + for (let i = 0; i < tableNamesLength; ++i) + tableNamesHash[tableNames[i]] = true; + + for (const tableName in tableViews) { + if (!(tableName in tableNamesHash)) { + if (panel.visibleView === tableViews[tableName]) + panel.showView(null); + delete tableViews[tableName]; } } - database.getTableNames(tableNamesCallback); + + await databasesTreeElement.updateChildren(); } /** @@ -863,10 +867,11 @@ * @override */ onexpand() { - this._updateChildren(); + this.updateChildren(); } - async _updateChildren() { + async updateChildren() { + this.removeChildren(); const tableNames = await this._database.tableNames(); for (const tableName of tableNames) this.appendChild(new Resources.DatabaseTableTreeElement(this._sidebar, this._database, tableName));
diff --git a/third_party/blink/renderer/devtools/front_end/resources/CookieItemsView.js b/third_party/blink/renderer/devtools/front_end/resources/CookieItemsView.js index b3f2338..87f39a4 100644 --- a/third_party/blink/renderer/devtools/front_end/resources/CookieItemsView.js +++ b/third_party/blink/renderer/devtools/front_end/resources/CookieItemsView.js
@@ -35,6 +35,7 @@ constructor(model, cookieDomain) { super(Common.UIString('Cookies'), 'cookiesPanel'); + this.registerRequiredCSS('resources/cookieItemsView.css'); this.element.classList.add('storage-view'); this._model = model; @@ -42,10 +43,34 @@ this._totalSize = 0; /** @type {?CookieTable.CookiesTable} */ - this._cookiesTable = null; + this._cookiesTable = this._cookiesTable = new CookieTable.CookiesTable( + /* renderInline */ false, this._saveCookie.bind(this), this.refreshItems.bind(this), + this._handleCookieSelected.bind(this), this._deleteCookie.bind(this)); + + this._cookiesTable.setMinimumSize(0, 50); + + this._splitWidget = new UI.SplitWidget(false, false); + this._splitWidget.show(this.element); + this._splitWidget.setSecondIsSidebar(true); + + this._previewPanel = new UI.VBox(); + const resizer = this._previewPanel.element.createChild('div', 'preview-panel-resizer'); + + this._splitWidget.setMainWidget(this._cookiesTable); + this._splitWidget.setSidebarWidget(this._previewPanel); + this._splitWidget.installResizer(resizer); + + this._refreshThrottler = new Common.Throttler(300); /** @type {!Array<!Common.EventTarget.EventDescriptor>} */ this._eventDescriptors = []; + + + /** @type {?UI.Widget} */ + this._preview = null; + /** @type {?SDK.Cookie} */ + this._previewValue = null; + this.setCookiesDomain(model, cookieDomain); } @@ -61,6 +86,57 @@ const networkManager = model.target().model(SDK.NetworkManager); this._eventDescriptors = [networkManager.addEventListener(SDK.NetworkManager.Events.ResponseReceived, this._onResponseReceived, this)]; + + this._showPreview(null, null); + } + + /** + * @param {?UI.Widget} preview + * @param {?SDK.Cookie} value + */ + _showPreview(preview, value) { + if (this._preview && this._previewValue === value) + return; + + if (this._preview) + this._preview.detach(); + + if (!preview) + preview = new UI.EmptyWidget(ls`Select a cookie to preview it value`); + + this._previewValue = value; + this._preview = preview; + + preview.show(this._previewPanel.contentElement); + } + + _handleCookieSelected() { + const cookie = this._cookiesTable.selectedCookie(); + this.setCanDeleteSelected(!!cookie); + + if (!cookie) { + this._showPreview(null, null); + return; + } + + const value = createElementWithClass('div', 'cookie-value'); + value.textContent = cookie.value(); + value.addEventListener('dblclick', handleDblClickOnCookieValue); + + const preview = new UI.VBox(); + preview.contentElement.appendChild(value); + + this._showPreview(preview, cookie); + + /** + * @suppressGlobalPropertiesCheck + */ + function handleDblClickOnCookieValue() { + const range = document.createRange(); + range.selectNode(value); + window.getSelection().removeAllRanges(); + window.getSelection().addRange(range); + } } /** @@ -90,19 +166,12 @@ _updateWithCookies(allCookies) { this._totalSize = allCookies.reduce((size, cookie) => size + cookie.size(), 0); - if (!this._cookiesTable) { - this._cookiesTable = new CookieTable.CookiesTable( - /* renderInline */ false, this._saveCookie.bind(this), this.refreshItems.bind(this), - () => this.setCanDeleteSelected(!!this._cookiesTable.selectedCookie()), this._deleteCookie.bind(this)); - } - const parsedURL = this._cookieDomain.asParsedURL(); const host = parsedURL ? parsedURL.host : ''; this._cookiesTable.setCookieDomain(host); const shownCookies = this.filter(allCookies, cookie => `${cookie.name()} ${cookie.value()} ${cookie.domain()}`); this._cookiesTable.setCookies(shownCookies); - this._cookiesTable.show(this.element); this.setCanFilter(true); this.setCanDeleteAll(true); this.setCanDeleteSelected(!!this._cookiesTable.selectedCookie());
diff --git a/third_party/blink/renderer/devtools/front_end/resources/cookieItemsView.css b/third_party/blink/renderer/devtools/front_end/resources/cookieItemsView.css new file mode 100644 index 0000000..b2b9930 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/resources/cookieItemsView.css
@@ -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. + */ + +.cookie-value { + padding: 2px 6px; + overflow: auto; + user-select: text; + min-height: 100%; +} \ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/resources/module.json b/third_party/blink/renderer/devtools/front_end/resources/module.json index 9dbc544..182c1a4 100644 --- a/third_party/blink/renderer/devtools/front_end/resources/module.json +++ b/third_party/blink/renderer/devtools/front_end/resources/module.json
@@ -100,6 +100,7 @@ "resourcesPanel.css", "resourcesSidebar.css", "serviceWorkerCacheViews.css", - "serviceWorkersView.css" + "serviceWorkersView.css", + "cookieItemsView.css" ] }
diff --git a/third_party/blink/renderer/devtools/front_end/resources/resources_strings.grdp b/third_party/blink/renderer/devtools/front_end/resources/resources_strings.grdp index c425de1a..8cff6e0 100644 --- a/third_party/blink/renderer/devtools/front_end/resources/resources_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/resources/resources_strings.grdp
@@ -218,6 +218,9 @@ <message name="IDS_DEVTOOLS_9dce9dd0f39a17c2e029174f5bc86ef9" desc="Text in Background Service View of the Application panel"> Background Sync </message> + <message name="IDS_DEVTOOLS_9ea4dd36a0094fc33b5ea341a1f909ee" desc="Text in Cookie Items View of the Application panel"> + Select a cookie to preview it value + </message> <message name="IDS_DEVTOOLS_9ff9f5649294f7200b671d6389d17d9a" desc="Text in Application Panel Sidebar of the Application panel"> multiEntry </message> @@ -234,7 +237,7 @@ Cache Storage </message> <message name="IDS_DEVTOOLS_a9cd2046f50376846feaa11c68e56e2f" desc="Inform users that DevTools are recording/waiting for events in the Periodic Background Sync tool of the Application panel"> - DevTools will record all <ph name="FEATURENAME">$1s<ex>Background Fetch</ex></ph> activity for up to 3 days, even when closed. + <ph name="LOCKED_1">DevTools</ph> will record all <ph name="FEATURENAME">$1s<ex>Background Fetch</ex></ph> activity for up to 3 days, even when closed. </message> <message name="IDS_DEVTOOLS_ab0cf104f39708eabd07b8cb67e149ba" desc="Text in Application Panel Sidebar of the Application panel"> Cache @@ -267,7 +270,7 @@ Display </message> <message name="IDS_DEVTOOLS_ba8d2e1eca2bf52ab3cd0202d4d04c07" desc="Text in Service Workers View of the Application panel"> - Test push message from DevTools. + Test push message from <ph name="LOCKED_1">DevTools</ph>. </message> <message name="IDS_DEVTOOLS_bb8839cf9d324a22591ff426c28c5345" desc="Tooltip text that appears when hovering over the largeicon play button in the Indexed DBViews of the Application panel"> Show next page
diff --git a/third_party/blink/renderer/devtools/front_end/sdk/Connections.js b/third_party/blink/renderer/devtools/front_end/sdk/Connections.js index be2a939..a3ea04b 100644 --- a/third_party/blink/renderer/devtools/front_end/sdk/Connections.js +++ b/third_party/blink/renderer/devtools/front_end/sdk/Connections.js
@@ -13,9 +13,9 @@ this._messageSize = 0; this._eventListeners = [ InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.DispatchMessage, this._dispatchMessage, this), + Host.InspectorFrontendHostAPI.Events.DispatchMessage, this._dispatchMessage, this), InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.DispatchMessageChunk, this._dispatchMessageChunk, this), + Host.InspectorFrontendHostAPI.Events.DispatchMessageChunk, this._dispatchMessageChunk, this), ]; }
diff --git a/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js b/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js index f26799a..acda0f17 100644 --- a/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js +++ b/third_party/blink/renderer/devtools/front_end/sdk/RuntimeModel.js
@@ -366,7 +366,7 @@ */ _copyRequested(object) { if (!object.objectId) { - InspectorFrontendHost.copyText(object.unserializableValue() || object.value); + InspectorFrontendHost.copyText(object.unserializableValue() || /** @type {string} */ (object.value)); return; } object.callFunctionJSON(toStringForClipboard, [{value: object.subtype}])
diff --git a/third_party/blink/renderer/devtools/front_end/sdk/sdk_strings.grdp b/third_party/blink/renderer/devtools/front_end/sdk/sdk_strings.grdp index 7c854d82..fb3fdf74 100644 --- a/third_party/blink/renderer/devtools/front_end/sdk/sdk_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/sdk/sdk_strings.grdp
@@ -91,7 +91,7 @@ Hide frames per second (FPS) meter </message> <message name="IDS_DEVTOOLS_3ff9f750075f426831f71818a8f4ff12" desc="Text in Network Manager"> - Request was blocked by DevTools: "<ph name="NETWORKREQUEST_URL__">$1s<ex>https://example.com</ex></ph>". + Request was blocked by <ph name="LOCKED_1">DevTools</ph>: "<ph name="NETWORKREQUEST_URL__">$1s<ex>https://example.com</ex></ph>". </message> <message name="IDS_DEVTOOLS_40dba446b661ae69dea3a8e026f76dfd" desc="Title of a setting under the Rendering category that can be invoked through the Command Menu"> Hide paint flashing rectangles @@ -157,7 +157,7 @@ Show hit-test borders </message> <message name="IDS_DEVTOOLS_6948a469c79f7dd5426e4f291cba3db1" desc="Text in Network Log"> - Chrome Data Saver + <ph name="LOCKED_1">Chrome Data Saver</ph> </message> <message name="IDS_DEVTOOLS_6ce4d85a628a88bbdb3ac24a8e5a9c2e" desc="Text in DOMDebugger Model"> Keyboard @@ -346,7 +346,7 @@ Mouse </message> <message name="IDS_DEVTOOLS_f6137609f4decf877ede5bd3a3125629" desc="Text in CPUProfile Data Model"> - DevTools: CPU profile parser is fixing <ph name="COUNT">$1s<ex>2</ex></ph> missing samples. + <ph name="LOCKED_1">DevTools</ph>: CPU profile parser is fixing <ph name="COUNT">$1s<ex>2</ex></ph> missing samples. </message> <message name="IDS_DEVTOOLS_f7531e2d0ea27233ce00b5f01c5bf335" desc="A drop-down menu option to emulate css print media type"> print
diff --git a/third_party/blink/renderer/devtools/front_end/security/security_strings.grdp b/third_party/blink/renderer/devtools/front_end/security/security_strings.grdp index 18a339b..8eb546c 100644 --- a/third_party/blink/renderer/devtools/front_end/security/security_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/security/security_strings.grdp
@@ -97,7 +97,7 @@ View <ph name="FILTERREQUESTCOUNT">$1d<ex>2</ex></ph> requests in Network Panel </message> <message name="IDS_DEVTOOLS_a10edd2a3893a9ba446fb26e7c27556a" desc="Text in Security Panel of the Security panel"> - This request complies with Chrome's Certificate Transparency policy. + This request complies with <ph name="LOCKED_1">Chrome</ph>'s Certificate Transparency policy. </message> <message name="IDS_DEVTOOLS_a2b16c6b3db371738d0e5c3f3ba2b54d" desc="Text in Security Panel of the Security panel"> This response was loaded from cache. Some security details might be missing. @@ -115,7 +115,7 @@ Show more (<ph name="SANLIST_LENGTH">$1s<ex>2</ex></ph> total) </message> <message name="IDS_DEVTOOLS_b92f649b203ca680d444432324771186" desc="Text in Security Panel of the Security panel"> - This request does not comply with Chrome's Certificate Transparency policy. + This request does not comply with <ph name="LOCKED_1">Chrome</ph>'s Certificate Transparency policy. </message> <message name="IDS_DEVTOOLS_c3db8a95444ea6caa45cc7dcb6e78d64" desc="Summary div text content in Security Panel of the Security panel"> Security overview
diff --git a/third_party/blink/renderer/devtools/front_end/sources/sources_strings.grdp b/third_party/blink/renderer/devtools/front_end/sources/sources_strings.grdp index 5eb40451..461a9e51 100644 --- a/third_party/blink/renderer/devtools/front_end/sources/sources_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/sources/sources_strings.grdp
@@ -151,7 +151,7 @@ Override page assets with files from a local folder </message> <message name="IDS_DEVTOOLS_49a4a1505587da9f4475db7ee9958853" desc="Text in Sources Navigator of the Sources panel"> - Sync changes in DevTools with the local filesystem + Sync changes in <ph name="LOCKED_1">DevTools</ph> with the local filesystem </message> <message name="IDS_DEVTOOLS_4b3812a22a58f04fb5a0598658a3bd27" desc="Title of the Filtered List WidgetProvider of Quick Open"> Go to symbol @@ -385,7 +385,7 @@ Remove other breakpoints </message> <message name="IDS_DEVTOOLS_b9947e230aa5ac451e3b0649bdb1c7fc" desc="Event return value in Sources View of the Sources panel"> - DevTools have unsaved changes that will be permanently lost. + <ph name="LOCKED_1">DevTools</ph> have unsaved changes that will be permanently lost. </message> <message name="IDS_DEVTOOLS_bb9f288b958ce8c8d250cb392e2f1309" desc="Text in Debugger Plugin of the Sources panel"> You can click the <ph name="TOOLBAR_ELEMENT">$1s<ex>{}</ex></ph> button on the bottom status bar, and continue debugging with the new formatted source.
diff --git a/third_party/blink/renderer/devtools/front_end/timeline/TimelineEventOverview.js b/third_party/blink/renderer/devtools/front_end/timeline/TimelineEventOverview.js index e9a5be5..f24d822e 100644 --- a/third_party/blink/renderer/devtools/front_end/timeline/TimelineEventOverview.js +++ b/third_party/blink/renderer/devtools/front_end/timeline/TimelineEventOverview.js
@@ -740,12 +740,21 @@ let total = 0; let total_used = 0; + /** @type {!Map<!Coverage.CoverageInfo>} */ const usedByTimestamp = new Map(); + /** @type {!Map<!Coverage.CoverageInfo>} */ + const totalByTimestamp = new Map(); for (const urlInfo of this._coverageModel.entries()) { for (const info of urlInfo.entries()) { total += info.size(); for (const [stamp, used] of info.usedByTimestamp()) { total_used += used; + + if (!totalByTimestamp.has(stamp)) + totalByTimestamp.set(stamp, new Set()); + + totalByTimestamp.get(stamp).add(info); + if (!usedByTimestamp.has(stamp)) usedByTimestamp.set(stamp, used); else @@ -753,6 +762,26 @@ } } } + + /** @type {!Set<!Coverage.CoverageInfo>} */ + const seen = new Set(); + /** @type {!Map<number, number>} */ + const coverageByTimestamp = new Map(); + let sumTotal = 0, sumUsed = 0; + + const sortedByTimestamp = Array.from(totalByTimestamp.entries()).sort((a, b) => a[0] - b[0]); + for (const [stamp, infos] of sortedByTimestamp) { + for (const info of infos.values()) { + if (seen.has(info)) + continue; + + seen.add(info); + sumTotal += info.size(); + } + sumUsed += usedByTimestamp.get(stamp); + coverageByTimestamp.set(stamp, sumUsed / sumTotal); + } + const percentUsed = total ? Math.round(100 * total_used / total) : 0; const lowerOffset = 3 * ratio; @@ -764,48 +793,41 @@ const width = this.width(); const height = this.height() - lowerOffset; const xFactor = width / (maxTime - minTime); - const yFactor = (height - lineWidth) / Math.max(total, 1); + const yFactor = height - lineWidth; - - let y = 0; + let yOffset = 0; const ctx = this.context(); const heightBeyondView = height + lowerOffset + lineWidth; ctx.translate(0.5, 0.5); ctx.beginPath(); ctx.moveTo(-lineWidth, heightBeyondView); - ctx.lineTo(-lineWidth, height - y); + ctx.lineTo(-lineWidth, height - yOffset); - const entries = Array.from(usedByTimestamp.entries()).sort((a, b) => a[0] - b[0]); - let cummulative_used = 0; - for (const [stamp, used] of entries) { + for (const [stamp, coverage] of coverageByTimestamp) { if (stamp > maxTime) break; const x = (stamp - minTime) * xFactor; - cummulative_used += used; - y = cummulative_used * yFactor; - ctx.lineTo(x, height - y); + yOffset = coverage * yFactor; + ctx.lineTo(x, height - yOffset); } - - ctx.lineTo(width + lineWidth, height - y); + ctx.lineTo(width + lineWidth, height - yOffset); ctx.lineTo(width + lineWidth, heightBeyondView); ctx.closePath(); - ctx.fillStyle = 'hsla(220, 90%, 70%, 0.2)'; ctx.fill(); ctx.lineWidth = lineWidth; ctx.strokeStyle = 'hsl(220, 90%, 70%)'; ctx.stroke(); - cummulative_used = 0; - for (const [stamp, used] of entries) { + for (const [stamp, coverage] of coverageByTimestamp) { if (stamp > maxTime) break; - cummulative_used += used; ctx.beginPath(); const x = (stamp - minTime) * xFactor; - ctx.arc(x, height - cummulative_used * yFactor, 2 * lineWidth, 0, 2 * Math.PI, false); + const y = height - coverage * yFactor; + ctx.arc(x, y, 2 * lineWidth, 0, 2 * Math.PI, false); ctx.closePath(); ctx.stroke(); ctx.fill();
diff --git a/third_party/blink/renderer/devtools/front_end/timeline/timeline_strings.grdp b/third_party/blink/renderer/devtools/front_end/timeline/timeline_strings.grdp index 0d615980..d1c3bd0d 100644 --- a/third_party/blink/renderer/devtools/front_end/timeline/timeline_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/timeline/timeline_strings.grdp
@@ -89,7 +89,7 @@ Click the reload button <ph name="RELOADBUTTON">$3s<ex>reload</ex></ph> or hit <ph name="RELOADKEY">$4s<ex>Ctrl + R</ex></ph> to record the page load. </message> <message name="IDS_DEVTOOLS_0e8dfe937d359c7df31b16ea7e9cca81" desc="Title of a setting under the Performance category in Settings"> - Hide chrome frame in Layers view + Hide <ph name="LOCKED_1">chrome</ph> frame in Layers view </message> <message name="IDS_DEVTOOLS_10aab9f12eca6bca3a6215914bab2745" desc="Text in Timeline UIUtils of the Performance panel"> Allotted Time @@ -124,9 +124,6 @@ <message name="IDS_DEVTOOLS_1b2c363066d5912ae8b27a1527f3d45e" desc="Text in Timeline Tree View of the Performance panel"> Group by Domain </message> - <message name="IDS_DEVTOOLS_1c481aa99d081c32182011a758f73d33" desc="Duration text in the Performance panel"> - <ph name="DURATIONTEXT">$1s<ex>100ms (at 200ms)</ex></ph> - </message> <message name="IDS_DEVTOOLS_1e3eaaac8d3c9cffea8ee7f03a8a6121" desc="Text in Timeline UIUtils of the Performance panel"> DOMContentLoaded Event </message> @@ -482,7 +479,7 @@ Decrypt </message> <message name="IDS_DEVTOOLS_76e815d5323a5f3c80a3d186c416e92b" desc="Text in Timeline Tree View of the Performance panel"> - [Chrome extensions overhead] + [<ph name="LOCKED_1">Chrome</ph> extensions overhead] </message> <message name="IDS_DEVTOOLS_76ecb02d1f339c2dd6f14c41ead368c1" desc="Span text content in Timeline UIUtils of the Performance panel"> Handler took <ph name="NUMBER_MILLISTOSTRING_EVENT_DURATION__TRUE_">$1s<ex>10ms</ex></ph> @@ -691,7 +688,7 @@ Layout root </message> <message name="IDS_DEVTOOLS_b3bfefedfa27aa11e79f637b22b16d09" desc="Text in Timeline Tree View of the Performance panel"> - [V8 Runtime] + [<ph name="LOCKED_1">V8</ph> Runtime] </message> <message name="IDS_DEVTOOLS_b49fe3f49a656887d446c2da3851a88a" desc="Text in Timeline UIUtils of the Performance panel"> Network request
diff --git a/third_party/blink/renderer/devtools/front_end/ui/ContextMenu.js b/third_party/blink/renderer/devtools/front_end/ui/ContextMenu.js index 69b9b89..9e877c75 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/ContextMenu.js +++ b/third_party/blink/renderer/devtools/front_end/ui/ContextMenu.js
@@ -368,7 +368,7 @@ } static initialize() { - InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SetUseSoftMenu, setUseSoftMenu); + InspectorFrontendHost.events.addEventListener(Host.InspectorFrontendHostAPI.Events.SetUseSoftMenu, setUseSoftMenu); /** * @param {!Common.Event} event */ @@ -447,9 +447,9 @@ */ function listenToEvents() { InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.ContextMenuCleared, this._menuCleared, this); + Host.InspectorFrontendHostAPI.Events.ContextMenuCleared, this._menuCleared, this); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.ContextMenuItemSelected, this._onItemSelected, this); + Host.InspectorFrontendHostAPI.Events.ContextMenuItemSelected, this._onItemSelected, this); } // showContextMenuAtPoint call above synchronously issues a clear event for previous context menu (if any), @@ -492,9 +492,9 @@ _menuCleared() { InspectorFrontendHost.events.removeEventListener( - InspectorFrontendHostAPI.Events.ContextMenuCleared, this._menuCleared, this); + Host.InspectorFrontendHostAPI.Events.ContextMenuCleared, this._menuCleared, this); InspectorFrontendHost.events.removeEventListener( - InspectorFrontendHostAPI.Events.ContextMenuItemSelected, this._onItemSelected, this); + Host.InspectorFrontendHostAPI.Events.ContextMenuItemSelected, this._onItemSelected, this); } /**
diff --git a/third_party/blink/renderer/devtools/front_end/ui/ForwardedInputEventHandler.js b/third_party/blink/renderer/devtools/front_end/ui/ForwardedInputEventHandler.js index 6baa49a8..fa85a40c 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/ForwardedInputEventHandler.js +++ b/third_party/blink/renderer/devtools/front_end/ui/ForwardedInputEventHandler.js
@@ -7,7 +7,7 @@ UI.ForwardedInputEventHandler = class { constructor() { InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.KeyEventUnhandled, this._onKeyEventUnhandled, this); + Host.InspectorFrontendHostAPI.Events.KeyEventUnhandled, this._onKeyEventUnhandled, this); } /**
diff --git a/third_party/blink/renderer/devtools/front_end/ui/InspectorView.js b/third_party/blink/renderer/devtools/front_end/ui/InspectorView.js index c19d2825..960c308d 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/InspectorView.js +++ b/third_party/blink/renderer/devtools/front_end/ui/InspectorView.js
@@ -93,7 +93,7 @@ this._drawerSplitWidget.setMainWidget(this._tabbedPane); this._keyDownBound = this._keyDown.bind(this); - InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.ShowPanel, showPanel.bind(this)); + InspectorFrontendHost.events.addEventListener(Host.InspectorFrontendHostAPI.Events.ShowPanel, showPanel.bind(this)); /** * @this {UI.InspectorView}
diff --git a/third_party/blink/renderer/devtools/front_end/ui/ui_strings.grdp b/third_party/blink/renderer/devtools/front_end/ui/ui_strings.grdp index bfa706a..5a861bfe 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/ui_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/ui/ui_strings.grdp
@@ -85,7 +85,7 @@ Step out </message> <message name="IDS_DEVTOOLS_44ac014b674d7d86a04702e6fd1fa858" desc="Text in a dialog box showing how to reconnect to DevTools when remote debugging has been terminated"> - Reconnect when ready by reopening DevTools. + Reconnect when ready by reopening <ph name="LOCKED_1">DevTools</ph>. </message> <message name="IDS_DEVTOOLS_45b471827af8ba9628e1914afbb13980" desc="Minutes format in UIUtils"> <ph name="PH1">$1.1f<ex>2.2</ex></ph> min @@ -136,13 +136,13 @@ Save profile </message> <message name="IDS_DEVTOOLS_63e29f78b2e7788d9234a5790897fa71" desc="Text in dialog box when the target page crashed"> - DevTools was disconnected from the page. + <ph name="LOCKED_1">DevTools</ph> was disconnected from the page. </message> <message name="IDS_DEVTOOLS_650654cb12c12b00e68b4384e0aede82" desc="Aria alert to read the suggestion for the suggestion box when typing in text editor"> <ph name="THIS__ONLYCOMPLETION_TEXT">$1s<ex>name</ex></ph>, suggestion </message> <message name="IDS_DEVTOOLS_678b7bbae3b9b67cee8bce1fac3067d7" desc="Text for a hyperlink to the shortcut documentation in Shortcuts page"> - Full list of DevTools keyboard shortcuts and gestures + Full list of <ph name="LOCKED_1">DevTools</ph> keyboard shortcuts and gestures </message> <message name="IDS_DEVTOOLS_6e0e121820384f135321cb766273f4da" desc="Text in the Shortcuts page to explain a keyboard shortcut (soft undo in text editor)"> Soft undo @@ -178,7 +178,7 @@ Zoom in </message> <message name="IDS_DEVTOOLS_7cf206a681131cf4d86fc190f2d9ad27" desc="Text on a button to reconnect Devtools when remote debugging terminated"> - Reconnect DevTools + Reconnect <ph name="LOCKED_1">DevTools</ph> </message> <message name="IDS_DEVTOOLS_7dce122004969d56ae2e0245cb754d35" desc="Text on a button to start editing text"> Edit @@ -193,7 +193,7 @@ Layers Panel </message> <message name="IDS_DEVTOOLS_86e8f8f8327d28b74e5bd3ab581f77ee" desc="Text that appears when hover over the filter bar in the Network tool"> - e.g. /small[\d]+/ url:a.com/b + e.g. <ph name="LOCKED_1">/small[\d]+/ url:a.com/b</ph> </message> <message name="IDS_DEVTOOLS_89345110b204ed302eddff2ddbd0f4d9" desc="Text in the Shortcuts page to explain a keyboard shortcut (enable toggle breakpoint shortcut in debugger)"> Toggle breakpoint enabled @@ -235,7 +235,7 @@ Toggle all breakpoints </message> <message name="IDS_DEVTOOLS_a950da8e902568f9a6879abe4313efe7" desc="Text content of content element"> - Once page is reloaded, DevTools will automatically reconnect. + Once page is reloaded, <ph name="LOCKED_1">DevTools</ph> will automatically reconnect. </message> <message name="IDS_DEVTOOLS_ad91a1da588ce256d30b1af38f78f84e" desc="Accessibility label for unchecked items in the SoftContextMenu"> unchecked
diff --git a/third_party/blink/renderer/devtools/front_end/workspace/FileManager.js b/third_party/blink/renderer/devtools/front_end/workspace/FileManager.js index 740a6ec..21b5cbe 100644 --- a/third_party/blink/renderer/devtools/front_end/workspace/FileManager.js +++ b/third_party/blink/renderer/devtools/front_end/workspace/FileManager.js
@@ -36,11 +36,11 @@ super(); /** @type {!Map<string, function(?{fileSystemPath: (string|undefined)})>} */ this._saveCallbacks = new Map(); - InspectorFrontendHost.events.addEventListener(InspectorFrontendHostAPI.Events.SavedURL, this._savedURL, this); + InspectorFrontendHost.events.addEventListener(Host.InspectorFrontendHostAPI.Events.SavedURL, this._savedURL, this); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.CanceledSaveURL, this._canceledSavedURL, this); + Host.InspectorFrontendHostAPI.Events.CanceledSaveURL, this._canceledSavedURL, this); InspectorFrontendHost.events.addEventListener( - InspectorFrontendHostAPI.Events.AppendedToURL, this._appendedToURL, this); + Host.InspectorFrontendHostAPI.Events.AppendedToURL, this._appendedToURL, this); } /**
diff --git a/third_party/blink/renderer/devtools/scripts/compile_frontend.py b/third_party/blink/renderer/devtools/scripts/compile_frontend.py index 0f251ebe..a15c1bc3 100755 --- a/third_party/blink/renderer/devtools/scripts/compile_frontend.py +++ b/third_party/blink/renderer/devtools/scripts/compile_frontend.py
@@ -358,9 +358,7 @@ devtools_js_compile_command = closure_compiler_command + [ '--externs', - to_platform_path(GLOBAL_EXTERNS_FILE), '--externs', - to_platform_path(path.join(DEVTOOLS_FRONTEND_PATH, 'host', 'InspectorFrontendHostAPI.js')), - '--jscomp_off=externsValidation', '--js', + to_platform_path(GLOBAL_EXTERNS_FILE), '--jscomp_off=externsValidation', '--js', to_platform_path(path.join(DEVTOOLS_FRONTEND_PATH, 'devtools_compatibility.js')) ] devtools_js_compile_proc = popen(devtools_js_compile_command)
diff --git a/third_party/blink/renderer/devtools/tests/front_end/common/Color.ts b/third_party/blink/renderer/devtools/tests/front_end/common/Color.ts new file mode 100644 index 0000000..341d126e --- /dev/null +++ b/third_party/blink/renderer/devtools/tests/front_end/common/Color.ts
@@ -0,0 +1,62 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +const { assert } = chai; + +import { default as Color } from '../../../front_end/common/Color.js'; + +describe('Color', () => { + describe('parse', () => { + it('parses hex values', () => { + assert.deepEqual(Color.parse('#FF00FF').rgba(), [1, 0, 1, 1]); + assert.deepEqual(Color.parse('#F0F').rgba(), [1, 0, 1, 1]); + assert.deepEqual(Color.parse('#F0F0').rgba(), [1, 0, 1, 0]); + assert.deepEqual(Color.parse('#FF00FF00').rgba(), [1, 0, 1, 0]); + }); + + it('parses nickname values', () => { + assert.deepEqual(Color.parse('red').rgba(), [1, 0, 0, 1]); + }); + + it('parses rgb(a) values', () => { + const colorOne = Color.parse('rgb(255, 255, 0)'); + assert.deepEqual(colorOne.rgba(), [1, 1, 0, 1]); + + const colorTwo = Color.parse('rgba(0, 255, 255, 0.5)'); + assert.deepEqual(colorTwo.rgba(), [0, 1, 1, 0.5]); + + const colorThree = Color.parse('rgb(255 255 255)'); + assert.deepEqual(colorThree.rgba(), [1, 1, 1, 1]); + + const colorFour = Color.parse('rgb(10% 10% 10%)'); + assert.deepEqual(colorFour.rgba(), [0.1, 0.1, 0.1, 1]); + + const colorFive = Color.parse('rgb(10% 10% 10% / 0.4)'); + assert.deepEqual(colorFive.rgba(), [0.1, 0.1, 0.1, 0.4]); + }); + + it('parses hsl(a) values', () => { + const colorOne = Color.parse('hsl(0, 100%, 50%)'); + assert.deepEqual(colorOne.rgba(), [1, 0, 0, 1]); + + const colorTwo = Color.parse('hsla(0, 100%, 50%, 0.5)'); + assert.deepEqual(colorTwo.rgba(), [1, 0, 0, 0.5]); + + const colorThree = Color.parse('hsla(50deg 100% 100% / 50%)'); + assert.deepEqual(colorThree.rgba(), [1, 1, 1, 0.5]); + }); + + it('handles invalid values', () => { + assert.isNull(Color.parse('#FAFAFA Trailing')); + assert.isNull(Color.parse('#FAFAFG')); + assert.isNull(Color.parse('gooseberry')); + assert.isNull(Color.parse('rgb(10% 10% 10% /)')); + assert.isNull(Color.parse('rgb(10% 10% 10% 0.4 40)')); + assert.isNull(Color.parse('hsl(0, carrot, 30%)')); + assert.isNull(Color.parse('hsl(0)')); + assert.isNull(Color.parse('rgb(255)')); + assert.isNull(Color.parse('rgba(1 golf 30)')); + }); + }); +});
diff --git a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc index b35b45c..50fdf34 100644 --- a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc +++ b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
@@ -228,16 +228,13 @@ base::nullopt /* response_address_space */, nullptr /* OriginTrialTokens */, worker_start_data->devtools_worker_token, std::move(worker_settings), - static_cast<V8CacheOptions>(worker_start_data->v8_cache_options), + // Generate the full code cache in the first execution of the script. + kV8CacheOptionsFullCodeWithoutHeatCheck, nullptr /* worklet_module_respones_map */, std::move(interface_provider_info), std::move(browser_interface_broker), BeginFrameProviderParams(), nullptr /* parent_feature_policy */, base::UnguessableToken() /* agent_cluster_id */); - // Generate the full code cache in the first execution of the script. - global_scope_creation_params->v8_cache_options = - kV8CacheOptionsFullCodeWithoutHeatCheck; - worker_thread_ = std::make_unique<ServiceWorkerThread>( std::make_unique<ServiceWorkerGlobalScopeProxy>( *this, *worker_context_client_, initiator_thread_task_runner),
diff --git a/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h b/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h index 85b46e1..f050a85 100644 --- a/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h +++ b/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h
@@ -92,10 +92,10 @@ std::move(destruction_callback_).Run(std::move(callbacks_)); } - ScopedWebCallbacks(ScopedWebCallbacks&& other) noexcept = default; + ScopedWebCallbacks(ScopedWebCallbacks&& other) = default; ScopedWebCallbacks(const ScopedWebCallbacks& other) = delete; - ScopedWebCallbacks& operator=(ScopedWebCallbacks&& other) noexcept = default; + ScopedWebCallbacks& operator=(ScopedWebCallbacks&& other) = default; ScopedWebCallbacks& operator=(const ScopedWebCallbacks& other) = delete; std::unique_ptr<CallbacksType> PassCallbacks() {
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request.h b/third_party/blink/renderer/modules/indexeddb/idb_request.h index f85b864..d3f1132 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request.h +++ b/third_party/blink/renderer/modules/indexeddb/idb_request.h
@@ -110,13 +110,13 @@ ~AsyncTraceState(); // Used to transfer the trace end event state to an IDBRequest. - AsyncTraceState(AsyncTraceState&& other) noexcept { + AsyncTraceState(AsyncTraceState&& other) { DCHECK(IsEmpty()); this->trace_event_name_ = other.trace_event_name_; this->id_ = other.id_; other.trace_event_name_ = nullptr; } - AsyncTraceState& operator=(AsyncTraceState&& rhs) noexcept { + AsyncTraceState& operator=(AsyncTraceState&& rhs) { DCHECK(IsEmpty()); this->trace_event_name_ = rhs.trace_event_name_; this->id_ = rhs.id_;
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc b/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc index 9c8d28d..f5cfb941 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc
@@ -435,10 +435,9 @@ class AsyncTraceStateForTesting : public IDBRequest::AsyncTraceState { public: AsyncTraceStateForTesting() : IDBRequest::AsyncTraceState() {} - AsyncTraceStateForTesting(AsyncTraceStateForTesting&& other) noexcept + AsyncTraceStateForTesting(AsyncTraceStateForTesting&& other) : IDBRequest::AsyncTraceState(std::move(other)) {} - AsyncTraceStateForTesting& operator=( - AsyncTraceStateForTesting&& rhs) noexcept { + AsyncTraceStateForTesting& operator=(AsyncTraceStateForTesting&& rhs) { AsyncTraceState::operator=(std::move(rhs)); return *this; }
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc index 24499bd..3bf00e9 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc
@@ -134,13 +134,13 @@ VideoCaptureSettings::VideoCaptureSettings(const VideoCaptureSettings& other) = default; -VideoCaptureSettings::VideoCaptureSettings( - VideoCaptureSettings&& other) noexcept = default; +VideoCaptureSettings::VideoCaptureSettings(VideoCaptureSettings&& other) = + default; VideoCaptureSettings::~VideoCaptureSettings() = default; VideoCaptureSettings& VideoCaptureSettings::operator=( const VideoCaptureSettings& other) = default; VideoCaptureSettings& VideoCaptureSettings::operator=( - VideoCaptureSettings&& other) noexcept = default; + VideoCaptureSettings&& other) = default; AudioCaptureSettings::AudioCaptureSettings() : AudioCaptureSettings("") {} @@ -166,10 +166,10 @@ default; AudioCaptureSettings& AudioCaptureSettings::operator=( const AudioCaptureSettings& other) = default; -AudioCaptureSettings::AudioCaptureSettings( - AudioCaptureSettings&& other) noexcept = default; +AudioCaptureSettings::AudioCaptureSettings(AudioCaptureSettings&& other) = + default; AudioCaptureSettings& AudioCaptureSettings::operator=( - AudioCaptureSettings&& other) noexcept = default; + AudioCaptureSettings&& other) = default; bool GetConstraintValueAsBoolean( const WebMediaConstraints& constraints,
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc index 96992217..67c8bab 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc
@@ -529,9 +529,9 @@ facing_mode(facing_mode) {} VideoInputDeviceCapabilities::VideoInputDeviceCapabilities( - VideoInputDeviceCapabilities&& other) noexcept = default; + VideoInputDeviceCapabilities&& other) = default; VideoInputDeviceCapabilities& VideoInputDeviceCapabilities::operator=( - VideoInputDeviceCapabilities&& other) noexcept = default; + VideoInputDeviceCapabilities&& other) = default; VideoInputDeviceCapabilities::~VideoInputDeviceCapabilities() = default; @@ -557,10 +557,10 @@ VideoDeviceCaptureCapabilities::VideoDeviceCaptureCapabilities() = default; VideoDeviceCaptureCapabilities::VideoDeviceCaptureCapabilities( - VideoDeviceCaptureCapabilities&& other) noexcept = default; + VideoDeviceCaptureCapabilities&& other) = default; VideoDeviceCaptureCapabilities::~VideoDeviceCaptureCapabilities() = default; VideoDeviceCaptureCapabilities& VideoDeviceCaptureCapabilities::operator=( - VideoDeviceCaptureCapabilities&& other) noexcept = default; + VideoDeviceCaptureCapabilities&& other) = default; VideoCaptureSettings SelectSettingsVideoDeviceCapture( const VideoDeviceCaptureCapabilities& capabilities,
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h index 66ae103..94d8ed96 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h +++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h
@@ -34,9 +34,8 @@ Vector<media::VideoCaptureFormat> formats, media::VideoFacingMode facing_mode); VideoInputDeviceCapabilities(); - VideoInputDeviceCapabilities(VideoInputDeviceCapabilities&& other) noexcept; - VideoInputDeviceCapabilities& operator=( - VideoInputDeviceCapabilities&& other) noexcept; + VideoInputDeviceCapabilities(VideoInputDeviceCapabilities&& other); + VideoInputDeviceCapabilities& operator=(VideoInputDeviceCapabilities&& other); ~VideoInputDeviceCapabilities(); String device_id; @@ -47,11 +46,10 @@ struct MODULES_EXPORT VideoDeviceCaptureCapabilities { VideoDeviceCaptureCapabilities(); - VideoDeviceCaptureCapabilities( - VideoDeviceCaptureCapabilities&& other) noexcept; + VideoDeviceCaptureCapabilities(VideoDeviceCaptureCapabilities&& other); ~VideoDeviceCaptureCapabilities(); VideoDeviceCaptureCapabilities& operator=( - VideoDeviceCaptureCapabilities&& other) noexcept; + VideoDeviceCaptureCapabilities&& other); // Each capabilities field is independent of each other. // TODO(crbug.com/704136): Replace VideoInputDeviceCapabilities in the
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc index 7651e476..99759c10 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc
@@ -461,10 +461,10 @@ callback(callback) {} MediaStreamVideoSource::PendingTrackInfo::PendingTrackInfo( - PendingTrackInfo&& other) noexcept = default; + PendingTrackInfo&& other) = default; MediaStreamVideoSource::PendingTrackInfo& MediaStreamVideoSource::PendingTrackInfo::operator=( - MediaStreamVideoSource::PendingTrackInfo&& other) noexcept = default; + MediaStreamVideoSource::PendingTrackInfo&& other) = default; MediaStreamVideoSource::PendingTrackInfo::~PendingTrackInfo() {}
diff --git a/third_party/blink/renderer/modules/payments/basic_card_helper.cc b/third_party/blink/renderer/modules/payments/basic_card_helper.cc index 6f3ca2d6..96d7c5f 100644 --- a/third_party/blink/renderer/modules/payments/basic_card_helper.cc +++ b/third_party/blink/renderer/modules/payments/basic_card_helper.cc
@@ -41,6 +41,7 @@ const ScriptValue& input, Vector<BasicCardNetwork>& supported_networks_output, Vector<BasicCardType>& supported_types_output, + bool* has_supported_card_types, ExceptionState& exception_state) { DCHECK(!input.IsEmpty()); @@ -68,6 +69,10 @@ } if (basic_card->hasSupportedTypes()) { + if (has_supported_card_types) { + *has_supported_card_types = true; + } + if (basic_card->supportedTypes().size() > PaymentRequest::kMaxListSize) { exception_state.ThrowTypeError( "basic-card supportedTypes cannot be longer than 1024 elements");
diff --git a/third_party/blink/renderer/modules/payments/basic_card_helper.h b/third_party/blink/renderer/modules/payments/basic_card_helper.h index f764cbd..239e305 100644 --- a/third_party/blink/renderer/modules/payments/basic_card_helper.h +++ b/third_party/blink/renderer/modules/payments/basic_card_helper.h
@@ -20,11 +20,15 @@ // Parse 'basic-card' data in |input| and store result in // |supported_networks_output| and |supported_types_output| or throw // exception. + // + // If |has_supported_card_types| is not null, then it is set to true if the + // basic-card specific method data has the "supportedTypes" field. static void ParseBasiccardData( const ScriptValue& input, Vector<::payments::mojom::blink::BasicCardNetwork>& supported_networks_output, Vector<::payments::mojom::blink::BasicCardType>& supported_types_output, + bool* has_supported_card_types, ExceptionState&); // Check whether |input| is 'basic-card' network name.
diff --git a/third_party/blink/renderer/modules/payments/basic_card_request.idl b/third_party/blink/renderer/modules/payments/basic_card_request.idl index 8269e80..9bd0aeb9 100644 --- a/third_party/blink/renderer/modules/payments/basic_card_request.idl +++ b/third_party/blink/renderer/modules/payments/basic_card_request.idl
@@ -12,5 +12,5 @@ dictionary BasicCardRequest { sequence<DOMString> supportedNetworks; - [MeasureAs=BasicCardType] sequence<BasicCardType> supportedTypes; + sequence<BasicCardType> supportedTypes; };
diff --git a/third_party/blink/renderer/modules/payments/payment_instruments.cc b/third_party/blink/renderer/modules/payments/payment_instruments.cc index 2aa69c4a..fb39539a 100644 --- a/third_party/blink/renderer/modules/payments/payment_instruments.cc +++ b/third_party/blink/renderer/modules/payments/payment_instruments.cc
@@ -365,7 +365,8 @@ "PaymentInstruments", "set"); BasicCardHelper::ParseBasiccardData( details->capabilities(), instrument->supported_networks, - instrument->supported_types, exception_state); + instrument->supported_types, /*has_supported_card_types=*/nullptr, + exception_state); if (exception_state.HadException()) { resolver->Reject(exception_state); return;
diff --git a/third_party/blink/renderer/modules/payments/payment_manager.cc b/third_party/blink/renderer/modules/payments/payment_manager.cc index b41c340..029f5ce 100644 --- a/third_party/blink/renderer/modules/payments/payment_manager.cc +++ b/third_party/blink/renderer/modules/payments/payment_manager.cc
@@ -4,7 +4,7 @@ #include "third_party/blink/renderer/modules/payments/payment_manager.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -92,10 +92,9 @@ DCHECK(registration); if (ExecutionContext* context = registration->GetExecutionContext()) { - if (auto* interface_provider = context->GetInterfaceProvider()) { - interface_provider->GetInterface(manager_.BindNewPipeAndPassReceiver( - context->GetTaskRunner(TaskType::kUserInteraction))); - } + context->GetBrowserInterfaceBroker().GetInterface( + manager_.BindNewPipeAndPassReceiver( + context->GetTaskRunner(TaskType::kUserInteraction))); } manager_.set_disconnect_handler(WTF::Bind(
diff --git a/third_party/blink/renderer/modules/payments/payment_request.cc b/third_party/blink/renderer/modules/payments/payment_request.cc index 0fe17dfc..4795bd55 100644 --- a/third_party/blink/renderer/modules/payments/payment_request.cc +++ b/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -393,19 +393,13 @@ output->api_version = android_pay->apiVersion(); } -// Parses basic-card data to avoid parsing JSON in the browser. -void SetBasicCardMethodData(const ScriptValue& input, - PaymentMethodDataPtr& output, - ExceptionState& exception_state) { - BasicCardHelper::ParseBasiccardData(input, output->supported_networks, - output->supported_types, exception_state); -} - -void StringifyAndParseMethodSpecificData(v8::Isolate* isolate, - const String& supported_method, - const ScriptValue& input, - PaymentMethodDataPtr& output, - ExceptionState& exception_state) { +void StringifyAndParseMethodSpecificData( + v8::Isolate* isolate, + const String& supported_method, + const ScriptValue& input, + PaymentMethodDataPtr& output, + bool* basic_card_has_supported_card_types, + ExceptionState& exception_state) { PaymentsValidators::ValidateAndStringifyObject( isolate, "Payment method data", input, output->stringified_data, exception_state); @@ -423,13 +417,17 @@ } if (supported_method == "basic-card") { - SetBasicCardMethodData(input, output, exception_state); + // Parses basic-card data to avoid parsing JSON in the browser. + BasicCardHelper::ParseBasiccardData( + input, output->supported_networks, output->supported_types, + basic_card_has_supported_card_types, exception_state); } } void ValidateAndConvertPaymentDetailsModifiers( const HeapVector<Member<PaymentDetailsModifier>>& input, Vector<PaymentDetailsModifierPtr>& output, + bool* basic_card_has_supported_card_types, ExecutionContext& execution_context, ExceptionState& exception_state) { if (input.size() > PaymentRequest::kMaxListSize) { @@ -469,19 +467,22 @@ if (modifier->hasData() && !modifier->data().IsEmpty()) { StringifyAndParseMethodSpecificData( execution_context.GetIsolate(), modifier->supportedMethod(), - modifier->data(), output.back()->method_data, exception_state); + modifier->data(), output.back()->method_data, + basic_card_has_supported_card_types, exception_state); } else { output.back()->method_data->stringified_data = ""; } } } -void ValidateAndConvertPaymentDetailsBase(const PaymentDetailsBase* input, - const PaymentOptions* options, - PaymentDetailsPtr& output, - String& shipping_option_output, - ExecutionContext& execution_context, - ExceptionState& exception_state) { +void ValidateAndConvertPaymentDetailsBase( + const PaymentDetailsBase* input, + const PaymentOptions* options, + PaymentDetailsPtr& output, + String& shipping_option_output, + bool* basic_card_has_supported_card_types, + ExecutionContext& execution_context, + ExceptionState& exception_state) { if (input->hasDisplayItems()) { output->display_items = Vector<PaymentItemPtr>(); ValidateAndConvertDisplayItems(input->displayItems(), "display items", @@ -507,26 +508,29 @@ if (input->hasModifiers()) { output->modifiers = Vector<PaymentDetailsModifierPtr>(); ValidateAndConvertPaymentDetailsModifiers( - input->modifiers(), *output->modifiers, execution_context, + input->modifiers(), *output->modifiers, + basic_card_has_supported_card_types, execution_context, exception_state); } } -void ValidateAndConvertPaymentDetailsInit(const PaymentDetailsInit* input, - const PaymentOptions* options, - PaymentDetailsPtr& output, - String& shipping_option_output, - ExecutionContext& execution_context, - ExceptionState& exception_state) { +void ValidateAndConvertPaymentDetailsInit( + const PaymentDetailsInit* input, + const PaymentOptions* options, + PaymentDetailsPtr& output, + String& shipping_option_output, + bool* basic_card_has_supported_card_types, + ExecutionContext& execution_context, + ExceptionState& exception_state) { DCHECK(input->hasTotal()); ValidateAndConvertTotal(input->total(), "total", output->total, execution_context, exception_state); if (exception_state.HadException()) return; - ValidateAndConvertPaymentDetailsBase(input, options, output, - shipping_option_output, - execution_context, exception_state); + ValidateAndConvertPaymentDetailsBase( + input, options, output, shipping_option_output, + basic_card_has_supported_card_types, execution_context, exception_state); } void ValidateAndConvertPaymentDetailsUpdate(const PaymentDetailsUpdate* input, @@ -535,9 +539,9 @@ String& shipping_option_output, ExecutionContext& execution_context, ExceptionState& exception_state) { - ValidateAndConvertPaymentDetailsBase(input, options, output, - shipping_option_output, - execution_context, exception_state); + ValidateAndConvertPaymentDetailsBase( + input, options, output, shipping_option_output, + /*has_supported_card_types=*/nullptr, execution_context, exception_state); if (exception_state.HadException()) return; @@ -585,6 +589,7 @@ bool& skip_to_gpay_ready, Vector<payments::mojom::blink::PaymentMethodDataPtr>& output, HashSet<String>& method_names, + bool* basic_card_has_supported_card_types, ExecutionContext& execution_context, ExceptionState& exception_state) { if (input.IsEmpty()) { @@ -621,7 +626,7 @@ StringifyAndParseMethodSpecificData( execution_context.GetIsolate(), payment_method_data->supportedMethod(), payment_method_data->data(), - output.back(), exception_state); + output.back(), basic_card_has_supported_card_types, exception_state); if (exception_state.HadException()) continue; @@ -719,6 +724,10 @@ WebFeature::kPaymentRequestShowWithoutGesture); } + if (basic_card_has_supported_card_types_) { + UseCounter::Count(GetExecutionContext(), WebFeature::kBasicCardType); + } + // TODO(crbug.com/779126): add support for handling payment requests in // immersive mode. if (GetFrame()->GetDocument()->GetSettings()->GetImmersiveModeEnabled()) { @@ -1088,7 +1097,8 @@ execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI), this, &PaymentRequest::OnUpdatePaymentDetailsTimeout), - is_waiting_for_show_promise_to_resolve_(false) { + is_waiting_for_show_promise_to_resolve_(false), + basic_card_has_supported_card_types_(false) { DCHECK(GetExecutionContext()->IsSecureContext()); if (!AllowedToUsePaymentRequest(execution_context)) { @@ -1118,13 +1128,15 @@ Vector<payments::mojom::blink::PaymentMethodDataPtr> validated_method_data; ValidateAndConvertPaymentMethodData(method_data, options_, skip_to_gpay_ready, validated_method_data, method_names_, + &basic_card_has_supported_card_types_, *GetExecutionContext(), exception_state); if (exception_state.HadException()) return; ValidateAndConvertPaymentDetailsInit(details, options_, validated_details, - shipping_option_, *GetExecutionContext(), - exception_state); + shipping_option_, + &basic_card_has_supported_card_types_, + *GetExecutionContext(), exception_state); if (exception_state.HadException()) return;
diff --git a/third_party/blink/renderer/modules/payments/payment_request.h b/third_party/blink/renderer/modules/payments/payment_request.h index 25442453..d8f2a2c1 100644 --- a/third_party/blink/renderer/modules/payments/payment_request.h +++ b/third_party/blink/renderer/modules/payments/payment_request.h
@@ -171,6 +171,7 @@ TaskRunnerTimer<PaymentRequest> complete_timer_; TaskRunnerTimer<PaymentRequest> update_payment_details_timer_; bool is_waiting_for_show_promise_to_resolve_; + bool basic_card_has_supported_card_types_; DISALLOW_COPY_AND_ASSIGN(PaymentRequest); };
diff --git a/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc b/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc index 9f871bf..34884c49 100644 --- a/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc +++ b/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
@@ -27,7 +27,6 @@ #include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h" #include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h" #include "third_party/blink/public/web/web_embedded_worker_start_data.h" -#include "third_party/blink/public/web/web_settings.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_error.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" @@ -209,7 +208,6 @@ start_data->script_type = mojom::ScriptType::kClassic; start_data->wait_for_debugger_mode = WebEmbeddedWorkerStartData::kDontWaitForDebugger; - start_data->v8_cache_options = WebSettings::V8CacheOptions::kDefault; return start_data; }
diff --git a/third_party/blink/renderer/modules/sms/sms_receiver.cc b/third_party/blink/renderer/modules/sms/sms_receiver.cc index be89fae..127220a1 100644 --- a/third_party/blink/renderer/modules/sms/sms_receiver.cc +++ b/third_party/blink/renderer/modules/sms/sms_receiver.cc
@@ -6,7 +6,7 @@ #include "third_party/blink/renderer/modules/sms/sms_receiver.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/mojom/sms/sms_receiver.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -46,7 +46,7 @@ GetExecutionContext()->GetTaskRunner(TaskType::kInternalIPC); if (!service_) { - GetExecutionContext()->GetInterfaceProvider()->GetInterface( + GetExecutionContext()->GetBrowserInterfaceBroker().GetInterface( service_.BindNewPipeAndPassReceiver(task_runner)); service_.set_disconnect_handler(WTF::Bind( &SMSReceiver::OnSMSReceiverConnectionError, WrapWeakPersistent(this)));
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_origin_3d.idl b/third_party/blink/renderer/modules/webgpu/gpu_origin_3d.idl index d1359ba..fbfb79b 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_origin_3d.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_origin_3d.idl
@@ -5,7 +5,7 @@ // https://gpuweb.github.io/gpuweb/ dictionary GPUOrigin3D { - required unsigned long x; - required unsigned long y; - required unsigned long z; + unsigned long x = 0; + unsigned long y = 0; + unsigned long z = 0; };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl b/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl index c0630b9..b5ffa0a22 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl
@@ -8,5 +8,5 @@ required GPUTexture texture; unsigned long mipLevel = 0; unsigned long arrayLayer = 0; - required GPUOrigin3D origin; + GPUOrigin3D origin; };
diff --git a/third_party/blink/renderer/platform/bindings/dom_data_store.h b/third_party/blink/renderer/platform/bindings/dom_data_store.h index d660b674..0660dd18 100644 --- a/third_party/blink/renderer/platform/bindings/dom_data_store.h +++ b/third_party/blink/renderer/platform/bindings/dom_data_store.h
@@ -230,12 +230,11 @@ : TraceWrapperV8Reference(isolate, handle) {} // Move support without write barrier. - DOMWorldWrapperReference(DOMWorldWrapperReference&& other) noexcept + DOMWorldWrapperReference(DOMWorldWrapperReference&& other) : TraceWrapperV8Reference() { handle_ = std::move(other.handle_); } - DOMWorldWrapperReference& operator=( - DOMWorldWrapperReference&& rhs) noexcept { + DOMWorldWrapperReference& operator=(DOMWorldWrapperReference&& rhs) { handle_ = std::move(rhs.handle_); return *this; }
diff --git a/third_party/blink/renderer/platform/exported/web_string.cc b/third_party/blink/renderer/platform/exported/web_string.cc index 71d4c07..fbe4828 100644 --- a/third_party/blink/renderer/platform/exported/web_string.cc +++ b/third_party/blink/renderer/platform/exported/web_string.cc
@@ -51,9 +51,9 @@ WebString::~WebString() = default; WebString::WebString() = default; WebString::WebString(const WebString&) = default; -WebString::WebString(WebString&&) noexcept = default; +WebString::WebString(WebString&&) = default; WebString& WebString::operator=(const WebString&) = default; -WebString& WebString::operator=(WebString&&) noexcept = default; +WebString& WebString::operator=(WebString&&) = default; WebString::WebString(const WebUChar* data, size_t len) : impl_(StringImpl::Create8BitIfPossible(data, len)) {}
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource.cc b/third_party/blink/renderer/platform/graphics/canvas_resource.cc index f15bd95..f6b8014 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource.cc
@@ -564,13 +564,10 @@ scoped_refptr<StaticBitmapImage> image; // If its cross thread, then the sync token was already verified. If not, then - // it doesn't need to be verified. - if (!is_cross_thread()) - owning_thread_data().mailbox_sync_mode = kUnverifiedSyncToken; - + // we don't need one. The image lazily generates a token if needed. + gpu::SyncToken token = is_cross_thread() ? sync_token() : gpu::SyncToken(); image = AcceleratedStaticBitmapImage::CreateFromCanvasMailbox( - mailbox(), is_cross_thread() ? sync_token() : GetSyncToken(), - texture_id_for_image, image_info, texture_target_, + mailbox(), token, texture_id_for_image, image_info, texture_target_, context_provider_wrapper_, owning_thread_id_, is_origin_top_left_, std::move(release_callback));
diff --git a/third_party/blink/renderer/platform/graphics/compositing_reasons.cc b/third_party/blink/renderer/platform/graphics/compositing_reasons.cc index 1245f2dc..4aa0e2d 100644 --- a/third_party/blink/renderer/platform/graphics/compositing_reasons.cc +++ b/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
@@ -110,8 +110,6 @@ "tree"}, {CompositingReason::kLayerForDescendantClip, "layerForDescendantClip", "Secondary layer, to clip descendants of the owning layer"}, - {CompositingReason::kLayerForPerspective, "layerForPerspective", - "Secondary layer, to house the perspective transform for all descendants"}, {CompositingReason::kLayerForHorizontalScrollbar, "layerForHorizontalScrollbar", "Secondary layer, the horizontal scrollbar layer"},
diff --git a/third_party/blink/renderer/platform/graphics/compositing_reasons.h b/third_party/blink/renderer/platform/graphics/compositing_reasons.h index 64298eb2..3de897d 100644 --- a/third_party/blink/renderer/platform/graphics/compositing_reasons.h +++ b/third_party/blink/renderer/platform/graphics/compositing_reasons.h
@@ -70,7 +70,6 @@ /* CompositedLayerMapping internal hierarchy reasons. */ \ V(LayerForAncestorClip) \ V(LayerForDescendantClip) \ - V(LayerForPerspective) \ V(LayerForHorizontalScrollbar) \ V(LayerForVerticalScrollbar) \ V(LayerForOverflowControlsHost) \
diff --git a/third_party/blink/renderer/platform/graphics/contiguous_container.cc b/third_party/blink/renderer/platform/graphics/contiguous_container.cc index fd01c00..19cb6f2 100644 --- a/third_party/blink/renderer/platform/graphics/contiguous_container.cc +++ b/third_party/blink/renderer/platform/graphics/contiguous_container.cc
@@ -69,7 +69,7 @@ : end_index_(0), max_object_size_(max_object_size) {} ContiguousContainerBase::ContiguousContainerBase( - ContiguousContainerBase&& source) noexcept + ContiguousContainerBase&& source) : ContiguousContainerBase(source.max_object_size_) { Swap(source); } @@ -77,7 +77,7 @@ ContiguousContainerBase::~ContiguousContainerBase() = default; ContiguousContainerBase& ContiguousContainerBase::operator=( - ContiguousContainerBase&& source) noexcept { + ContiguousContainerBase&& source) { Swap(source); return *this; }
diff --git a/third_party/blink/renderer/platform/graphics/contiguous_container.h b/third_party/blink/renderer/platform/graphics/contiguous_container.h index 867e59c..3eee558 100644 --- a/third_party/blink/renderer/platform/graphics/contiguous_container.h +++ b/third_party/blink/renderer/platform/graphics/contiguous_container.h
@@ -42,10 +42,10 @@ protected: explicit ContiguousContainerBase(size_t max_object_size); - ContiguousContainerBase(ContiguousContainerBase&&) noexcept; + ContiguousContainerBase(ContiguousContainerBase&&); ~ContiguousContainerBase(); - ContiguousContainerBase& operator=(ContiguousContainerBase&&) noexcept; + ContiguousContainerBase& operator=(ContiguousContainerBase&&); size_t size() const { return elements_.size(); } bool IsEmpty() const { return !size(); } @@ -147,7 +147,7 @@ WTF_HEAP_PROFILER_TYPE_NAME(BaseElementType)); } - ContiguousContainer(ContiguousContainer&& source) noexcept + ContiguousContainer(ContiguousContainer&& source) : ContiguousContainerBase(std::move(source)) {} ~ContiguousContainer() { @@ -157,7 +157,7 @@ } } - ContiguousContainer& operator=(ContiguousContainer&& source) noexcept { + ContiguousContainer& operator=(ContiguousContainer&& source) { // Must clear in the derived class to ensure that element destructors // care called. Clear();
diff --git a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc index 66bc765..ecad189 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
@@ -246,9 +246,9 @@ } ImageLayerBridge::RegisteredBitmap::RegisteredBitmap() = default; -ImageLayerBridge::RegisteredBitmap::RegisteredBitmap( - RegisteredBitmap&& other) noexcept = default; +ImageLayerBridge::RegisteredBitmap::RegisteredBitmap(RegisteredBitmap&& other) = + default; ImageLayerBridge::RegisteredBitmap& ImageLayerBridge::RegisteredBitmap:: -operator=(RegisteredBitmap&& other) noexcept = default; +operator=(RegisteredBitmap&& other) = default; } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h index 4a08050..d550eb47 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h +++ b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h
@@ -64,8 +64,8 @@ // only with software compositing. struct RegisteredBitmap { RegisteredBitmap(); - RegisteredBitmap(RegisteredBitmap&& other) noexcept; - RegisteredBitmap& operator=(RegisteredBitmap&& other) noexcept; + RegisteredBitmap(RegisteredBitmap&& other); + RegisteredBitmap& operator=(RegisteredBitmap&& other); scoped_refptr<cc::CrossThreadSharedBitmap> bitmap; cc::SharedBitmapIdRegistration registration;
diff --git a/third_party/blink/renderer/platform/graphics/paint/display_item_list.h b/third_party/blink/renderer/platform/graphics/paint/display_item_list.h index cd3ed2f..9ee2571 100644 --- a/third_party/blink/renderer/platform/graphics/paint/display_item_list.h +++ b/third_party/blink/renderer/platform/graphics/paint/display_item_list.h
@@ -28,10 +28,10 @@ public: DisplayItemList(size_t initial_size_bytes) : ContiguousContainer(kMaximumDisplayItemSize, initial_size_bytes) {} - DisplayItemList(DisplayItemList&& source) noexcept + DisplayItemList(DisplayItemList&& source) : ContiguousContainer(std::move(source)) {} - DisplayItemList& operator=(DisplayItemList&& source) noexcept { + DisplayItemList& operator=(DisplayItemList&& source) { ContiguousContainer::operator=(std::move(source)); return *this; }
diff --git a/third_party/blink/renderer/platform/heap/heap_test.cc b/third_party/blink/renderer/platform/heap/heap_test.cc index a3b0d0a..54b950c 100644 --- a/third_party/blink/renderer/platform/heap/heap_test.cc +++ b/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -145,7 +145,7 @@ } KeyWithCopyingMoveConstructor(const KeyWithCopyingMoveConstructor&) = default; // The move constructor delegates to the copy constructor intentionally. - KeyWithCopyingMoveConstructor(KeyWithCopyingMoveConstructor&& x) noexcept + KeyWithCopyingMoveConstructor(KeyWithCopyingMoveConstructor&& x) : KeyWithCopyingMoveConstructor(x) {} KeyWithCopyingMoveConstructor& operator=( const KeyWithCopyingMoveConstructor&) = default;
diff --git a/third_party/blink/renderer/platform/image-decoders/segment_stream.cc b/third_party/blink/renderer/platform/image-decoders/segment_stream.cc index 4024f9c..5a98701 100644 --- a/third_party/blink/renderer/platform/image-decoders/segment_stream.cc +++ b/third_party/blink/renderer/platform/image-decoders/segment_stream.cc
@@ -10,10 +10,10 @@ SegmentStream::SegmentStream() = default; -SegmentStream::SegmentStream(SegmentStream&& rhs) noexcept +SegmentStream::SegmentStream(SegmentStream&& rhs) : reader_(std::move(rhs.reader_)), position_(rhs.position_) {} -SegmentStream& SegmentStream::operator=(SegmentStream&& rhs) noexcept { +SegmentStream& SegmentStream::operator=(SegmentStream&& rhs) { reader_ = std::move(rhs.reader_); position_ = rhs.position_;
diff --git a/third_party/blink/renderer/platform/image-decoders/segment_stream.h b/third_party/blink/renderer/platform/image-decoders/segment_stream.h index f49f551..fa1ccf2 100644 --- a/third_party/blink/renderer/platform/image-decoders/segment_stream.h +++ b/third_party/blink/renderer/platform/image-decoders/segment_stream.h
@@ -19,8 +19,8 @@ SegmentStream(); SegmentStream(const SegmentStream&) = delete; SegmentStream& operator=(const SegmentStream&) = delete; - SegmentStream(SegmentStream&&) noexcept; - SegmentStream& operator=(SegmentStream&&) noexcept; + SegmentStream(SegmentStream&&); + SegmentStream& operator=(SegmentStream&&); ~SegmentStream() override;
diff --git a/third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h b/third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h index 555be28..34bad3f 100644 --- a/third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h +++ b/third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h
@@ -41,7 +41,7 @@ RevocableInterfacePtr(std::nullptr_t) {} // Takes over the binding of another RevocableInterfacePtr. - RevocableInterfacePtr(RevocableInterfacePtr&& other) noexcept { + RevocableInterfacePtr(RevocableInterfacePtr&& other) { interface_ptr_ = std::move(other.interface_ptr_); SetInvalidator(other.invalidator_.get()); // Reset the other interface ptr to remove it as an observer of the @@ -58,7 +58,7 @@ // Takes over the binding of another RevocableInterfacePtr, and closes any // message pipe already bound to this pointer. - RevocableInterfacePtr& operator=(RevocableInterfacePtr&& other) noexcept { + RevocableInterfacePtr& operator=(RevocableInterfacePtr&& other) { reset(); interface_ptr_ = std::move(other.interface_ptr_); SetInvalidator(other.invalidator_.get());
diff --git a/third_party/blink/renderer/platform/network/encoded_form_data.cc b/third_party/blink/renderer/platform/network/encoded_form_data.cc index bc4ec14d7..1b660e6f 100644 --- a/third_party/blink/renderer/platform/network/encoded_form_data.cc +++ b/third_party/blink/renderer/platform/network/encoded_form_data.cc
@@ -61,11 +61,10 @@ : type_(kDataPipe), data_pipe_getter_(std::move(data_pipe_getter)) {} FormDataElement::FormDataElement(const FormDataElement&) = default; -FormDataElement::FormDataElement(FormDataElement&&) noexcept = default; +FormDataElement::FormDataElement(FormDataElement&&) = default; FormDataElement::~FormDataElement() = default; FormDataElement& FormDataElement::operator=(const FormDataElement&) = default; -FormDataElement& FormDataElement::operator=(FormDataElement&&) noexcept = - default; +FormDataElement& FormDataElement::operator=(FormDataElement&&) = default; bool operator==(const FormDataElement& a, const FormDataElement& b) { if (&a == &b)
diff --git a/third_party/blink/renderer/platform/network/encoded_form_data.h b/third_party/blink/renderer/platform/network/encoded_form_data.h index 48f84c8..865f664 100644 --- a/third_party/blink/renderer/platform/network/encoded_form_data.h +++ b/third_party/blink/renderer/platform/network/encoded_form_data.h
@@ -61,12 +61,12 @@ explicit FormDataElement(scoped_refptr<WrappedDataPipeGetter>); FormDataElement(const FormDataElement&); - FormDataElement(FormDataElement&&) noexcept; + FormDataElement(FormDataElement&&); ~FormDataElement(); FormDataElement& operator=(const FormDataElement&); - FormDataElement& operator=(FormDataElement&&) noexcept; + FormDataElement& operator=(FormDataElement&&); bool IsSafeToSendToAnotherThread() const;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 6fb001f6..ee86fde 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -203,7 +203,7 @@ }, { name: "Badging", - origin_trial_feature_name: "BadgingV2", + origin_trial_feature_name: "Badging", status: "experimental", }, {
diff --git a/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc b/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc index ebe99ff..e971856 100644 --- a/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc
@@ -28,15 +28,14 @@ } FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle:: - SchedulingAffectingFeatureHandle( - SchedulingAffectingFeatureHandle&& other) noexcept + SchedulingAffectingFeatureHandle(SchedulingAffectingFeatureHandle&& other) : feature_(other.feature_), scheduler_(std::move(other.scheduler_)) { other.scheduler_ = nullptr; } FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle& FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle::operator=( - SchedulingAffectingFeatureHandle&& other) noexcept { + SchedulingAffectingFeatureHandle&& other) { feature_ = other.feature_; policy_ = std::move(other.policy_); scheduler_ = std::move(other.scheduler_);
diff --git a/third_party/blink/renderer/platform/scheduler/common/post_cancellable_task.cc b/third_party/blink/renderer/platform/scheduler/common/post_cancellable_task.cc index 2c84d70..fad56ee1 100644 --- a/third_party/blink/renderer/platform/scheduler/common/post_cancellable_task.cc +++ b/third_party/blink/renderer/platform/scheduler/common/post_cancellable_task.cc
@@ -103,9 +103,9 @@ Cancel(); } -TaskHandle::TaskHandle(TaskHandle&&) noexcept = default; +TaskHandle::TaskHandle(TaskHandle&&) = default; -TaskHandle& TaskHandle::operator=(TaskHandle&& other) noexcept { +TaskHandle& TaskHandle::operator=(TaskHandle&& other) { TaskHandle tmp(std::move(other)); runner_.swap(tmp.runner_); return *this;
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/web_scoped_virtual_time_pauser.cc b/third_party/blink/renderer/platform/scheduler/main_thread/web_scoped_virtual_time_pauser.cc index f55730a..b64ec9d 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/web_scoped_virtual_time_pauser.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/web_scoped_virtual_time_pauser.cc
@@ -28,7 +28,7 @@ } WebScopedVirtualTimePauser::WebScopedVirtualTimePauser( - WebScopedVirtualTimePauser&& other) noexcept { + WebScopedVirtualTimePauser&& other) { virtual_time_when_paused_ = other.virtual_time_when_paused_; paused_ = other.paused_; duration_ = other.duration_; @@ -39,7 +39,7 @@ } WebScopedVirtualTimePauser& WebScopedVirtualTimePauser::operator=( - WebScopedVirtualTimePauser&& other) noexcept { + WebScopedVirtualTimePauser&& other) { if (scheduler_ && paused_) DecrementVirtualTimePauseCount(); virtual_time_when_paused_ = other.virtual_time_when_paused_;
diff --git a/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h index 0e91c6f..3ded554 100644 --- a/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h
@@ -57,12 +57,11 @@ public: SchedulingAffectingFeatureHandle() = default; - SchedulingAffectingFeatureHandle( - SchedulingAffectingFeatureHandle&&) noexcept; + SchedulingAffectingFeatureHandle(SchedulingAffectingFeatureHandle&&); inline ~SchedulingAffectingFeatureHandle() { reset(); } SchedulingAffectingFeatureHandle& operator=( - SchedulingAffectingFeatureHandle&&) noexcept; + SchedulingAffectingFeatureHandle&&); inline void reset() { if (scheduler_)
diff --git a/third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h b/third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h index 38cbf63..ae66c73c 100644 --- a/third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h +++ b/third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h
@@ -28,8 +28,8 @@ TaskHandle(); ~TaskHandle(); - TaskHandle(TaskHandle&&) noexcept; - TaskHandle& operator=(TaskHandle&&) noexcept; + TaskHandle(TaskHandle&&); + TaskHandle& operator=(TaskHandle&&); // Returns true if the task will run later. Returns false if the task is // cancelled or the task is run already.
diff --git a/third_party/blink/renderer/platform/weborigin/origin_access_entry.cc b/third_party/blink/renderer/platform/weborigin/origin_access_entry.cc index 2e9a9d1..c9d777e7 100644 --- a/third_party/blink/renderer/platform/weborigin/origin_access_entry.cc +++ b/third_party/blink/renderer/platform/weborigin/origin_access_entry.cc
@@ -59,8 +59,7 @@ network::mojom::CorsPortMatchMode::kAllowOnlySpecifiedPort, priority) {} -OriginAccessEntry::OriginAccessEntry(OriginAccessEntry&& from) noexcept = - default; +OriginAccessEntry::OriginAccessEntry(OriginAccessEntry&& from) = default; network::cors::OriginAccessEntry::MatchResult OriginAccessEntry::MatchesOrigin( const SecurityOrigin& origin) const {
diff --git a/third_party/blink/renderer/platform/weborigin/origin_access_entry.h b/third_party/blink/renderer/platform/weborigin/origin_access_entry.h index b3e5674..5113a406 100644 --- a/third_party/blink/renderer/platform/weborigin/origin_access_entry.h +++ b/third_party/blink/renderer/platform/weborigin/origin_access_entry.h
@@ -58,7 +58,7 @@ network::mojom::CorsDomainMatchMode, network::mojom::CorsOriginAccessMatchPriority priority = network::mojom::CorsOriginAccessMatchPriority::kDefaultPriority); - OriginAccessEntry(OriginAccessEntry&& from) noexcept; + OriginAccessEntry(OriginAccessEntry&& from); network::cors::OriginAccessEntry::MatchResult MatchesOrigin( const SecurityOrigin&) const;
diff --git a/third_party/blink/renderer/platform/wtf/deque.h b/third_party/blink/renderer/platform/wtf/deque.h index c6fe1b9..4a98ffb 100644 --- a/third_party/blink/renderer/platform/wtf/deque.h +++ b/third_party/blink/renderer/platform/wtf/deque.h
@@ -66,8 +66,8 @@ Deque(); Deque(const Deque&); Deque& operator=(const Deque&); - Deque(Deque&&) noexcept; - Deque& operator=(Deque&&) noexcept; + Deque(Deque&&); + Deque& operator=(Deque&&); void Finalize(); @@ -343,14 +343,14 @@ } template <typename T, wtf_size_t inlineCapacity, typename Allocator> -inline Deque<T, inlineCapacity, Allocator>::Deque(Deque&& other) noexcept +inline Deque<T, inlineCapacity, Allocator>::Deque(Deque&& other) : start_(0), end_(0) { Swap(other); } template <typename T, wtf_size_t inlineCapacity, typename Allocator> inline Deque<T, inlineCapacity, Allocator>& -Deque<T, inlineCapacity, Allocator>::operator=(Deque&& other) noexcept { +Deque<T, inlineCapacity, Allocator>::operator=(Deque&& other) { Swap(other); return *this; }
diff --git a/third_party/blink/renderer/platform/wtf/functional.h b/third_party/blink/renderer/platform/wtf/functional.h index 2c5aeea5f..5e4b373 100644 --- a/third_party/blink/renderer/platform/wtf/functional.h +++ b/third_party/blink/renderer/platform/wtf/functional.h
@@ -117,8 +117,7 @@ class PassedWrapper final { public: explicit PassedWrapper(T&& scoper) : scoper_(std::move(scoper)) {} - PassedWrapper(PassedWrapper&& other) noexcept - : scoper_(std::move(other.scoper_)) {} + PassedWrapper(PassedWrapper&& other) : scoper_(std::move(other.scoper_)) {} T MoveOut() const { return std::move(scoper_); } private: @@ -319,9 +318,8 @@ CrossThreadFunction(const CrossThreadFunction&) = delete; CrossThreadFunction& operator=(const CrossThreadFunction&) = delete; - CrossThreadFunction(CrossThreadFunction&& other) noexcept = default; - CrossThreadFunction& operator=(CrossThreadFunction&& other) noexcept = - default; + CrossThreadFunction(CrossThreadFunction&& other) = default; + CrossThreadFunction& operator=(CrossThreadFunction&& other) = default; R Run(Args... args) const & { return callback_.Run(std::forward<Args>(args)...); @@ -356,9 +354,8 @@ CrossThreadOnceFunction(const CrossThreadOnceFunction&) = delete; CrossThreadOnceFunction& operator=(const CrossThreadOnceFunction&) = delete; - CrossThreadOnceFunction(CrossThreadOnceFunction&& other) noexcept = default; - CrossThreadOnceFunction& operator=(CrossThreadOnceFunction&& other) noexcept = - default; + CrossThreadOnceFunction(CrossThreadOnceFunction&& other) = default; + CrossThreadOnceFunction& operator=(CrossThreadOnceFunction&& other) = default; R Run(Args... args) && { return std::move(callback_).Run(std::forward<Args>(args)...);
diff --git a/third_party/blink/renderer/platform/wtf/hash_map.h b/third_party/blink/renderer/platform/wtf/hash_map.h index 8a002a8..46b39e0 100644 --- a/third_party/blink/renderer/platform/wtf/hash_map.h +++ b/third_party/blink/renderer/platform/wtf/hash_map.h
@@ -106,8 +106,8 @@ #endif HashMap(const HashMap&) = default; HashMap& operator=(const HashMap&) = default; - HashMap(HashMap&&) noexcept = default; - HashMap& operator=(HashMap&&) noexcept = default; + HashMap(HashMap&&) = default; + HashMap& operator=(HashMap&&) = default; // For example, HashMap<int, int>({{1, 11}, {2, 22}, {3, 33}}) will give you // a HashMap containing a mapping {1 -> 11, 2 -> 22, 3 -> 33}.
diff --git a/third_party/blink/renderer/platform/wtf/hash_set.h b/third_party/blink/renderer/platform/wtf/hash_set.h index c79e45f1..d7cdeed 100644 --- a/third_party/blink/renderer/platform/wtf/hash_set.h +++ b/third_party/blink/renderer/platform/wtf/hash_set.h
@@ -74,8 +74,8 @@ } HashSet(const HashSet&) = default; HashSet& operator=(const HashSet&) = default; - HashSet(HashSet&&) noexcept = default; - HashSet& operator=(HashSet&&) noexcept = default; + HashSet(HashSet&&) = default; + HashSet& operator=(HashSet&&) = default; HashSet(std::initializer_list<ValueType> elements); HashSet& operator=(std::initializer_list<ValueType> elements);
diff --git a/third_party/blink/renderer/platform/wtf/hash_table.h b/third_party/blink/renderer/platform/wtf/hash_table.h index 373280f..52483ec5 100644 --- a/third_party/blink/renderer/platform/wtf/hash_table.h +++ b/third_party/blink/renderer/platform/wtf/hash_table.h
@@ -747,10 +747,10 @@ } HashTable(const HashTable&); - HashTable(HashTable&&) noexcept; + HashTable(HashTable&&); void swap(HashTable&); HashTable& operator=(const HashTable&); - HashTable& operator=(HashTable&&) noexcept; + HashTable& operator=(HashTable&&); // When the hash table is empty, just return the same iterator for end as // for begin. This is more efficient because we don't have to skip all the @@ -1929,7 +1929,7 @@ typename KeyTraits, typename Allocator> HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>:: - HashTable(HashTable&& other) noexcept + HashTable(HashTable&& other) : table_(nullptr), table_size_(0), key_count_(0), @@ -2008,7 +2008,7 @@ typename Allocator> HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>& HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>:: -operator=(HashTable&& other) noexcept { +operator=(HashTable&& other) { swap(other); return *this; }
diff --git a/third_party/blink/renderer/platform/wtf/linked_hash_set.h b/third_party/blink/renderer/platform/wtf/linked_hash_set.h index 79c3d76d..71ef37a 100644 --- a/third_party/blink/renderer/platform/wtf/linked_hash_set.h +++ b/third_party/blink/renderer/platform/wtf/linked_hash_set.h
@@ -121,7 +121,7 @@ LinkedHashSetNodeBase(const LinkedHashSetNodeBase& other) : prev_(nullptr), next_(nullptr) {} - LinkedHashSetNodeBase(LinkedHashSetNodeBase&& other) noexcept + LinkedHashSetNodeBase(LinkedHashSetNodeBase&& other) : prev_(other.prev_), next_(other.next_) { other.prev_ = nullptr; other.next_ = nullptr; @@ -151,7 +151,7 @@ LinkedHashSetNodeBase* next) : LinkedHashSetNodeBase(prev, next), value_(std::move(value)) {} - LinkedHashSetNode(LinkedHashSetNode&& other) noexcept + LinkedHashSetNode(LinkedHashSetNode&& other) : LinkedHashSetNodeBase(std::move(other)), value_(std::move(other.value_)) {} @@ -214,9 +214,9 @@ LinkedHashSet(); LinkedHashSet(const LinkedHashSet&); - LinkedHashSet(LinkedHashSet&&) noexcept; + LinkedHashSet(LinkedHashSet&&); LinkedHashSet& operator=(const LinkedHashSet&); - LinkedHashSet& operator=(LinkedHashSet&&) noexcept; + LinkedHashSet& operator=(LinkedHashSet&&); // Needs finalization. The anchor needs to unlink itself from the chain. ~LinkedHashSet(); @@ -748,7 +748,7 @@ } template <typename T, typename U, typename V, typename W> -inline LinkedHashSet<T, U, V, W>::LinkedHashSet(LinkedHashSet&& other) noexcept +inline LinkedHashSet<T, U, V, W>::LinkedHashSet(LinkedHashSet&& other) : anchor_() { Swap(other); } @@ -763,7 +763,7 @@ template <typename T, typename U, typename V, typename W> inline LinkedHashSet<T, U, V, W>& LinkedHashSet<T, U, V, W>::operator=( - LinkedHashSet&& other) noexcept { + LinkedHashSet&& other) { Swap(other); return *this; }
diff --git a/third_party/blink/renderer/platform/wtf/list_hash_set.h b/third_party/blink/renderer/platform/wtf/list_hash_set.h index ead6a87..78bd279 100644 --- a/third_party/blink/renderer/platform/wtf/list_hash_set.h +++ b/third_party/blink/renderer/platform/wtf/list_hash_set.h
@@ -149,9 +149,9 @@ ListHashSet(); ListHashSet(const ListHashSet&); - ListHashSet(ListHashSet&&) noexcept; + ListHashSet(ListHashSet&&); ListHashSet& operator=(const ListHashSet&); - ListHashSet& operator=(ListHashSet&&) noexcept; + ListHashSet& operator=(ListHashSet&&); void Finalize(); void Swap(ListHashSet&); @@ -780,8 +780,7 @@ } template <typename T, size_t inlineCapacity, typename U, typename V> -inline ListHashSet<T, inlineCapacity, U, V>::ListHashSet( - ListHashSet&& other) noexcept +inline ListHashSet<T, inlineCapacity, U, V>::ListHashSet(ListHashSet&& other) : head_(nullptr), tail_(nullptr) { Swap(other); } @@ -796,7 +795,7 @@ template <typename T, size_t inlineCapacity, typename U, typename V> inline ListHashSet<T, inlineCapacity, U, V>& -ListHashSet<T, inlineCapacity, U, V>::operator=(ListHashSet&& other) noexcept { +ListHashSet<T, inlineCapacity, U, V>::operator=(ListHashSet&& other) { Swap(other); return *this; }
diff --git a/third_party/blink/renderer/platform/wtf/type_traits_test.cc b/third_party/blink/renderer/platform/wtf/type_traits_test.cc index 0930b73..1b45d55 100644 --- a/third_party/blink/renderer/platform/wtf/type_traits_test.cc +++ b/third_party/blink/renderer/platform/wtf/type_traits_test.cc
@@ -158,7 +158,7 @@ STACK_ALLOCATED(); public: - CopyAssignmentDeleted& operator=(CopyAssignmentDeleted&&) noexcept; + CopyAssignmentDeleted& operator=(CopyAssignmentDeleted&&); private: CopyAssignmentDeleted& operator=(const CopyAssignmentDeleted&) = delete; @@ -173,7 +173,7 @@ STACK_ALLOCATED(); public: - CopyAssignmentPrivate& operator=(CopyAssignmentPrivate&&) noexcept; + CopyAssignmentPrivate& operator=(CopyAssignmentPrivate&&); private: CopyAssignmentPrivate& operator=(const CopyAssignmentPrivate&); @@ -188,7 +188,7 @@ STACK_ALLOCATED(); public: - CopyAssignmentUndeclared& operator=(CopyAssignmentUndeclared&&) noexcept; + CopyAssignmentUndeclared& operator=(CopyAssignmentUndeclared&&); }; static_assert(!std::is_copy_assignable<CopyAssignmentUndeclared>::value,
diff --git a/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h b/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h index 3f44cd2..ee7c89a 100644 --- a/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h +++ b/third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h
@@ -68,7 +68,7 @@ deleter_(deleter), deleter_info_(deleter_info) {} // Move constructor - DataHandle(DataHandle&& other) noexcept { *this = std::move(other); } + DataHandle(DataHandle&& other) { *this = std::move(other); } ~DataHandle() { if (!data_) return; @@ -76,7 +76,7 @@ } // Move operator - DataHandle& operator=(DataHandle&& other) noexcept { + DataHandle& operator=(DataHandle&& other) { data_ = other.data_; data_length_ = other.data_length_; deleter_ = other.deleter_;
diff --git a/third_party/blink/renderer/platform/wtf/vector.h b/third_party/blink/renderer/platform/wtf/vector.h index 2783c2b..43a27f7 100644 --- a/third_party/blink/renderer/platform/wtf/vector.h +++ b/third_party/blink/renderer/platform/wtf/vector.h
@@ -1018,8 +1018,8 @@ Vector& operator=(const Vector<T, otherCapacity, Allocator>&); // Moving. - Vector(Vector&&) noexcept; - Vector& operator=(Vector&&) noexcept; + Vector(Vector&&); + Vector& operator=(Vector&&); // Construct with an initializer list. You can do e.g. // Vector<int> v({1, 2, 3}); @@ -1459,7 +1459,7 @@ template <typename T, wtf_size_t inlineCapacity, typename Allocator> Vector<T, inlineCapacity, Allocator>::Vector( - Vector<T, inlineCapacity, Allocator>&& other) noexcept { + Vector<T, inlineCapacity, Allocator>&& other) { size_ = 0; // It's a little weird to implement a move constructor using swap but this // way we don't have to add a move constructor to VectorBuffer. @@ -1468,7 +1468,7 @@ template <typename T, wtf_size_t inlineCapacity, typename Allocator> Vector<T, inlineCapacity, Allocator>& Vector<T, inlineCapacity, Allocator>:: -operator=(Vector<T, inlineCapacity, Allocator>&& other) noexcept { +operator=(Vector<T, inlineCapacity, Allocator>&& other) { swap(other); return *this; }
diff --git a/third_party/blink/renderer/platform/wtf/vector_test.cc b/third_party/blink/renderer/platform/wtf/vector_test.cc index aa8a138c..788cc2bb 100644 --- a/third_party/blink/renderer/platform/wtf/vector_test.cc +++ b/third_party/blink/renderer/platform/wtf/vector_test.cc
@@ -420,8 +420,8 @@ class MojoMoveOnlyType final { public: MojoMoveOnlyType(); - MojoMoveOnlyType(MojoMoveOnlyType&&) noexcept; - MojoMoveOnlyType& operator=(MojoMoveOnlyType&&) noexcept; + MojoMoveOnlyType(MojoMoveOnlyType&&); + MojoMoveOnlyType& operator=(MojoMoveOnlyType&&); ~MojoMoveOnlyType(); private:
diff --git a/third_party/blink/renderer/platform/wtf/wtf_test_helper.h b/third_party/blink/renderer/platform/wtf/wtf_test_helper.h index e797445..8f31365 100644 --- a/third_party/blink/renderer/platform/wtf/wtf_test_helper.h +++ b/third_party/blink/renderer/platform/wtf/wtf_test_helper.h
@@ -36,9 +36,9 @@ public: explicit MoveOnly(int i = 0) : i_(i) {} - MoveOnly(MoveOnly&& other) noexcept : i_(other.i_) { other.i_ = 0; } + MoveOnly(MoveOnly&& other) : i_(other.i_) { other.i_ = 0; } - MoveOnly& operator=(MoveOnly&& other) noexcept { + MoveOnly& operator=(MoveOnly&& other) { if (this != &other) { i_ = other.i_; other.i_ = 0; @@ -62,12 +62,12 @@ explicit MoveOnlyHashValue(int value = kEmpty, int id = 0) : value_(value), id_(id) {} - MoveOnlyHashValue(MoveOnlyHashValue&& other) noexcept + MoveOnlyHashValue(MoveOnlyHashValue&& other) : value_(other.value_), id_(other.id_) { other.value_ = kMovedOut; other.id_ = 0; } - MoveOnlyHashValue& operator=(MoveOnlyHashValue&& other) noexcept { + MoveOnlyHashValue& operator=(MoveOnlyHashValue&& other) { value_ = other.value_; id_ = other.id_; other.value_ = kMovedOut;
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 07836b12..81f62043 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3226,6 +3226,21 @@ crbug.com/618969 external/wpt/css/css-grid/subgrid/ [ Skip ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Win10 ] external/wpt/css/css-text/line-breaking/line-breaking-021.html [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/css/css-text/text-justify/text-justify-006.html [ Failure ] +crbug.com/626703 [ Mac ] external/wpt/css/css-text/text-justify/text-justify-006.html [ Failure ] +crbug.com/626703 [ Win ] external/wpt/css/css-text/text-justify/text-justify-006.html [ Failure ] +crbug.com/626703 [ Win7 ] external/wpt/pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch.html [ Timeout ] +crbug.com/626703 [ Linux ] external/wpt/css/css-text/white-space/seg-break-transformation-019.html [ Failure ] +crbug.com/626703 [ Mac ] external/wpt/css/css-text/white-space/seg-break-transformation-019.html [ Failure ] +crbug.com/626703 [ Win ] external/wpt/css/css-text/white-space/seg-break-transformation-019.html [ Failure ] +crbug.com/626703 [ Linux ] external/wpt/css/css-text/text-transform/text-transform-fullwidth-009.html [ Failure ] +crbug.com/626703 [ Mac ] external/wpt/css/css-text/text-transform/text-transform-fullwidth-009.html [ Failure ] +crbug.com/626703 [ Win ] external/wpt/css/css-text/text-transform/text-transform-fullwidth-009.html [ Failure ] +crbug.com/626703 [ Win7 ] external/wpt/pointerevents/pointerevent_touch-action-inherit_child-none_touch.html [ Timeout ] +crbug.com/626703 [ Linux ] external/wpt/css/css-text/text-transform/text-transform-fullwidth-008.html [ Failure ] +crbug.com/626703 [ Mac ] external/wpt/css/css-text/text-transform/text-transform-fullwidth-008.html [ Failure ] +crbug.com/626703 [ Win ] external/wpt/css/css-text/text-transform/text-transform-fullwidth-008.html [ Failure ] crbug.com/626703 [ Win ] external/wpt/css/css-text/word-break/word-break-keep-all-008.html [ Failure ] crbug.com/626703 [ Win ] external/wpt/css/css-text/word-break/word-break-keep-all-007.html [ Failure ] crbug.com/626703 [ Mac10.11 ] external/wpt/shape-detection/idlharness.https.any.sharedworker.html [ Failure Timeout ] @@ -6207,3 +6222,6 @@ # Sheriff 2019-09-26 crbug.com/1008257 external/wpt/service-workers/service-worker/claim-shared-worker-fetch.https.html [ Pass Crash ] crbug.com/1008257 external/wpt/service-workers/service-worker/worker-interception-redirect.https.html [ Pass Crash ] + +# Sheriff 2019-09-27 +crbug.com/1008826 [ Mac10.13 ] http/tests/security/frameNavigation/xss-ALLOWED-parent-navigation-change.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt b/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt index 0162eb6..dd344048 100644 --- a/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt +++ b/third_party/blink/web_tests/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt
@@ -31,51 +31,46 @@ "drawsContent": false }, { - "name": "Child Transform Layer", - "drawsContent": false, - "transform": 2 - }, - { "name": "LayoutNGBlockFlow DIV id='camera' class='rotate-3d-start'", "contentsOpaque": true, "drawsContent": false, - "transform": 3 + "transform": 2 }, { "name": "LayoutNGBlockFlow (positioned) DIV class='side side-1'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 4 + "transform": 3 }, { "name": "LayoutNGBlockFlow (positioned) DIV class='side side-2'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 5 + "transform": 4 }, { "name": "LayoutNGBlockFlow (positioned) DIV class='side side-3'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 6 + "transform": 5 }, { "name": "LayoutNGBlockFlow (positioned) DIV class='side side-4'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 7 + "transform": 6 }, { "name": "LayoutNGBlockFlow (positioned) DIV class='side side-5'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 8 + "transform": 7 }, { "name": "LayoutNGBlockFlow (positioned) DIV class='side side-6'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 9 + "transform": 8 } ], "transforms": [ @@ -92,9 +87,9 @@ "id": 2, "parent": 1, "transform": [ - [1, 0, 0, 0], - [0, 1, 0, 0], - [0, 0, 1, -0.005], + [0.353553390593274, 0.25, -0.5, 0], + [0, 0.353553390593274, 0.707106781186548, 0], + [0.353553390593274, -0.25, 0.5, 0], [0, 0, 0, 1] ], "origin": [50, 50] @@ -103,18 +98,6 @@ "id": 3, "parent": 2, "transform": [ - [0.353553390593274, 0.25, -0.5, 0], - [0, 0.353553390593274, 0.707106781186548, 0], - [0.353553390593274, -0.25, 0.5, 0], - [0, 0, 0, 1] - ], - "origin": [50, 50], - "flattenInheritedTransform": false - }, - { - "id": 4, - "parent": 3, - "transform": [ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], @@ -123,8 +106,8 @@ "flattenInheritedTransform": false }, { - "id": 5, - "parent": 3, + "id": 4, + "parent": 2, "transform": [ [0, 0, -1, 0], [0, 1, 0, 0], @@ -135,8 +118,8 @@ "flattenInheritedTransform": false }, { - "id": 6, - "parent": 3, + "id": 5, + "parent": 2, "transform": [ [-1, 0, 0, 0], [0, 1, 0, 0], @@ -147,8 +130,8 @@ "flattenInheritedTransform": false }, { - "id": 7, - "parent": 3, + "id": 6, + "parent": 2, "transform": [ [0, 0, 1, 0], [0, 1, 0, 0], @@ -159,8 +142,8 @@ "flattenInheritedTransform": false }, { - "id": 8, - "parent": 3, + "id": 7, + "parent": 2, "transform": [ [1, 0, 0, 0], [0, 0, 1, 0], @@ -171,8 +154,8 @@ "flattenInheritedTransform": false }, { - "id": 9, - "parent": 3, + "id": 8, + "parent": 2, "transform": [ [1, 0, 0, 0], [0, 0, -1, 0], @@ -212,51 +195,46 @@ "drawsContent": false }, { - "name": "Child Transform Layer", - "drawsContent": false, - "transform": 2 - }, - { "name": "LayoutNGBlockFlow DIV id='camera' class='rotate-3d-start rotate-3d-end'", "contentsOpaque": true, "drawsContent": false, - "transform": 3 + "transform": 2 }, { "name": "LayoutNGBlockFlow (positioned) DIV class='side side-1'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 4 + "transform": 3 }, { "name": "LayoutNGBlockFlow (positioned) DIV class='side side-2'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 5 + "transform": 4 }, { "name": "LayoutNGBlockFlow (positioned) DIV class='side side-3'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 6 + "transform": 5 }, { "name": "LayoutNGBlockFlow (positioned) DIV class='side side-4'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 7 + "transform": 6 }, { "name": "LayoutNGBlockFlow (positioned) DIV class='side side-5'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 8 + "transform": 7 }, { "name": "LayoutNGBlockFlow (positioned) DIV class='side side-6'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 9 + "transform": 8 }, { "name": "Squashing Containment Layer", @@ -289,9 +267,9 @@ "id": 2, "parent": 1, "transform": [ - [1, 0, 0, 0], - [0, 1, 0, 0], - [0, 0, 1, -0.005], + [0.707106781186548, 0.5, -0.5, 0], + [0, 0.707106781186548, 0.707106781186548, 0], + [0.707106781186548, -0.5, 0.5, 0], [0, 0, 0, 1] ], "origin": [50, 50] @@ -300,18 +278,6 @@ "id": 3, "parent": 2, "transform": [ - [0.707106781186548, 0.5, -0.5, 0], - [0, 0.707106781186548, 0.707106781186548, 0], - [0.707106781186548, -0.5, 0.5, 0], - [0, 0, 0, 1] - ], - "origin": [50, 50], - "flattenInheritedTransform": false - }, - { - "id": 4, - "parent": 3, - "transform": [ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], @@ -320,8 +286,8 @@ "flattenInheritedTransform": false }, { - "id": 5, - "parent": 3, + "id": 4, + "parent": 2, "transform": [ [0, 0, -1, 0], [0, 1, 0, 0], @@ -332,8 +298,8 @@ "flattenInheritedTransform": false }, { - "id": 6, - "parent": 3, + "id": 5, + "parent": 2, "transform": [ [-1, 0, 0, 0], [0, 1, 0, 0], @@ -344,8 +310,8 @@ "flattenInheritedTransform": false }, { - "id": 7, - "parent": 3, + "id": 6, + "parent": 2, "transform": [ [0, 0, 1, 0], [0, 1, 0, 0], @@ -356,8 +322,8 @@ "flattenInheritedTransform": false }, { - "id": 8, - "parent": 3, + "id": 7, + "parent": 2, "transform": [ [1, 0, 0, 0], [0, 0, 1, 0], @@ -368,8 +334,8 @@ "flattenInheritedTransform": false }, { - "id": 9, - "parent": 3, + "id": 8, + "parent": 2, "transform": [ [1, 0, 0, 0], [0, 0, -1, 0],
diff --git a/third_party/blink/web_tests/compositing/overflow/accelerated-overflow-scroll-should-not-affect-perspective-expected.txt b/third_party/blink/web_tests/compositing/overflow/accelerated-overflow-scroll-should-not-affect-perspective-expected.txt index 871971a..ec0fe1d 100644 --- a/third_party/blink/web_tests/compositing/overflow/accelerated-overflow-scroll-should-not-affect-perspective-expected.txt +++ b/third_party/blink/web_tests/compositing/overflow/accelerated-overflow-scroll-should-not-affect-perspective-expected.txt
@@ -18,41 +18,35 @@ "backgroundColor": "#FFFFFF" }, { - "name": "LayoutBlockFlow (positioned) DIV class='container'", + "name": "LayoutNGBlockFlow (positioned) DIV class='container'", "position": [8, 8], "bounds": [200, 200] }, { - "name": "Child Transform Layer", - "bounds": [200, 200], - "drawsContent": false, - "transform": 2 - }, - { "name": "Scrolling Layer", + "position": [8, 8], "bounds": [185, 185], - "drawsContent": false, - "transform": 2 + "drawsContent": false }, { "name": "Scrolling Contents Layer", + "position": [8, 8], "bounds": [185, 290], - "drawsContent": false, - "transform": 2 + "drawsContent": false }, { - "name": "LayoutBlockFlow (positioned) DIV class='child first'", + "name": "LayoutNGBlockFlow (positioned) DIV class='child first'", "bounds": [60, 200], "contentsOpaque": true, "backgroundColor": "#008000", - "transform": 4 + "transform": 2 }, { - "name": "LayoutBlockFlow (positioned) DIV class='child second'", + "name": "LayoutNGBlockFlow (positioned) DIV class='child second'", "bounds": [60, 200], "contentsOpaque": true, "backgroundColor": "#0000FF", - "transform": 6 + "transform": 4 }, { "name": "Overflow Controls Host Layer", @@ -85,9 +79,8 @@ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], - [8, 8, 0, 1] - ], - "flattenInheritedTransform": false + [8, 73, 0, 1] + ] }, { "id": 2, @@ -95,22 +88,18 @@ "transform": [ [1, 0, 0, 0], [0, 1, 0, 0], - [0, 0, 1, -0.01], - [0, 0, 0, 1] - ], - "origin": [100, 100], - "flattenInheritedTransform": false + [0, 0, 1, 0], + [0, 0, 10, 1] + ] }, { "id": 3, - "parent": 2, "transform": [ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], - [0, 65, 0, 1] - ], - "flattenInheritedTransform": false + [73, 73, 0, 1] + ] }, { "id": 4, @@ -119,31 +108,8 @@ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], - [0, 0, 10, 1] - ], - "flattenInheritedTransform": false - }, - { - "id": 5, - "parent": 2, - "transform": [ - [1, 0, 0, 0], - [0, 1, 0, 0], - [0, 0, 1, 0], - [65, 65, 0, 1] - ], - "flattenInheritedTransform": false - }, - { - "id": 6, - "parent": 5, - "transform": [ - [1, 0, 0, 0], - [0, 1, 0, 0], - [0, 0, 1, 0], [0, 0, 20, 1] - ], - "flattenInheritedTransform": false + ] } ] }
diff --git a/third_party/blink/web_tests/compositing/squashing/squashing-inside-perspective-expected.txt b/third_party/blink/web_tests/compositing/squashing/squashing-inside-perspective-expected.txt index e7ecd61..33ea495 100644 --- a/third_party/blink/web_tests/compositing/squashing/squashing-inside-perspective-expected.txt +++ b/third_party/blink/web_tests/compositing/squashing/squashing-inside-perspective-expected.txt
@@ -18,22 +18,17 @@ "backgroundColor": "#FFFFFF" }, { - "name": "LayoutBlockFlow (positioned) DIV", + "name": "LayoutNGBlockFlow (positioned) DIV", "position": [8, 8], "contentsOpaque": true, "drawsContent": false }, { - "name": "Child Transform Layer", - "drawsContent": false, - "transform": 2 - }, - { - "name": "LayoutBlockFlow (positioned) DIV", + "name": "LayoutNGBlockFlow (positioned) DIV", "bounds": [200, 200], "contentsOpaque": true, "backgroundColor": "#00008B", - "transform": 3 + "transform": 2 } ], "transforms": [ @@ -52,21 +47,9 @@ "transform": [ [1, 0, 0, 0], [0, 1, 0, 0], - [0, 0, 1, -0.001], - [0, 0, 0, 1] - ], - "origin": [0, 0] - }, - { - "id": 3, - "parent": 2, - "transform": [ - [1, 0, 0, 0], - [0, 1, 0, 0], [0, 0, 1, 0], [0, 74, 200, 1] - ], - "flattenInheritedTransform": false + ] } ] }
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index 7fa5856..564f6b12 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -69843,6 +69843,18 @@ {} ] ], + "css/css-text/line-breaking/line-breaking-021.html": [ + [ + "css/css-text/line-breaking/line-breaking-021.html", + [ + [ + "/css/css-text/line-breaking/reference/line-breaking-021-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-text/line-breaking/line-breaking-atomic-001.html": [ [ "css/css-text/line-breaking/line-breaking-atomic-001.html", @@ -71127,6 +71139,18 @@ {} ] ], + "css/css-text/text-align/text-align-last-wins-001.html": [ + [ + "css/css-text/text-align/text-align-last-wins-001.html", + [ + [ + "/css/css-text/text-align/reference/text-align-last-wins-001-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-text/text-align/text-align-start-001.html": [ [ "css/css-text/text-align/text-align-start-001.html", @@ -71475,6 +71499,18 @@ {} ] ], + "css/css-text/text-justify/text-justify-006.html": [ + [ + "css/css-text/text-justify/text-justify-006.html", + [ + [ + "/css/css-text/text-justify/reference/text-justify-006-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-text/text-transform/math/text-transform-math-auto-001.tentative.html": [ [ "css/css-text/text-transform/math/text-transform-math-auto-001.tentative.html", @@ -72039,6 +72075,30 @@ {} ] ], + "css/css-text/text-transform/text-transform-fullwidth-008.html": [ + [ + "css/css-text/text-transform/text-transform-fullwidth-008.html", + [ + [ + "/css/css-text/text-transform/reference/text-transform-fullwidth-008-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/text-transform/text-transform-fullwidth-009.html": [ + [ + "css/css-text/text-transform/text-transform-fullwidth-009.html", + [ + [ + "/css/css-text/text-transform/reference/text-transform-fullwidth-009-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-text/text-transform/text-transform-lowercase-001.xht": [ [ "css/css-text/text-transform/text-transform-lowercase-001.xht", @@ -74355,6 +74415,30 @@ {} ] ], + "css/css-text/white-space/seg-break-transformation-018.html": [ + [ + "css/css-text/white-space/seg-break-transformation-018.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/seg-break-transformation-019.html": [ + [ + "css/css-text/white-space/seg-break-transformation-019.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "css/css-text/white-space/tab-stop-threshold-001.html": [ [ "css/css-text/white-space/tab-stop-threshold-001.html", @@ -115885,6 +115969,18 @@ {} ] ], + "mathml/presentation-markup/scripts/underover-legacy-align-attribute-001.html": [ + [ + "mathml/presentation-markup/scripts/underover-legacy-align-attribute-001.html", + [ + [ + "/mathml/presentation-markup/scripts/underover-legacy-align-attribute-001-ref.html", + "==" + ] + ], + {} + ] + ], "mathml/presentation-markup/spaces/mspace-children.html": [ [ "mathml/presentation-markup/spaces/mspace-children.html", @@ -122683,6 +122779,9 @@ ] }, "support": { + ".github/META.yml": [ + [] + ], ".github/workflows/pull_request.yml": [ [] ], @@ -141994,6 +142093,9 @@ "css/css-text/line-breaking/reference/line-breaking-019-ref.html": [ [] ], + "css/css-text/line-breaking/reference/line-breaking-021-ref.html": [ + [] + ], "css/css-text/line-breaking/reference/line-breaking-atomic-003-ref.html": [ [] ], @@ -142402,6 +142504,9 @@ "css/css-text/text-align/reference/text-align-justifyall-ref-006.html": [ [] ], + "css/css-text/text-align/reference/text-align-last-wins-001-ref.html": [ + [] + ], "css/css-text/text-align/reference/text-align-start-ref-001.html": [ [] ], @@ -142477,6 +142582,9 @@ "css/css-text/text-indent/reference/text-indent-tab-positions-001-ref.html": [ [] ], + "css/css-text/text-justify/reference/text-justify-006-ref.html": [ + [] + ], "css/css-text/text-justify/reference/text-justify-ref-001.html": [ [] ], @@ -142621,6 +142729,12 @@ "css/css-text/text-transform/reference/text-transform-fullwidth-007-ref.html": [ [] ], + "css/css-text/text-transform/reference/text-transform-fullwidth-008-ref.html": [ + [] + ], + "css/css-text/text-transform/reference/text-transform-fullwidth-009-ref.html": [ + [] + ], "css/css-text/text-transform/reference/text-transform-lowercase-001-ref.xht": [ [] ], @@ -145369,9 +145483,18 @@ "css/css-values/minmax-angle-serialize-expected.txt": [ [] ], + "css/css-values/minmax-length-percent-serialize-expected.txt": [ + [] + ], "css/css-values/minmax-length-serialize-expected.txt": [ [] ], + "css/css-values/minmax-number-serialize-expected.txt": [ + [] + ], + "css/css-values/minmax-percentage-serialize-expected.txt": [ + [] + ], "css/css-values/minmax-time-serialize-expected.txt": [ [] ], @@ -158140,6 +158263,27 @@ "html/interaction/focus/sequential-focus-navigation-and-the-tabindex-attribute/tabindex-getter-expected.txt": [ [] ], + "html/interaction/focus/the-autofocus-attribute/resources/child-autofocus.html": [ + [] + ], + "html/interaction/focus/the-autofocus-attribute/resources/child-iframe.html": [ + [] + ], + "html/interaction/focus/the-autofocus-attribute/resources/erase-first.css": [ + [] + ], + "html/interaction/focus/the-autofocus-attribute/resources/frame-with-autofocus-element.html": [ + [] + ], + "html/interaction/focus/the-autofocus-attribute/resources/grand-child-autofocus.html": [ + [] + ], + "html/interaction/focus/the-autofocus-attribute/resources/moving-autofocus-to-parent.html": [ + [] + ], + "html/interaction/focus/the-autofocus-attribute/resources/utils.js": [ + [] + ], "html/obsolete/META.yml": [ [] ], @@ -159511,27 +159655,6 @@ "html/semantics/forms/attributes-common-to-form-controls/dirname-ltr-iframe.html": [ [] ], - "html/semantics/forms/autofocus/resources/child-autofocus.html": [ - [] - ], - "html/semantics/forms/autofocus/resources/child-iframe.html": [ - [] - ], - "html/semantics/forms/autofocus/resources/erase-first.css": [ - [] - ], - "html/semantics/forms/autofocus/resources/frame-with-autofocus-element.html": [ - [] - ], - "html/semantics/forms/autofocus/resources/grand-child-autofocus.html": [ - [] - ], - "html/semantics/forms/autofocus/resources/moving-autofocus-to-parent.html": [ - [] - ], - "html/semantics/forms/autofocus/resources/utils.js": [ - [] - ], "html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt": [ [] ], @@ -162439,6 +162562,9 @@ "mathml/presentation-markup/radicals/radical-rendering-from-in-flow-ref.html": [ [] ], + "mathml/presentation-markup/scripts/underover-legacy-align-attribute-001-ref.html": [ + [] + ], "mathml/presentation-markup/spaces/mspace-children-ref.html": [ [] ], @@ -216741,6 +216867,12 @@ {} ] ], + "css/css-values/minmax-length-percent-serialize.html": [ + [ + "css/css-values/minmax-length-percent-serialize.html", + {} + ] + ], "css/css-values/minmax-length-serialize.html": [ [ "css/css-values/minmax-length-serialize.html", @@ -216759,6 +216891,12 @@ {} ] ], + "css/css-values/minmax-number-serialize.html": [ + [ + "css/css-values/minmax-number-serialize.html", + {} + ] + ], "css/css-values/minmax-percentage-computed.html": [ [ "css/css-values/minmax-percentage-computed.html", @@ -216771,6 +216909,12 @@ {} ] ], + "css/css-values/minmax-percentage-serialize.html": [ + [ + "css/css-values/minmax-percentage-serialize.html", + {} + ] + ], "css/css-values/minmax-time-computed.html": [ [ "css/css-values/minmax-time-computed.html", @@ -241575,6 +241719,124 @@ {} ] ], + "html/interaction/focus/the-autofocus-attribute/autofocus-in-not-fully-active-document.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/autofocus-in-not-fully-active-document.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/autofocus-on-stable-document.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/autofocus-on-stable-document.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/first-reconnected.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/first-reconnected.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/first-when-later-but-before.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/first-when-later-but-before.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/first-when-later.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/first-when-later.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/first.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/first.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/focusable-area-in-top-document.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/focusable-area-in-top-document.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/no-cross-origin-autofocus.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/no-cross-origin-autofocus.html", + { + "testdriver": true + } + ] + ], + "html/interaction/focus/the-autofocus-attribute/no-sandboxed-automatic-features.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/no-sandboxed-automatic-features.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/not-on-first-task.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/not-on-first-task.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/queue-non-focusable.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/queue-non-focusable.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/same-origin-autofocus.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/same-origin-autofocus.html", + { + "testdriver": true + } + ] + ], + "html/interaction/focus/the-autofocus-attribute/skip-another-top-level-browsing-context.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/skip-another-top-level-browsing-context.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/skip-document-with-fragment.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/skip-document-with-fragment.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/skip-non-focusable.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/skip-non-focusable.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/skip-not-fully-active.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/skip-not-fully-active.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/spin-by-blocking-style-sheet.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/spin-by-blocking-style-sheet.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/supported-elements.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/supported-elements.html", + {} + ] + ], + "html/interaction/focus/the-autofocus-attribute/update-the-rendering.html": [ + [ + "html/interaction/focus/the-autofocus-attribute/update-the-rendering.html", + {} + ] + ], "html/obsolete/requirements-for-implementations/other-elements-attributes-and-apis/document-all.html": [ [ "html/obsolete/requirements-for-implementations/other-elements-attributes-and-apis/document-all.html", @@ -245455,124 +245717,6 @@ {} ] ], - "html/semantics/forms/autofocus/autofocus-in-not-fully-active-document.html": [ - [ - "html/semantics/forms/autofocus/autofocus-in-not-fully-active-document.html", - {} - ] - ], - "html/semantics/forms/autofocus/autofocus-on-stable-document.html": [ - [ - "html/semantics/forms/autofocus/autofocus-on-stable-document.html", - {} - ] - ], - "html/semantics/forms/autofocus/first-reconnected.html": [ - [ - "html/semantics/forms/autofocus/first-reconnected.html", - {} - ] - ], - "html/semantics/forms/autofocus/first-when-later-but-before.html": [ - [ - "html/semantics/forms/autofocus/first-when-later-but-before.html", - {} - ] - ], - "html/semantics/forms/autofocus/first-when-later.html": [ - [ - "html/semantics/forms/autofocus/first-when-later.html", - {} - ] - ], - "html/semantics/forms/autofocus/first.html": [ - [ - "html/semantics/forms/autofocus/first.html", - {} - ] - ], - "html/semantics/forms/autofocus/focusable-area-in-top-document.html": [ - [ - "html/semantics/forms/autofocus/focusable-area-in-top-document.html", - {} - ] - ], - "html/semantics/forms/autofocus/no-cross-origin-autofocus.html": [ - [ - "html/semantics/forms/autofocus/no-cross-origin-autofocus.html", - { - "testdriver": true - } - ] - ], - "html/semantics/forms/autofocus/no-sandboxed-automatic-features.html": [ - [ - "html/semantics/forms/autofocus/no-sandboxed-automatic-features.html", - {} - ] - ], - "html/semantics/forms/autofocus/not-on-first-task.html": [ - [ - "html/semantics/forms/autofocus/not-on-first-task.html", - {} - ] - ], - "html/semantics/forms/autofocus/queue-non-focusable.html": [ - [ - "html/semantics/forms/autofocus/queue-non-focusable.html", - {} - ] - ], - "html/semantics/forms/autofocus/same-origin-autofocus.html": [ - [ - "html/semantics/forms/autofocus/same-origin-autofocus.html", - { - "testdriver": true - } - ] - ], - "html/semantics/forms/autofocus/skip-another-top-level-browsing-context.html": [ - [ - "html/semantics/forms/autofocus/skip-another-top-level-browsing-context.html", - {} - ] - ], - "html/semantics/forms/autofocus/skip-document-with-fragment.html": [ - [ - "html/semantics/forms/autofocus/skip-document-with-fragment.html", - {} - ] - ], - "html/semantics/forms/autofocus/skip-non-focusable.html": [ - [ - "html/semantics/forms/autofocus/skip-non-focusable.html", - {} - ] - ], - "html/semantics/forms/autofocus/skip-not-fully-active.html": [ - [ - "html/semantics/forms/autofocus/skip-not-fully-active.html", - {} - ] - ], - "html/semantics/forms/autofocus/spin-by-blocking-style-sheet.html": [ - [ - "html/semantics/forms/autofocus/spin-by-blocking-style-sheet.html", - {} - ] - ], - "html/semantics/forms/autofocus/supported-elements.html": [ - [ - "html/semantics/forms/autofocus/supported-elements.html", - {} - ] - ], - "html/semantics/forms/autofocus/update-the-rendering.html": [ - [ - "html/semantics/forms/autofocus/update-the-rendering.html", - {} - ] - ], "html/semantics/forms/constraints/form-validation-checkValidity.html": [ [ "html/semantics/forms/constraints/form-validation-checkValidity.html", @@ -320589,6 +320733,10 @@ } }, "paths": { + ".github/META.yml": [ + "06083d1cd0ec0085ec9b4acbab4baad9aa133a33", + "support" + ], ".github/workflows/pull_request.yml": [ "81a53c67f4b11ca3c7ddde916dcebb35cf83a021", "support" @@ -380114,7 +380262,7 @@ "testharness" ], "css/css-properties-values-api/idlharness-expected.txt": [ - "36819f86bfb7c04e8440d389c5ecf8530b5538c2", + "20e8217b395a881e61296f15be372ad23b983e7b", "support" ], "css/css-properties-values-api/idlharness.html": [ @@ -388365,6 +388513,10 @@ "7c8d0f119edb5ef768b37a5a41b8df9bb9e59600", "testharness" ], + "css/css-text/line-breaking/line-breaking-021.html": [ + "b3b907410e82d87ac3912e0f27cfc1dbea17d3a9", + "reftest" + ], "css/css-text/line-breaking/line-breaking-atomic-001.html": [ "e071378c95fd436484a3056ecb2ba6ff35ddbaae", "reftest" @@ -388461,6 +388613,10 @@ "4a7772aa290f5ba72b3f9c604e9935438269e6f9", "support" ], + "css/css-text/line-breaking/reference/line-breaking-021-ref.html": [ + "b1cc22bd2049f66a86f61bd8bf8f6c8a6ec26258", + "support" + ], "css/css-text/line-breaking/reference/line-breaking-atomic-003-ref.html": [ "a9fdd2591b3f3af3d2a9accfd8c65db028f87749", "support" @@ -389549,6 +389705,10 @@ "4496c3866ee10cee2da3b716203ec46d6730a6c0", "support" ], + "css/css-text/text-align/reference/text-align-last-wins-001-ref.html": [ + "997d58a79884ac3086426da2a84b992019bfd100", + "support" + ], "css/css-text/text-align/reference/text-align-start-ref-001.html": [ "72e11fae2dd1eccb5d9742970a401db54b72dfc0", "support" @@ -389789,6 +389949,10 @@ "fd3d706d1ee4acd3fda03cd46c12f20dfb69b9b9", "testharness" ], + "css/css-text/text-align/text-align-last-wins-001.html": [ + "30f1a07864b073b1d11953be867f17c0e6ef129d", + "reftest" + ], "css/css-text/text-align/text-align-start-001.html": [ "43219cc248fcca0a20cacae5993860b7e4cd292e", "reftest" @@ -389953,6 +390117,10 @@ "5bf766ce7607bd21892a558f67901a564fc64994", "reftest" ], + "css/css-text/text-justify/reference/text-justify-006-ref.html": [ + "595485c5f4ea346b011f07128649da3f2c020902", + "support" + ], "css/css-text/text-justify/reference/text-justify-ref-001.html": [ "976df7f4dcee2efbb4e232cbd3a86ec4d7ac8943", "support" @@ -389977,6 +390145,10 @@ "afbc036cce43268a4764e3dea75190a0ed44be3c", "visual" ], + "css/css-text/text-justify/text-justify-006.html": [ + "7744f52afea63d9b1abe7c7edab4880d703be855", + "reftest" + ], "css/css-text/text-transform/math/text-transform-math-auto-001.tentative-ref.html": [ "d41d618769e85a581ceada90e020d6fc979ad7d5", "support" @@ -390241,6 +390413,14 @@ "b8fc5662bd83d9f29aabadbd4eb973e91621f1ed", "support" ], + "css/css-text/text-transform/reference/text-transform-fullwidth-008-ref.html": [ + "efe6508e2e61dddd9a132891e4fdd8a3e155067d", + "support" + ], + "css/css-text/text-transform/reference/text-transform-fullwidth-009-ref.html": [ + "915e8444f1335e920073e2c8091281241370f830", + "support" + ], "css/css-text/text-transform/reference/text-transform-lowercase-001-ref.xht": [ "3d6eb4af8ac5aeb7fd54e1b2e2aec325886ddca0", "support" @@ -390597,6 +390777,14 @@ "f1089f19ab67a4c34bea126a9dec4bc23e7de0fe", "reftest" ], + "css/css-text/text-transform/text-transform-fullwidth-008.html": [ + "d6cd9c4c9833973d2fcfa2bfedc74a64b1872ec8", + "reftest" + ], + "css/css-text/text-transform/text-transform-fullwidth-009.html": [ + "afcb89b0cfcc6db2ca3517b1f99e91abdca321fa", + "reftest" + ], "css/css-text/text-transform/text-transform-lowercase-001.xht": [ "dc3fadf64caf5786123250da2cc50187ec693d2b", "reftest" @@ -391693,6 +391881,14 @@ "52b7ce1f6ab15ac1833067cdf957b1e4c6b4af21", "testharness" ], + "css/css-text/white-space/seg-break-transformation-018.html": [ + "2faf185856baf75b4820b57cd9b4ffe4161f7a29", + "reftest" + ], + "css/css-text/white-space/seg-break-transformation-019.html": [ + "afbba2642524209eda0378577305b5c0e48d1232", + "reftest" + ], "css/css-text/white-space/tab-stop-threshold-001.html": [ "dae6012bf7f42bfa4154f2c88c439db6959e80cb", "reftest" @@ -402437,6 +402633,14 @@ "ee086ef269d07bf6b0db5d1306a0f24af0ad8fab", "testharness" ], + "css/css-values/minmax-length-percent-serialize-expected.txt": [ + "4431554f9d0c19079e4297c888639adae6715cf5", + "support" + ], + "css/css-values/minmax-length-percent-serialize.html": [ + "f0ffd4ea2ce2e3ae3246793cc3191ccb290d0697", + "testharness" + ], "css/css-values/minmax-length-serialize-expected.txt": [ "7859bd08aa09515ccc30515a574bd9c3c35fe21a", "support" @@ -402453,6 +402657,14 @@ "3f34fde2f23732ed1b9bc540a098e5914ad674bf", "testharness" ], + "css/css-values/minmax-number-serialize-expected.txt": [ + "d09f724749ab3809edf085d5865cc5e7954e055b", + "support" + ], + "css/css-values/minmax-number-serialize.html": [ + "e05ccc339c90a1c8df22d6b9f46ff7c357dc36af", + "testharness" + ], "css/css-values/minmax-percentage-computed.html": [ "9f9d0a59d12c2642bfea8ca5a3e2f8528067c80e", "testharness" @@ -402461,6 +402673,14 @@ "48d2cdabec1bee5cde0d5d6f4c3524f463916db1", "testharness" ], + "css/css-values/minmax-percentage-serialize-expected.txt": [ + "1d7b870dbbc3b44fffceec1d66481852cd2870c3", + "support" + ], + "css/css-values/minmax-percentage-serialize.html": [ + "79624be529e5ec91b847a995d497e515736f66cc", + "testharness" + ], "css/css-values/minmax-time-computed.html": [ "36bcf601eb808311732562a6c1c6a7c801f33e9d", "testharness" @@ -438937,6 +439157,110 @@ "e40bc077594351019591de8cbfae8fb0d6af13fe", "testharness" ], + "html/interaction/focus/the-autofocus-attribute/autofocus-in-not-fully-active-document.html": [ + "a26a44dbfb6e8c3eb81c7b216f9aa1c0da8bb9ed", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/autofocus-on-stable-document.html": [ + "47e3e3fd0abdc93e8447c099314935f8cdc31c42", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/first-reconnected.html": [ + "99ee9198d1b0a39605ee7115ba71b1178e815943", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/first-when-later-but-before.html": [ + "f361463401b555f4c90cc25f195dd8b6c7e03b0b", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/first-when-later.html": [ + "1d64b863a16e8a0745c4f207d5a92e80175ee34f", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/first.html": [ + "02ebb79a3e9dff0f1b0211eb187b7a91f7de8c17", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/focusable-area-in-top-document.html": [ + "327040eeeeb7da9bf134cb7120b60c7d1e76d5c7", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/no-cross-origin-autofocus.html": [ + "2cf7428f36cb30b3831b58744ad4c322fee0bdec", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/no-sandboxed-automatic-features.html": [ + "991373d3363a195bde7c7e4e9ad255026e173e47", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/not-on-first-task.html": [ + "50efc176935c710f43a42c31ecc0b7676e96b833", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/queue-non-focusable.html": [ + "e3b556035d35f6ea18d51cd3772651a22940d161", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/resources/child-autofocus.html": [ + "afd5601a523ff0a1d60d37b171b2098a38600ace", + "support" + ], + "html/interaction/focus/the-autofocus-attribute/resources/child-iframe.html": [ + "f60acfc8710192f72813738f0f67e4f512f8163e", + "support" + ], + "html/interaction/focus/the-autofocus-attribute/resources/erase-first.css": [ + "bbbcf799393fc047dae6d47836c3696868df8fb7", + "support" + ], + "html/interaction/focus/the-autofocus-attribute/resources/frame-with-autofocus-element.html": [ + "985cba41494919525031081d236e4409aace453c", + "support" + ], + "html/interaction/focus/the-autofocus-attribute/resources/grand-child-autofocus.html": [ + "88be6e0b04a99b8477925107e1f534024f021b5e", + "support" + ], + "html/interaction/focus/the-autofocus-attribute/resources/moving-autofocus-to-parent.html": [ + "fc6c298a46e376cf45089f168cf841cab59ffd5c", + "support" + ], + "html/interaction/focus/the-autofocus-attribute/resources/utils.js": [ + "0eeb5a9f0adf1d09959227241cd71fe32ebb485c", + "support" + ], + "html/interaction/focus/the-autofocus-attribute/same-origin-autofocus.html": [ + "6e67aa6c0d39aa8e5ffe3fc513e04f9edd683f45", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/skip-another-top-level-browsing-context.html": [ + "d392b903f075276a03189207e57d789608523de1", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/skip-document-with-fragment.html": [ + "a4301e13516634e9fc09d1b8084091a2697b1f24", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/skip-non-focusable.html": [ + "008371d8e163fbdec937e29435fe61dffd520cde", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/skip-not-fully-active.html": [ + "fa5b608d050de2b59e4f55bf9490d503844b1bcc", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/spin-by-blocking-style-sheet.html": [ + "22a4c3573cccf909d3a5675db2aab97a4f366bc0", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/supported-elements.html": [ + "761936715a3060ba4c6cca1068612c21c465ea02", + "testharness" + ], + "html/interaction/focus/the-autofocus-attribute/update-the-rendering.html": [ + "afaf0926f5b55e4f1925010c7262ed26a616d3be", + "testharness" + ], "html/obsolete/META.yml": [ "c1dd8dddf9eec3ab3fb58df01c549c251f3a3fdf", "support" @@ -444017,110 +444341,6 @@ "82798eaa84f533cdc675c653ef22fcb12b52137e", "testharness" ], - "html/semantics/forms/autofocus/autofocus-in-not-fully-active-document.html": [ - "a26a44dbfb6e8c3eb81c7b216f9aa1c0da8bb9ed", - "testharness" - ], - "html/semantics/forms/autofocus/autofocus-on-stable-document.html": [ - "47e3e3fd0abdc93e8447c099314935f8cdc31c42", - "testharness" - ], - "html/semantics/forms/autofocus/first-reconnected.html": [ - "99ee9198d1b0a39605ee7115ba71b1178e815943", - "testharness" - ], - "html/semantics/forms/autofocus/first-when-later-but-before.html": [ - "f361463401b555f4c90cc25f195dd8b6c7e03b0b", - "testharness" - ], - "html/semantics/forms/autofocus/first-when-later.html": [ - "1d64b863a16e8a0745c4f207d5a92e80175ee34f", - "testharness" - ], - "html/semantics/forms/autofocus/first.html": [ - "02ebb79a3e9dff0f1b0211eb187b7a91f7de8c17", - "testharness" - ], - "html/semantics/forms/autofocus/focusable-area-in-top-document.html": [ - "327040eeeeb7da9bf134cb7120b60c7d1e76d5c7", - "testharness" - ], - "html/semantics/forms/autofocus/no-cross-origin-autofocus.html": [ - "c3974bd02a3655cef5513258e81f65e2f86e07d3", - "testharness" - ], - "html/semantics/forms/autofocus/no-sandboxed-automatic-features.html": [ - "991373d3363a195bde7c7e4e9ad255026e173e47", - "testharness" - ], - "html/semantics/forms/autofocus/not-on-first-task.html": [ - "50efc176935c710f43a42c31ecc0b7676e96b833", - "testharness" - ], - "html/semantics/forms/autofocus/queue-non-focusable.html": [ - "e3b556035d35f6ea18d51cd3772651a22940d161", - "testharness" - ], - "html/semantics/forms/autofocus/resources/child-autofocus.html": [ - "afd5601a523ff0a1d60d37b171b2098a38600ace", - "support" - ], - "html/semantics/forms/autofocus/resources/child-iframe.html": [ - "2645a180e4866ed9d1f0a107fc912d53b7437247", - "support" - ], - "html/semantics/forms/autofocus/resources/erase-first.css": [ - "bbbcf799393fc047dae6d47836c3696868df8fb7", - "support" - ], - "html/semantics/forms/autofocus/resources/frame-with-autofocus-element.html": [ - "985cba41494919525031081d236e4409aace453c", - "support" - ], - "html/semantics/forms/autofocus/resources/grand-child-autofocus.html": [ - "88be6e0b04a99b8477925107e1f534024f021b5e", - "support" - ], - "html/semantics/forms/autofocus/resources/moving-autofocus-to-parent.html": [ - "fc6c298a46e376cf45089f168cf841cab59ffd5c", - "support" - ], - "html/semantics/forms/autofocus/resources/utils.js": [ - "0eeb5a9f0adf1d09959227241cd71fe32ebb485c", - "support" - ], - "html/semantics/forms/autofocus/same-origin-autofocus.html": [ - "9cfcdb925cf16cc883ac37f126dc40673066a8b0", - "testharness" - ], - "html/semantics/forms/autofocus/skip-another-top-level-browsing-context.html": [ - "d392b903f075276a03189207e57d789608523de1", - "testharness" - ], - "html/semantics/forms/autofocus/skip-document-with-fragment.html": [ - "a4301e13516634e9fc09d1b8084091a2697b1f24", - "testharness" - ], - "html/semantics/forms/autofocus/skip-non-focusable.html": [ - "008371d8e163fbdec937e29435fe61dffd520cde", - "testharness" - ], - "html/semantics/forms/autofocus/skip-not-fully-active.html": [ - "fa5b608d050de2b59e4f55bf9490d503844b1bcc", - "testharness" - ], - "html/semantics/forms/autofocus/spin-by-blocking-style-sheet.html": [ - "22a4c3573cccf909d3a5675db2aab97a4f366bc0", - "testharness" - ], - "html/semantics/forms/autofocus/supported-elements.html": [ - "761936715a3060ba4c6cca1068612c21c465ea02", - "testharness" - ], - "html/semantics/forms/autofocus/update-the-rendering.html": [ - "afaf0926f5b55e4f1925010c7262ed26a616d3be", - "testharness" - ], "html/semantics/forms/constraints/form-validation-checkValidity.html": [ "2e790c75d82dec2f60f64199ea4e1cba1164bc63", "testharness" @@ -451962,7 +452182,7 @@ "support" ], "interfaces/css-properties-values-api.idl": [ - "d8f54b1e15bc020ef101ab53626eee6985c63dcb", + "ee444ebb29d8b5b15c96d259bb8a1f2bdd280d5f", "support" ], "interfaces/css-pseudo.idl": [ @@ -453717,6 +453937,14 @@ "5b718707de9ab316c6abb0ae7bf26667af191447", "testharness" ], + "mathml/presentation-markup/scripts/underover-legacy-align-attribute-001-ref.html": [ + "a9545c60f400d73eae4513316d7cf731676c9b68", + "support" + ], + "mathml/presentation-markup/scripts/underover-legacy-align-attribute-001.html": [ + "31920c61f4ebe7e341f1771dd7556bff0f8bbcb2", + "reftest" + ], "mathml/presentation-markup/scripts/underover-parameters-1.html": [ "9217488a561735c75798e2c05197f5a84b233237", "testharness" @@ -479082,7 +479310,7 @@ "support" ], "resources/chromium/sms_mock.js": [ - "a8cd81a5ceffc29ab1f4c6ea20d2771793f42d69", + "bdfbc2052fa102a0e502937a610a9c64d79d1bbe", "support" ], "resources/chromium/string16.mojom.js": [ @@ -487522,7 +487750,7 @@ "support" ], "svg/struct/scripted/autofocus-attribute.svg": [ - "d8f25741ee40cc488d504065548342c095cbc4c3", + "edf200c4c7be31f2e1fea39003b991695610e6c3", "testharness" ], "svg/struct/scripted/blank.svg": [ @@ -488226,7 +488454,7 @@ "support" ], "tools/ci/run_tc.py": [ - "ea4a1ac1a6ac4a9a2b2a0265e74c70dc5fdc957d", + "b2826bf075e9b1e82ee3d021003134930231f556", "support" ], "tools/ci/taskcluster-run.py": [ @@ -495142,7 +495370,7 @@ "support" ], "web-animations/animation-model/animation-types/accumulation-per-property-expected.txt": [ - "30400b22f20c0343e93d064e90f44fe829946478", + "21f5bd82c5df91569054b3c3c9f8f182f8877f5f", "support" ], "web-animations/animation-model/animation-types/accumulation-per-property.html": [ @@ -495150,7 +495378,7 @@ "testharness" ], "web-animations/animation-model/animation-types/addition-per-property-expected.txt": [ - "b7d391086a37903b2bf59817c00eff3f20c20eed", + "d8f9003384fd8716a822d945161c17ebe86677a7", "support" ], "web-animations/animation-model/animation-types/addition-per-property.html": [ @@ -495174,7 +495402,7 @@ "support" ], "web-animations/animation-model/animation-types/property-types.js": [ - "9f549c9a199e8078612932a7b666b85c0d7439ab", + "75f7d61161a8569beef9b1104ce0e2c9b8e70a06", "support" ], "web-animations/animation-model/animation-types/visibility.html": [
diff --git a/third_party/blink/web_tests/external/wpt/.github/META.yml b/third_party/blink/web_tests/external/wpt/.github/META.yml new file mode 100644 index 0000000..06083d1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/.github/META.yml
@@ -0,0 +1,3 @@ +suggested_reviewers: + - jgraham + - jugglinmike
diff --git a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/idlharness-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/idlharness-expected.txt index 36819f8..20e8217b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/idlharness-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/idlharness-expected.txt
@@ -3,6 +3,8 @@ PASS idl_test validation PASS Partial namespace CSS: original namespace defined PASS Partial namespace CSS: member names are unique +PASS Partial interface CSSRule: original interface defined +PASS Partial interface CSSRule: member names are unique FAIL CSSPropertyRule interface: existence and properties of interface object assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing FAIL CSSPropertyRule interface object length assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing FAIL CSSPropertyRule interface object name assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing @@ -13,6 +15,8 @@ FAIL CSSPropertyRule interface: attribute syntax assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing FAIL CSSPropertyRule interface: attribute inherits assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing FAIL CSSPropertyRule interface: attribute initialValue assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing +FAIL CSSRule interface: constant PROPERTY_RULE on interface object assert_own_property: expected property "PROPERTY_RULE" missing +FAIL CSSRule interface: constant PROPERTY_RULE on interface prototype object assert_own_property: expected property "PROPERTY_RULE" missing PASS CSS namespace: operation escape(CSSOMString) PASS CSS namespace: operation registerProperty(PropertyDefinition) Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/line-breaking-021.html b/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/line-breaking-021.html new file mode 100644 index 0000000..b3b9074 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/line-breaking-021.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text Test: Simple line breaking test</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#line-break-details"> +<link rel="match" href="reference/line-breaking-021-ref.html"> +<meta name=assert content="Line breaking behavior defined for the ZWJ line-breaking classes in [UAX14] must be honored."> +<style> +div { + width: 0; +} +</style> + +<p>This test passes if there the text below is on a single line. + +<div>じ‍字‍자‍😂‍😭</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/reference/line-breaking-021-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/reference/line-breaking-021-ref.html new file mode 100644 index 0000000..b1cc22b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/reference/line-breaking-021-ref.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>test reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net"> +</style> + +<p>This test passes if there the text below is on a single line. + +<div>じ‍字‍자‍😂‍😭</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-align/reference/text-align-last-wins-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/reference/text-align-last-wins-001-ref.html new file mode 100644 index 0000000..997d58a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/reference/text-align-last-wins-001-ref.html
@@ -0,0 +1,16 @@ +<!doctype html> +<html lang=en> +<meta charset=utf-8> +<title>test reference</title> +<style> +div { + text-align: right; + width: 300px; + border: solid; +} +</style> + +<p>Test passes if the words below are aligned to the right of the box. + +<div>right<br>right</div> +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-last-wins-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-last-wins-001.html new file mode 100644 index 0000000..30f1a07 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-last-wins-001.html
@@ -0,0 +1,20 @@ +<!doctype html> +<html lang=en> +<meta charset=utf-8> +<title>CSS text test: text-align-last has precedence over text-align-all</title> +<link rel=help href="https://drafts.csswg.org/css-text-3/#text-align-all-property"> +<link rel=help href="https://drafts.csswg.org/css-text-3/#text-align-last-property"> +<link rel="match" href="reference/text-align-last-wins-001-ref.html"> +<meta name=assert content="If a line is both the first and last line, text-align-last applies"> +<style> +div { + text-align-last: right; + width: 300px; + border: solid; +} +</style> + +<p>Test passes if the words below are aligned to the right of the box. + +<div>right<br>right</div> +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-justify/reference/text-justify-006-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-justify/reference/text-justify-006-ref.html new file mode 100644 index 0000000..595485c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-justify/reference/text-justify-006-ref.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html lang="en" > +<head> +<meta charset="utf-8"> +<title>test reference</title> +<link rel='author' title='Florian Rivoal' href='https://florian.rivoal.net'> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + font: 20px/1 Ahem; + white-space: pre; +} +#ref { + color: orange; +} +#test { + color: blue; +} + +/* this is just filler content to have an invisible last line, as jutification does not affect the last line */ +a { color: white; } +</style> + +<p>Test passes if the the blue and orange boxes are aligned. + +<div id=ref>X X X X</div> +<div id=test>X X X X</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-justify/text-justify-006.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-justify/text-justify-006.html new file mode 100644 index 0000000..7744f52 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-justify/text-justify-006.html
@@ -0,0 +1,35 @@ +<!DOCTYPE html> +<html lang="en" > +<head> +<meta charset="utf-8"> +<title>CSS text tests: text-justify applies inline</title> +<link rel='author' title='Florian Rivoal' href='https://florian.rivoal.net'> +<link rel='help' href='https://drafts.csswg.org/css-text-3/#text-justify-property'> +<link rel='match' href='reference/text-justify-006-ref.html'> +<meta name="assert" content="text-justify applies to inline elements"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + font: 20px/1 Ahem; + width: 11ch; +} +#ref { + white-space: pre; + color: orange; +} +#test { + text-align: justify; + color: blue; +} +span { + text-justify: none; +} + +/* this is just filler content to have an invisible last line, as jutification does not affect the last line */ +a { color: white; } +</style> + +<p>Test passes if the the blue and orange boxes are aligned. + +<div id=ref>X X X X</div> +<div id=test>X <span>X X</span> X <a>###########</a></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/reference/text-transform-fullwidth-008-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/reference/text-transform-fullwidth-008-ref.html new file mode 100644 index 0000000..efe6508 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/reference/text-transform-fullwidth-008-ref.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>test reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + font: 20px/1 Ahem; + margin: 1em 0; + white-space: pre; +} +</style> + +<p>Test passes if all black boxes below have the same width and height and are aligned vertically. +<div> x<br> x</div> +<div> x<br> x</div> +<div> x<br> x</div> +<div> x<br> x</div> +<div> x<br> x</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/reference/text-transform-fullwidth-009-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/reference/text-transform-fullwidth-009-ref.html new file mode 100644 index 0000000..915e8444 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/reference/text-transform-fullwidth-009-ref.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>test reference</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + font: 10px/1 Ahem; + margin: 1em 0; + white-space: pre; +} +</style> + +<p>Test passes if all black boxes below have the same width and height and are aligned vertically. +<div> x<br> x</div> +<div> x<br> x</div> +<div> x<br> x</div> +<div> x<br> x</div> +<div> x<br> x</div> +<div> x<br> x</div> +<div> x<br> x</div> +<div> x<br> x</div> +<div> x<br> x</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/text-transform-fullwidth-008.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/text-transform-fullwidth-008.html new file mode 100644 index 0000000..d6cd9c4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/text-transform-fullwidth-008.html
@@ -0,0 +1,37 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: text-transform:fullwidth and trailing spaces</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://www.w3.org/TR/css-text-3/#text-transform-property"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/text-transform-fullwidth-008-ref.html"> +<meta name="assert" content="full-width does transforms U+0020 spaces to U+3000 after phase 1, but before phase 2, so that end-of-line transformed spaces get the same treatment as natural ones: hang when white-space is normal."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + font: 20px/1 Ahem; + margin: 1em 0; +} +.pre { + white-space: pre; +} +#test, #ref { + width: 2em; + text-align: right; +} +span { + text-transform: full-width; +} +#test2, #ref2 { + width: min-content; + margin-left: 1em; + background: black; +} +</style> + +<p>Test passes if all black boxes below have the same width and height and are aligned vertically. +<div class=pre> x<br> x</div> +<div id=ref>x x</div> +<div id=test>x<span> </span>x</div> +<div id=ref2>x x</div> +<div id=test2>x<span> </span>x</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/text-transform-fullwidth-009.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/text-transform-fullwidth-009.html new file mode 100644 index 0000000..afcb89b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-transform/text-transform-fullwidth-009.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: text-transform:fullwidth and trailing spaces, with pre-wrap</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://www.w3.org/TR/css-text-3/#text-transform-property"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-phase-2"> +<link rel="match" href="reference/text-transform-fullwidth-009-ref.html"> +<meta name="assert" content="full-width does transforms U+0020 spaces to U+3000 after phase 1, but before phase 2, so that end-of-line transformed spaces get the same treatment as natural ones: hang at the end of soft-wrapped lines, and conditionally hang before forced breaks when white-space is pre-wrap."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + font: 10px/1 Ahem; + margin: 1em 0; +} +.pre { + white-space: pre; +} +#test, #ref, +#test3, #ref3 { + width: 2em; + text-align: right; + white-space: pre-wrap; +} +#test3, #ref3 { + margin-left: 1em; +} +span { + text-transform: full-width; +} +#test2, #ref2, +#test4, #ref4 { + width: min-content; + margin-left: 1em; + white-space: pre-wrap; + background: black; +} +</style> + +<p>Test passes if all black boxes below have the same width and height and are aligned vertically. +<div class=pre> x<br> x</div> +<div id=ref>x x</div> +<div id=test>x<span> </span>x</div> +<div id=ref2>x x</div> +<div id=test2>x<span> </span>x</div> + +<div id=ref3>x <br>x </div> +<div id=test3>x<span> </span><br>x<span> </span></div> +<div id=ref4>x <br>x </div> +<div id=test4>x<span> </span><br>x<span> </span></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/seg-break-transformation-018.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/seg-break-transformation-018.html new file mode 100644 index 0000000..2faf185 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/seg-break-transformation-018.html
@@ -0,0 +1,46 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: inline element boundary and segment break transformations</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#text-encoding"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#line-break-transform"> +<link rel=match href="../../reference/ref-filled-green-100px-square.xht"> +<meta name="assert" content="intervening inline box boundaries must be ignored for segment break transformations"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + font: 20px/1 Ahem; + color: green; +} +#b { border-right: solid 20px green; } +#p { padding-right: 20px; background: green; } +#m { margin-right: 20px; } +#m2 { margin-right: -20px; } + +#red { + width: 100px; + height: 100px; + background: red; + position: absolute; + z-index: -1; +} +</style> + +<p>Test passes if there is a filled green square and <strong>no red</strong>. + +<div id=red></div> + +<div>aa​ +bbb</div> + +<div>aa<span>​</span> +bbb</div> + +<div>aa<span id=b>​</span> +bb</div> + +<div>aa<span id=p>​</span> +bb</div> + +<div>aa<span id=m>​</span><span id=m2></span> +bbb</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/white-space/seg-break-transformation-019.html b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/seg-break-transformation-019.html new file mode 100644 index 0000000..afbba26 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/white-space/seg-break-transformation-019.html
@@ -0,0 +1,48 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Text level 3 Test: out of flow elements and segment break transformations</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#text-encoding"> +<link rel="help" href="https://drafts.csswg.org/css-text-3/#line-break-transform"> +<link rel=match href="../../reference/ref-filled-green-100px-square.xht"> +<meta name="assert" content="Out-of-flow elements must be ignored for segment break transformations"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +div { + font: 20px/1 Ahem; + color: green; +} +aside { + color: transparent; +} +#abs { position: absolute; } +#fixed { position: fixed; } +#float-r { float: right; } +#float-l { float: left; margin-left: -3em; } +#red { + width: 100px; + height: 100px; + background: red; + position: absolute; + z-index: -1; +} +</style> + +<p>Test passes if there is a filled green square and <strong>no red</strong>. + +<div id=red></div> + +<div>aa​ +bbb</div> + +<div>aa​<aside id=abs>foo</aside> +bbb</div> + +<div>aa​<aside id=fixed>foo</aside> +bbb</div> + +<div>aa​<aside id=float-r>foo</aside> +bbb</div> + +<div>aa​<aside id=float-l>foo</aside> +bbb</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/minmax-length-percent-serialize-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-values/minmax-length-percent-serialize-expected.txt new file mode 100644 index 0000000..4431554f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-values/minmax-length-percent-serialize-expected.txt
@@ -0,0 +1,64 @@ +This is a testharness.js-based test. +Found 60 tests; 52 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS e.style['margin-left'] = "min(1px + 1%)" should set the property value +PASS e.style['margin-left'] = "min(1cm + 1%)" should set the property value +PASS e.style['margin-left'] = "min(1mm + 1%)" should set the property value +PASS e.style['margin-left'] = "min(1Q + 1%)" should set the property value +PASS e.style['margin-left'] = "min(1in + 1%)" should set the property value +PASS e.style['margin-left'] = "min(1pc + 1%)" should set the property value +PASS e.style['margin-left'] = "min(1pt + 1%)" should set the property value +PASS e.style['margin-left'] = "min(1em + 1%)" should set the property value +PASS e.style['margin-left'] = "min(1ex + 1%)" should set the property value +PASS e.style['margin-left'] = "min(1ch + 1%)" should set the property value +PASS e.style['margin-left'] = "min(1rem + 1%)" should set the property value +PASS e.style['margin-left'] = "min(1vh + 1%)" should set the property value +PASS e.style['margin-left'] = "min(1vw + 1%)" should set the property value +PASS e.style['margin-left'] = "min(1vmin + 1%)" should set the property value +PASS e.style['margin-left'] = "min(1vmax + 1%)" should set the property value +PASS e.style['margin-left'] = "max(1px + 1%)" should set the property value +PASS e.style['margin-left'] = "max(1cm + 1%)" should set the property value +PASS e.style['margin-left'] = "max(1mm + 1%)" should set the property value +PASS e.style['margin-left'] = "max(1Q + 1%)" should set the property value +PASS e.style['margin-left'] = "max(1in + 1%)" should set the property value +PASS e.style['margin-left'] = "max(1pc + 1%)" should set the property value +PASS e.style['margin-left'] = "max(1pt + 1%)" should set the property value +PASS e.style['margin-left'] = "max(1em + 1%)" should set the property value +PASS e.style['margin-left'] = "max(1ex + 1%)" should set the property value +PASS e.style['margin-left'] = "max(1ch + 1%)" should set the property value +PASS e.style['margin-left'] = "max(1rem + 1%)" should set the property value +PASS e.style['margin-left'] = "max(1vh + 1%)" should set the property value +PASS e.style['margin-left'] = "max(1vw + 1%)" should set the property value +PASS e.style['margin-left'] = "max(1vmin + 1%)" should set the property value +PASS e.style['margin-left'] = "max(1vmax + 1%)" should set the property value +PASS e.style['margin-left'] = "min(20px, 10%)" should set the property value +PASS e.style['margin-left'] = "min(1em, 10%)" should set the property value +PASS e.style['margin-left'] = "max(20px, 10%)" should set the property value +PASS e.style['margin-left'] = "max(1em, 10%)" should set the property value +PASS e.style['margin-left'] = "min(10%, 20px)" should set the property value +PASS e.style['margin-left'] = "min(10%, 1em)" should set the property value +PASS e.style['margin-left'] = "max(10%, 20px)" should set the property value +PASS e.style['margin-left'] = "max(10%, 1em)" should set the property value +PASS e.style['margin-left'] = "min(10% + 30px, 5% + 60px)" should set the property value +PASS e.style['margin-left'] = "max(10% + 2em, 5% + 1em)" should set the property value +PASS e.style['margin-left'] = "calc(min(10%) + max(1em) + min(20px))" should set the property value +PASS e.style['margin-left'] = "calc(max(20px) + min(1em) + max(10%))" should set the property value +PASS e.style['margin-left'] = "calc(max(10%) + min(1em) + max(20px))" should set the property value +PASS e.style['margin-left'] = "calc(min(20px) + max(1em) + min(10%))" should set the property value +PASS e.style['margin-left'] = "calc(20px + min(10%))" should set the property value +PASS e.style['margin-left'] = "calc(10% + min(20px))" should set the property value +PASS e.style['margin-left'] = "calc(1em + min(10%))" should set the property value +PASS e.style['margin-left'] = "calc(10% + min(1em))" should set the property value +FAIL e.style['margin-left'] = "calc(min(10%) + 20px)" should set the property value assert_equals: serialization should be canonical expected "calc(20px + min(10%))" but got "calc(min(10%) + 20px)" +FAIL e.style['margin-left'] = "calc(min(20px) + 10%)" should set the property value assert_equals: serialization should be canonical expected "calc(10% + min(20px))" but got "calc(min(20px) + 10%)" +FAIL e.style['margin-left'] = "calc(min(10%) + 1em)" should set the property value assert_equals: serialization should be canonical expected "calc(1em + min(10%))" but got "calc(min(10%) + 1em)" +FAIL e.style['margin-left'] = "calc(min(1em) + 10%)" should set the property value assert_equals: serialization should be canonical expected "calc(10% + min(1em))" but got "calc(min(1em) + 10%)" +PASS e.style['margin-left'] = "calc(20px + max(10%))" should set the property value +PASS e.style['margin-left'] = "calc(10% + max(20px))" should set the property value +PASS e.style['margin-left'] = "calc(1em + max(10%))" should set the property value +PASS e.style['margin-left'] = "calc(10% + max(1em))" should set the property value +FAIL e.style['margin-left'] = "calc(max(10%) + 20px)" should set the property value assert_equals: serialization should be canonical expected "calc(20px + max(10%))" but got "calc(max(10%) + 20px)" +FAIL e.style['margin-left'] = "calc(max(20px) + 10%)" should set the property value assert_equals: serialization should be canonical expected "calc(10% + max(20px))" but got "calc(max(20px) + 10%)" +FAIL e.style['margin-left'] = "calc(max(10%) + 1em)" should set the property value assert_equals: serialization should be canonical expected "calc(1em + max(10%))" but got "calc(max(10%) + 1em)" +FAIL e.style['margin-left'] = "calc(max(1em) + 10%)" should set the property value assert_equals: serialization should be canonical expected "calc(10% + max(1em))" but got "calc(max(1em) + 10%)" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/minmax-length-percent-serialize.html b/third_party/blink/web_tests/external/wpt/css/css-values/minmax-length-percent-serialize.html new file mode 100644 index 0000000..f0ffd4e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-values/minmax-length-percent-serialize.html
@@ -0,0 +1,81 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func"> +<link rel="help" href="https://drafts.csswg.org/css-values-4/#mixed-percentages"> +<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize"> +<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../support/parsing-testcommon.js"></script> +<script> +const property = 'margin-left'; + +function test_valid_length_percent(value, expected) { + test_valid_value(property, value, expected); +} + +test_valid_length_percent('min(1px + 1%)', 'min(1px + 1%)'); +test_valid_length_percent('min(1cm + 1%)', 'min(1cm + 1%)'); +test_valid_length_percent('min(1mm + 1%)', 'min(1mm + 1%)'); +test_valid_length_percent('min(1Q + 1%)', 'min(1q + 1%)'); +test_valid_length_percent('min(1in + 1%)', 'min(1in + 1%)'); +test_valid_length_percent('min(1pc + 1%)', 'min(1pc + 1%)'); +test_valid_length_percent('min(1pt + 1%)', 'min(1pt + 1%)'); +test_valid_length_percent('min(1em + 1%)', 'min(1em + 1%)'); +test_valid_length_percent('min(1ex + 1%)', 'min(1ex + 1%)'); +test_valid_length_percent('min(1ch + 1%)', 'min(1ch + 1%)'); +test_valid_length_percent('min(1rem + 1%)', 'min(1rem + 1%)'); +test_valid_length_percent('min(1vh + 1%)', 'min(1vh + 1%)'); +test_valid_length_percent('min(1vw + 1%)', 'min(1vw + 1%)'); +test_valid_length_percent('min(1vmin + 1%)', 'min(1vmin + 1%)'); +test_valid_length_percent('min(1vmax + 1%)', 'min(1vmax + 1%)'); +test_valid_length_percent('max(1px + 1%)', 'max(1px + 1%)'); +test_valid_length_percent('max(1cm + 1%)', 'max(1cm + 1%)'); +test_valid_length_percent('max(1mm + 1%)', 'max(1mm + 1%)'); +test_valid_length_percent('max(1Q + 1%)', 'max(1q + 1%)'); +test_valid_length_percent('max(1in + 1%)', 'max(1in + 1%)'); +test_valid_length_percent('max(1pc + 1%)', 'max(1pc + 1%)'); +test_valid_length_percent('max(1pt + 1%)', 'max(1pt + 1%)'); +test_valid_length_percent('max(1em + 1%)', 'max(1em + 1%)'); +test_valid_length_percent('max(1ex + 1%)', 'max(1ex + 1%)'); +test_valid_length_percent('max(1ch + 1%)', 'max(1ch + 1%)'); +test_valid_length_percent('max(1rem + 1%)', 'max(1rem + 1%)'); +test_valid_length_percent('max(1vh + 1%)', 'max(1vh + 1%)'); +test_valid_length_percent('max(1vw + 1%)', 'max(1vw + 1%)'); +test_valid_length_percent('max(1vmin + 1%)', 'max(1vmin + 1%)'); +test_valid_length_percent('max(1vmax + 1%)', 'max(1vmax + 1%)'); + +test_valid_length_percent('min(20px, 10%)', 'min(20px, 10%)'); +test_valid_length_percent('min(1em, 10%)', 'min(1em, 10%)'); +test_valid_length_percent('max(20px, 10%)', 'max(20px, 10%)'); +test_valid_length_percent('max(1em, 10%)', 'max(1em, 10%)'); +test_valid_length_percent('min(10%, 20px)', 'min(10%, 20px)'); +test_valid_length_percent('min(10%, 1em)', 'min(10%, 1em)'); +test_valid_length_percent('max(10%, 20px)', 'max(10%, 20px)'); +test_valid_length_percent('max(10%, 1em)', 'max(10%, 1em)'); + +test_valid_length_percent('min(10% + 30px, 5% + 60px)', 'min(10% + 30px, 5% + 60px)') +test_valid_length_percent('max(10% + 2em, 5% + 1em)', 'max(10% + 2em, 5% + 1em)') + +test_valid_length_percent('calc(min(10%) + max(1em) + min(20px))', 'calc(min(10%) + max(1em) + min(20px))'); +test_valid_length_percent('calc(max(20px) + min(1em) + max(10%))', 'calc(max(20px) + min(1em) + max(10%))'); +test_valid_length_percent('calc(max(10%) + min(1em) + max(20px))', 'calc(max(10%) + min(1em) + max(20px))'); +test_valid_length_percent('calc(min(20px) + max(1em) + min(10%))', 'calc(min(20px) + max(1em) + min(10%))'); + +test_valid_length_percent('calc(20px + min(10%))', 'calc(20px + min(10%))'); +test_valid_length_percent('calc(10% + min(20px))', 'calc(10% + min(20px))'); +test_valid_length_percent('calc(1em + min(10%))', 'calc(1em + min(10%))'); +test_valid_length_percent('calc(10% + min(1em))', 'calc(10% + min(1em))'); +test_valid_length_percent('calc(min(10%) + 20px)', 'calc(20px + min(10%))'); +test_valid_length_percent('calc(min(20px) + 10%)', 'calc(10% + min(20px))'); +test_valid_length_percent('calc(min(10%) + 1em)', 'calc(1em + min(10%))'); +test_valid_length_percent('calc(min(1em) + 10%)', 'calc(10% + min(1em))'); +test_valid_length_percent('calc(20px + max(10%))', 'calc(20px + max(10%))'); +test_valid_length_percent('calc(10% + max(20px))', 'calc(10% + max(20px))'); +test_valid_length_percent('calc(1em + max(10%))', 'calc(1em + max(10%))'); +test_valid_length_percent('calc(10% + max(1em))', 'calc(10% + max(1em))'); +test_valid_length_percent('calc(max(10%) + 20px)', 'calc(20px + max(10%))'); +test_valid_length_percent('calc(max(20px) + 10%)', 'calc(10% + max(20px))'); +test_valid_length_percent('calc(max(10%) + 1em)', 'calc(1em + max(10%))'); +test_valid_length_percent('calc(max(1em) + 10%)', 'calc(10% + max(1em))'); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/minmax-number-serialize-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-values/minmax-number-serialize-expected.txt new file mode 100644 index 0000000..d09f724 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-values/minmax-number-serialize-expected.txt
@@ -0,0 +1,15 @@ +This is a testharness.js-based test. +FAIL e.style['opacity'] = "min(1)" should set the property value assert_equals: serialization should be canonical expected "min(1)" but got "1" +FAIL e.style['opacity'] = "max(1)" should set the property value assert_equals: serialization should be canonical expected "max(1)" but got "1" +FAIL e.style['opacity'] = "min(1, 2, 3)" should set the property value assert_equals: serialization should be canonical expected "min(1, 2, 3)" but got "1" +FAIL e.style['opacity'] = "min(3, 2, 1)" should set the property value assert_equals: serialization should be canonical expected "min(3, 2, 1)" but got "1" +FAIL e.style['opacity'] = "max(1, 2, 3)" should set the property value assert_equals: serialization should be canonical expected "max(1, 2, 3)" but got "3" +FAIL e.style['opacity'] = "max(3, 2, 1)" should set the property value assert_equals: serialization should be canonical expected "max(3, 2, 1)" but got "3" +FAIL e.style['opacity'] = "calc(min(1) + min(2))" should set the property value assert_equals: serialization should be canonical expected "calc(min(1) + min(2))" but got "3" +FAIL e.style['opacity'] = "calc(max(1) + max(2))" should set the property value assert_equals: serialization should be canonical expected "calc(max(1) + max(2))" but got "3" +FAIL e.style['opacity'] = "calc(1 + min(1))" should set the property value assert_equals: serialization should be canonical expected "calc(1 + min(1))" but got "2" +FAIL e.style['opacity'] = "calc(min(1) + 1)" should set the property value assert_equals: serialization should be canonical expected "calc(1 + min(1))" but got "2" +FAIL e.style['opacity'] = "calc(1 + max(1))" should set the property value assert_equals: serialization should be canonical expected "calc(1 + max(1))" but got "2" +FAIL e.style['opacity'] = "calc(max(1) + 1)" should set the property value assert_equals: serialization should be canonical expected "calc(1 + max(1))" but got "2" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/minmax-number-serialize.html b/third_party/blink/web_tests/external/wpt/css/css-values/minmax-number-serialize.html new file mode 100644 index 0000000..e05ccc33 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-values/minmax-number-serialize.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func"> +<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers"> +<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize"> +<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../support/parsing-testcommon.js"></script> +<script> +function test_valid_number(value, expected) { + test_valid_value('opacity', value, expected); +} + +test_valid_number('min(1)', 'min(1)'); +test_valid_number('max(1)', 'max(1)'); + +test_valid_number('min(1, 2, 3)', 'min(1, 2, 3)'); +test_valid_number('min(3, 2, 1)', 'min(3, 2, 1)'); +test_valid_number('max(1, 2, 3)', 'max(1, 2, 3)'); +test_valid_number('max(3, 2, 1)', 'max(3, 2, 1)'); + +test_valid_number('calc(min(1) + min(2))', 'calc(min(1) + min(2))'); +test_valid_number('calc(max(1) + max(2))', 'calc(max(1) + max(2))'); +test_valid_number('calc(1 + min(1))', 'calc(1 + min(1))'); +test_valid_number('calc(min(1) + 1)', 'calc(1 + min(1))'); +test_valid_number('calc(1 + max(1))', 'calc(1 + max(1))'); +test_valid_number('calc(max(1) + 1)', 'calc(1 + max(1))'); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/minmax-percentage-serialize-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-values/minmax-percentage-serialize-expected.txt new file mode 100644 index 0000000..1d7b870d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-values/minmax-percentage-serialize-expected.txt
@@ -0,0 +1,15 @@ +This is a testharness.js-based test. +PASS e.style['margin-left'] = "min(1%)" should set the property value +PASS e.style['margin-left'] = "max(1%)" should set the property value +PASS e.style['margin-left'] = "min(1%, 2%, 3%)" should set the property value +PASS e.style['margin-left'] = "min(3%, 2%, 1%)" should set the property value +PASS e.style['margin-left'] = "max(1%, 2%, 3%)" should set the property value +PASS e.style['margin-left'] = "max(3%, 2%, 1%)" should set the property value +PASS e.style['margin-left'] = "calc(min(1%) + min(2%))" should set the property value +PASS e.style['margin-left'] = "calc(max(1%) + max(2%))" should set the property value +PASS e.style['margin-left'] = "calc(1% + min(1%))" should set the property value +FAIL e.style['margin-left'] = "calc(min(1%) + 1%)" should set the property value assert_equals: serialization should be canonical expected "calc(1% + min(1%))" but got "calc(min(1%) + 1%)" +PASS e.style['margin-left'] = "calc(1% + max(1%))" should set the property value +FAIL e.style['margin-left'] = "calc(max(1%) + 1%)" should set the property value assert_equals: serialization should be canonical expected "calc(1% + max(1%))" but got "calc(max(1%) + 1%)" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/minmax-percentage-serialize.html b/third_party/blink/web_tests/external/wpt/css/css-values/minmax-percentage-serialize.html new file mode 100644 index 0000000..79624be --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-values/minmax-percentage-serialize.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func"> +<link rel="help" href="https://drafts.csswg.org/css-values-4/#percentages"> +<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize"> +<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="../support/parsing-testcommon.js"></script> +<script> +function test_valid_percentage(value, expected) { + test_valid_value('margin-left', value, expected); +} + +test_valid_percentage('min(1%)', 'min(1%)'); +test_valid_percentage('max(1%)', 'max(1%)'); + +test_valid_percentage('min(1%, 2%, 3%)', 'min(1%, 2%, 3%)'); +test_valid_percentage('min(3%, 2%, 1%)', 'min(3%, 2%, 1%)'); +test_valid_percentage('max(1%, 2%, 3%)', 'max(1%, 2%, 3%)'); +test_valid_percentage('max(3%, 2%, 1%)', 'max(3%, 2%, 1%)'); + +test_valid_percentage('calc(min(1%) + min(2%))', 'calc(min(1%) + min(2%))'); +test_valid_percentage('calc(max(1%) + max(2%))', 'calc(max(1%) + max(2%))'); +test_valid_percentage('calc(1% + min(1%))', 'calc(1% + min(1%))'); +test_valid_percentage('calc(min(1%) + 1%)', 'calc(1% + min(1%))'); +test_valid_percentage('calc(1% + max(1%))', 'calc(1% + max(1%))'); +test_valid_percentage('calc(max(1%) + 1%)', 'calc(1% + max(1%))'); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/css-properties-values-api.idl b/third_party/blink/web_tests/external/wpt/interfaces/css-properties-values-api.idl index d8f54b1e..ee444eb 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/css-properties-values-api.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/css-properties-values-api.idl
@@ -14,6 +14,10 @@ void registerProperty(PropertyDefinition definition); }; +partial interface CSSRule { + const unsigned short PROPERTY_RULE = 18; +}; + [Exposed=Window] interface CSSPropertyRule : CSSRule { readonly attribute CSSOMString name;
diff --git a/third_party/blink/web_tests/external/wpt/layout-instability/observe-layout-shift.html b/third_party/blink/web_tests/external/wpt/layout-instability/observe-layout-shift.html index 8e5624e0..1c35fe2 100644 --- a/third_party/blink/web_tests/external/wpt/layout-instability/observe-layout-shift.html +++ b/third_party/blink/web_tests/external/wpt/layout-instability/observe-layout-shift.html
@@ -4,6 +4,11 @@ <body> <style> #myDiv { position: relative; width: 300px; height: 100px; } + +/* Disable the button's focus ring, which otherwise expands its visual rect by + * 1px on all sides, triggering a layout shift event. + */ +#button { outline: none; } </style> <div id='myDiv'></div> <button id='button'>Generate a 'click' event</button>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-legacy-align-attribute-001-ref.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-legacy-align-attribute-001-ref.html new file mode 100644 index 0000000..a9545c6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-legacy-align-attribute-001-ref.html
@@ -0,0 +1,61 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>munder/mover/munderover align (reference)</title> + </head> + <body> + <p>Test passes if the center of the following rectangles is aligned + on the same vertical axis.</p> + <p> + <math> + <munder> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munder> + </math> + </p> + <p> + <math> + <munder> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munder> + </math> + </p> + <p> + <math> + <mover> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </mover> + </math> + </p> + <p> + <math> + <mover> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </mover> + </math> + </p> + <p> + <math> + <munderover> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munderover> + </math> + </p> + <p> + <math> + <munderover> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munderover> + </math> + </p> + </body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-legacy-align-attribute-001.html b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-legacy-align-attribute-001.html new file mode 100644 index 0000000..31920c6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/mathml/presentation-markup/scripts/underover-legacy-align-attribute-001.html
@@ -0,0 +1,72 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>munder/mover/munderover align</title> + <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> + <link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.munder"> + <link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.mover"> + <link rel="help" href="https://www.w3.org/TR/MathML3/chapter3.html#presm.munderover"> + <meta name="assert" content="Check that the legacy align attribute is ignored."> + <link rel="match" href="underover-legacy-align-attribute-001-ref.html"> + </head> + <body> + <p>Test passes if the center of the following rectangles is aligned + on the same vertical axis.</p> + <p> + <math> + <munder align="left"> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munder> + </math> + </p> + <p> + <math> + <munder align="right"> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munder> + </math> + </p> + <p> + <math> + <mover align="left"> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </mover> + </math> + </p> + <p> + <math> + <mover align="right"> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </mover> + </math> + </p> + <p> + <math> + <munderover align="left"> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munderover> + </math> + </p> + <p> + <math> + <munderover align="right"> + <mspace width="30px" height="20px" style="background: cyan;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + <mspace width="10px" height="20px" style="background: blue;"></mspace> + </munderover> + </math> + </p> + <script src="/mathml/support/feature-detection.js"></script> + <script> + MathMLFeatureDetection.ensure_for_match_reftest("has_mspace"); + MathMLFeatureDetection.ensure_for_match_reftest("has_munderover"); + </script> + </body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/sms_mock.js b/third_party/blink/web_tests/external/wpt/resources/chromium/sms_mock.js index a8cd81a..bdfbc20 100644 --- a/third_party/blink/web_tests/external/wpt/resources/chromium/sms_mock.js +++ b/third_party/blink/web_tests/external/wpt/resources/chromium/sms_mock.js
@@ -8,7 +8,7 @@ this.mojoReceiver_ = new blink.mojom.SmsReceiverReceiver(this); this.interceptor_ = new MojoInterfaceInterceptor( - blink.mojom.SmsReceiver.$interfaceName) + blink.mojom.SmsReceiver.$interfaceName, "context", true) this.interceptor_.oninterfacerequest = (e) => { this.mojoReceiver_.$.bindHandle(e.handle);
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/run_tc.py b/third_party/blink/web_tests/external/wpt/tools/ci/run_tc.py index ea4a1ac..b2826bf0 100755 --- a/third_party/blink/web_tests/external/wpt/tools/ci/run_tc.py +++ b/third_party/blink/web_tests/external/wpt/tools/ci/run_tc.py
@@ -124,8 +124,12 @@ def install_chrome(channel): + deb_prefix = "https://dl.google.com/linux/direct/" if channel in ("experimental", "dev", "nightly"): - deb_archive = "google-chrome-unstable_current_amd64.deb" + # Pinned to 78 as 79 consistently fails reftests. TODO(foolip). + # See https://github.com/web-platform-tests/wpt/issues/19297. + deb_archive = "google-chrome-unstable_78.0.3904.17-1_amd64.deb" + deb_prefix = "https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-unstable/" elif channel == "beta": deb_archive = "google-chrome-beta_current_amd64.deb" elif channel == "stable": @@ -134,7 +138,7 @@ raise ValueError("Unrecognized release channel: %s" % channel) dest = os.path.join("/tmp", deb_archive) - resp = urlopen("https://dl.google.com/linux/direct/%s" % deb_archive) + resp = urlopen(deb_prefix + deb_archive) with open(dest, "w") as f: f.write(resp.read())
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt index 30400b2..21f5bd8 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt +++ b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 563 tests; 530 PASS, 33 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 563 tests; 531 PASS, 32 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Setup PASS align-content (type: discrete) has testAccumulation function PASS align-content: "flex-end" onto "flex-start" @@ -543,7 +543,7 @@ PASS vector-effect: "non-scaling-stroke" onto "none" PASS vector-effect: "none" onto "non-scaling-stroke" PASS visibility (type: visibility) has testAccumulation function -FAIL visibility: onto "visible" assert_equals: The value should be visible at 1000ms expected "visible" but got "hidden" +PASS visibility: onto "visible" PASS visibility: onto "hidden" PASS white-space (type: discrete) has testAccumulation function PASS white-space: "nowrap" onto "pre"
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt index b7d3910..d8f90033 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt +++ b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 559 tests; 537 PASS, 22 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 559 tests; 538 PASS, 21 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Setup PASS align-content (type: discrete) has testAddition function PASS align-content: "flex-end" onto "flex-start" @@ -539,7 +539,7 @@ PASS vector-effect: "non-scaling-stroke" onto "none" PASS vector-effect: "none" onto "non-scaling-stroke" PASS visibility (type: visibility) has testAddition function -FAIL visibility: onto "visible" assert_equals: The value should be visible at 1000ms expected "visible" but got "hidden" +PASS visibility: onto "visible" PASS visibility: onto "hidden" PASS white-space (type: discrete) has testAddition function PASS white-space: "nowrap" onto "pre"
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-types.js b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-types.js index 9f549c9..75f7d61 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-types.js +++ b/third_party/blink/web_tests/external/wpt/web-animations/animation-model/animation-types/property-types.js
@@ -617,7 +617,7 @@ composite }); testAnimationSamples(animation, idlName, [{ time: 0, expected: 'visible' }, - { time: 1000, expected: 'visible' }]); + { time: 1000, expected: 'hidden' }]); }, `${property}: onto "visible"`); test(t => {
diff --git a/third_party/blink/web_tests/fast/forms/controls-new-ui-high-contrast/details-expected.png b/third_party/blink/web_tests/fast/forms/controls-new-ui-high-contrast/details-expected.png new file mode 100644 index 0000000..cbfb8bd23 --- /dev/null +++ b/third_party/blink/web_tests/fast/forms/controls-new-ui-high-contrast/details-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/fast/forms/controls-new-ui-high-contrast/details.html b/third_party/blink/web_tests/fast/forms/controls-new-ui-high-contrast/details.html new file mode 100644 index 0000000..fae398c9 --- /dev/null +++ b/third_party/blink/web_tests/fast/forms/controls-new-ui-high-contrast/details.html
@@ -0,0 +1,4 @@ +<details open> + <summary>Summary</summary> + Description +</details> \ No newline at end of file
diff --git a/third_party/blink/web_tests/fast/forms/state-restore-dynamic-controls.html b/third_party/blink/web_tests/fast/forms/state-restore-dynamic-controls.html index 67ad178..af57ac4 100644 --- a/third_party/blink/web_tests/fast/forms/state-restore-dynamic-controls.html +++ b/third_party/blink/web_tests/fast/forms/state-restore-dynamic-controls.html
@@ -1,7 +1,7 @@ <!DOCTYPE html> <script src="../../resources/testharness.js"></script> <script src="../../resources/testharnessreport.js"></script> -<script src="../../external/wpt/html/semantics/forms/autofocus/resources/utils.js"></script> +<script src="../../external/wpt/html/interaction/focus/the-autofocus-attribute/resources/utils.js"></script> <body> <iframe src="resources/state-restore-dynamic-controls-frame.html"></iframe> <script>
diff --git a/third_party/blink/web_tests/flag-specific/disable-blink-features=LayoutNG/compositing/geometry/preserve-3d-switching-expected.txt b/third_party/blink/web_tests/flag-specific/disable-blink-features=LayoutNG/compositing/geometry/preserve-3d-switching-expected.txt index 5ef1c8a2..bfb0722 100644 --- a/third_party/blink/web_tests/flag-specific/disable-blink-features=LayoutNG/compositing/geometry/preserve-3d-switching-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-blink-features=LayoutNG/compositing/geometry/preserve-3d-switching-expected.txt
@@ -26,17 +26,11 @@ "bounds": [304, 304] }, { - "name": "Child Transform Layer", - "bounds": [304, 304], - "drawsContent": false, - "transform": 2 - }, - { "name": "LayoutBlockFlow DIV id='parent'", "bounds": [280, 280], "contentsOpaque": true, "backgroundColor": "#FFFF00", - "transform": 4 + "transform": 2 }, { "name": "LayoutBlockFlow (positioned) DIV", @@ -44,7 +38,7 @@ "opacity": 0.699999988079071, "contentsOpaque": true, "backgroundColor": "#008000", - "transform": 6 + "transform": 4 } ], "transforms": [ @@ -54,46 +48,23 @@ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], - [108, 73, 0, 1] + [120, 85, 0, 1] ] }, { "id": 2, "parent": 1, "transform": [ - [1, 0, 0, 0], - [0, 1, 0, 0], - [0, 0, 1, -0.002], - [0, 0, 0, 1] - ], - "origin": [152, 152] - }, - { - "id": 3, - "parent": 2, - "transform": [ - [1, 0, 0, 0], - [0, 1, 0, 0], - [0, 0, 1, 0], - [12, 12, 0, 1] - ], - "flattenInheritedTransform": false - }, - { - "id": 4, - "parent": 3, - "transform": [ [0.766044443118978, -0.556670399226419, -0.32139380484327, 0], [0, 0.5, -0.866025403784439, 0], [0.642787609686539, 0.663413948168938, 0.383022221559489, 0], [0, 0, 0, 1] ], - "origin": [140, 140], - "flattenInheritedTransform": false + "origin": [140, 140] }, { - "id": 5, - "parent": 4, + "id": 3, + "parent": 2, "transform": [ [1, 0, 0, 0], [0, 1, 0, 0], @@ -103,8 +74,8 @@ "flattenInheritedTransform": false }, { - "id": 6, - "parent": 5, + "id": 4, + "parent": 3, "transform": [ [0.766044443118978, 0, 0.642787609686539, 0], [0, 1, 0, 0],
diff --git a/third_party/blink/web_tests/flag-specific/disable-blink-features=LayoutNG/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt b/third_party/blink/web_tests/flag-specific/disable-blink-features=LayoutNG/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt index 6cd565c..b0a9727 100644 --- a/third_party/blink/web_tests/flag-specific/disable-blink-features=LayoutNG/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-blink-features=LayoutNG/compositing/layer-creation/overlap-transformed-preserved-3d-expected.txt
@@ -31,51 +31,46 @@ "drawsContent": false }, { - "name": "Child Transform Layer", - "drawsContent": false, - "transform": 2 - }, - { "name": "LayoutBlockFlow DIV id='camera' class='rotate-3d-start'", "contentsOpaque": true, "drawsContent": false, - "transform": 3 + "transform": 2 }, { "name": "LayoutBlockFlow (positioned) DIV class='side side-1'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 4 + "transform": 3 }, { "name": "LayoutBlockFlow (positioned) DIV class='side side-2'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 5 + "transform": 4 }, { "name": "LayoutBlockFlow (positioned) DIV class='side side-3'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 6 + "transform": 5 }, { "name": "LayoutBlockFlow (positioned) DIV class='side side-4'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 7 + "transform": 6 }, { "name": "LayoutBlockFlow (positioned) DIV class='side side-5'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 8 + "transform": 7 }, { "name": "LayoutBlockFlow (positioned) DIV class='side side-6'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 9 + "transform": 8 } ], "transforms": [ @@ -92,9 +87,9 @@ "id": 2, "parent": 1, "transform": [ - [1, 0, 0, 0], - [0, 1, 0, 0], - [0, 0, 1, -0.005], + [0.353553390593274, 0.25, -0.5, 0], + [0, 0.353553390593274, 0.707106781186548, 0], + [0.353553390593274, -0.25, 0.5, 0], [0, 0, 0, 1] ], "origin": [50, 50] @@ -103,18 +98,6 @@ "id": 3, "parent": 2, "transform": [ - [0.353553390593274, 0.25, -0.5, 0], - [0, 0.353553390593274, 0.707106781186548, 0], - [0.353553390593274, -0.25, 0.5, 0], - [0, 0, 0, 1] - ], - "origin": [50, 50], - "flattenInheritedTransform": false - }, - { - "id": 4, - "parent": 3, - "transform": [ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], @@ -123,8 +106,8 @@ "flattenInheritedTransform": false }, { - "id": 5, - "parent": 3, + "id": 4, + "parent": 2, "transform": [ [0, 0, -1, 0], [0, 1, 0, 0], @@ -135,8 +118,8 @@ "flattenInheritedTransform": false }, { - "id": 6, - "parent": 3, + "id": 5, + "parent": 2, "transform": [ [-1, 0, 0, 0], [0, 1, 0, 0], @@ -147,8 +130,8 @@ "flattenInheritedTransform": false }, { - "id": 7, - "parent": 3, + "id": 6, + "parent": 2, "transform": [ [0, 0, 1, 0], [0, 1, 0, 0], @@ -159,8 +142,8 @@ "flattenInheritedTransform": false }, { - "id": 8, - "parent": 3, + "id": 7, + "parent": 2, "transform": [ [1, 0, 0, 0], [0, 0, 1, 0], @@ -171,8 +154,8 @@ "flattenInheritedTransform": false }, { - "id": 9, - "parent": 3, + "id": 8, + "parent": 2, "transform": [ [1, 0, 0, 0], [0, 0, -1, 0], @@ -212,51 +195,46 @@ "drawsContent": false }, { - "name": "Child Transform Layer", - "drawsContent": false, - "transform": 2 - }, - { "name": "LayoutBlockFlow DIV id='camera' class='rotate-3d-start rotate-3d-end'", "contentsOpaque": true, "drawsContent": false, - "transform": 3 + "transform": 2 }, { "name": "LayoutBlockFlow (positioned) DIV class='side side-1'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 4 + "transform": 3 }, { "name": "LayoutBlockFlow (positioned) DIV class='side side-2'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 5 + "transform": 4 }, { "name": "LayoutBlockFlow (positioned) DIV class='side side-3'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 6 + "transform": 5 }, { "name": "LayoutBlockFlow (positioned) DIV class='side side-4'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 7 + "transform": 6 }, { "name": "LayoutBlockFlow (positioned) DIV class='side side-5'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 8 + "transform": 7 }, { "name": "LayoutBlockFlow (positioned) DIV class='side side-6'", "bounds": [100, 100], "backgroundColor": "#00FF00CC", - "transform": 9 + "transform": 8 }, { "name": "Squashing Containment Layer", @@ -289,9 +267,9 @@ "id": 2, "parent": 1, "transform": [ - [1, 0, 0, 0], - [0, 1, 0, 0], - [0, 0, 1, -0.005], + [0.707106781186548, 0.5, -0.5, 0], + [0, 0.707106781186548, 0.707106781186548, 0], + [0.707106781186548, -0.5, 0.5, 0], [0, 0, 0, 1] ], "origin": [50, 50] @@ -300,18 +278,6 @@ "id": 3, "parent": 2, "transform": [ - [0.707106781186548, 0.5, -0.5, 0], - [0, 0.707106781186548, 0.707106781186548, 0], - [0.707106781186548, -0.5, 0.5, 0], - [0, 0, 0, 1] - ], - "origin": [50, 50], - "flattenInheritedTransform": false - }, - { - "id": 4, - "parent": 3, - "transform": [ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], @@ -320,8 +286,8 @@ "flattenInheritedTransform": false }, { - "id": 5, - "parent": 3, + "id": 4, + "parent": 2, "transform": [ [0, 0, -1, 0], [0, 1, 0, 0], @@ -332,8 +298,8 @@ "flattenInheritedTransform": false }, { - "id": 6, - "parent": 3, + "id": 5, + "parent": 2, "transform": [ [-1, 0, 0, 0], [0, 1, 0, 0], @@ -344,8 +310,8 @@ "flattenInheritedTransform": false }, { - "id": 7, - "parent": 3, + "id": 6, + "parent": 2, "transform": [ [0, 0, 1, 0], [0, 1, 0, 0], @@ -356,8 +322,8 @@ "flattenInheritedTransform": false }, { - "id": 8, - "parent": 3, + "id": 7, + "parent": 2, "transform": [ [1, 0, 0, 0], [0, 0, 1, 0], @@ -368,8 +334,8 @@ "flattenInheritedTransform": false }, { - "id": 9, - "parent": 3, + "id": 8, + "parent": 2, "transform": [ [1, 0, 0, 0], [0, 0, -1, 0],
diff --git a/third_party/blink/web_tests/flag-specific/disable-blink-features=LayoutNG/compositing/overflow/accelerated-overflow-scroll-should-not-affect-perspective-expected.txt b/third_party/blink/web_tests/flag-specific/disable-blink-features=LayoutNG/compositing/overflow/accelerated-overflow-scroll-should-not-affect-perspective-expected.txt new file mode 100644 index 0000000..b245fa2 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/disable-blink-features=LayoutNG/compositing/overflow/accelerated-overflow-scroll-should-not-affect-perspective-expected.txt
@@ -0,0 +1,116 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "drawsContent": false, + "backgroundColor": "#FFFFFF" + }, + { + "name": "Scrolling Layer", + "bounds": [800, 600], + "drawsContent": false + }, + { + "name": "Scrolling Contents Layer", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutBlockFlow (positioned) DIV class='container'", + "position": [8, 8], + "bounds": [200, 200] + }, + { + "name": "Scrolling Layer", + "position": [8, 8], + "bounds": [185, 185], + "drawsContent": false + }, + { + "name": "Scrolling Contents Layer", + "position": [8, 8], + "bounds": [185, 290], + "drawsContent": false + }, + { + "name": "LayoutBlockFlow (positioned) DIV class='child first'", + "bounds": [60, 200], + "contentsOpaque": true, + "backgroundColor": "#008000", + "transform": 2 + }, + { + "name": "LayoutBlockFlow (positioned) DIV class='child second'", + "bounds": [60, 200], + "contentsOpaque": true, + "backgroundColor": "#0000FF", + "transform": 4 + }, + { + "name": "Overflow Controls Host Layer", + "position": [8, 8], + "bounds": [200, 200], + "drawsContent": false + }, + { + "name": "Horizontal Scrollbar Layer", + "position": [8, 193], + "bounds": [185, 15], + "drawsContent": false + }, + { + "name": "Vertical Scrollbar Layer", + "position": [193, 8], + "bounds": [15, 185], + "drawsContent": false + }, + { + "name": "Scroll Corner Layer", + "position": [193, 193], + "bounds": [15, 15] + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, 73, 0, 1] + ] + }, + { + "id": 2, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, 0, 10, 1] + ] + }, + { + "id": 3, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [73, 73, 0, 1] + ] + }, + { + "id": 4, + "parent": 3, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, 0, 20, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/flag-specific/disable-blink-features=LayoutNG/compositing/squashing/squashing-inside-perspective-expected.txt b/third_party/blink/web_tests/flag-specific/disable-blink-features=LayoutNG/compositing/squashing/squashing-inside-perspective-expected.txt new file mode 100644 index 0000000..40fc40f --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/disable-blink-features=LayoutNG/compositing/squashing/squashing-inside-perspective-expected.txt
@@ -0,0 +1,56 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "drawsContent": false, + "backgroundColor": "#FFFFFF" + }, + { + "name": "Scrolling Layer", + "bounds": [800, 600], + "drawsContent": false + }, + { + "name": "Scrolling Contents Layer", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF" + }, + { + "name": "LayoutBlockFlow (positioned) DIV", + "position": [8, 8], + "contentsOpaque": true, + "drawsContent": false + }, + { + "name": "LayoutBlockFlow (positioned) DIV", + "bounds": [200, 200], + "contentsOpaque": true, + "backgroundColor": "#00008B", + "transform": 2 + } + ], + "transforms": [ + { + "id": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [8, 8, 0, 1] + ] + }, + { + "id": 2, + "parent": 1, + "transform": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, 74, 200, 1] + ] + } + ] +} +
diff --git a/third_party/blink/web_tests/http/tests/devtools/file-system-project.js b/third_party/blink/web_tests/http/tests/devtools/file-system-project.js index ac6a8d5..c6ec9f8 100644 --- a/third_party/blink/web_tests/http/tests/devtools/file-system-project.js +++ b/third_party/blink/web_tests/http/tests/devtools/file-system-project.js
@@ -174,7 +174,7 @@ dir.addFile('bar.js', ''); InspectorFrontendHost.events.dispatchEventToListeners( - InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, + Host.InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, {changed: [], added: ['/var/www4/html/bar.js'], removed: []}); TestRunner.addResult('-- File added externally --');
diff --git a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/badging-origin-trial-interfaces.html b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/badging-origin-trial-interfaces.html index e88af7eb..9459b0ca 100644 --- a/third_party/blink/web_tests/http/tests/origin_trials/webexposed/badging-origin-trial-interfaces.html +++ b/third_party/blink/web_tests/http/tests/origin_trials/webexposed/badging-origin-trial-interfaces.html
@@ -1,10 +1,10 @@ <!DOCTYPE html> <meta charset="utf-8"> <!-- Generate token with the command: -generate_token.py http://127.0.0.1:8000 BadgingV2 --expire-timestamp=2000000000 +generate_token.py http://127.0.0.1:8000 Badging --expire-timestamp=2000000000 --> -<meta http-equiv="origin-trial" content="AqzH1yAjqt/6grJkR3r1584FLOYa+kkfoenZBdnmBOShEN/eGrOF7OoxdPXg5e2b+KeB+ysH8qp/F9eyimHZygIAAABReyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiQmFkZ2luZ1YyIiwgImV4cGlyeSI6IDIwMDAwMDAwMDB9" /> +<meta http-equiv="origin-trial" content="AjMyKQIep8aE/3H2rfLKB0UEt0aGtfdVGult8LN5tjpYZnkhbaGEm8KirzODRym/5KnVfv33DaXex0tUZoDQFQ0AAABPeyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiQmFkZ2luZyIsICJleHBpcnkiOiAyMDAwMDAwMDAwfQ==" /> <title>Badging API - interfaces exposed by origin trial</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> @@ -16,4 +16,4 @@ assert_own_property(window.ExperimentalBadge, 'set', 'Set is not defined on the ExperimentalBadge API'); assert_own_property(window.ExperimentalBadge, 'clear', 'Clear is not defined on the ExperimentalBadge API'); }, 'Badge API interfaces and properties in Origin-Trial enabled document.'); -</script> +</script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/platform/linux/compositing/geometry/preserve-3d-switching-expected.txt b/third_party/blink/web_tests/platform/linux/compositing/geometry/preserve-3d-switching-expected.txt index 7cb51745..cad01fd9 100644 --- a/third_party/blink/web_tests/platform/linux/compositing/geometry/preserve-3d-switching-expected.txt +++ b/third_party/blink/web_tests/platform/linux/compositing/geometry/preserve-3d-switching-expected.txt
@@ -26,17 +26,11 @@ "bounds": [304, 304] }, { - "name": "Child Transform Layer", - "bounds": [304, 304], - "drawsContent": false, - "transform": 2 - }, - { "name": "LayoutNGBlockFlow DIV id='parent'", "bounds": [280, 280], "contentsOpaque": true, "backgroundColor": "#FFFF00", - "transform": 4 + "transform": 2 }, { "name": "LayoutNGBlockFlow (positioned) DIV", @@ -44,7 +38,7 @@ "opacity": 0.699999988079071, "contentsOpaque": true, "backgroundColor": "#008000", - "transform": 6 + "transform": 4 } ], "transforms": [ @@ -54,46 +48,23 @@ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], - [108, 73, 0, 1] + [120, 85, 0, 1] ] }, { "id": 2, "parent": 1, "transform": [ - [1, 0, 0, 0], - [0, 1, 0, 0], - [0, 0, 1, -0.002], - [0, 0, 0, 1] - ], - "origin": [152, 152] - }, - { - "id": 3, - "parent": 2, - "transform": [ - [1, 0, 0, 0], - [0, 1, 0, 0], - [0, 0, 1, 0], - [12, 12, 0, 1] - ], - "flattenInheritedTransform": false - }, - { - "id": 4, - "parent": 3, - "transform": [ [0.766044443118978, -0.556670399226419, -0.32139380484327, 0], [0, 0.5, -0.866025403784439, 0], [0.642787609686539, 0.663413948168938, 0.383022221559489, 0], [0, 0, 0, 1] ], - "origin": [140, 140], - "flattenInheritedTransform": false + "origin": [140, 140] }, { - "id": 5, - "parent": 4, + "id": 3, + "parent": 2, "transform": [ [1, 0, 0, 0], [0, 1, 0, 0], @@ -103,8 +74,8 @@ "flattenInheritedTransform": false }, { - "id": 6, - "parent": 5, + "id": 4, + "parent": 3, "transform": [ [0.766044443118978, 0, 0.642787609686539, 0], [0, 1, 0, 0],
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/controls-new-ui-high-contrast/details-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/controls-new-ui-high-contrast/details-expected.png new file mode 100644 index 0000000..9cfa1a6 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/fast/forms/controls-new-ui-high-contrast/details-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png new file mode 100644 index 0000000..9cfa1a6 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png new file mode 100644 index 0000000..7de77fd --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png new file mode 100644 index 0000000..7de77fd --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png new file mode 100644 index 0000000..7de77fd --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png b/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png new file mode 100644 index 0000000..7de77fd --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/compositing/geometry/preserve-3d-switching-expected.txt b/third_party/blink/web_tests/platform/mac/compositing/geometry/preserve-3d-switching-expected.txt index 7cb51745..cad01fd9 100644 --- a/third_party/blink/web_tests/platform/mac/compositing/geometry/preserve-3d-switching-expected.txt +++ b/third_party/blink/web_tests/platform/mac/compositing/geometry/preserve-3d-switching-expected.txt
@@ -26,17 +26,11 @@ "bounds": [304, 304] }, { - "name": "Child Transform Layer", - "bounds": [304, 304], - "drawsContent": false, - "transform": 2 - }, - { "name": "LayoutNGBlockFlow DIV id='parent'", "bounds": [280, 280], "contentsOpaque": true, "backgroundColor": "#FFFF00", - "transform": 4 + "transform": 2 }, { "name": "LayoutNGBlockFlow (positioned) DIV", @@ -44,7 +38,7 @@ "opacity": 0.699999988079071, "contentsOpaque": true, "backgroundColor": "#008000", - "transform": 6 + "transform": 4 } ], "transforms": [ @@ -54,46 +48,23 @@ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], - [108, 73, 0, 1] + [120, 85, 0, 1] ] }, { "id": 2, "parent": 1, "transform": [ - [1, 0, 0, 0], - [0, 1, 0, 0], - [0, 0, 1, -0.002], - [0, 0, 0, 1] - ], - "origin": [152, 152] - }, - { - "id": 3, - "parent": 2, - "transform": [ - [1, 0, 0, 0], - [0, 1, 0, 0], - [0, 0, 1, 0], - [12, 12, 0, 1] - ], - "flattenInheritedTransform": false - }, - { - "id": 4, - "parent": 3, - "transform": [ [0.766044443118978, -0.556670399226419, -0.32139380484327, 0], [0, 0.5, -0.866025403784439, 0], [0.642787609686539, 0.663413948168938, 0.383022221559489, 0], [0, 0, 0, 1] ], - "origin": [140, 140], - "flattenInheritedTransform": false + "origin": [140, 140] }, { - "id": 5, - "parent": 4, + "id": 3, + "parent": 2, "transform": [ [1, 0, 0, 0], [0, 1, 0, 0], @@ -103,8 +74,8 @@ "flattenInheritedTransform": false }, { - "id": 6, - "parent": 5, + "id": 4, + "parent": 3, "transform": [ [0.766044443118978, 0, 0.642787609686539, 0], [0, 1, 0, 0],
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/controls-new-ui-high-contrast/details-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/controls-new-ui-high-contrast/details-expected.png new file mode 100644 index 0000000..7de77fd --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/fast/forms/controls-new-ui-high-contrast/details-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png new file mode 100644 index 0000000..7de77fd --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/compositing/geometry/preserve-3d-switching-expected.txt b/third_party/blink/web_tests/platform/win/compositing/geometry/preserve-3d-switching-expected.txt index 3eca5361..2fc12cd0 100644 --- a/third_party/blink/web_tests/platform/win/compositing/geometry/preserve-3d-switching-expected.txt +++ b/third_party/blink/web_tests/platform/win/compositing/geometry/preserve-3d-switching-expected.txt
@@ -26,17 +26,11 @@ "bounds": [304, 304] }, { - "name": "Child Transform Layer", - "bounds": [304, 304], - "drawsContent": false, - "transform": 2 - }, - { "name": "LayoutNGBlockFlow DIV id='parent'", "bounds": [280, 280], "contentsOpaque": true, "backgroundColor": "#FFFF00", - "transform": 4 + "transform": 2 }, { "name": "LayoutNGBlockFlow (positioned) DIV", @@ -44,7 +38,7 @@ "opacity": 0.699999988079071, "contentsOpaque": true, "backgroundColor": "#008000", - "transform": 6 + "transform": 4 } ], "transforms": [ @@ -54,46 +48,23 @@ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], - [108, 72, 0, 1] + [120, 84, 0, 1] ] }, { "id": 2, "parent": 1, "transform": [ - [1, 0, 0, 0], - [0, 1, 0, 0], - [0, 0, 1, -0.002], - [0, 0, 0, 1] - ], - "origin": [152, 152] - }, - { - "id": 3, - "parent": 2, - "transform": [ - [1, 0, 0, 0], - [0, 1, 0, 0], - [0, 0, 1, 0], - [12, 12, 0, 1] - ], - "flattenInheritedTransform": false - }, - { - "id": 4, - "parent": 3, - "transform": [ [0.766044443118978, -0.556670399226419, -0.32139380484327, 0], [0, 0.5, -0.866025403784439, 0], [0.642787609686539, 0.663413948168938, 0.383022221559489, 0], [0, 0, 0, 1] ], - "origin": [140, 140], - "flattenInheritedTransform": false + "origin": [140, 140] }, { - "id": 5, - "parent": 4, + "id": 3, + "parent": 2, "transform": [ [1, 0, 0, 0], [0, 1, 0, 0], @@ -103,8 +74,8 @@ "flattenInheritedTransform": false }, { - "id": 6, - "parent": 5, + "id": 4, + "parent": 3, "transform": [ [0.766044443118978, 0, 0.642787609686539, 0], [0, 1, 0, 0],
diff --git a/third_party/blink/web_tests/virtual/at-property/external/wpt/css/css-properties-values-api/idlharness-expected.txt b/third_party/blink/web_tests/virtual/at-property/external/wpt/css/css-properties-values-api/idlharness-expected.txt index 7a11537..87fb499 100644 --- a/third_party/blink/web_tests/virtual/at-property/external/wpt/css/css-properties-values-api/idlharness-expected.txt +++ b/third_party/blink/web_tests/virtual/at-property/external/wpt/css/css-properties-values-api/idlharness-expected.txt
@@ -3,6 +3,8 @@ PASS idl_test validation PASS Partial namespace CSS: original namespace defined PASS Partial namespace CSS: member names are unique +PASS Partial interface CSSRule: original interface defined +PASS Partial interface CSSRule: member names are unique PASS CSSPropertyRule interface: existence and properties of interface object PASS CSSPropertyRule interface object length PASS CSSPropertyRule interface object name @@ -13,6 +15,8 @@ FAIL CSSPropertyRule interface: attribute syntax assert_true: The prototype object must have a property "syntax" expected true got false FAIL CSSPropertyRule interface: attribute inherits assert_true: The prototype object must have a property "inherits" expected true got false FAIL CSSPropertyRule interface: attribute initialValue assert_true: The prototype object must have a property "initialValue" expected true got false +FAIL CSSRule interface: constant PROPERTY_RULE on interface object assert_equals: property has wrong value expected 18 but got 1001 +FAIL CSSRule interface: constant PROPERTY_RULE on interface prototype object assert_equals: property has wrong value expected 18 but got 1001 PASS CSS namespace: operation escape(CSSOMString) PASS CSS namespace: operation registerProperty(PropertyDefinition) Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/cascade/external/wpt/css/css-properties-values-api/idlharness-expected.txt b/third_party/blink/web_tests/virtual/cascade/external/wpt/css/css-properties-values-api/idlharness-expected.txt new file mode 100644 index 0000000..20e8217b --- /dev/null +++ b/third_party/blink/web_tests/virtual/cascade/external/wpt/css/css-properties-values-api/idlharness-expected.txt
@@ -0,0 +1,23 @@ +This is a testharness.js-based test. +PASS idl_test setup +PASS idl_test validation +PASS Partial namespace CSS: original namespace defined +PASS Partial namespace CSS: member names are unique +PASS Partial interface CSSRule: original interface defined +PASS Partial interface CSSRule: member names are unique +FAIL CSSPropertyRule interface: existence and properties of interface object assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing +FAIL CSSPropertyRule interface object length assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing +FAIL CSSPropertyRule interface object name assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing +FAIL CSSPropertyRule interface: existence and properties of interface prototype object assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing +FAIL CSSPropertyRule interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing +FAIL CSSPropertyRule interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing +FAIL CSSPropertyRule interface: attribute name assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing +FAIL CSSPropertyRule interface: attribute syntax assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing +FAIL CSSPropertyRule interface: attribute inherits assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing +FAIL CSSPropertyRule interface: attribute initialValue assert_own_property: self does not have own property "CSSPropertyRule" expected property "CSSPropertyRule" missing +FAIL CSSRule interface: constant PROPERTY_RULE on interface object assert_own_property: expected property "PROPERTY_RULE" missing +FAIL CSSRule interface: constant PROPERTY_RULE on interface prototype object assert_own_property: expected property "PROPERTY_RULE" missing +PASS CSS namespace: operation escape(CSSOMString) +PASS CSS namespace: operation registerProperty(PropertyDefinition) +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png b/third_party/blink/web_tests/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png new file mode 100644 index 0000000..cbfb8bd23 --- /dev/null +++ b/third_party/blink/web_tests/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/details-expected.png Binary files differ
diff --git a/tools/android/elf_compression/README.md b/tools/android/elf_compression/README.md index ed068a2..9d41fd94 100644 --- a/tools/android/elf_compression/README.md +++ b/tools/android/elf_compression/README.md
@@ -16,11 +16,19 @@ constructor's symbols to point at the cutted range and to the compressed version. ### Library constructor -TODO(https://crbug.com/998082): describe this. +Located at `constructor/` path and should be build together with the target +library. + +It decompresses data from compressed section, provided by compression script +and populates the target range. ## Usage -Firstly, the library needs to be build with the tool's constructor. -TODO(https://crbug.com/998082): describe this. +Firstly, the library needs to be build with the tool's constructor. To do this +add the following file to your build: + + constructor/library_constructor.c + +Additionally the library must be linked with `-pthread` option. After the library build is complete, the compression script must be applied to it in the following way:
diff --git a/tools/android/elf_compression/compress_section.py b/tools/android/elf_compression/compress_section.py index 7f145266..64d39e4 100755 --- a/tools/android/elf_compression/compress_section.py +++ b/tools/android/elf_compression/compress_section.py
@@ -38,6 +38,15 @@ COMPRESSED_SECTION_NAME = '.compressed_library_data' ADDRESS_ALIGN = 0x1000 +CUT_RANGE_BEGIN_MAGIC = bytearray( + [0x2e, 0x2a, 0xee, 0xf6, 0x45, 0x03, 0xd2, 0x50]) +CUT_RANGE_END_MAGIC = bytearray( + [0x52, 0x40, 0xeb, 0x9d, 0xdb, 0x11, 0xed, 0x1a]) +COMPRESSED_RANGE_BEGIN_MAGIC = bytearray( + [0x5e, 0x49, 0x4a, 0x4c, 0xae, 0x28, 0xc8, 0xbb]) +COMPRESSED_RANGE_END_MAGIC = bytearray( + [0xdd, 0x60, 0xed, 0xcf, 0xc3, 0x29, 0xa6, 0xd6]) + # src/third_party/llvm-build/Release+Asserts/bin/llvm-objcopy OBJCOPY_PATH = pathlib.Path(__file__).resolve().parents[3].joinpath( 'third_party/llvm-build/Release+Asserts/bin/llvm-objcopy') @@ -253,7 +262,9 @@ def _CreateLoadForCompressedSection(data): - """Creates a LOAD segment to previously created COMPRESSED_SECTION_NAME.""" + """Creates a LOAD segment to previously created COMPRESSED_SECTION_NAME. + + Returns the virtual address range corresponding to created segment.""" elf_hdr = elf_headers.ElfHeader(data) section_offset = None @@ -282,6 +293,7 @@ p_align=ADDRESS_ALIGN, )) elf_hdr.PatchData(data) + return new_vaddr, new_vaddr + section_size def _SplitLoadSegmentAndNullifyRange(data, l, r): @@ -293,6 +305,8 @@ The resulting LOAD segment containing [l, r) is edited so it sets the corresponding virtual address range to zeroes, ignoring file content. + + Returns virtual address range corresponding to [l, r). """ elf_hdr = elf_headers.ElfHeader(data) @@ -349,6 +363,7 @@ range_phdr.p_memsz = r - l elf_hdr.PatchData(data) + return central_segment_address, central_segment_address + (r - l) def _CutRangeAndCorrectFile(data, l, r): @@ -397,6 +412,30 @@ elf.PatchData(data) +def _PatchConstructorBytes(data, cut_range_virt_l, cut_range_virt_r, + compressed_range_virt_l, compressed_range_virt_r): + """Sets magic bytes given by constructor to the given ranges.""" + elf = elf_headers.ElfHeader(data) + + to_patch = [ + (CUT_RANGE_BEGIN_MAGIC, cut_range_virt_l, 'cut range begin'), + (CUT_RANGE_END_MAGIC, cut_range_virt_r, 'cut range end'), + (COMPRESSED_RANGE_BEGIN_MAGIC, compressed_range_virt_l, + 'compressed range begin'), + (COMPRESSED_RANGE_END_MAGIC, compressed_range_virt_r, + 'compressed range end'), + ] + + for magic_bytes, new_value, name in to_patch: + magic_idx = data.find(magic_bytes) + if magic_idx == -1: + raise RuntimeError('failed to find %s magic bytes' % name) + if data.rfind(magic_bytes) != magic_idx: + raise RuntimeError('%s magic bytes occures more then once' % name) + new_value_bytes = new_value.to_bytes(length=8, byteorder=elf.byte_order) + data[magic_idx:magic_idx + 8] = new_value_bytes + + def _ShrinkRangeToAlignVirtualAddress(data, l, r): virtual_l, virtual_r = _FileRangeToVirtualAddressRange(data, l, r) # LOAD segments borders are being rounded to the page size so we have to @@ -422,9 +461,12 @@ _CopyRangeIntoCompressedSection(data, left_range, right_range) _MovePhdrToTheEnd(data) - _CreateLoadForCompressedSection(data) - _SplitLoadSegmentAndNullifyRange(data, left_range, right_range) + compressed_virt_l, compressed_virt_r = _CreateLoadForCompressedSection(data) + virt_l, virt_r = _SplitLoadSegmentAndNullifyRange(data, left_range, + right_range) _CutRangeAndCorrectFile(data, left_range, right_range) + _PatchConstructorBytes(data, virt_l, virt_r, compressed_virt_l, + compressed_virt_r) with open(args.output, 'wb') as f: f.write(data)
diff --git a/tools/android/elf_compression/constructor/library_constructor.c b/tools/android/elf_compression/constructor/library_constructor.c new file mode 100644 index 0000000..c808131 --- /dev/null +++ b/tools/android/elf_compression/constructor/library_constructor.c
@@ -0,0 +1,327 @@ +// 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. + +// This file contains userfaultfd watcher constructor which decompress +// parts of the library's code, compressed by compress_section.py script. +#include <asm-generic/ioctls.h> +#include <asm/unistd_64.h> +#include <errno.h> +#include <fcntl.h> +#include <linux/userfaultfd.h> +#include <poll.h> +#include <pthread.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/poll.h> +#include <sys/syscall.h> +#include <sys/ttydefaults.h> +#include <sys/types.h> +#include <unistd.h> + +// Symbol with virtual address of the start of ELF header of the library. Set by +// linker. +extern char __ehdr_start; + +// This function can be used to prevent a value or expression from being +// optimized away by the compiler. +// +// This method is clang specific, hence the #error +#ifndef __clang__ +#error "DoNotOptimize is clang specific method" +#endif +void DoNotOptimize(void* value) { + __asm__ volatile("" : : "r,m"(value) : "memory"); +} + +// The following 4 arrays are here to be patched into by compress_section.py +// script. They currently contain magic bytes that will be used to locate them +// in the library file. DoNotOptimize method is applied to them at the +// beginning of the constructor to ensure that the arrays are not optimized +// away. +unsigned char g_dummy_cut_range_begin[8] = {0x2e, 0x2a, 0xee, 0xf6, + 0x45, 0x03, 0xd2, 0x50}; +unsigned char g_dummy_cut_range_end[8] = {0x52, 0x40, 0xeb, 0x9d, + 0xdb, 0x11, 0xed, 0x1a}; +unsigned char g_dummy_compressed_range_begin[8] = {0x5e, 0x49, 0x4a, 0x4c, + 0xae, 0x28, 0xc8, 0xbb}; +unsigned char g_dummy_compressed_range_end[8] = {0xdd, 0x60, 0xed, 0xcf, + 0xc3, 0x29, 0xa6, 0xd6}; + +static void DecompressPage(void* cut_start, + void* compressed_start, + void* page_start, + size_t page_size, + void* buffer) { + // TODO(https://crbug.com/998082): Update the method to work with arbitrary + // block sizes. + + // This method is a stub to plug the decompression login into. + uint64_t delta = page_start - cut_start; + void* compressed_page_start = compressed_start + delta; + memcpy(buffer, compressed_page_start, page_size); +} + +typedef struct PollArray { + struct pollfd* pollfd_array; + size_t size; + size_t capacity; +} PollArray; + +PollArray* CreatePollArray() { + PollArray* array = calloc(1, sizeof(PollArray)); + return array; +} + +void DestroyPollArray(PollArray* arr) { + free(arr->pollfd_array); + free(arr); +} + +void IncreasePollArrayCapacity(PollArray* arr) { + if (arr->capacity == 0) { + arr->capacity = 1; + } else { + arr->capacity *= 2; + } + arr->pollfd_array = + realloc(arr->pollfd_array, arr->capacity * sizeof(struct pollfd)); +} + +void PollArrayPush(PollArray* arr, struct pollfd el) { + if (arr->size == arr->capacity) { + IncreasePollArrayCapacity(arr); + } + arr->pollfd_array[arr->size] = el; + arr->size++; +} + +void PollArrayPop(PollArray* arr) { + arr->size--; +} + +typedef struct ThreadArguments { + int uffd; + void* cut_start; + void* compressed_start; + size_t cut_length; + size_t page_size; +} ThreadArguments; + +static void HandlePageFault(int uffd, + void* pagefault_address, + void* cut_start, + void* compressed_start, + size_t page_size, + void* buffer) { + DecompressPage(cut_start, compressed_start, pagefault_address, page_size, + buffer); + struct uffdio_copy copy; + copy.dst = (uint64_t)pagefault_address; + copy.src = (uint64_t)buffer; + copy.len = page_size; + copy.mode = 0; + if (ioctl(uffd, UFFDIO_COPY, ©)) { + switch (errno) { + case EINVAL: + case EAGAIN: + perror("UFFDIO_COPY failed"); + } + } +} + +static void* WatcherThreadFunc(void* thread_args) { + ThreadArguments* args = thread_args; + + void* buffer = calloc(args->page_size, sizeof(char)); + struct uffd_msg message; + + PollArray* poll_array = CreatePollArray(); + struct pollfd poll_fd = {.fd = args->uffd, .events = POLLIN}; + PollArrayPush(poll_array, poll_fd); + + // TODO(https://crbug.com/998082): Use epoll instead + while (poll_array->size && + poll(poll_array->pollfd_array, poll_array->size, -1) >= 0) { + for (int i = 0; i < poll_array->size; i++) { + struct pollfd* current_fd = &poll_array->pollfd_array[i]; + if (current_fd->revents & POLLIN) { + read(current_fd->fd, &message, sizeof(message)); + if (message.event == UFFD_EVENT_FORK) { + struct pollfd new_fd = {.fd = message.arg.fork.ufd, .events = POLLIN}; + PollArrayPush(poll_array, new_fd); + } + if (message.event == UFFD_EVENT_PAGEFAULT) { + HandlePageFault(current_fd->fd, (void*)message.arg.pagefault.address, + args->cut_start, args->compressed_start, + args->page_size, buffer); + } + } else if (current_fd->revents & POLLHUP) { + close(current_fd->fd); + poll_array->pollfd_array[i] = + poll_array->pollfd_array[poll_array->size - 1]; + PollArrayPop(poll_array); + } + } + } + // Everything died, the thread is free. + free(buffer); + free(thread_args); + DestroyPollArray(poll_array); + return NULL; +} + +static int StartWatcherThread(void* cut_addr, + void* compressed_l, + size_t cut_length, + size_t page_size, + int uffd) { + pthread_attr_t attr; + if (pthread_attr_init(&attr)) { + return -1; + } + if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { + pthread_attr_destroy(&attr); + return -1; + } + ThreadArguments* args = malloc(sizeof(ThreadArguments)); + args->uffd = uffd; + args->cut_start = cut_addr; + args->compressed_start = compressed_l; + args->page_size = page_size; + + pthread_t thread_id; + if (pthread_create(&thread_id, &attr, WatcherThreadFunc, (void*)args)) { + pthread_attr_destroy(&attr); + free(args); + return -1; + } + pthread_attr_destroy(&attr); + return 0; +} + +static int SetupUserfaultFd(void* cut_start, size_t cut_length) { + int uffd = syscall(__NR_userfaultfd, O_NONBLOCK | O_CLOEXEC); + if (uffd == -1) { + perror("Userfaultfd syscall failed"); + return -1; + } + // Enabling userfaultfd. + struct uffdio_api api = {.api = UFFD_API, + .features = UFFD_FEATURE_EVENT_FORK}; + if (ioctl(uffd, UFFDIO_API, &api)) { + perror("ioctl UFFDIO_API failed"); + close(uffd); + return -1; + } + // Setting userfaultfd watch over cut region. + struct uffdio_register uffd_register; + uffd_register.range.start = (uint64_t)cut_start; + uffd_register.range.len = cut_length; + uffd_register.mode = UFFDIO_REGISTER_MODE_MISSING; + if (ioctl(uffd, UFFDIO_REGISTER, &uffd_register)) { + perror("ioctl UFFDIO_REGISTER failed"); + close(uffd); + return -1; + } + return uffd; +} + +// Unregisters the userfaultfd watch on cut range. Used to revert to +// DecompressWholeRange in case of error during the creation of the thread. +static void UnregisterUserfaultFd(void* cut_start, + size_t cut_length, + int uffd) { + struct uffdio_register uffd_unregister; + uffd_unregister.range.start = (uint64_t)cut_start; + uffd_unregister.range.len = cut_length; + uffd_unregister.mode = UFFDIO_REGISTER_MODE_MISSING; + // No error handling here since we are already resorting to the fallback + // option. + ioctl(uffd, UFFDIO_UNREGISTER, &uffd_unregister); +} + +// Backup slow solution for the constructor. Fully decompresses and populates +// the cut range. This method is used if the userfaultfd setup failed to ensure +// that the library will still function despite the failure. +static void DecompressWholeRange(void* cut_start, + void* compressed_start, + size_t cut_length, + size_t page_size) { + if (mprotect(cut_start, cut_length, PROT_READ | PROT_EXEC | PROT_WRITE)) { + perror("Failed to enable PROT_WRITE on cut range"); + exit(1); + } + + void* buffer = calloc(page_size, sizeof(char)); + for (uint64_t offset = 0; offset < cut_length; offset += page_size) { + DecompressPage(cut_start, compressed_start, cut_start + offset, page_size, + buffer); + memcpy(cut_start + offset, buffer, page_size); + } + free(buffer); + + if (mprotect(cut_start, cut_length, PROT_READ | PROT_EXEC)) { + perror("Failed to disable PROT_WRITE on cut range"); + exit(1); + } +} + +static unsigned char* MapCutRange(void* cut_start, size_t cut_length) { + void* addr = mmap(cut_start, cut_length, PROT_READ | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); + if (addr == MAP_FAILED) { + perror("Constructor cut range mapping failed"); + // If we fail at this point of time there is no way for us to recover since + // without valid mapping we can't change the cut region. + exit(1); + } + return addr; +} + +void* ConvertDummyArrayToAddress(void* dummy_array) { + uintptr_t* value_ptr = (uintptr_t*)dummy_array; + uintptr_t value = *value_ptr; + value += (uintptr_t)&__ehdr_start; + return (void*)value; +} + +void __attribute__((constructor(100))) InitLibraryDecompressor() { + // The constructor only works on 64 bit systems and as such expecting the + // pointer size to be 8 bytes. + _Static_assert(sizeof(uint64_t) == sizeof(uintptr_t), + "Pointer size is not 8 bytes"); + + DoNotOptimize(g_dummy_cut_range_begin); + DoNotOptimize(g_dummy_cut_range_end); + DoNotOptimize(g_dummy_compressed_range_begin); + DoNotOptimize(g_dummy_compressed_range_end); + + void* cut_l = ConvertDummyArrayToAddress(g_dummy_cut_range_begin); + void* cut_r = ConvertDummyArrayToAddress(g_dummy_cut_range_end); + void* compressed_l = + ConvertDummyArrayToAddress(g_dummy_compressed_range_begin); + void* compressed_r = ConvertDummyArrayToAddress(g_dummy_compressed_range_end); + + uint64_t cut_range_length = (uintptr_t)cut_r - (uintptr_t)cut_l; + void* cut_addr = MapCutRange(cut_l, cut_range_length); + + size_t page_size = sysconf(_SC_PAGESIZE); + int uffd = SetupUserfaultFd(cut_addr, cut_range_length); + if (uffd == -1) { + DecompressWholeRange(cut_addr, compressed_l, cut_range_length, page_size); + return; + } + if (StartWatcherThread(cut_addr, compressed_l, cut_range_length, page_size, + uffd)) { + UnregisterUserfaultFd(cut_addr, cut_range_length, uffd); + close(uffd); + DecompressWholeRange(cut_addr, compressed_l, cut_range_length, page_size); + return; + } +}
diff --git a/tools/android/elf_compression/elf_headers.py b/tools/android/elf_compression/elf_headers.py index f929191b..c517b19 100644 --- a/tools/android/elf_compression/elf_headers.py +++ b/tools/android/elf_compression/elf_headers.py
@@ -297,7 +297,6 @@ string_table_offset = self.e_shoff + self.e_shstrndx * self.e_shentsize string_table = StringTableHeader.FromBytes(self.byte_order, data, string_table_offset) - for shdr in self.shdrs: shdr.SetStrName(string_table.GetName(data, shdr.sh_name)) @@ -426,7 +425,7 @@ self.phdrs.sort(key=HeaderToKey) def _PatchProgramHeaders(self, data): - """Patch all program headers.""" + """Patches all program headers.""" current_offset = self.e_phoff self._OrderProgramHeaders() for phdr in self.GetProgramHeaders(): @@ -434,6 +433,14 @@ data[current_offset:current_offset + len(phdr_bytes)] = phdr_bytes current_offset += self.e_phentsize + def _PatchSectionHeaders(self, data): + """Patches all section headers.""" + current_offset = self.e_shoff + for shdr in self.GetSectionHeaders(): + shdr_bytes = shdr.ToBytes() + data[current_offset:current_offset + len(shdr_bytes)] = shdr_bytes + current_offset += self.e_shentsize + def PatchData(self, data): """Patches the given data array to reflect all changes made to the header. @@ -453,3 +460,4 @@ elf_bytes = self.ToBytes() data[:len(elf_bytes)] = elf_bytes self._PatchProgramHeaders(data) + self._PatchSectionHeaders(data)
diff --git a/tools/android/elf_compression/test/compression_script_test.py b/tools/android/elf_compression/test/compression_script_test.py index 4ec8213..8627734a 100755 --- a/tools/android/elf_compression/test/compression_script_test.py +++ b/tools/android/elf_compression/test/compression_script_test.py
@@ -17,11 +17,15 @@ LIBRARY_CC_NAME = 'libtest.cc' OPENER_CC_NAME = 'library_opener.cc' +CONSTRUCTOR_C_PATH = '../constructor/library_constructor.c' SCRIPT_PATH = '../compress_section.py' # src/third_party/llvm-build/Release+Asserts/bin/clang++ -LLVM_CLANG_PATH = pathlib.Path(__file__).resolve().parents[4].joinpath( +LLVM_CLANG_CC_PATH = pathlib.Path(__file__).resolve().parents[4].joinpath( 'third_party/llvm-build/Release+Asserts/bin/clang++') +# src/third_party/llvm-build/Release+Asserts/bin/clang +LLVM_CLANG_PATH = pathlib.Path(__file__).resolve().parents[4].joinpath( + 'third_party/llvm-build/Release+Asserts/bin/clang') # The array that we are trying to cut out of the file have those bytes at # its start and end. This is done to simplify the test code to not perform @@ -44,6 +48,7 @@ self.library_cc_path = os.path.join(script_dir, LIBRARY_CC_NAME) self.opener_cc_path = os.path.join(script_dir, OPENER_CC_NAME) self.script_path = os.path.join(script_dir, SCRIPT_PATH) + self.constructor_c_path = os.path.join(script_dir, CONSTRUCTOR_C_PATH) def tearDown(self): self.tmpdir_object.cleanup() @@ -58,9 +63,23 @@ def _BuildLibrary(self): library_path = os.path.join(self.tmpdir, 'libtest.so') + library_object_path = os.path.join(self.tmpdir, 'libtest.o') + constructor_object_path = os.path.join(self.tmpdir, 'constructor.o') + library_object_build_result = subprocess.run([ + LLVM_CLANG_CC_PATH, '-c', '-fPIC', '-O2', self.library_cc_path, '-o', + library_object_path + ]) + self.assertEqual(library_object_build_result.returncode, 0) + + constructor_object_build_result = subprocess.run([ + LLVM_CLANG_PATH, '-c', '-fPIC', '-O2', self.constructor_c_path, '-o', + constructor_object_path + ]) + self.assertEqual(constructor_object_build_result.returncode, 0) + library_build_result = subprocess.run([ - LLVM_CLANG_PATH, '-shared', '-fPIC', '-O2', self.library_cc_path, '-o', - library_path + LLVM_CLANG_PATH, '-shared', '-fPIC', '-O2', library_object_path, + constructor_object_path, '-o', library_path, '-pthread' ]) self.assertEqual(library_build_result.returncode, 0) return library_path @@ -68,7 +87,8 @@ def _BuildOpener(self): opener_path = os.path.join(self.tmpdir, 'library_opener') opener_build_result = subprocess.run([ - LLVM_CLANG_PATH, '-O2', self.opener_cc_path, '-o', opener_path, '-ldl' + LLVM_CLANG_CC_PATH, '-O2', self.opener_cc_path, '-o', opener_path, + '-ldl' ]) self.assertEqual(opener_build_result.returncode, 0) return opener_path @@ -105,7 +125,6 @@ stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8') - self.assertEqual(opener_run_result.stderr, '') self.assertEqual(opener_run_result.returncode, 0) return opener_run_result.stdout @@ -116,8 +135,9 @@ opener_path = self._BuildOpener() patched_library_path = self._RunScript(library_path) - opener_output = self._RunOpener(opener_path, patched_library_path) - self.assertEqual(opener_output, '4096\n') + for _ in range(10): + opener_output = self._RunOpener(opener_path, patched_library_path) + self.assertEqual(opener_output, '1046543\n') def testAlignUp(self): """Tests for AlignUp method of the script."""
diff --git a/tools/android/elf_compression/test/library_opener.cc b/tools/android/elf_compression/test/library_opener.cc index f4075f43..bfc78f84 100644 --- a/tools/android/elf_compression/test/library_opener.cc +++ b/tools/android/elf_compression/test/library_opener.cc
@@ -24,13 +24,13 @@ return 1; } - TestFunction get_zeroes = - reinterpret_cast<TestFunction>(dlsym(handle, "GetZeroes")); - if (get_zeroes == nullptr) { + TestFunction get_sum = + reinterpret_cast<TestFunction>(dlsym(handle, "GetSum")); + if (get_sum == nullptr) { std::cerr << "GetSum method not found" << std::endl; return 1; } - std::cout << get_zeroes() << std::endl; + std::cout << get_sum() << std::endl; return 0; }
diff --git a/tools/android/elf_compression/test/libtest.cc b/tools/android/elf_compression/test/libtest.cc index aa1832bb..d31ede2 100644 --- a/tools/android/elf_compression/test/libtest.cc +++ b/tools/android/elf_compression/test/libtest.cc
@@ -8,20 +8,20 @@ // for the script. We expect library to not crash and return the 55 as a // result. -#include <algorithm> +#include <numeric> #include <vector> #include "libtest_array.h" // NOLINT(build/include) extern "C" { -int GetZeroes(); +int GetSum(); } -int GetZeroes() { +int GetSum() { // We are using some c++ features here to better simulate a c++ library and // cause more code reach to catch potential memory errors. std::vector<int> sum_array(std::begin(array), std::end(array)); - int count = std::count(sum_array.begin(), sum_array.end(), 0); - // count should be equal to 4096. - return count; + int sum = std::accumulate(sum_array.begin(), sum_array.end(), 0); + // sum should be equal to 1046543. + return sum; }
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 3a6262b..ccbb647 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -740,11 +740,7 @@ 'chromeos-kevin-compile-rel': 'cros_chrome_sdk_headless_ozone', 'chromeos-kevin-experimental-rel': 'cros_chrome_sdk_headless_ozone', 'chromeos-kevin-rel': 'cros_chrome_sdk_headless_ozone', - 'linux-chromeos-rel': 'chromeos_with_codecs_release_trybot', - # Replicate linux-chromeos-rel for code coverage experiment. - # TODO(crbug.com/1000367): Remove once linux-chromeos-coverage-rel is - # folded into linux-chromeos-rel. - 'linux-chromeos-coverage-rel': 'chromeos_with_codecs_release_trybot_code_coverage', + 'linux-chromeos-rel': 'chromeos_with_codecs_release_trybot_code_coverage', 'linux-chromeos-compile-dbg': 'chromeos_with_codecs_debug_bot', 'linux-chromeos-dbg': 'chromeos_with_codecs_debug_bot', }, @@ -1301,6 +1297,7 @@ 'chromeos_with_codecs', 'release_trybot', 'no_symbols', ], + # Keep in sync with chromeos_with_codecs_release_trybot. 'chromeos_with_codecs_release_trybot_code_coverage': [ 'chromeos_with_codecs', 'release_trybot', 'no_symbols', 'use_clang_coverage', 'partial_code_coverage_instrumentation', @@ -1654,6 +1651,8 @@ 'gpu_tests', 'release_trybot', 'no_symbols', 'use_dummy_lastchange', ], + # Keep in sync with + # gpu_tests_release_trybot_no_symbols_use_dummy_lastchange. 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange_code_coverage': [ 'gpu_tests', 'release_trybot', 'no_symbols', 'use_dummy_lastchange', 'use_clang_coverage', 'partial_code_coverage_instrumentation',
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 00aa5730..81ecc50 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -18131,6 +18131,8 @@ <int value="611" label="DeviceLoginScreenDictationEnabled"/> <int value="612" label="DeviceLoginScreenSelectToSpeakEnabled"/> <int value="613" label="DeviceLoginScreenCursorHighlightEnabled"/> + <int value="614" label="DeviceLoginScreenCaretHighlightEnabled"/> + <int value="615" label="DeviceLoginScreenMonoAudioEnabled"/> </enum> <enum name="EnterprisePolicyInvalidations">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index d28e464..27a0345 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -36480,12 +36480,12 @@ </histogram> <histogram name="Enterprise.LockToSingleUserResult" - enum="LockToSingleUserResult" expires_after="M79"> + enum="LockToSingleUserResult" expires_after="M82"> <owner>emaxx@chromium.org</owner> <owner>igorcov@chromium.org</owner> <summary> Chrome OS only. The result of D-Bus call to lock device to single user. - Estimated that till version M79 we should get enough stats to understand if + Estimated that till version M82 we should get enough stats to understand if there are big problems with the D-Bus call. </summary> </histogram> @@ -94576,54 +94576,63 @@ <histogram name="OOBE.RecommendApps.Fetcher.AppCount" units="units" expires_after="2019-08-30"> + <owner>rsorokin@chromium.org</owner> <owner>play-bm-eng@google.com</owner> <summary>The number of recommended apps.</summary> </histogram> <histogram name="OOBE.RecommendApps.Fetcher.DownloadTime" units="ms" expires_after="2019-08-30"> + <owner>rsorokin@chromium.org</owner> <owner>play-bm-eng@google.com</owner> <summary>The time it takes to fetch the recommended apps.</summary> </histogram> <histogram name="OOBE.RecommendApps.Fetcher.ResponseCode" enum="HttpResponseCode" expires_after="2019-08-30"> + <owner>rsorokin@chromium.org</owner> <owner>chromesky-eng@google.com</owner> <summary>The response code of fetching the recommended apps.</summary> </histogram> <histogram name="OOBE.RecommendApps.Fetcher.ResponseParseResult" enum="RecommendAppsResponseParseResult" expires_after="2019-08-30"> + <owner>rsorokin@chromium.org</owner> <owner>chromesky-eng@google.com</owner> <summary>The result of parsing the recommend-apps response.</summary> </histogram> <histogram name="OOBE.RecommendApps.Fetcher.ResponseSize" units="KB" expires_after="2019-08-30"> + <owner>rsorokin@chromium.org</owner> <owner>chromesky-eng@google.com</owner> <summary>The size of the recommend-apps JSON response.</summary> </histogram> <histogram name="OOBE.RecommendApps.Screen.Action" enum="RecommendAppsScreenAction" expires_after="2019-08-30"> + <owner>rsorokin@chromium.org</owner> <owner>chromesky-eng@google.com</owner> <summary>The user action on the recommend apps screen.</summary> </histogram> <histogram name="OOBE.RecommendApps.Screen.SelectedAppCount" units="units" expires_after="2019-08-30"> + <owner>rsorokin@chromium.org</owner> <owner>chromesky-eng@google.com</owner> <summary>The number of apps user selected.</summary> </histogram> <histogram name="OOBE.RecommendApps.Screen.SelectedRecommendedPercentage" units="%" expires_after="2019-08-30"> + <owner>rsorokin@chromium.org</owner> <owner>chromesky-eng@google.com</owner> <summary>The ratio of selected and recommended apps.</summary> </histogram> <histogram name="OOBE.RecommendApps.Screen.State" enum="RecommendAppsScreenState" expires_after="2019-08-30"> + <owner>rsorokin@chromium.org</owner> <owner>chromesky-eng@google.com</owner> <summary>Whether the reocmmend apps screen is shown.</summary> </histogram>
diff --git a/tools/perf/benchmarks/system_health_smoke_test.py b/tools/perf/benchmarks/system_health_smoke_test.py index 9d39be4..16e6b337 100644 --- a/tools/perf/benchmarks/system_health_smoke_test.py +++ b/tools/perf/benchmarks/system_health_smoke_test.py
@@ -159,7 +159,6 @@ # crbug.com/1008001 'system_health.memory_desktop/browse:tools:sheets:2019', - 'system_health.memory_desktop/browse:tools:maps:2019', # The following tests are disabled because they are disabled on the perf # waterfall (using tools/perf/expectations.config) on one platform or another.
diff --git a/tools/perf/core/results_processor/command_line.py b/tools/perf/core/results_processor/command_line.py index faf113e..b3f305fc 100644 --- a/tools/perf/core/results_processor/command_line.py +++ b/tools/perf/core/results_processor/command_line.py
@@ -15,14 +15,20 @@ from py_utils import cloud_storage +from core.results_processor import formatters -SUPPORTED_FORMATS = ['none', 'json-test-results'] + +# These formats are always handled natively, and never handed over to Telemetry. +HANDLED_NATIVELY = ['none', 'json-test-results'] def ArgumentParser(standalone=False, legacy_formats=None): """Create an ArgumentParser defining options required by the processor.""" - all_output_formats = sorted( - set(SUPPORTED_FORMATS).union(legacy_formats or ())) + if standalone: + all_output_formats = formatters.FORMATTERS.keys() + else: + all_output_formats = sorted( + set(HANDLED_NATIVELY).union(legacy_formats or ())) parser, group = _CreateTopLevelParser(standalone) group.add_argument( '--output-format', action='append', dest='output_formats', @@ -65,7 +71,7 @@ return parser -def ProcessOptions(options): +def ProcessOptions(options, standalone=False): """Adjust result processing options as needed before running benchmarks. Note: The intended scope of this function is limited to only adjust options @@ -78,6 +84,8 @@ Args: options: An options object with values parsed from the command line. + standalone: Whether this is a standalone Results Processor run (as + opposed to the run with Telemetry). """ # The output_dir option is None or missing if the selected Telemetry command # does not involve output generation, e.g. "run_benchmark list", and the @@ -116,7 +124,7 @@ for output_format in chosen_formats: if output_format == 'none': continue - elif output_format in SUPPORTED_FORMATS: + elif standalone or output_format in HANDLED_NATIVELY: options.output_formats.append(output_format) else: options.legacy_output_formats.append(output_format)
diff --git a/tools/perf/core/results_processor/command_line_unittest.py b/tools/perf/core/results_processor/command_line_unittest.py index 2220cd01..f67154c 100644 --- a/tools/perf/core/results_processor/command_line_unittest.py +++ b/tools/perf/core/results_processor/command_line_unittest.py
@@ -17,7 +17,7 @@ import mock from core.results_processor import command_line -from core.results_processor import processor +from core.results_processor import formatters # To easily mock module level symbols within the command_line module. @@ -133,7 +133,7 @@ with self.assertRaises(SystemExit): self.ParseArgs(['--output-format', 'unknown']) - @mock.patch(module('SUPPORTED_FORMATS'), ['new-format']) + @mock.patch(module('HANDLED_NATIVELY'), ['new-format']) def testOutputFormatsSplit(self): self.legacy_formats = ['old-format'] options = self.ParseArgs( @@ -141,7 +141,7 @@ self.assertEqual(options.output_formats, ['new-format']) self.assertEqual(options.legacy_output_formats, ['old-format']) - @mock.patch(module('SUPPORTED_FORMATS'), ['new-format']) + @mock.patch(module('HANDLED_NATIVELY'), ['new-format']) def testNoDuplicateOutputFormats(self): self.legacy_formats = ['old-format'] options = self.ParseArgs( @@ -160,23 +160,22 @@ with self.assertRaises(SystemExit): self.ParseArgs([]) - @mock.patch(module('SUPPORTED_FORMATS'), ['new-format']) def testIntermediateDirRequired(self): with self.assertRaises(SystemExit): - self.ParseArgs(['--output-format', 'new-format']) + self.ParseArgs(['--output-format', 'json-test-results']) - @mock.patch(module('SUPPORTED_FORMATS'), ['new-format']) def testSuccessful(self): options = self.ParseArgs( - ['--output-format', 'new-format', '--intermediate-dir', 'some_dir']) - self.assertEqual(options.output_formats, ['new-format']) + ['--output-format', 'json-test-results', + '--intermediate-dir', 'some_dir']) + self.assertEqual(options.output_formats, ['json-test-results']) self.assertEqual(options.intermediate_dir, '/path/to/curdir/some_dir') self.assertEqual(options.output_dir, '/path/to/output_dir') -class TestSupportedFormats(unittest.TestCase): - def testAllSupportedFormatsHaveFormatters(self): - for output_format in command_line.SUPPORTED_FORMATS: +class TestNativelyHandledFormats(unittest.TestCase): + def testNativelyHandledFormatsHaveFormatters(self): + for output_format in command_line.HANDLED_NATIVELY: if output_format == 'none': continue - self.assertIn(output_format, processor.FORMATTERS) + self.assertIn(output_format, formatters.FORMATTERS)
diff --git a/tools/perf/core/results_processor/formatters/__init__.py b/tools/perf/core/results_processor/formatters/__init__.py new file mode 100644 index 0000000..f75ff697 --- /dev/null +++ b/tools/perf/core/results_processor/formatters/__init__.py
@@ -0,0 +1,14 @@ +# 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. + +from core.results_processor.formatters import histograms_output +from core.results_processor.formatters import html_output +from core.results_processor.formatters import json3_output + + +FORMATTERS = { + 'json-test-results': json3_output, + 'histograms': histograms_output, + 'html': html_output, +}
diff --git a/tools/perf/core/results_processor/histograms_output.py b/tools/perf/core/results_processor/formatters/histograms_output.py similarity index 100% rename from tools/perf/core/results_processor/histograms_output.py rename to tools/perf/core/results_processor/formatters/histograms_output.py
diff --git a/tools/perf/core/results_processor/histograms_output_unittest.py b/tools/perf/core/results_processor/formatters/histograms_output_unittest.py similarity index 98% rename from tools/perf/core/results_processor/histograms_output_unittest.py rename to tools/perf/core/results_processor/formatters/histograms_output_unittest.py index b3ea74d..7b4cd36 100644 --- a/tools/perf/core/results_processor/histograms_output_unittest.py +++ b/tools/perf/core/results_processor/formatters/histograms_output_unittest.py
@@ -9,7 +9,7 @@ import shutil import tempfile -from core.results_processor import histograms_output +from core.results_processor.formatters import histograms_output from core.results_processor import command_line from core.results_processor import testing
diff --git a/tools/perf/core/results_processor/html_output.py b/tools/perf/core/results_processor/formatters/html_output.py similarity index 93% rename from tools/perf/core/results_processor/html_output.py rename to tools/perf/core/results_processor/formatters/html_output.py index dff1de9..a8f3cab 100644 --- a/tools/perf/core/results_processor/html_output.py +++ b/tools/perf/core/results_processor/formatters/html_output.py
@@ -7,7 +7,7 @@ import codecs import os -from core.results_processor import histograms_output +from core.results_processor.formatters import histograms_output from tracing_build import vulcanize_histograms_viewer
diff --git a/tools/perf/core/results_processor/json3_output.py b/tools/perf/core/results_processor/formatters/json3_output.py similarity index 100% rename from tools/perf/core/results_processor/json3_output.py rename to tools/perf/core/results_processor/formatters/json3_output.py
diff --git a/tools/perf/core/results_processor/json3_output_unittest.py b/tools/perf/core/results_processor/formatters/json3_output_unittest.py similarity index 98% rename from tools/perf/core/results_processor/json3_output_unittest.py rename to tools/perf/core/results_processor/formatters/json3_output_unittest.py index 3c9b118d..297ca30e 100644 --- a/tools/perf/core/results_processor/json3_output_unittest.py +++ b/tools/perf/core/results_processor/formatters/json3_output_unittest.py
@@ -5,7 +5,7 @@ import copy import unittest -from core.results_processor import json3_output +from core.results_processor.formatters import json3_output from core.results_processor import testing
diff --git a/tools/perf/core/results_processor/processor.py b/tools/perf/core/results_processor/processor.py index 3cf53cb..c0874b7 100644 --- a/tools/perf/core/results_processor/processor.py +++ b/tools/perf/core/results_processor/processor.py
@@ -12,18 +12,11 @@ import os from core.results_processor import command_line -from core.results_processor import json3_output -from core.results_processor import histograms_output -from core.results_processor import html_output +from core.results_processor import formatters HTML_TRACE_NAME = 'trace.html' TELEMETRY_RESULTS = '_telemetry_results.jsonl' -FORMATTERS = { - 'json-test-results': json3_output, - 'histograms': histograms_output, - 'html': html_output, -} def ProcessResults(options): @@ -48,10 +41,10 @@ _UploadArtifacts(intermediate_results, options.upload_bucket) for output_format in options.output_formats: - if output_format not in FORMATTERS: + if output_format not in formatters.FORMATTERS: raise NotImplementedError(output_format) - formatter = FORMATTERS[output_format] + formatter = formatters.FORMATTERS[output_format] formatter.Process(intermediate_results, options) @@ -106,5 +99,5 @@ """Entry point for the standalone version of the results_processor script.""" parser = command_line.ArgumentParser(standalone=True) options = parser.parse_args(args) - command_line.ProcessOptions(options) + command_line.ProcessOptions(options, standalone=True) return ProcessResults(options)
diff --git a/tools/perf/core/results_processor/processor_test.py b/tools/perf/core/results_processor/processor_test.py index 05adfd8b..f2a802c 100644 --- a/tools/perf/core/results_processor/processor_test.py +++ b/tools/perf/core/results_processor/processor_test.py
@@ -15,11 +15,9 @@ import tempfile import unittest -import mock - -from core.results_processor import json3_output -from core.results_processor import histograms_output -from core.results_processor import html_output +from core.results_processor.formatters import json3_output +from core.results_processor.formatters import histograms_output +from core.results_processor.formatters import html_output from core.results_processor import processor from core.results_processor import testing @@ -105,10 +103,6 @@ self.assertEqual(artifacts['logs'], ['gs://logs.txt']) self.assertEqual(artifacts['trace.html'], ['gs://trace.html']) - # TODO(crbug.com/981349): Remove this mock when histograms format - # is enabled in results_processor. - @mock.patch('core.results_processor.command_line.SUPPORTED_FORMATS', - ['histograms']) def testHistogramsOutput(self): hist_file = os.path.join(self.output_dir, histograms_output.HISTOGRAM_DICTS_NAME) @@ -154,10 +148,6 @@ self.assertIn([['documentation', 'url']], diag_values) self.assertIn(['label'], diag_values) - # TODO(crbug.com/981349): Remove this mock when histograms format - # is enabled in results_processor. - @mock.patch('core.results_processor.command_line.SUPPORTED_FORMATS', - ['histograms']) def testHistogramsOutputResetResults(self): hist_file = os.path.join(self.output_dir, histograms_output.HISTOGRAM_DICTS_NAME) @@ -199,10 +189,6 @@ self.assertNotIn(['label1'], diag_values) self.assertIn(['label2'], diag_values) - # TODO(crbug.com/981349): Remove this mock when histograms format - # is enabled in results_processor. - @mock.patch('core.results_processor.command_line.SUPPORTED_FORMATS', - ['histograms']) def testHistogramsOutputAppendResults(self): hist_file = os.path.join(self.output_dir, histograms_output.HISTOGRAM_DICTS_NAME) @@ -243,10 +229,6 @@ self.assertIn(['label1'], diag_values) self.assertIn(['label2'], diag_values) - # TODO(crbug.com/981349): Remove this mock when html format - # is enabled in results_processor. - @mock.patch('core.results_processor.command_line.SUPPORTED_FORMATS', - ['html']) def testHtmlOutput(self): hist_file = os.path.join(self.output_dir, histograms_output.HISTOGRAM_DICTS_NAME) @@ -292,10 +274,6 @@ self.assertIn([['documentation', 'url']], diag_values) self.assertIn(['label'], diag_values) - # TODO(crbug.com/981349): Remove this mock when html format - # is enabled in results_processor. - @mock.patch('core.results_processor.command_line.SUPPORTED_FORMATS', - ['html']) def testHtmlOutputResetResults(self): self.SerializeIntermediateResults([]) @@ -324,10 +302,6 @@ self.assertNotIn(['label1'], diag_values) self.assertIn(['label2'], diag_values) - # TODO(crbug.com/981349): Remove this mock when html format - # is enabled in results_processor. - @mock.patch('core.results_processor.command_line.SUPPORTED_FORMATS', - ['html']) def testHtmlOutputAppendResults(self): self.SerializeIntermediateResults([])
diff --git a/tools/perf/results_processor b/tools/perf/results_processor index ce11f3b..0cc14995 100755 --- a/tools/perf/results_processor +++ b/tools/perf/results_processor
@@ -7,6 +7,7 @@ from core import path_util path_util.AddPyUtilsToPath() +path_util.AddTracingToPath() from core import results_processor
diff --git a/ui/android/java/src/org/chromium/ui/widget/Toast.java b/ui/android/java/src/org/chromium/ui/widget/Toast.java index 7ae15c5..b0cb5202 100644 --- a/ui/android/java/src/org/chromium/ui/widget/Toast.java +++ b/ui/android/java/src/org/chromium/ui/widget/Toast.java
@@ -12,6 +12,7 @@ import android.content.pm.ApplicationInfo; import android.content.res.Resources; import android.os.Build; +import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; @@ -168,4 +169,36 @@ public static void setGlobalExtraYOffset(int yOffsetPx) { sExtraYOffset = yOffsetPx; } + + /** + * Shows a toast anchored on a view. + * @param context The context to use for the toast. + * @param view The view to anchor the toast. + * @param description The string shown in the toast. + * @return Whether a toast has been shown successfully. + */ + @SuppressLint("RtlHardcoded") + public static boolean showAnchoredToast(Context context, View view, CharSequence description) { + if (description == null) return false; + + final int screenWidth = context.getResources().getDisplayMetrics().widthPixels; + final int screenHeight = context.getResources().getDisplayMetrics().heightPixels; + final int[] screenPos = new int[2]; + view.getLocationOnScreen(screenPos); + final int width = view.getWidth(); + final int height = view.getHeight(); + + final int horizontalGravity = + (screenPos[0] < screenWidth / 2) ? Gravity.LEFT : Gravity.RIGHT; + final int xOffset = (screenPos[0] < screenWidth / 2) + ? screenPos[0] + width / 2 + : screenWidth - screenPos[0] - width / 2; + final int yOffset = (screenPos[1] < screenHeight / 2) ? screenPos[1] + height / 2 + : screenPos[1] - height * 3 / 2; + + Toast toast = Toast.makeText(context, description, Toast.LENGTH_SHORT); + toast.setGravity(Gravity.TOP | horizontalGravity, xOffset, yOffset); + toast.show(); + return true; + } }
diff --git a/ui/android/view_android.h b/ui/android/view_android.h index ccd504e..c8eefde 100644 --- a/ui/android/view_android.h +++ b/ui/android/view_android.h
@@ -163,7 +163,7 @@ void OnBottomControlsChanged(float bottom_controls_offset, float bottom_content_offset); - // Gets the Visual Viewport inset to apply. + // Gets the Visual Viewport inset to apply in physical pixels. int GetViewportInsetBottom(); ScopedAnchorView AcquireAnchorView();
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index 0436f7fa..b11bad9 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc
@@ -25,6 +25,7 @@ #include "cc/base/switches.h" #include "cc/input/input_handler.h" #include "cc/layers/layer.h" +#include "cc/metrics/begin_main_frame_metrics.h" #include "cc/trees/latency_info_swap_promise.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" @@ -626,6 +627,11 @@ observer.OnCompositingDidCommit(this); } +std::unique_ptr<cc::BeginMainFrameMetrics> +Compositor::GetBeginMainFrameMetrics() { + return nullptr; +} + void Compositor::DidReceiveCompositorFrameAck() { ++activated_frame_count_; for (auto& observer : observer_list_) @@ -661,7 +667,7 @@ NOTREACHED(); } -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) void Compositor::OnCompleteSwapWithNewSize(const gfx::Size& size) { for (auto& observer : observer_list_) observer.OnCompositingCompleteSwapWithNewSize(this, size);
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h index d8d1fbb..e5b62b3 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h
@@ -400,6 +400,8 @@ const gfx::PresentationFeedback& feedback) override; void RecordStartOfFrameMetrics() override {} void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) override {} + std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics() + override; // cc::LayerTreeHostSingleThreadClient implementation. void DidSubmitCompositorFrame() override; @@ -410,7 +412,7 @@ void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override; void OnFrameTokenChanged(uint32_t frame_token) override; -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) void OnCompleteSwapWithNewSize(const gfx::Size& size); #endif
diff --git a/ui/compositor/compositor_observer.h b/ui/compositor/compositor_observer.h index 62d9da2d..501aa3d 100644 --- a/ui/compositor/compositor_observer.h +++ b/ui/compositor/compositor_observer.h
@@ -6,6 +6,7 @@ #define UI_COMPOSITOR_COMPOSITOR_OBSERVER_H_ #include "base/time/time.h" +#include "build/build_config.h" #include "ui/compositor/compositor_export.h" namespace gfx { @@ -41,11 +42,11 @@ // Called when a child of the compositor is resizing. virtual void OnCompositingChildResizing(Compositor* compositor) {} -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) // Called when a swap with new size is completed. virtual void OnCompositingCompleteSwapWithNewSize(ui::Compositor* compositor, const gfx::Size& size) {} -#endif +#endif // defined(OS_LINUX) // Called at the top of the compositor's destructor, to give observers a // chance to remove themselves.
diff --git a/ui/compositor/host/host_context_factory_private.cc b/ui/compositor/host/host_context_factory_private.cc index bf8d8d2..820b70f 100644 --- a/ui/compositor/host/host_context_factory_private.cc +++ b/ui/compositor/host/host_context_factory_private.cc
@@ -29,7 +29,7 @@ static const char* kBrowser = "Browser"; -#if defined(USE_X11) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) class HostDisplayClient : public viz::HostDisplayClient { public: explicit HostDisplayClient(ui::Compositor* compositor)
diff --git a/ui/gfx/font.cc b/ui/gfx/font.cc index a3f46a86..21367fd7 100644 --- a/ui/gfx/font.cc +++ b/ui/gfx/font.cc
@@ -100,4 +100,21 @@ } #endif +Font::Weight FontWeightFromInt(int weight) { + static const Font::Weight weights[] = { + Font::Weight::INVALID, Font::Weight::THIN, Font::Weight::EXTRA_LIGHT, + Font::Weight::LIGHT, Font::Weight::NORMAL, Font::Weight::MEDIUM, + Font::Weight::SEMIBOLD, Font::Weight::BOLD, Font::Weight::EXTRA_BOLD, + Font::Weight::BLACK}; + + const Font::Weight* next_bigger_weight = std::lower_bound( + std::begin(weights), std::end(weights), weight, + [](const Font::Weight& a, const int& b) { + return static_cast<std::underlying_type<Font::Weight>::type>(a) < b; + }); + if (next_bigger_weight != std::end(weights)) + return *next_bigger_weight; + return Font::Weight::INVALID; +} + } // namespace gfx
diff --git a/ui/gfx/font.h b/ui/gfx/font.h index 0f71876..6d53975 100644 --- a/ui/gfx/font.h +++ b/ui/gfx/font.h
@@ -140,6 +140,9 @@ const Font::Weight weight); #endif +// Returns the Font::Weight that matches |weight| or the next bigger one. +GFX_EXPORT Font::Weight FontWeightFromInt(int weight); + } // namespace gfx #endif // UI_GFX_FONT_H_
diff --git a/ui/gfx/font_fallback_skia.cc b/ui/gfx/font_fallback_skia.cc index 2a87842..03bf25e 100644 --- a/ui/gfx/font_fallback_skia.cc +++ b/ui/gfx/font_fallback_skia.cc
@@ -12,6 +12,7 @@ #include "build/build_config.h" #include "ui/gfx/font.h" #include "ui/gfx/font_fallback_skia_impl.h" +#include "ui/gfx/platform_font.h" namespace gfx { @@ -28,14 +29,18 @@ if (text.empty()) return false; - std::string skia_family_name = - GetFallbackFontFamilyNameSkia(font, locale, text); + sk_sp<SkTypeface> fallback_typeface = + GetSkiaFallbackTypeface(font, locale, text); - if (skia_family_name.empty()) + if (!fallback_typeface) return false; - *result = Font(std::string(skia_family_name.c_str(), skia_family_name.size()), - font.GetFontSize()); + // Fallback needs to keep the exact SkTypeface, as re-matching the font using + // family name and styling information loses access to the underlying platform + // font handles and is not guaranteed to result in the correct typeface, see + // https://crbug.com/1003829 + *result = Font(PlatformFont::CreateFromSkTypeface( + std::move(fallback_typeface), font.GetFontSize())); return true; }
diff --git a/ui/gfx/font_fallback_skia_impl.cc b/ui/gfx/font_fallback_skia_impl.cc index 11870a6..2000d3fa 100644 --- a/ui/gfx/font_fallback_skia_impl.cc +++ b/ui/gfx/font_fallback_skia_impl.cc
@@ -14,11 +14,11 @@ namespace gfx { -std::string GetFallbackFontFamilyNameSkia(const Font& template_font, +sk_sp<SkTypeface> GetSkiaFallbackTypeface(const Font& template_font, const std::string& locale, base::StringPiece16 text) { if (text.empty()) - return std::string(); + return nullptr; sk_sp<SkFontMgr> font_mgr(SkFontMgr::RefDefault()); @@ -35,7 +35,7 @@ italic ? SkFontStyle::kItalic_Slant : SkFontStyle::kUpright_Slant); std::set<SkFontID> tested_typeface; - SkString skia_family_name; + sk_sp<SkTypeface> fallback_typeface; size_t fewest_missing_glyphs = text.length() + 1; size_t offset = 0; @@ -62,7 +62,7 @@ if (missing_glyphs < fewest_missing_glyphs) { fewest_missing_glyphs = missing_glyphs; - typeface->getFamilyName(&skia_family_name); + fallback_typeface = typeface; } // The font is a valid fallback font for the given text. @@ -70,7 +70,7 @@ break; } - return skia_family_name.c_str(); + return fallback_typeface; } } // namespace gfx
diff --git a/ui/gfx/font_fallback_skia_impl.h b/ui/gfx/font_fallback_skia_impl.h index 2284c780..1908dee 100644 --- a/ui/gfx/font_fallback_skia_impl.h +++ b/ui/gfx/font_fallback_skia_impl.h
@@ -10,9 +10,12 @@ #include "base/strings/string_piece.h" #include "ui/gfx/font.h" +#include "third_party/skia/include/core/SkRefCnt.h" +#include "third_party/skia/include/core/SkTypeface.h" + namespace gfx { -std::string GetFallbackFontFamilyNameSkia(const Font& template_font, +sk_sp<SkTypeface> GetSkiaFallbackTypeface(const Font& template_font, const std::string& locale, base::StringPiece16 text); }
diff --git a/ui/gfx/font_fallback_win.cc b/ui/gfx/font_fallback_win.cc index 65d96cb0..716badf 100644 --- a/ui/gfx/font_fallback_win.cc +++ b/ui/gfx/font_fallback_win.cc
@@ -20,6 +20,7 @@ #include "ui/gfx/font.h" #include "ui/gfx/font_fallback.h" #include "ui/gfx/font_fallback_skia_impl.h" +#include "ui/gfx/platform_font.h" namespace gfx { @@ -250,13 +251,18 @@ if (text.find(kNulCharacter) != base::StringPiece16::npos) return false; - std::string skia_fallback_family = - GetFallbackFontFamilyNameSkia(font, locale, text); + sk_sp<SkTypeface> fallback_typeface = + GetSkiaFallbackTypeface(font, locale, text); - if (skia_fallback_family.empty()) + if (!fallback_typeface) return false; - *result = Font(skia_fallback_family, font.GetFontSize()); + // Fallback needs to keep the exact SkTypeface, as re-matching the font using + // family name and styling information loses access to the underlying platform + // font handles and is not guaranteed to result in the correct typeface, see + // https://crbug.com/1003829 + *result = Font(PlatformFont::CreateFromSkTypeface( + std::move(fallback_typeface), font.GetFontSize())); return true; }
diff --git a/ui/gfx/font_unittest.cc b/ui/gfx/font_unittest.cc index 0aeae3c..399fea2 100644 --- a/ui/gfx/font_unittest.cc +++ b/ui/gfx/font_unittest.cc
@@ -161,5 +161,20 @@ } #endif // defined(OS_WIN) +TEST_F(FontTest, WeightConversion) { + struct WeightMatchExpectation { + int weight; + Font::Weight enum_value; + } expectations[] = { + {-10, Font::Weight::INVALID}, {-1, Font::Weight::INVALID}, + {0, Font::Weight::THIN}, {1, Font::Weight::THIN}, + {100, Font::Weight::THIN}, {350, Font::Weight::NORMAL}, + {400, Font::Weight::NORMAL}, {899, Font::Weight::BLACK}, + {900, Font::Weight::BLACK}, {901, Font::Weight::INVALID}}; + for (const auto& expectation : expectations) { + EXPECT_EQ(FontWeightFromInt(expectation.weight), expectation.enum_value); + } +} + } // namespace } // namespace gfx
diff --git a/ui/gfx/platform_font.h b/ui/gfx/platform_font.h index 7bdcf2505..8a2b375 100644 --- a/ui/gfx/platform_font.h +++ b/ui/gfx/platform_font.h
@@ -39,6 +39,15 @@ static PlatformFont* CreateFromNameAndSize(const std::string& font_name, int font_size); + // Creates a PlatformFont instance from the provided SkTypeface, ideally by + // just wrapping it without triggering a new font match. Implemented for + // PlatformFontWin and PlatformFontSkia, where only the latter provides true + // wrapping of the provided SkTypeface, while PlatformFontWin creates a + // PlatformFont object by extracting the family name and falls back to + // CreateFromNameAndSize(). + static PlatformFont* CreateFromSkTypeface(sk_sp<SkTypeface> typeface, + int size); + // Returns a new Font derived from the existing font. // |size_delta| is the size in pixels to add to the current font. // The style parameter specifies the new style for the font, and is a
diff --git a/ui/gfx/platform_font_skia.cc b/ui/gfx/platform_font_skia.cc index bf25331c..64cb1ea1 100644 --- a/ui/gfx/platform_font_skia.cc +++ b/ui/gfx/platform_font_skia.cc
@@ -292,6 +292,27 @@ render_params); } +PlatformFontSkia::PlatformFontSkia(sk_sp<SkTypeface> typeface, int size) { + TRACE_EVENT0("fonts", "PlatformFontSkia::PlatformFontSkia (from typeface)"); + DCHECK(typeface); + + SkString family_name; + typeface->getFamilyName(&family_name); + + SkFontStyle font_style = typeface->fontStyle(); + Font::Weight font_weight = FontWeightFromInt(font_style.weight()); + + FontRenderParamsQuery query; + query.families.push_back(family_name.c_str()); + query.pixel_size = size; + query.weight = font_weight; + + int style = typeface->isItalic() ? Font::ITALIC : Font::NORMAL; + + InitFromDetails(std::move(typeface), family_name.c_str(), size, style, + font_weight, gfx::GetFontRenderParams(query, nullptr)); +} + PlatformFontSkia::~PlatformFontSkia() {} void PlatformFontSkia::InitFromDetails(sk_sp<SkTypeface> typeface, @@ -426,6 +447,13 @@ TRACE_EVENT0("fonts", "PlatformFont::CreateFromNameAndSize"); return new PlatformFontSkia(font_name, font_size); } + +// static +PlatformFont* PlatformFont::CreateFromSkTypeface(sk_sp<SkTypeface> typeface, + int font_size_pixels) { + TRACE_EVENT0("fonts", "PlatformFont::CreateFromSkTypeface"); + return new PlatformFontSkia(typeface, font_size_pixels); +} #endif // !defined(OS_WIN) } // namespace gfx
diff --git a/ui/gfx/platform_font_skia.h b/ui/gfx/platform_font_skia.h index 4615a77..9456af32 100644 --- a/ui/gfx/platform_font_skia.h +++ b/ui/gfx/platform_font_skia.h
@@ -25,6 +25,9 @@ PlatformFontSkia(); PlatformFontSkia(const std::string& font_name, int font_size_pixels); + // Wraps the provided SkTypeface without triggering a font rematch. + PlatformFontSkia(sk_sp<SkTypeface> typeface, int font_size_pixels); + // Initials the default PlatformFont. Returns true if this is successful, or // false if fonts resources are not available. If this returns false, the // calling service should shut down.
diff --git a/ui/gfx/platform_font_win.cc b/ui/gfx/platform_font_win.cc index a9963ab..0acdf331 100644 --- a/ui/gfx/platform_font_win.cc +++ b/ui/gfx/platform_font_win.cc
@@ -649,4 +649,22 @@ return new PlatformFontWin(font_name, font_size); } +// static +PlatformFont* PlatformFont::CreateFromSkTypeface(sk_sp<SkTypeface> typeface, + int size) { + TRACE_EVENT0("fonts", "PlatformFont::CreateFromSkTypeface"); + if (base::FeatureList::IsEnabled(kPlatformFontSkiaOnWindows)) + return new PlatformFontSkia(typeface, size); + + // This is a transitional code path until we complete migrating to + // PlatformFontSkia on Windows. Being unable to wrap the SkTypeface into a + // PlatformFontSkia and performing a rematching by font family name instead + // loses platform font handles encapsulated in SkTypeface, and in turn leads + // to instantiating a different font than what was returned by font fallback, + // compare https://crbug.com/1003829. + SkString family_name; + typeface->getFamilyName(&family_name); + return new PlatformFontWin(family_name.c_str(), size); +} + } // namespace gfx
diff --git a/ui/login/display_manager.js b/ui/login/display_manager.js index f3a9602..d72f89a 100644 --- a/ui/login/display_manager.js +++ b/ui/login/display_manager.js
@@ -304,7 +304,7 @@ */ setShelfHeight: function(height) { document.documentElement.style.setProperty( - '--shelf-area-height', height + 'px'); + '--shelf-area-height-base', height + 'px'); }, /** @@ -747,13 +747,36 @@ * @param {!HTMLElement} screen Screen that is being shown. */ updateScreenSize: function(screen) { + if (!cr.isChromeOS) { + // Have to reset any previously predefined screen size first + // so that screen contents would define it instead. + $('inner-container').style.height = ''; + $('inner-container').style.width = ''; + screen.style.width = ''; + screen.style.height = ''; + } + $('outer-container').classList.toggle( 'fullscreen', screen.classList.contains('fullscreen')); + var width = screen.getPreferredSize().width; + var height = screen.getPreferredSize().height; + + if (!cr.isChromeOS) { + if (screen.classList.contains('fullscreen')) { + $('inner-container').style.height = '100%'; + $('inner-container').style.width = '100%'; + } else { + $('inner-container').style.height = height + 'px'; + $('inner-container').style.width = width + 'px'; + } + // This requires |screen| to have 'box-sizing: border-box'. + screen.style.width = width + 'px'; + screen.style.height = height + 'px'; + screen.style.margin = 'auto'; + } if (this.showingViewsLogin) { - var width = screen.getPreferredSize().width; - var height = screen.getPreferredSize().height; chrome.send('updateOobeDialogSize', [width, height]); $('scroll-container').classList.toggle('disable-scroll', true); $('inner-container').classList.toggle('disable-scroll', true);
diff --git a/ui/login/oobe.css b/ui/login/oobe.css index d7fa837..7e028d9 100644 --- a/ui/login/oobe.css +++ b/ui/login/oobe.css
@@ -8,7 +8,7 @@ :root { --google-grey-700: rgb(95, 99, 104); - --shelf-area-height: 57px; + --shelf-area-height-base: 57px; } html, @@ -17,6 +17,14 @@ width: 100%; } +html { + --shelf-area-height: var(--shelf-area-height-base); +} + +html[screen=gaia-signin] { + --shelf-area-height: 0; +} + body { background-color: transparent; cursor: default;
diff --git a/ui/ozone/demo/demo_window.h b/ui/ozone/demo/demo_window.h index 9514366f..e0e7871 100644 --- a/ui/ozone/demo/demo_window.h +++ b/ui/ozone/demo/demo_window.h
@@ -10,12 +10,12 @@ #include "base/memory/weak_ptr.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" +#include "ui/platform_window/platform_window.h" #include "ui/platform_window/platform_window_delegate.h" namespace ui { class Event; -class PlatformWindow; class Renderer; class RendererFactory; class WindowManager;
diff --git a/ui/ozone/public/ozone_platform.h b/ui/ozone/public/ozone_platform.h index 33a9467..2f12f9d 100644 --- a/ui/ozone/public/ozone_platform.h +++ b/ui/ozone/public/ozone_platform.h
@@ -14,6 +14,7 @@ #include "base/message_loop/message_pump_type.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "ui/gfx/buffer_types.h" +#include "ui/platform_window/platform_window.h" #include "ui/platform_window/platform_window_delegate.h" namespace display { @@ -31,7 +32,6 @@ class GpuPlatformSupportHost; class OverlayManagerOzone; class PlatformScreen; -class PlatformWindow; class SurfaceFactoryOzone; class SystemInputInjector; class PlatformClipboard;
diff --git a/ui/platform_window/BUILD.gn b/ui/platform_window/BUILD.gn index 8330427..d826a8a 100644 --- a/ui/platform_window/BUILD.gn +++ b/ui/platform_window/BUILD.gn
@@ -6,8 +6,9 @@ source_set("platform_window") { sources = [ - "platform_window.cc", "platform_window.h", + "platform_window_base.cc", + "platform_window_base.h", "platform_window_delegate.h", "platform_window_delegate_base.cc", "platform_window_delegate_base.h", @@ -39,6 +40,8 @@ sources += [ "platform_window_delegate_linux.cc", "platform_window_delegate_linux.h", + "platform_window_linux.cc", + "platform_window_linux.h", ] } }
diff --git a/ui/platform_window/platform_window.cc b/ui/platform_window/platform_window.cc deleted file mode 100644 index 3b52261..0000000 --- a/ui/platform_window/platform_window.cc +++ /dev/null
@@ -1,27 +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 "ui/platform_window/platform_window.h" - -namespace ui { - -PlatformWindow::PlatformWindow() = default; - -PlatformWindow::~PlatformWindow() = default; - -bool PlatformWindow::ShouldWindowContentsBeTransparent() const { - return false; -} - -void PlatformWindow::SetZOrderLevel(ZOrderLevel order) {} - -ZOrderLevel PlatformWindow::GetZOrderLevel() const { - return ZOrderLevel::kNormal; -} - -void PlatformWindow::StackAbove(gfx::AcceleratedWidget widget) {} - -void PlatformWindow::StackAtTop() {} - -} // namespace ui
diff --git a/ui/platform_window/platform_window.h b/ui/platform_window/platform_window.h index 113ddef..aa0b4df 100644 --- a/ui/platform_window/platform_window.h +++ b/ui/platform_window/platform_window.h
@@ -1,102 +1,27 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. +// 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_PLATFORM_WINDOW_PLATFORM_WINDOW_H_ #define UI_PLATFORM_WINDOW_PLATFORM_WINDOW_H_ -#include <memory> +#include "build/build_config.h" -#include "base/strings/string16.h" -#include "ui/base/class_property.h" -#include "ui/base/cursor/cursor.h" -#include "ui/base/ui_base_types.h" -#include "ui/gfx/native_widget_types.h" -#include "ui/platform_window/platform_window_delegate.h" - -namespace gfx { -class Point; -class Rect; -} // namespace gfx +// By default, PlatformWindowBase is used. However, different platforms +// should specify what window they would like to use if needed. +#if defined(OS_LINUX) +#include "ui/platform_window/platform_window_linux.h" +#else +#include "ui/platform_window/platform_window_base.h" +#endif namespace ui { -// Platform window. -// -// Each instance of PlatformWindow represents a single window in the -// underlying platform windowing system (i.e. X11/Win/OSX). -class PlatformWindow : public PropertyHandler { - public: - PlatformWindow(); - ~PlatformWindow() override; - - // PlatformWindow maybe called with the |inactive| set to true in some cases. - // That means that the Window Manager must not activate the window when it is - // shown. Most of PlatformWindow may ignore this value if not supported. - virtual void Show(bool inactive = false) = 0; - virtual void Hide() = 0; - virtual void Close() = 0; - - virtual bool IsVisible() const = 0; - - // Informs the window it is going to be destroyed sometime soon. This is only - // called for specific code paths, for example by Ash, so it shouldn't be - // assumed this will get called before destruction. - virtual void PrepareForShutdown() = 0; - - // Sets and gets the bounds of the platform-window. Note that the bounds is in - // physical pixel coordinates. - virtual void SetBounds(const gfx::Rect& bounds) = 0; - virtual gfx::Rect GetBounds() = 0; - - virtual void SetTitle(const base::string16& title) = 0; - - virtual void SetCapture() = 0; - virtual void ReleaseCapture() = 0; - virtual bool HasCapture() const = 0; - - virtual void ToggleFullscreen() = 0; - virtual void Maximize() = 0; - virtual void Minimize() = 0; - virtual void Restore() = 0; - virtual PlatformWindowState GetPlatformWindowState() const = 0; - - virtual void Activate() = 0; - virtual void Deactivate() = 0; - - // Sets whether the window should have the standard title bar provided by the - // underlying windowing system. For the main browser window, this may be - // changed by the user at any time via 'Show system title bar' option in the - // tab strip menu. - virtual void SetUseNativeFrame(bool use_native_frame) = 0; - - virtual void SetCursor(PlatformCursor cursor) = 0; - - // Moves the cursor to |location|. Location is in platform window coordinates. - virtual void MoveCursorTo(const gfx::Point& location) = 0; - - // Confines the cursor to |bounds| when it is in the platform window. |bounds| - // is in platform window coordinates. - virtual void ConfineCursorToBounds(const gfx::Rect& bounds) = 0; - - // Sets and gets the restored bounds of the platform-window. - virtual void SetRestoredBoundsInPixels(const gfx::Rect& bounds) = 0; - virtual gfx::Rect GetRestoredBoundsInPixels() const = 0; - - // Tells if the content of the platform window should be transparent. By - // default returns false. - virtual bool ShouldWindowContentsBeTransparent() const; - - // Sets and gets ZOrderLevel of the PlatformWindow. Such platforms that do not - // support ordering, should not implement these methods as the default - // implementation always returns ZOrderLevel::kNormal value. - virtual void SetZOrderLevel(ZOrderLevel order); - virtual ZOrderLevel GetZOrderLevel() const; - - // Asks the PlatformWindow to stack itself on top of |widget|. - virtual void StackAbove(gfx::AcceleratedWidget widget); - virtual void StackAtTop(); -}; +#if defined(OS_LINUX) +using PlatformWindow = PlatformWindowLinux; +#else +using PlatformWindow = PlatformWindowBase; +#endif } // namespace ui
diff --git a/ui/platform_window/platform_window_base.cc b/ui/platform_window/platform_window_base.cc new file mode 100644 index 0000000..23a4e70 --- /dev/null +++ b/ui/platform_window/platform_window_base.cc
@@ -0,0 +1,27 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/platform_window/platform_window_base.h" + +namespace ui { + +PlatformWindowBase::PlatformWindowBase() = default; + +PlatformWindowBase::~PlatformWindowBase() = default; + +bool PlatformWindowBase::ShouldWindowContentsBeTransparent() const { + return false; +} + +void PlatformWindowBase::SetZOrderLevel(ZOrderLevel order) {} + +ZOrderLevel PlatformWindowBase::GetZOrderLevel() const { + return ZOrderLevel::kNormal; +} + +void PlatformWindowBase::StackAbove(gfx::AcceleratedWidget widget) {} + +void PlatformWindowBase::StackAtTop() {} + +} // namespace ui
diff --git a/ui/platform_window/platform_window_base.h b/ui/platform_window/platform_window_base.h new file mode 100644 index 0000000..a19254d1 --- /dev/null +++ b/ui/platform_window/platform_window_base.h
@@ -0,0 +1,103 @@ +// Copyright 2014 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_PLATFORM_WINDOW_PLATFORM_WINDOW_BASE_H_ +#define UI_PLATFORM_WINDOW_PLATFORM_WINDOW_BASE_H_ + +#include <memory> + +#include "base/strings/string16.h" +#include "ui/base/class_property.h" +#include "ui/base/cursor/cursor.h" +#include "ui/base/ui_base_types.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/platform_window/platform_window_delegate.h" + +namespace gfx { +class Point; +class Rect; +} // namespace gfx + +namespace ui { + +// Platform window. +// +// Each instance of PlatformWindowBase represents a single window in the +// underlying platform windowing system (i.e. X11/Win/OSX). +class PlatformWindowBase : public PropertyHandler { + public: + PlatformWindowBase(); + ~PlatformWindowBase() override; + + // PlatformWindow may be called with the |inactive| set to true in some cases. + // That means that the Window Manager must not activate the window when it is + // shown. Most of PlatformWindow may ignore this value if not supported. + virtual void Show(bool inactive = false) = 0; + virtual void Hide() = 0; + virtual void Close() = 0; + + virtual bool IsVisible() const = 0; + + // Informs the window it is going to be destroyed sometime soon. This is only + // called for specific code paths, for example by Ash, so it shouldn't be + // assumed this will get called before destruction. + virtual void PrepareForShutdown() = 0; + + // Sets and gets the bounds of the platform-window. Note that the bounds is in + // physical pixel coordinates. + virtual void SetBounds(const gfx::Rect& bounds) = 0; + virtual gfx::Rect GetBounds() = 0; + + virtual void SetTitle(const base::string16& title) = 0; + + virtual void SetCapture() = 0; + virtual void ReleaseCapture() = 0; + virtual bool HasCapture() const = 0; + + virtual void ToggleFullscreen() = 0; + virtual void Maximize() = 0; + virtual void Minimize() = 0; + virtual void Restore() = 0; + virtual PlatformWindowState GetPlatformWindowState() const = 0; + + virtual void Activate() = 0; + virtual void Deactivate() = 0; + + // Sets whether the window should have the standard title bar provided by the + // underlying windowing system. For the main browser window, this may be + // changed by the user at any time via 'Show system title bar' option in the + // tab strip menu. + virtual void SetUseNativeFrame(bool use_native_frame) = 0; + + virtual void SetCursor(PlatformCursor cursor) = 0; + + // Moves the cursor to |location|. Location is in platform window coordinates. + virtual void MoveCursorTo(const gfx::Point& location) = 0; + + // Confines the cursor to |bounds| when it is in the platform window. |bounds| + // is in platform window coordinates. + virtual void ConfineCursorToBounds(const gfx::Rect& bounds) = 0; + + // Sets and gets the restored bounds of the platform-window. + virtual void SetRestoredBoundsInPixels(const gfx::Rect& bounds) = 0; + virtual gfx::Rect GetRestoredBoundsInPixels() const = 0; + + // Tells if the content of the platform window should be transparent. By + // default returns false. + virtual bool ShouldWindowContentsBeTransparent() const; + + // Sets and gets ZOrderLevel of the PlatformWindow. Such platforms that do not + // support ordering, should not implement these methods as the default + // implementation always returns ZOrderLevel::kNormal value. + virtual void SetZOrderLevel(ZOrderLevel order); + virtual ZOrderLevel GetZOrderLevel() const; + + // Asks the PlatformWindow to stack itself on top of |widget|. + virtual void StackAbove(gfx::AcceleratedWidget widget); + virtual void StackAtTop(); +}; + +} // namespace ui + +#endif // UI_PLATFORM_WINDOW_PLATFORM_WINDOW_BASE_H_
diff --git a/ui/platform_window/platform_window_handler/wm_drag_handler.h b/ui/platform_window/platform_window_handler/wm_drag_handler.h index 1fc3af3..2789c3e 100644 --- a/ui/platform_window/platform_window_handler/wm_drag_handler.h +++ b/ui/platform_window/platform_window_handler/wm_drag_handler.h
@@ -7,11 +7,11 @@ #include "base/bind.h" #include "ui/gfx/native_widget_types.h" +#include "ui/platform_window/platform_window.h" #include "ui/platform_window/platform_window_handler/wm_platform_export.h" namespace ui { class OSExchangeData; -class PlatformWindow; class WM_PLATFORM_EXPORT WmDragHandler { public:
diff --git a/ui/platform_window/platform_window_handler/wm_drop_handler.h b/ui/platform_window/platform_window_handler/wm_drop_handler.h index 768d9e3..fc7a81f 100644 --- a/ui/platform_window/platform_window_handler/wm_drop_handler.h +++ b/ui/platform_window/platform_window_handler/wm_drop_handler.h
@@ -8,6 +8,7 @@ #include <memory> #include "ui/gfx/native_widget_types.h" +#include "ui/platform_window/platform_window.h" #include "ui/platform_window/platform_window_handler/wm_platform_export.h" namespace gfx { @@ -16,7 +17,6 @@ namespace ui { class OSExchangeData; -class PlatformWindow; class WM_PLATFORM_EXPORT WmDropHandler { public:
diff --git a/ui/platform_window/platform_window_handler/wm_move_resize_handler.h b/ui/platform_window/platform_window_handler/wm_move_resize_handler.h index ac30160..3da718c 100644 --- a/ui/platform_window/platform_window_handler/wm_move_resize_handler.h +++ b/ui/platform_window/platform_window_handler/wm_move_resize_handler.h
@@ -5,6 +5,7 @@ #ifndef UI_PLATFORM_WINDOW_PLATFORM_WINDOW_HANDLER_WM_MOVE_RESIZE_HANDLER_H_ #define UI_PLATFORM_WINDOW_PLATFORM_WINDOW_HANDLER_WM_MOVE_RESIZE_HANDLER_H_ +#include "ui/platform_window/platform_window.h" #include "ui/platform_window/platform_window_handler/wm_platform_export.h" namespace gfx { @@ -13,8 +14,6 @@ namespace ui { -class PlatformWindow; - class WmMoveResizeHandler { public: // A system window manager starts interactive drag or resize of a window based
diff --git a/ui/platform_window/platform_window_linux.cc b/ui/platform_window/platform_window_linux.cc new file mode 100644 index 0000000..d3aabb5 --- /dev/null +++ b/ui/platform_window/platform_window_linux.cc
@@ -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. + +#include "ui/platform_window/platform_window_linux.h" + +namespace ui { + +PlatformWindowLinux::PlatformWindowLinux() = default; + +PlatformWindowLinux::~PlatformWindowLinux() = default; + +bool PlatformWindowLinux::IsSyncExtensionAvailable() const { + return false; +} + +void PlatformWindowLinux::OnCompleteSwapAfterResize() {} + +} // namespace ui
diff --git a/ui/platform_window/platform_window_linux.h b/ui/platform_window/platform_window_linux.h new file mode 100644 index 0000000..257a978 --- /dev/null +++ b/ui/platform_window/platform_window_linux.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_PLATFORM_WINDOW_PLATFORM_WINDOW_LINUX_H_ +#define UI_PLATFORM_WINDOW_PLATFORM_WINDOW_LINUX_H_ + +#include "ui/platform_window/platform_window_base.h" + +namespace ui { + +// Linux extensions to the PlatformWindowBase. +class PlatformWindowLinux : public PlatformWindowBase { + public: + PlatformWindowLinux(); + ~PlatformWindowLinux() override; + + // X11-specific. Returns whether an XSync extension is available at the + // current platform. + virtual bool IsSyncExtensionAvailable() const; + // X11-specific. Handles CompleteSwapAfterResize event coming from the + // compositor observer. + virtual void OnCompleteSwapAfterResize(); +}; + +} // namespace ui + +#endif // UI_PLATFORM_WINDOW_PLATFORM_WINDOW_LINUX_H_
diff --git a/ui/platform_window/x11/x11_window.cc b/ui/platform_window/x11/x11_window.cc index e8d926b..d3593f3 100644 --- a/ui/platform_window/x11/x11_window.cc +++ b/ui/platform_window/x11/x11_window.cc
@@ -279,6 +279,14 @@ XWindow::Deactivate(); } +bool X11Window::IsSyncExtensionAvailable() const { + return ui::IsSyncExtensionAvailable(); +} + +void X11Window::OnCompleteSwapAfterResize() { + XWindow::NotifySwapAfterResize(); +} + void X11Window::SetUseNativeFrame(bool use_native_frame) { XWindow::SetUseNativeFrame(use_native_frame); }
diff --git a/ui/platform_window/x11/x11_window.h b/ui/platform_window/x11/x11_window.h index 8effaaf..8f62267 100644 --- a/ui/platform_window/x11/x11_window.h +++ b/ui/platform_window/x11/x11_window.h
@@ -64,6 +64,8 @@ PlatformWindowState GetPlatformWindowState() const override; void Activate() override; void Deactivate() override; + bool IsSyncExtensionAvailable() const override; + void OnCompleteSwapAfterResize() override; void SetUseNativeFrame(bool use_native_frame) override; void SetCursor(PlatformCursor cursor) override; void MoveCursorTo(const gfx::Point& location) override;
diff --git a/ui/views/controls/table/table_view.cc b/ui/views/controls/table/table_view.cc index f8e19ec9..3cbd1965 100644 --- a/ui/views/controls/table/table_view.cc +++ b/ui/views/controls/table/table_view.cc
@@ -298,17 +298,15 @@ if (GetHasFocusIndicator()) { // Draw a focus indicator around the active column. - focus_ring_ = FocusRing::Install(this); const gfx::Rect cell_bounds(GetCellBounds( ModelToView(selection_model_.active()), active_visible_column_index_)); auto path = std::make_unique<SkPath>(); path->addRect(gfx::RectToSkRect(cell_bounds)); SetProperty(views::kHighlightPathKey, path.release()); - focus_ring_->SchedulePaint(); } else { ClearProperty(views::kHighlightPathKey); - focus_ring_.reset(); } + focus_ring_->SchedulePaint(); } const TableView::VisibleColumn& TableView::GetVisibleColumn(int index) { @@ -404,8 +402,7 @@ gfx::Size(width, header_->GetPreferredSize().height()))); } - if (focus_ring_) - focus_ring_->Layout(); + focus_ring_->Layout(); } gfx::Size TableView::CalculatePreferredSize() const { @@ -822,19 +819,12 @@ } void TableView::OnFocus() { - ScrollView* scroll_view = ScrollView::GetScrollViewForContents(this); - if (scroll_view) - scroll_view->SetHasFocusIndicator(true); - SchedulePaintForSelection(); ResetFocusIndicator(); UpdateAccessibilityFocus(); } void TableView::OnBlur() { - ScrollView* scroll_view = ScrollView::GetScrollViewForContents(this); - if (scroll_view) - scroll_view->SetHasFocusIndicator(false); SchedulePaintForSelection(); ResetFocusIndicator(); UpdateAccessibilityFocus();
diff --git a/ui/views/controls/table/table_view.h b/ui/views/controls/table/table_view.h index 835b6db..fa19a25 100644 --- a/ui/views/controls/table/table_view.h +++ b/ui/views/controls/table/table_view.h
@@ -369,7 +369,7 @@ int active_visible_column_index_ = -1; // Used to draw a focus indicator around the active cell. - std::unique_ptr<FocusRing> focus_ring_; + std::unique_ptr<FocusRing> focus_ring_ = FocusRing::Install(this); // The header. This is only created if more than one column is specified or // the first column has a non-empty title.
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc index cea50c2..d5799a1 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc
@@ -15,6 +15,42 @@ namespace views { +namespace { + +class SwapWithNewSizeObserverHelper : public ui::CompositorObserver { + public: + using HelperCallback = base::RepeatingCallback<void(const gfx::Size&)>; + SwapWithNewSizeObserverHelper(ui::Compositor* compositor, + const HelperCallback& callback) + : compositor_(compositor), callback_(callback) { + compositor_->AddObserver(this); + } + ~SwapWithNewSizeObserverHelper() override { + if (compositor_) + compositor_->RemoveObserver(this); + } + + private: + // ui::CompositorObserver: + void OnCompositingCompleteSwapWithNewSize(ui::Compositor* compositor, + const gfx::Size& size) override { + DCHECK_EQ(compositor, compositor_); + callback_.Run(size); + } + void OnCompositingShuttingDown(ui::Compositor* compositor) override { + DCHECK_EQ(compositor, compositor_); + compositor_->RemoveObserver(this); + compositor_ = nullptr; + } + + ui::Compositor* compositor_; + const HelperCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(SwapWithNewSizeObserverHelper); +}; + +} // namespace + DesktopWindowTreeHostLinux::DesktopWindowTreeHostLinux( internal::NativeWidgetDelegate* native_widget_delegate, DesktopNativeWidgetAura* desktop_native_widget_aura) @@ -33,6 +69,18 @@ DesktopWindowTreeHostPlatform::OnNativeWidgetCreated(params); } +void DesktopWindowTreeHostLinux::Init(const Widget::InitParams& params) { + DesktopWindowTreeHostPlatform::Init(params); + + if (platform_window()->IsSyncExtensionAvailable()) { + compositor_observer_ = std::make_unique<SwapWithNewSizeObserverHelper>( + compositor(), + base::BindRepeating( + &DesktopWindowTreeHostLinux::OnCompleteSwapWithNewSize, + base::Unretained(this))); + } +} + void DesktopWindowTreeHostLinux::OnDisplayMetricsChanged( const display::Display& display, uint32_t changed_metrics) { @@ -91,6 +139,11 @@ properties->x_visual_id = pending_x_visual_id_; } +void DesktopWindowTreeHostLinux::OnCompleteSwapWithNewSize( + const gfx::Size& size) { + platform_window()->OnCompleteSwapAfterResize(); +} + void DesktopWindowTreeHostLinux::AddNonClientEventFilter() { DCHECK(!non_client_window_event_filter_); non_client_window_event_filter_ = std::make_unique<WindowEventFilterLinux>(
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h index daa7aa5..69e3d36 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h
@@ -33,6 +33,9 @@ // PlatformWindowDelegateBase: void OnClosed() override; + // DesktopWindowTreeHostPlatform: + void Init(const Widget::InitParams& params) override; + private: FRIEND_TEST_ALL_PREFIXES(DesktopWindowTreeHostLinuxTest, HitTest); @@ -45,6 +48,9 @@ const Widget::InitParams& params, ui::PlatformWindowInitProperties* properties) override; + // Called back by compositor_observer_ if the latter is set. + virtual void OnCompleteSwapWithNewSize(const gfx::Size& size); + void AddNonClientEventFilter(); void RemoveNonClientEventFilter(); @@ -56,6 +62,8 @@ // initialization of the host. base::Optional<int> pending_x_visual_id_; + std::unique_ptr<CompositorObserver> compositor_observer_; + DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostLinux); };
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc index f1295c8..486e49e 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -81,38 +81,6 @@ namespace { -class SwapWithNewSizeObserverHelper : public ui::CompositorObserver { - public: - using HelperCallback = base::RepeatingCallback<void(const gfx::Size&)>; - SwapWithNewSizeObserverHelper(ui::Compositor* compositor, - const HelperCallback& callback) - : compositor_(compositor), callback_(callback) { - compositor_->AddObserver(this); - } - ~SwapWithNewSizeObserverHelper() override { - if (compositor_) - compositor_->RemoveObserver(this); - } - - private: - // ui::CompositorObserver: - void OnCompositingCompleteSwapWithNewSize(ui::Compositor* compositor, - const gfx::Size& size) override { - DCHECK_EQ(compositor, compositor_); - callback_.Run(size); - } - void OnCompositingShuttingDown(ui::Compositor* compositor) override { - DCHECK_EQ(compositor, compositor_); - compositor_->RemoveObserver(this); - compositor_ = nullptr; - } - - ui::Compositor* compositor_; - const HelperCallback callback_; - - DISALLOW_COPY_AND_ASSIGN(SwapWithNewSizeObserverHelper); -}; - bool ShouldDiscardKeyEvent(XEvent* xev) { #if BUILDFLAG(USE_ATK) return ui::AtkUtilAuraLinux::HandleKeyEvent(xev) == @@ -203,7 +171,7 @@ // DesktopWindowTreeHostX11, DesktopWindowTreeHost implementation: void DesktopWindowTreeHostX11::Init(const Widget::InitParams& params) { - DesktopWindowTreeHostPlatform::Init(params); + DesktopWindowTreeHostLinux::Init(params); // Set XEventDelegate to receive selection, drag&drop and raw key events. // @@ -212,15 +180,6 @@ // unified so that DragAndrDropClientOzone is used and XEvent are handled on // platform level. static_cast<ui::X11Window*>(platform_window())->SetXEventDelegate(this); - - // Can it be unified and will Ozone benefit from this? Check comment above - // where this class is defined and declared. - if (ui::IsSyncExtensionAvailable()) { - compositor_observer_ = std::make_unique<SwapWithNewSizeObserverHelper>( - compositor(), base::BindRepeating( - &DesktopWindowTreeHostX11::OnCompleteSwapWithNewSize, - base::Unretained(this))); - } } void DesktopWindowTreeHostX11::OnNativeWidgetCreated(
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h index cc1dd17..bef3c948 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
@@ -156,7 +156,7 @@ void EnableEventListening(); // Callback for a swapbuffer after resize. - void OnCompleteSwapWithNewSize(const gfx::Size& size); + void OnCompleteSwapWithNewSize(const gfx::Size& size) override; // PlatformWindowDelegate overrides: // @@ -206,8 +206,6 @@ uint32_t modal_dialog_counter_ = 0; - std::unique_ptr<CompositorObserver> compositor_observer_; - // The display and the native X window hosting the root window. base::WeakPtrFactory<DesktopWindowTreeHostX11> weak_factory_{this};