diff --git a/DEPS b/DEPS index c9e1757..69cfddf1 100644 --- a/DEPS +++ b/DEPS
@@ -133,11 +133,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': '673c538f8d74ff5a2ac8f81ed3f6364253c04f7a', + 'skia_revision': '93b94512391327fb74b07d162aac8f1f677375f4', # 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': 'f7cc35d707c060d94ce8d3ef4855055752ceea42', + 'v8_revision': 'e51a5299c81b118cfb084568b1f5241af4d96c54', # 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. @@ -145,11 +145,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': '4e87659e289c37602e3c94264e7302fe7a8dfaa7', + 'angle_revision': '494afea985e678cbefb3de80a816f3f54762bea6', # 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': '25ec7b0cd393f08c41f35fbf86c65d7828759b8c', + 'swiftshader_revision': '6480d4e10cb57f36baa2b03f8eb40b8d04f0e39f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -196,7 +196,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '293a9a2e27bad0075e68b614c14efa79d0818c1a', + 'catapult_revision': '2afe880da0ce34181cbfbc2d95550aa6e589537a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -248,7 +248,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': '9d29c37ac507a67272da548d85e90fac4befecc1', + 'spv_tools_revision': '6df8a917a4496f1a46e8ae21ffa3d00075380e47', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -760,7 +760,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '6b83d6b9933549a371076c6b5a439453a847d168', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'ede69d84cfc7290b7f44a4bccb566c70f6839808', 'condition': 'checkout_linux', }, @@ -785,7 +785,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '8b94108e684872a89f7108f51ba74f01220d64fa', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'deb384f985d00de73ee29a65760b826f08a60983', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1298,7 +1298,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a0f51b2e123f39c9ff12e621b0b47dd28dd64424', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '208634763a17606672e6bc3ecad01387bff9deea', + Var('webrtc_git') + '/src.git' + '@' + 'cc3503248f1dc7edd3ab505b5194c69718d0f711', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1339,7 +1339,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@62079cb0286869f82f886f9fa45873ce26796633', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@a94bdfdb451cfc9d285f7c89c1e96c4fdb554338', 'condition': 'checkout_src_internal', },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 8943046..119dfe65 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -208,9 +208,6 @@ _BANNED_CPP_FUNCTIONS = ( - # Make sure that gtest's FRIEND_TEST() macro is not used; the - # FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be - # used instead since that allows for FLAKY_ and DISABLED_ prefixes. ( r'\bNULL\b', ( @@ -219,6 +216,9 @@ True, (), ), + # Make sure that gtest's FRIEND_TEST() macro is not used; the + # FRIEND_TEST_ALL_PREFIXES() macro from base/gtest_prod_util.h should be + # used instead since that allows for FLAKY_ and DISABLED_ prefixes. ( 'FRIEND_TEST(', ( @@ -591,6 +591,17 @@ True, (), ), + ( + 'DEFINE_TYPE_CASTS', + ( + 'DEFINE_TYPE_CASTS is deprecated. Instead, use downcast helpers from ', + '//third_party/blink/renderer/platform/casting.h.' + ), + True, + ( + r'^third_party/blink/renderer/.*\.(cc|h)$', + ), + ), )
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index ccad462..e7c16ac 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -946,7 +946,7 @@ "//device/gamepad:java", "//net/android:net_java", "//services/network/public/mojom:mojom_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/blink/public:blink_headers_java", "//ui/android:ui_java", ] @@ -1047,7 +1047,7 @@ deps = [ "//base:base_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] # The appropriate .class file will be loaded via a dependency to a library
diff --git a/android_webview/browser/gfx/surfaces_instance.cc b/android_webview/browser/gfx/surfaces_instance.cc index f04202a..ec79f72a 100644 --- a/android_webview/browser/gfx/surfaces_instance.cc +++ b/android_webview/browser/gfx/surfaces_instance.cc
@@ -264,8 +264,9 @@ render_pass->SetNew(1, rect, rect, gfx::Transform()); viz::SharedQuadState* quad_state = render_pass->CreateAndAppendSharedQuadState(); - quad_state->SetAll(gfx::Transform(), rect, rect, rect, is_clipped, - are_contents_opaque, 1.f, SkBlendMode::kSrcOver, 0); + quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, + is_clipped, are_contents_opaque, 1.f, + SkBlendMode::kSrcOver, 0); viz::SolidColorDrawQuad* solid_quad = render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>(); solid_quad->SetNew(quad_state, rect, rect, SK_ColorBLACK, false);
diff --git a/android_webview/tools/automated_ui_tests/BUILD.gn b/android_webview/tools/automated_ui_tests/BUILD.gn index f40cc0de..8a84ad7 100644 --- a/android_webview/tools/automated_ui_tests/BUILD.gn +++ b/android_webview/tools/automated_ui_tests/BUILD.gn
@@ -57,7 +57,7 @@ ":webview_ui_test_app_java", "//base:base_java", "//base:base_java_test_support", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/android_tools:android_test_base_java",
diff --git a/android_webview/tools/cts_config/webview_cts_gcs_path.json b/android_webview/tools/cts_config/webview_cts_gcs_path.json index 5cc30cf..3c183ba 100644 --- a/android_webview/tools/cts_config/webview_cts_gcs_path.json +++ b/android_webview/tools/cts_config/webview_cts_gcs_path.json
@@ -213,10 +213,6 @@ { "match": "android.webkit.cts.WebViewSslTest#testSecureServerRequiringClientCertDoesCancelRequest", "_bug_id": "crbug.com/922400" - }, - { - "match": "android.webkit.cts.WebViewTest#testLoadDataWithBaseUrl", - "_bug_id": "crbug.com/900915" } ] }, @@ -248,10 +244,6 @@ { "match": "android.webkit.cts.WebViewSslTest#testSecureServerRequiringClientCertDoesCancelRequest", "_bug_id": "crbug.com/922400" - }, - { - "match": "android.webkit.cts.WebViewTest#testLoadDataWithBaseUrl", - "_bug_id": "crbug.com/900915" } ] },
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index fd65797..09e42768 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -454,6 +454,8 @@ "metrics/demo_session_metrics_recorder.h", "metrics/desktop_task_switch_metric_recorder.cc", "metrics/desktop_task_switch_metric_recorder.h", + "metrics/histogram_macros.cc", + "metrics/histogram_macros.h", "metrics/login_metrics_recorder.cc", "metrics/login_metrics_recorder.h", "metrics/pip_uma.h", @@ -1666,6 +1668,7 @@ "media/media_notification_view_unittest.cc", "metrics/demo_session_metrics_recorder_unittest.cc", "metrics/desktop_task_switch_metric_recorder_unittest.cc", + "metrics/histogram_macros_unittest.cc", "metrics/login_metrics_recorder_unittest.cc", "metrics/pointer_metrics_recorder_unittest.cc", "metrics/task_switch_metrics_recorder_unittest.cc",
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc index 68953804..3cc430544 100644 --- a/ash/app_list/app_list_controller_impl.cc +++ b/ash/app_list/app_list_controller_impl.cc
@@ -8,6 +8,7 @@ #include <vector> #include "ash/app_list/app_list_controller_observer.h" +#include "ash/app_list/app_list_metrics.h" #include "ash/app_list/app_list_presenter_delegate_impl.h" #include "ash/app_list/model/app_list_folder_item.h" #include "ash/app_list/model/app_list_item.h" @@ -916,6 +917,10 @@ client_->LogSearchClick(result_id, suggestion_index, launched_from); } +void AppListControllerImpl::LogSearchAbandonHistogram() { + app_list::RecordSearchAbandonWithQueryLengthHistogram(GetLastQueryLength()); +} + void AppListControllerImpl::InvokeSearchResultAction( const std::string& result_id, int action_index, @@ -952,6 +957,9 @@ } void AppListControllerImpl::ViewClosing() { + if (presenter_.GetView()->search_box_view()->is_search_box_active()) + LogSearchAbandonHistogram(); + CloseAssistantUi(AssistantExitPoint::kLauncherClose); if (client_) client_->ViewClosing(); @@ -1235,4 +1243,8 @@ } } +int AppListControllerImpl::GetLastQueryLength() { + return search_model_.search_box()->text().length(); +} + } // namespace ash
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h index 84f9817..26176cb 100644 --- a/ash/app_list/app_list_controller_impl.h +++ b/ash/app_list/app_list_controller_impl.h
@@ -169,6 +169,7 @@ void LogResultLaunchHistogram( app_list::SearchResultLaunchLocation launch_location, int suggestion_index) override; + void LogSearchAbandonHistogram() override; void InvokeSearchResultAction(const std::string& result_id, int action_index, int event_flags) override; @@ -313,6 +314,9 @@ // Updates which container the launcher window should be in. void UpdateLauncherContainer(); +// Returns the length of the most recent query. + int GetLastQueryLength(); + base::string16 last_raw_query_; mojom::AppListClientPtr client_;
diff --git a/ash/app_list/app_list_metrics.cc b/ash/app_list/app_list_metrics.cc index 57a1e07..5be6692 100644 --- a/ash/app_list/app_list_metrics.cc +++ b/ash/app_list/app_list_metrics.cc
@@ -63,6 +63,12 @@ constexpr char kAppListZeroStateSearchResultRemovalHistogram[] = "Apps.ZeroStateSearchResutRemovalDecision"; +// The UMA histogram that logs the length of the query when user abandons +// results of a queried search or recommendations of zero state(zero length +// query) in launcher UI. +constexpr char kSearchAbandonQueryLengthHistogram[] = + "Apps.AppListSearchAbandonQueryLength"; + // The different sources from which a search result is displayed. These values // are written to logs. New enum values can be added, but existing enums must // never be renumbered or deleted and reused. @@ -135,6 +141,12 @@ } } +void RecordSearchAbandonWithQueryLengthHistogram(int query_length) { + UMA_HISTOGRAM_EXACT_LINEAR(kSearchAbandonQueryLengthHistogram, + std::min(query_length, kMaxLoggedQueryLength), + kMaxLoggedQueryLength); +} + void RecordZeroStateSearchResultUserActionHistogram( ZeroStateSearchResultUserActionType action) { UMA_HISTOGRAM_ENUMERATION(kAppListZeroStateSearchResultUserActionHistogram,
diff --git a/ash/app_list/app_list_metrics.h b/ash/app_list/app_list_metrics.h index 6bb5ad9e7..b2e65144 100644 --- a/ash/app_list/app_list_metrics.h +++ b/ash/app_list/app_list_metrics.h
@@ -221,6 +221,9 @@ void RecordZeroStateSearchResultRemovalHistogram( ZeroStateSearchResutRemovalConfirmation removal_decision); +APP_LIST_EXPORT void RecordSearchAbandonWithQueryLengthHistogram( + int query_length); + APP_LIST_EXPORT void RecordSearchResultOpenSource( const SearchResult* result, const AppListModel* model,
diff --git a/ash/app_list/app_list_view_delegate.h b/ash/app_list/app_list_view_delegate.h index 22f8737..30cb00c 100644 --- a/ash/app_list/app_list_view_delegate.h +++ b/ash/app_list/app_list_view_delegate.h
@@ -72,6 +72,9 @@ app_list::SearchResultLaunchLocation launch_location, int suggestion_index) = 0; + // Logs the UMA histogram metrics for user's abandonment of launcher search. + virtual void LogSearchAbandonHistogram() = 0; + // Called to invoke a custom action on a result with |result_id|. // |action_index| corresponds to the index of an icon in // |result.action_icons()|.
diff --git a/ash/app_list/test/app_list_test_view_delegate.h b/ash/app_list/test/app_list_test_view_delegate.h index 43527ec3..6ee59a7 100644 --- a/ash/app_list/test/app_list_test_view_delegate.h +++ b/ash/app_list/test/app_list_test_view_delegate.h
@@ -66,6 +66,7 @@ void LogResultLaunchHistogram( app_list::SearchResultLaunchLocation launch_location, int suggestion_index) override {} + void LogSearchAbandonHistogram() override {} void InvokeSearchResultAction(const std::string& result_id, int action_index, int event_flags) override {}
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc index 860684b..6a59675 100644 --- a/ash/app_list/views/app_list_view.cc +++ b/ash/app_list/views/app_list_view.cc
@@ -739,8 +739,7 @@ if (app_list_main_view()->contents_view()->IsShowingEmbeddedAssistantUI()) Back(); - search_box_view_->ClearSearch(); - search_box_view_->SetSearchBoxActive(false, ui::ET_UNKNOWN); + search_box_view_->ClearSearchAndDeactivateSearchBox(); } void AppListView::StartDrag(const gfx::Point& location) {
diff --git a/ash/app_list/views/contents_view.cc b/ash/app_list/views/contents_view.cc index d432f1e..ca035652 100644 --- a/ash/app_list/views/contents_view.cc +++ b/ash/app_list/views/contents_view.cc
@@ -508,8 +508,7 @@ break; } case ash::AppListState::kStateSearchResults: - GetSearchBoxView()->ClearSearch(); - GetSearchBoxView()->SetSearchBoxActive(false, ui::ET_UNKNOWN); + GetSearchBoxView()->ClearSearchAndDeactivateSearchBox(); ShowSearchResults(false); break; case ash::AppListState::kStateEmbeddedAssistant:
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index a8a8697..85c82a0 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -540,6 +540,16 @@ ContentsChanged(search_box(), new_query); } +void SearchBoxView::ClearSearchAndDeactivateSearchBox() { + if (!is_search_box_active()) + return; + + view_delegate_->LogSearchAbandonHistogram(); + + ClearSearch(); + SetSearchBoxActive(false, ui::ET_UNKNOWN); +} + bool SearchBoxView::HandleKeyEvent(views::Textfield* sender, const ui::KeyEvent& key_event) { if (key_event.type() == ui::ET_KEY_PRESSED && @@ -661,6 +671,7 @@ void SearchBoxView::ButtonPressed(views::Button* sender, const ui::Event& event) { if (close_button() && sender == close_button()) { + view_delegate_->LogSearchAbandonHistogram(); SetSearchBoxActive(false, ui::ET_UNKNOWN); } search_box::SearchBoxViewBase::ButtonPressed(sender, event);
diff --git a/ash/app_list/views/search_box_view.h b/ash/app_list/views/search_box_view.h index 10178eb..9c5576e 100644 --- a/ash/app_list/views/search_box_view.h +++ b/ash/app_list/views/search_box_view.h
@@ -95,6 +95,9 @@ // Updates the search box with |new_query| and starts a new search. void UpdateQuery(const base::string16& new_query); + // Clears the search query and de-activate the search box. + void ClearSearchAndDeactivateSearchBox(); + void set_contents_view(ContentsView* contents_view) { contents_view_ = contents_view; }
diff --git a/ash/components/fast_ink/fast_ink_view.cc b/ash/components/fast_ink/fast_ink_view.cc index 6b2a7a4..884707d 100644 --- a/ash/components/fast_ink/fast_ink_view.cc +++ b/ash/components/fast_ink/fast_ink_view.cc
@@ -467,6 +467,7 @@ buffer_to_target_transform, /*quad_layer_rect=*/output_rect, /*visible_quad_layer_rect=*/output_rect, + /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/gfx::Rect(), /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1.f, /*blend_mode=*/SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
diff --git a/ash/metrics/histogram_macros.cc b/ash/metrics/histogram_macros.cc new file mode 100644 index 0000000..bc7c795 --- /dev/null +++ b/ash/metrics/histogram_macros.cc
@@ -0,0 +1,17 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/metrics/histogram_macros.h" +#include "ash/shell.h" +#include "ash/wm/tablet_mode/tablet_mode_controller.h" + +namespace ash { + +bool IsInTabletMode() { + auto* shell = Shell::Get(); + return shell && shell->tablet_mode_controller() && + shell->tablet_mode_controller()->IsTabletModeWindowManagerEnabled(); +} + +} // namespace ash
diff --git a/ash/metrics/histogram_macros.h b/ash/metrics/histogram_macros.h new file mode 100644 index 0000000..7d1b616 --- /dev/null +++ b/ash/metrics/histogram_macros.h
@@ -0,0 +1,34 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_METRICS_HISTOGRAM_MACROS_H_ +#define ASH_METRICS_HISTOGRAM_MACROS_H_ + +#include "ash/ash_export.h" +#include "base/metrics/histogram_macros.h" + +// Use these instead of UMA_HISTOGRAM_PERCENTAGE if these histogram needs to be +// recorded separately in tablet/clamshell mode. +// TODO(oshima): Create a macro which record both that works with presubmit. +// crbug.com/923159. + +#define UMA_HISTOGRAM_PERCENTAGE_IN_TABLET(name, ...) \ + do { \ + if (ash::IsInTabletMode()) \ + UMA_HISTOGRAM_PERCENTAGE(name, __VA_ARGS__); \ + } while (0) + +#define UMA_HISTOGRAM_PERCENTAGE_IN_CLAMSHELL(name, ...) \ + do { \ + if (!ash::IsInTabletMode()) \ + UMA_HISTOGRAM_PERCENTAGE(name, __VA_ARGS__); \ + } while (0) + +namespace ash { + +ASH_EXPORT bool IsInTabletMode(); + +} // namespace ash + +#endif // ASH_METRICS_HISTOGRAM_MACROS_H_
diff --git a/ash/metrics/histogram_macros_unittest.cc b/ash/metrics/histogram_macros_unittest.cc new file mode 100644 index 0000000..4d99c9b --- /dev/null +++ b/ash/metrics/histogram_macros_unittest.cc
@@ -0,0 +1,35 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/metrics/histogram_macros.h" + +#include "ash/test/ash_test_base.h" +#include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h" +#include "base/test/metrics/histogram_tester.h" + +namespace ash { + +using HistogramMacrosTest = AshTestBase; + +TEST_F(HistogramMacrosTest, Basic) { + base::HistogramTester histograms; + const char* kTablet = "Test.Tablet"; + const char* kClamshell = "Test.Clamshell"; + + UMA_HISTOGRAM_PERCENTAGE_IN_TABLET(kTablet, 1); + UMA_HISTOGRAM_PERCENTAGE_IN_CLAMSHELL(kClamshell, 1); + + histograms.ExpectTotalCount(kClamshell, 1); + histograms.ExpectTotalCount(kTablet, 0); + + TabletModeControllerTestApi().EnterTabletMode(); + + UMA_HISTOGRAM_PERCENTAGE_IN_TABLET(kTablet, 1); + UMA_HISTOGRAM_PERCENTAGE_IN_CLAMSHELL(kClamshell, 1); + + histograms.ExpectTotalCount(kClamshell, 1); + histograms.ExpectTotalCount(kTablet, 1); +} + +} // namespace ash
diff --git a/ash/wm/overview/scoped_overview_animation_settings.cc b/ash/wm/overview/scoped_overview_animation_settings.cc index 9bb3ea34..f3eb9f07 100644 --- a/ash/wm/overview/scoped_overview_animation_settings.cc +++ b/ash/wm/overview/scoped_overview_animation_settings.cc
@@ -4,6 +4,7 @@ #include "ash/wm/overview/scoped_overview_animation_settings.h" +#include "ash/metrics/histogram_macros.h" #include "base/lazy_instance.h" #include "base/metrics/histogram_macros.h" #include "base/time/time.h" @@ -96,6 +97,10 @@ void Report(int value) override { UMA_HISTOGRAM_PERCENTAGE("Ash.WindowSelector.AnimationSmoothness.Enter", value); + UMA_HISTOGRAM_PERCENTAGE_IN_CLAMSHELL( + "Ash.Overview.AnimationSmoothness.Enter.Clamshell", value); + UMA_HISTOGRAM_PERCENTAGE_IN_TABLET( + "Ash.Overview.AnimationSmoothness.Enter.Tablet", value); } private: @@ -110,6 +115,10 @@ void Report(int value) override { UMA_HISTOGRAM_PERCENTAGE("Ash.WindowSelector.AnimationSmoothness.Exit", value); + UMA_HISTOGRAM_PERCENTAGE_IN_CLAMSHELL( + "Ash.Overview.AnimationSmoothness.Exit.Clamshell", value); + UMA_HISTOGRAM_PERCENTAGE_IN_TABLET( + "Ash.Overview.AnimationSmoothness.Exit.Table", value); } private: @@ -124,6 +133,10 @@ void Report(int value) override { UMA_HISTOGRAM_PERCENTAGE("Ash.WindowSelector.AnimationSmoothness.Close", value); + UMA_HISTOGRAM_PERCENTAGE_IN_CLAMSHELL( + "Ash.Overview.AnimationSmoothness.Close.ClamshellMode", value); + UMA_HISTOGRAM_PERCENTAGE_IN_TABLET( + "Ash.Overview.AnimationSmoothness.Close.TabletMode", value); } private:
diff --git a/ash/ws/window_service_delegate_impl_unittest.cc b/ash/ws/window_service_delegate_impl_unittest.cc index 6c06e1b..398cabf 100644 --- a/ash/ws/window_service_delegate_impl_unittest.cc +++ b/ash/ws/window_service_delegate_impl_unittest.cc
@@ -241,6 +241,27 @@ GetEventGenerator()->ReleaseLeftButton(); } +TEST_F(WindowServiceDelegateImplTest, NestedWindowMoveIsNotAllowed) { + GetWindowTreeTestHelper()->window_tree()->PerformWindowMove( + 21, GetTopLevelWindowId(), ws::mojom::MoveLoopSource::MOUSE, gfx::Point(), + HTCAPTION); + EXPECT_TRUE(event_handler()->is_drag_in_progress()); + GetWindowTreeClientChanges()->clear(); + + // Intentionally invokes PerformWindowMove to make sure it does not break + // anything. + GetWindowTreeTestHelper()->window_tree()->PerformWindowMove( + 22, GetTopLevelWindowId(), ws::mojom::MoveLoopSource::TOUCH, gfx::Point(), + HTCAPTION); + EXPECT_TRUE(ContainsChange(*GetWindowTreeClientChanges(), + "ChangeCompleted id=22 success=false")); + + GetWindowTreeClientChanges()->clear(); + GetEventGenerator()->ReleaseLeftButton(); + EXPECT_TRUE(ContainsChange(*GetWindowTreeClientChanges(), + "ChangeCompleted id=21 success=true")); +} + TEST_F(WindowServiceDelegateImplTest, SetWindowResizeShadow) { ResizeShadowController* controller = Shell::Get()->resize_shadow_controller();
diff --git a/base/BUILD.gn b/base/BUILD.gn index a9a84ad..a2b1e0a 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -2992,9 +2992,9 @@ deps = [ ":jni_java", - "//third_party/android_deps:android_support_annotations_java", - "//third_party/android_deps:android_support_multidex_java", "//third_party/android_deps:android_support_v4_java", + "//third_party/android_deps:com_android_support_multidex_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/jsr-305:jsr_305_javalib", ] @@ -3166,8 +3166,8 @@ ":base_java", ":jni_java", "//testing/android/reporter:reporter_java", - "//third_party/android_deps:android_support_annotations_java", - "//third_party/android_deps:android_support_compat_java", + "//third_party/android_deps:com_android_support_support_annotations_java", + "//third_party/android_deps:com_android_support_support_compat_java", "//third_party/android_support_test_runner:exposed_instrumentation_api_publish_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java",
diff --git a/base/test/BUILD.gn b/base/test/BUILD.gn index e334ed0..7887a60 100644 --- a/base/test/BUILD.gn +++ b/base/test/BUILD.gn
@@ -462,7 +462,7 @@ "//base:base_java", "//base:base_java_test_support", "//testing/android/native_test:native_main_runner_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/jsr-305:jsr_305_javalib", ] srcjar_deps = [ ":test_support_java_aidl" ]
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc index ec0db871..c2ef945 100644 --- a/base/test/test_suite.cc +++ b/base/test/test_suite.cc
@@ -68,6 +68,10 @@ #include "base/test/fontconfig_util_linux.h" #endif +#if defined(OS_FUCHSIA) +#include "base/base_paths_fuchsia.h" +#endif + namespace base { namespace { @@ -151,12 +155,25 @@ #if defined(OS_ANDROID) InitAndroidTestLogging(); #else + + FilePath log_filename; FilePath exe; PathService::Get(FILE_EXE, &exe); - FilePath log_filename = exe.ReplaceExtension(FILE_PATH_LITERAL("log")); + +#if defined(OS_FUCHSIA) + // Write logfiles to /data, because the default log location alongside the + // executable (/pkg) is read-only. + FilePath data_dir; + PathService::Get(DIR_APP_DATA, &data_dir); + log_filename = data_dir.Append(exe.BaseName()) + .ReplaceExtension(FILE_PATH_LITERAL("log")); +#else + log_filename = exe.ReplaceExtension(FILE_PATH_LITERAL("log")); +#endif // defined(OS_FUCHSIA) + logging::LoggingSettings settings; - settings.logging_dest = logging::LOG_TO_ALL; settings.log_file = log_filename.value().c_str(); + settings.logging_dest = logging::LOG_TO_ALL; settings.delete_old = logging::DELETE_OLD_LOG_FILE; logging::InitLogging(settings); // We want process and thread IDs because we may have multiple processes.
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h index 25f35a53..b9904c8 100644 --- a/base/threading/thread_restrictions.h +++ b/base/threading/thread_restrictions.h
@@ -139,6 +139,9 @@ class DWriteFontLookupTableBuilder; class GpuProcessTransportFactory; class NestedMessagePumpAndroid; +class RTCVideoDecoder; +class RTCVideoDecoderAdapter; +class RTCVideoEncoder; class SandboxHostLinux; class ScopedAllowWaitForDebugURL; class ServiceWorkerContextClient; @@ -441,6 +444,9 @@ friend class base::ScopedAllowThreadRecallForStackSamplingProfiler; friend class base::StackSamplingProfiler; friend class content::DesktopCaptureDevice; + friend class content::RTCVideoDecoder; + friend class content::RTCVideoDecoderAdapter; + friend class content::RTCVideoEncoder; friend class content::SandboxHostLinux; friend class content::ScopedAllowWaitForDebugURL; friend class content::SynchronousCompositor;
diff --git a/base/win/windows_version.cc b/base/win/windows_version.cc index 8f2b2da..b7e30da0 100644 --- a/base/win/windows_version.cc +++ b/base/win/windows_version.cc
@@ -57,9 +57,12 @@ } const _SYSTEM_INFO& GetSystemInfoStorage() { - static _SYSTEM_INFO system_info = {}; - ::GetNativeSystemInfo(&system_info); - return system_info; + static const NoDestructor<_SYSTEM_INFO> system_info([] { + _SYSTEM_INFO info = {}; + ::GetNativeSystemInfo(&info); + return info; + }()); + return *system_info; } } // namespace
diff --git a/cc/PRESUBMIT.py b/cc/PRESUBMIT.py index 89f5675..0b6761a2 100644 --- a/cc/PRESUBMIT.py +++ b/cc/PRESUBMIT.py
@@ -275,6 +275,27 @@ else: return [] +def CheckForDisallowMacros(input_api, output_api, white_list=CC_SOURCE_FILES, black_list=None): + black_list = tuple(black_list or input_api.DEFAULT_BLACK_LIST) + source_file_filter = lambda x: input_api.FilterSourceFile(x, white_list, black_list) + + disallow_macro_files = [] + + for f in input_api.AffectedSourceFiles(source_file_filter): + contents = input_api.ReadFile(f, 'rb') + # DISALLOW macros are not allowed, use deleted constructors instead. + if re.search(r"\bDISALLOW_COPY\(", contents) or \ + re.search(r"\bDISALLOW_ASSIGN\(", contents) or \ + re.search(r"\bDISALLOW_COPY_AND_ASSIGN\(", contents) or \ + re.search(r"\bDISALLOW_IMPLICIT_CONSTRUCTORS\(", contents): + disallow_macro_files.append(f.LocalPath()) + + if disallow_macro_files: + return [output_api.PresubmitError( + 'The following files use DISALLOW* macros. In cc, please use deleted constructors/operators instead.', + items=disallow_macro_files)] + return [] + def CheckChangeOnUpload(input_api, output_api): results = [] results += CheckAsserts(input_api, output_api) @@ -286,4 +307,5 @@ results += CheckNamespace(input_api, output_api) results += CheckForUseOfWrongClock(input_api, output_api) results += FindUselessIfdefs(input_api, output_api) + results += CheckForDisallowMacros(input_api, output_api) return results
diff --git a/cc/animation/animation.h b/cc/animation/animation.h index a4033d4..feb3302 100644 --- a/cc/animation/animation.h +++ b/cc/animation/animation.h
@@ -8,7 +8,6 @@ #include <vector> #include <memory> -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/time/time.h" #include "cc/animation/animation_curve.h" @@ -43,6 +42,9 @@ static scoped_refptr<Animation> Create(int id); virtual scoped_refptr<Animation> CreateImplInstance() const; + Animation(const Animation&) = delete; + Animation& operator=(const Animation&) = delete; + int id() const { return id_; } typedef size_t KeyframeEffectId; ElementId element_id_of_keyframe_effect( @@ -168,8 +170,6 @@ KeyframeEffects keyframe_effects_; int ticking_keyframe_effects_count; - - DISALLOW_COPY_AND_ASSIGN(Animation); }; } // namespace cc
diff --git a/cc/animation/animation_host.cc b/cc/animation/animation_host.cc index 96010f94c..33c4bc6 100644 --- a/cc/animation/animation_host.cc +++ b/cc/animation/animation_host.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/callback.h" -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/stl_util.h" #include "base/trace_event/trace_event.h"
diff --git a/cc/animation/animation_host.h b/cc/animation/animation_host.h index 70a33e85..7473db7e 100644 --- a/cc/animation/animation_host.h +++ b/cc/animation/animation_host.h
@@ -9,7 +9,6 @@ #include <unordered_map> #include <vector> -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" @@ -56,8 +55,12 @@ static std::unique_ptr<AnimationHost> CreateMainInstance(); static std::unique_ptr<AnimationHost> CreateForTesting( ThreadInstance thread_instance); + + AnimationHost(const AnimationHost&) = delete; ~AnimationHost() override; + AnimationHost& operator=(const AnimationHost&) = delete; + void AddAnimationTimeline(scoped_refptr<AnimationTimeline> timeline); void RemoveAnimationTimeline(scoped_refptr<AnimationTimeline> timeline); AnimationTimeline* GetTimelineById(int timeline_id) const; @@ -239,8 +242,6 @@ bool next_frame_has_pending_raf_ = false; base::WeakPtrFactory<AnimationHost> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(AnimationHost); }; } // namespace cc
diff --git a/cc/animation/animation_id_provider.h b/cc/animation/animation_id_provider.h index 62823be..cb7a84b 100644 --- a/cc/animation/animation_id_provider.h +++ b/cc/animation/animation_id_provider.h
@@ -5,21 +5,19 @@ #ifndef CC_ANIMATION_ANIMATION_ID_PROVIDER_H_ #define CC_ANIMATION_ANIMATION_ID_PROVIDER_H_ -#include "base/macros.h" #include "cc/animation/animation_export.h" namespace cc { class CC_ANIMATION_EXPORT AnimationIdProvider { public: + AnimationIdProvider() = delete; + // These functions each return monotonically increasing values. static int NextKeyframeModelId(); static int NextGroupId(); static int NextTimelineId(); static int NextAnimationId(); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(AnimationIdProvider); }; } // namespace cc
diff --git a/cc/animation/animation_timeline.h b/cc/animation/animation_timeline.h index 8b36e621..aebbef7e 100644 --- a/cc/animation/animation_timeline.h +++ b/cc/animation/animation_timeline.h
@@ -8,7 +8,6 @@ #include <memory> #include <unordered_map> -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "cc/animation/animation_export.h" @@ -27,6 +26,9 @@ static scoped_refptr<AnimationTimeline> Create(int id); scoped_refptr<AnimationTimeline> CreateImplInstance() const; + AnimationTimeline(const AnimationTimeline&) = delete; + AnimationTimeline& operator=(const AnimationTimeline&) = delete; + int id() const { return id_; } // Parent AnimationHost. @@ -73,8 +75,6 @@ // Impl-only AnimationTimeline has no main thread instance and lives on // it's own. bool is_impl_only_; - - DISALLOW_COPY_AND_ASSIGN(AnimationTimeline); }; } // namespace cc
diff --git a/cc/animation/element_animations.cc b/cc/animation/element_animations.cc index 7162033a..4926dbce 100644 --- a/cc/animation/element_animations.cc +++ b/cc/animation/element_animations.cc
@@ -8,7 +8,6 @@ #include <algorithm> -#include "base/macros.h" #include "base/numerics/ranges.h" #include "cc/animation/animation_delegate.h" #include "cc/animation/animation_events.h"
diff --git a/cc/animation/element_animations.h b/cc/animation/element_animations.h index 5270c95..7e8f124 100644 --- a/cc/animation/element_animations.h +++ b/cc/animation/element_animations.h
@@ -8,7 +8,6 @@ #include <memory> #include <vector> -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/observer_list.h" #include "cc/animation/animation_export.h" @@ -41,6 +40,9 @@ static scoped_refptr<ElementAnimations> Create(AnimationHost* host, ElementId element_id); + ElementAnimations(const ElementAnimations&) = delete; + ElementAnimations& operator=(const ElementAnimations&) = delete; + bool AnimationHostIs(AnimationHost* host) const { return animation_host_ == host; } @@ -199,8 +201,6 @@ PropertyAnimationState active_state_; PropertyAnimationState pending_state_; - - DISALLOW_COPY_AND_ASSIGN(ElementAnimations); }; } // namespace cc
diff --git a/cc/animation/keyframe_effect.h b/cc/animation/keyframe_effect.h index c41fef5..500f0bd 100644 --- a/cc/animation/keyframe_effect.h +++ b/cc/animation/keyframe_effect.h
@@ -5,7 +5,6 @@ #ifndef CC_ANIMATION_KEYFRAME_EFFECT_H_ #define CC_ANIMATION_KEYFRAME_EFFECT_H_ -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/time/time.h" #include "cc/animation/animation_events.h" @@ -41,8 +40,11 @@ class CC_ANIMATION_EXPORT KeyframeEffect { public: explicit KeyframeEffect(KeyframeEffectId id); + KeyframeEffect(const KeyframeEffect&) = delete; virtual ~KeyframeEffect(); + KeyframeEffect& operator=(const KeyframeEffect&) = delete; + static std::unique_ptr<KeyframeEffect> Create(KeyframeEffectId id); std::unique_ptr<KeyframeEffect> CreateImplInstance() const; @@ -202,8 +204,6 @@ base::TimeTicks last_tick_time_; bool needs_push_properties_; - - DISALLOW_COPY_AND_ASSIGN(KeyframeEffect); }; } // namespace cc
diff --git a/cc/animation/keyframe_model.h b/cc/animation/keyframe_model.h index cdbb2d5..43a22d88 100644 --- a/cc/animation/keyframe_model.h +++ b/cc/animation/keyframe_model.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "base/optional.h" #include "base/time/time.h" #include "cc/animation/animation_export.h" @@ -67,8 +66,11 @@ std::unique_ptr<KeyframeModel> CreateImplInstance( RunState initial_run_state) const; + KeyframeModel(const KeyframeModel&) = delete; virtual ~KeyframeModel(); + KeyframeModel& operator=(const KeyframeModel&) = delete; + int id() const { return id_; } int group() const { return group_; } int target_property_id() const { return target_property_id_; } @@ -279,8 +281,6 @@ // longer affect any elements, and are deleted. bool affects_active_elements_; bool affects_pending_elements_; - - DISALLOW_COPY_AND_ASSIGN(KeyframeModel); }; } // namespace cc
diff --git a/cc/animation/keyframed_animation_curve.h b/cc/animation/keyframed_animation_curve.h index 582a26c2..27e87ba3 100644 --- a/cc/animation/keyframed_animation_curve.h +++ b/cc/animation/keyframed_animation_curve.h
@@ -7,7 +7,6 @@ #include <vector> -#include "base/macros.h" #include "base/time/time.h" #include "cc/animation/animation_curve.h" #include "cc/animation/animation_export.h" @@ -19,6 +18,9 @@ class CC_ANIMATION_EXPORT Keyframe { public: + Keyframe(const Keyframe&) = delete; + Keyframe& operator=(const Keyframe&) = delete; + base::TimeDelta Time() const; const TimingFunction* timing_function() const { return timing_function_.get(); @@ -32,8 +34,6 @@ private: base::TimeDelta time_; std::unique_ptr<TimingFunction> timing_function_; - - DISALLOW_COPY_AND_ASSIGN(Keyframe); }; class CC_ANIMATION_EXPORT ColorKeyframe : public Keyframe { @@ -142,8 +142,12 @@ // It is required that the keyframes be sorted by time. static std::unique_ptr<KeyframedColorAnimationCurve> Create(); + KeyframedColorAnimationCurve(const KeyframedColorAnimationCurve&) = delete; ~KeyframedColorAnimationCurve() override; + KeyframedColorAnimationCurve& operator=(const KeyframedColorAnimationCurve&) = + delete; + void AddKeyframe(std::unique_ptr<ColorKeyframe> keyframe); void SetTimingFunction(std::unique_ptr<TimingFunction> timing_function) { timing_function_ = std::move(timing_function); @@ -168,8 +172,6 @@ std::vector<std::unique_ptr<ColorKeyframe>> keyframes_; std::unique_ptr<TimingFunction> timing_function_; double scaled_duration_; - - DISALLOW_COPY_AND_ASSIGN(KeyframedColorAnimationCurve); }; class CC_ANIMATION_EXPORT KeyframedFloatAnimationCurve @@ -178,8 +180,12 @@ // It is required that the keyframes be sorted by time. static std::unique_ptr<KeyframedFloatAnimationCurve> Create(); + KeyframedFloatAnimationCurve(const KeyframedFloatAnimationCurve&) = delete; ~KeyframedFloatAnimationCurve() override; + KeyframedFloatAnimationCurve& operator=(const KeyframedFloatAnimationCurve&) = + delete; + void AddKeyframe(std::unique_ptr<FloatKeyframe> keyframe); void SetTimingFunction(std::unique_ptr<TimingFunction> timing_function) { @@ -211,8 +217,6 @@ Keyframes keyframes_; std::unique_ptr<TimingFunction> timing_function_; double scaled_duration_; - - DISALLOW_COPY_AND_ASSIGN(KeyframedFloatAnimationCurve); }; class CC_ANIMATION_EXPORT KeyframedTransformAnimationCurve @@ -221,8 +225,13 @@ // It is required that the keyframes be sorted by time. static std::unique_ptr<KeyframedTransformAnimationCurve> Create(); + KeyframedTransformAnimationCurve(const KeyframedTransformAnimationCurve&) = + delete; ~KeyframedTransformAnimationCurve() override; + KeyframedTransformAnimationCurve& operator=( + const KeyframedTransformAnimationCurve&) = delete; + void AddKeyframe(std::unique_ptr<TransformKeyframe> keyframe); void SetTimingFunction(std::unique_ptr<TimingFunction> timing_function) { timing_function_ = std::move(timing_function); @@ -253,8 +262,6 @@ std::vector<std::unique_ptr<TransformKeyframe>> keyframes_; std::unique_ptr<TimingFunction> timing_function_; double scaled_duration_; - - DISALLOW_COPY_AND_ASSIGN(KeyframedTransformAnimationCurve); }; class CC_ANIMATION_EXPORT KeyframedFilterAnimationCurve @@ -263,8 +270,12 @@ // It is required that the keyframes be sorted by time. static std::unique_ptr<KeyframedFilterAnimationCurve> Create(); + KeyframedFilterAnimationCurve(const KeyframedFilterAnimationCurve&) = delete; ~KeyframedFilterAnimationCurve() override; + KeyframedFilterAnimationCurve& operator=( + const KeyframedFilterAnimationCurve&) = delete; + void AddKeyframe(std::unique_ptr<FilterKeyframe> keyframe); void SetTimingFunction(std::unique_ptr<TimingFunction> timing_function) { timing_function_ = std::move(timing_function); @@ -290,8 +301,6 @@ std::vector<std::unique_ptr<FilterKeyframe>> keyframes_; std::unique_ptr<TimingFunction> timing_function_; double scaled_duration_; - - DISALLOW_COPY_AND_ASSIGN(KeyframedFilterAnimationCurve); }; class CC_ANIMATION_EXPORT KeyframedSizeAnimationCurve @@ -300,8 +309,12 @@ // It is required that the keyframes be sorted by time. static std::unique_ptr<KeyframedSizeAnimationCurve> Create(); + KeyframedSizeAnimationCurve(const KeyframedSizeAnimationCurve&) = delete; ~KeyframedSizeAnimationCurve() override; + KeyframedSizeAnimationCurve& operator=(const KeyframedSizeAnimationCurve&) = + delete; + void AddKeyframe(std::unique_ptr<SizeKeyframe> keyframe); void SetTimingFunction(std::unique_ptr<TimingFunction> timing_function) { timing_function_ = std::move(timing_function); @@ -326,8 +339,6 @@ std::vector<std::unique_ptr<SizeKeyframe>> keyframes_; std::unique_ptr<TimingFunction> timing_function_; double scaled_duration_; - - DISALLOW_COPY_AND_ASSIGN(KeyframedSizeAnimationCurve); }; } // namespace cc
diff --git a/cc/animation/scroll_offset_animation_curve.h b/cc/animation/scroll_offset_animation_curve.h index 978fe82..fca9af6 100644 --- a/cc/animation/scroll_offset_animation_curve.h +++ b/cc/animation/scroll_offset_animation_curve.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "base/time/time.h" #include "cc/animation/animation_curve.h" #include "cc/animation/animation_export.h" @@ -47,8 +46,12 @@ DurationBehavior behavior, base::TimeDelta delayed_by); + ScrollOffsetAnimationCurve(const ScrollOffsetAnimationCurve&) = delete; ~ScrollOffsetAnimationCurve() override; + ScrollOffsetAnimationCurve& operator=(const ScrollOffsetAnimationCurve&) = + delete; + void SetInitialValue(const gfx::ScrollOffset& initial_value, base::TimeDelta delayed_by = base::TimeDelta()); bool HasSetInitialValue() const; @@ -93,8 +96,6 @@ bool has_set_initial_value_; static base::Optional<double> animation_duration_for_testing_; - - DISALLOW_COPY_AND_ASSIGN(ScrollOffsetAnimationCurve); }; } // namespace cc
diff --git a/cc/animation/scroll_offset_animations_impl.h b/cc/animation/scroll_offset_animations_impl.h index e64456e..311f62e 100644 --- a/cc/animation/scroll_offset_animations_impl.h +++ b/cc/animation/scroll_offset_animations_impl.h
@@ -5,7 +5,6 @@ #ifndef CC_ANIMATION_SCROLL_OFFSET_ANIMATIONS_IMPL_H_ #define CC_ANIMATION_SCROLL_OFFSET_ANIMATIONS_IMPL_H_ -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "cc/animation/animation_delegate.h" #include "cc/animation/scroll_offset_animation_curve.h" @@ -27,9 +26,12 @@ : public AnimationDelegate { public: explicit ScrollOffsetAnimationsImpl(AnimationHost* animation_host); - + ScrollOffsetAnimationsImpl(const ScrollOffsetAnimationsImpl&) = delete; ~ScrollOffsetAnimationsImpl() override; + ScrollOffsetAnimationsImpl& operator=(const ScrollOffsetAnimationsImpl&) = + delete; + // |delayed_by| shrinks the duration of the // animation. |animation_start_offset| causes us to start the animation // partway through. @@ -78,8 +80,6 @@ // I.e. only one element can have an impl-only scroll offset animation at // any given time. scoped_refptr<SingleKeyframeEffectAnimation> scroll_offset_animation_; - - DISALLOW_COPY_AND_ASSIGN(ScrollOffsetAnimationsImpl); }; } // namespace cc
diff --git a/cc/animation/single_keyframe_effect_animation.h b/cc/animation/single_keyframe_effect_animation.h index 6baeb76..474250c 100644 --- a/cc/animation/single_keyframe_effect_animation.h +++ b/cc/animation/single_keyframe_effect_animation.h
@@ -8,7 +8,6 @@ #include <vector> #include <memory> -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/time/time.h" #include "cc/animation/animation.h" @@ -37,6 +36,10 @@ static scoped_refptr<SingleKeyframeEffectAnimation> Create(int id); scoped_refptr<Animation> CreateImplInstance() const override; + SingleKeyframeEffectAnimation(const SingleKeyframeEffectAnimation&) = delete; + SingleKeyframeEffectAnimation& operator=( + const SingleKeyframeEffectAnimation&) = delete; + ElementId element_id() const; void AttachElement(ElementId element_id); @@ -64,8 +67,6 @@ std::unique_ptr<KeyframeEffect>); ~SingleKeyframeEffectAnimation() override; - - DISALLOW_COPY_AND_ASSIGN(SingleKeyframeEffectAnimation); }; } // namespace cc
diff --git a/cc/animation/timing_function.h b/cc/animation/timing_function.h index f5dc7f89..77969ac4 100644 --- a/cc/animation/timing_function.h +++ b/cc/animation/timing_function.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "cc/animation/animation_export.h" #include "ui/gfx/geometry/cubic_bezier.h" @@ -18,6 +17,8 @@ public: virtual ~TimingFunction(); + TimingFunction& operator=(const TimingFunction&) = delete; + // Note that LINEAR is a nullptr TimingFunction (for now). enum class Type { LINEAR, CUBIC_BEZIER, STEPS, FRAMES }; @@ -28,8 +29,6 @@ protected: TimingFunction(); - - DISALLOW_ASSIGN(TimingFunction); }; class CC_ANIMATION_EXPORT CubicBezierTimingFunction : public TimingFunction { @@ -44,6 +43,9 @@ double y2); ~CubicBezierTimingFunction() override; + CubicBezierTimingFunction& operator=(const CubicBezierTimingFunction&) = + delete; + // TimingFunction implementation. Type GetType() const override; double GetValue(double time) const override; @@ -62,8 +64,6 @@ gfx::CubicBezier bezier_; EaseType ease_type_; - - DISALLOW_ASSIGN(CubicBezierTimingFunction); }; class CC_ANIMATION_EXPORT StepsTimingFunction : public TimingFunction { @@ -77,6 +77,8 @@ StepPosition step_position); ~StepsTimingFunction() override; + StepsTimingFunction& operator=(const StepsTimingFunction&) = delete; + // TimingFunction implementation. Type GetType() const override; double GetValue(double t) const override; @@ -94,8 +96,6 @@ int steps_; StepPosition step_position_; - - DISALLOW_ASSIGN(StepsTimingFunction); }; class CC_ANIMATION_EXPORT FramesTimingFunction : public TimingFunction { @@ -103,6 +103,8 @@ static std::unique_ptr<FramesTimingFunction> Create(int frames); ~FramesTimingFunction() override; + FramesTimingFunction& operator=(const FramesTimingFunction&) = delete; + // TimingFunction implementation. Type GetType() const override; double GetValue(double t) const override; @@ -116,8 +118,6 @@ explicit FramesTimingFunction(int frames); int frames_; - - DISALLOW_ASSIGN(FramesTimingFunction); }; } // namespace cc
diff --git a/cc/animation/transform_operations.h b/cc/animation/transform_operations.h index 4a6706d7..f8e89ca 100644 --- a/cc/animation/transform_operations.h +++ b/cc/animation/transform_operations.h
@@ -11,7 +11,6 @@ #include "base/gtest_prod_util.h" #include "base/logging.h" -#include "base/macros.h" #include "cc/animation/animation_export.h" #include "cc/animation/transform_operation.h" #include "ui/gfx/transform.h"
diff --git a/cc/base/delayed_unique_notifier.h b/cc/base/delayed_unique_notifier.h index 4a7486e0..1666987 100644 --- a/cc/base/delayed_unique_notifier.h +++ b/cc/base/delayed_unique_notifier.h
@@ -6,7 +6,6 @@ #define CC_BASE_DELAYED_UNIQUE_NOTIFIER_H_ #include "base/callback.h" -#include "base/macros.h" #include "base/memory/weak_ptr.h" #include "cc/base/base_export.h" @@ -23,11 +22,14 @@ DelayedUniqueNotifier(base::SequencedTaskRunner* task_runner, base::RepeatingClosure closure, const base::TimeDelta& delay); + DelayedUniqueNotifier(const DelayedUniqueNotifier&) = delete; // Destroying the notifier will ensure that no further notifications will // happen from this class. virtual ~DelayedUniqueNotifier(); + DelayedUniqueNotifier& operator=(const DelayedUniqueNotifier&) = delete; + // Schedule a notification to be run. If another notification is already // pending, then it will happen in (at least) given delay from now. That is, // if delay is 16ms and a notification has been scheduled 10ms ago (ie, it @@ -66,8 +68,6 @@ bool notification_pending_; base::WeakPtrFactory<DelayedUniqueNotifier> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(DelayedUniqueNotifier); }; } // namespace cc
diff --git a/cc/base/devtools_instrumentation.h b/cc/base/devtools_instrumentation.h index 0697422..56077e04 100644 --- a/cc/base/devtools_instrumentation.h +++ b/cc/base/devtools_instrumentation.h
@@ -9,7 +9,6 @@ #include <memory> -#include "base/macros.h" #include "base/metrics/histogram_macros.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/traced_value.h" @@ -53,14 +52,15 @@ TRACE_EVENT_BEGIN1(internal::CategoryName::kTimeline, event_name_, internal::kLayerId, layer_id); } + ScopedLayerTask(const ScopedLayerTask&) = delete; ~ScopedLayerTask() { TRACE_EVENT_END0(internal::CategoryName::kTimeline, event_name_); } + ScopedLayerTask& operator=(const ScopedLayerTask&) = delete; + private: const char* event_name_; - - DISALLOW_COPY_AND_ASSIGN(ScopedLayerTask); }; class CC_BASE_EXPORT ScopedImageDecodeTask { @@ -71,13 +71,15 @@ ScopedImageDecodeTask(const void* image_ptr, DecodeType decode_type, TaskType task_type); + ScopedImageDecodeTask(const ScopedImageDecodeTask&) = delete; ~ScopedImageDecodeTask(); + ScopedImageDecodeTask& operator=(const ScopedImageDecodeTask&) = delete; + private: const DecodeType decode_type_; const TaskType task_type_; const base::TimeTicks start_time_; - DISALLOW_COPY_AND_ASSIGN(ScopedImageDecodeTask); }; class CC_BASE_EXPORT ScopedLayerTreeTask { @@ -90,14 +92,15 @@ internal::kLayerId, layer_id, internal::kLayerTreeId, layer_tree_host_id); } + ScopedLayerTreeTask(const ScopedLayerTreeTask&) = delete; ~ScopedLayerTreeTask() { TRACE_EVENT_END0(internal::CategoryName::kTimeline, event_name_); } + ScopedLayerTreeTask& operator=(const ScopedLayerTreeTask&) = delete; + private: const char* event_name_; - - DISALLOW_COPY_AND_ASSIGN(ScopedLayerTreeTask); }; struct CC_BASE_EXPORT ScopedCommitTrace { @@ -107,13 +110,13 @@ internal::kCompositeLayers, internal::kLayerTreeId, layer_tree_host_id); } + ScopedCommitTrace(const ScopedCommitTrace&) = delete; ~ScopedCommitTrace() { TRACE_EVENT_END0(internal::CategoryName::kTimeline, internal::kCompositeLayers); } - private: - DISALLOW_COPY_AND_ASSIGN(ScopedCommitTrace); + ScopedCommitTrace& operator=(const ScopedCommitTrace&) = delete; }; struct CC_BASE_EXPORT ScopedLayerObjectTracker @@ -124,9 +127,8 @@ TraceScopedTrackableObject<int, internal::CategoryName::kTimeline>( internal::kLayerId, layer_id) {} - - private: - DISALLOW_COPY_AND_ASSIGN(ScopedLayerObjectTracker); + ScopedLayerObjectTracker(const ScopedLayerObjectTracker&) = delete; + ScopedLayerObjectTracker& operator=(const ScopedLayerObjectTracker&) = delete; }; inline void CC_BASE_EXPORT DidActivateLayerTree(int layer_tree_host_id,
diff --git a/cc/base/histograms.h b/cc/base/histograms.h index dd88f8c0..d4f8a23 100644 --- a/cc/base/histograms.h +++ b/cc/base/histograms.h
@@ -6,7 +6,6 @@ #define CC_BASE_HISTOGRAMS_H_ #include "base/compiler_specific.h" -#include "base/macros.h" #include "base/metrics/histogram_base.h" #include "base/metrics/histogram_macros.h" #include "base/numerics/safe_math.h" @@ -92,6 +91,11 @@ class CC_BASE_EXPORT ScopedUMAHistogramAreaTimerBase { public: + ScopedUMAHistogramAreaTimerBase(const ScopedUMAHistogramAreaTimerBase&) = + delete; + ScopedUMAHistogramAreaTimerBase& operator=( + const ScopedUMAHistogramAreaTimerBase&) = delete; + void AddArea(const base::CheckedNumeric<int>& area) { area_ += area; } void SetArea(const base::CheckedNumeric<int>& area) { area_ = area; } @@ -115,7 +119,6 @@ base::CheckedNumeric<int> area_; friend class ScopedUMAHistogramAreaTimerBaseTest; - DISALLOW_COPY_AND_ASSIGN(ScopedUMAHistogramAreaTimerBase); }; } // namespace cc
diff --git a/cc/base/list_container.h b/cc/base/list_container.h index 0c20831..2c480e6 100644 --- a/cc/base/list_container.h +++ b/cc/base/list_container.h
@@ -10,7 +10,6 @@ #include <memory> #include "base/logging.h" -#include "base/macros.h" #include "cc/base/list_container_helper.h" namespace cc { @@ -35,6 +34,7 @@ : helper_(max_alignment, max_size_for_derived_class, num_of_elements_to_reserve_for) {} + ListContainer(const ListContainer&) = delete; ~ListContainer() { for (Iterator i = begin(); i != end(); ++i) { @@ -42,6 +42,8 @@ } } + ListContainer& operator=(const ListContainer&) = delete; + class Iterator; class ConstIterator; class ReverseIterator; @@ -358,8 +360,6 @@ private: ListContainerHelper helper_; - - DISALLOW_COPY_AND_ASSIGN(ListContainer); }; } // namespace cc
diff --git a/cc/base/list_container_helper.cc b/cc/base/list_container_helper.cc index 380ad3d..3a4c0b6 100644 --- a/cc/base/list_container_helper.cc +++ b/cc/base/list_container_helper.cc
@@ -10,7 +10,6 @@ #include <vector> #include "base/logging.h" -#include "base/macros.h" #include "base/memory/aligned_memory.h" namespace { @@ -30,6 +29,9 @@ // This class holds the raw memory chunk, as well as information about its // size and availability. struct InnerList { + InnerList(const InnerList&) = delete; + InnerList& operator=(const InnerList&) = delete; + std::unique_ptr<char[], base::AlignedFreeDeleter> data; // The number of elements in total the memory can hold. The difference // between capacity and size is the how many more elements this list can @@ -99,9 +101,6 @@ char* End() const { return data.get() + size * step; } char* LastElement() const { return data.get() + (size - 1) * step; } char* ElementAt(size_t index) const { return data.get() + index * step; } - - private: - DISALLOW_COPY_AND_ASSIGN(InnerList); }; CharAllocator(size_t alignment, size_t element_size, size_t element_count) @@ -119,8 +118,11 @@ last_list_ = storage_[last_list_index_].get(); } + CharAllocator(const CharAllocator&) = delete; ~CharAllocator() = default; + CharAllocator& operator=(const CharAllocator&) = delete; + void* Allocate() { if (last_list_->IsFull()) { // Only allocate a new list if there isn't a spare one still there from @@ -261,8 +263,6 @@ // This is equivalent to |storage_[last_list_index_]|. InnerList* last_list_; - - DISALLOW_COPY_AND_ASSIGN(CharAllocator); }; // PositionInCharAllocator
diff --git a/cc/base/list_container_helper.h b/cc/base/list_container_helper.h index c79cf1f..31658bc 100644 --- a/cc/base/list_container_helper.h +++ b/cc/base/list_container_helper.h
@@ -9,7 +9,6 @@ #include <memory> -#include "base/macros.h" #include "cc/base/base_export.h" namespace cc { @@ -25,8 +24,11 @@ explicit ListContainerHelper(size_t alignment, size_t max_size_for_derived_class, size_t num_of_elements_to_reserve_for); + ListContainerHelper(const ListContainerHelper&) = delete; ~ListContainerHelper(); + ListContainerHelper& operator=(const ListContainerHelper&) = delete; + // This class deals only with char* and void*. It does allocation and passing // out raw pointers, as well as memory deallocation when being destroyed. class CharAllocator; @@ -170,8 +172,6 @@ void* Allocate(size_t alignment, size_t size_of_actual_element_in_bytes); std::unique_ptr<CharAllocator> data_; - - DISALLOW_COPY_AND_ASSIGN(ListContainerHelper); }; } // namespace cc
diff --git a/cc/base/math_util.h b/cc/base/math_util.h index 2674b83e..c3d8179 100644 --- a/cc/base/math_util.h +++ b/cc/base/math_util.h
@@ -316,13 +316,16 @@ class CC_BASE_EXPORT ScopedSubnormalFloatDisabler { public: ScopedSubnormalFloatDisabler(); + ScopedSubnormalFloatDisabler(const ScopedSubnormalFloatDisabler&) = delete; ~ScopedSubnormalFloatDisabler(); - private: + ScopedSubnormalFloatDisabler& operator=(const ScopedSubnormalFloatDisabler&) = + delete; + #if defined(ARCH_CPU_X86_FAMILY) + private: unsigned int orig_state_; #endif - DISALLOW_COPY_AND_ASSIGN(ScopedSubnormalFloatDisabler); }; } // namespace cc
diff --git a/cc/base/rolling_time_delta_history.h b/cc/base/rolling_time_delta_history.h index f23d583..75832323 100644 --- a/cc/base/rolling_time_delta_history.h +++ b/cc/base/rolling_time_delta_history.h
@@ -11,7 +11,6 @@ #include "base/containers/circular_deque.h" #include "base/containers/flat_map.h" -#include "base/macros.h" #include "base/time/time.h" #include "cc/base/base_export.h" @@ -22,9 +21,12 @@ class CC_BASE_EXPORT RollingTimeDeltaHistory { public: explicit RollingTimeDeltaHistory(size_t max_size); + RollingTimeDeltaHistory(const RollingTimeDeltaHistory&) = delete; ~RollingTimeDeltaHistory(); + RollingTimeDeltaHistory& operator=(const RollingTimeDeltaHistory&) = delete; + void InsertSample(base::TimeDelta time); size_t sample_count() const { return sample_set_.size(); } @@ -44,8 +46,6 @@ size_t max_size_; mutable base::flat_map<double, base::TimeDelta> percentile_cache_; - - DISALLOW_COPY_AND_ASSIGN(RollingTimeDeltaHistory); }; } // namespace cc
diff --git a/cc/base/rtree.h b/cc/base/rtree.h index 840eaab..1b3b699 100644 --- a/cc/base/rtree.h +++ b/cc/base/rtree.h
@@ -42,8 +42,11 @@ class RTree { public: RTree(); + RTree(const RTree&) = delete; ~RTree(); + RTree& operator=(const RTree&) = delete; + // Constructs the rtree from a given container of gfx::Rects. Queries using // Search will then return indices into this container. template <typename Container> @@ -129,8 +132,6 @@ size_t num_data_elements_ = 0u; Branch<T> root_; std::vector<Node<T>> nodes_; - - DISALLOW_COPY_AND_ASSIGN(RTree); }; template <typename T>
diff --git a/cc/base/unique_notifier.h b/cc/base/unique_notifier.h index ff129c8b..ad2172b4 100644 --- a/cc/base/unique_notifier.h +++ b/cc/base/unique_notifier.h
@@ -6,7 +6,6 @@ #define CC_BASE_UNIQUE_NOTIFIER_H_ #include "base/callback.h" -#include "base/macros.h" #include "base/memory/weak_ptr.h" #include "cc/base/base_export.h" @@ -23,11 +22,14 @@ // Configure this notifier to issue the |closure| notification when scheduled. UniqueNotifier(base::SequencedTaskRunner* task_runner, base::RepeatingClosure closure); + UniqueNotifier(const UniqueNotifier&) = delete; // Destroying the notifier will ensure that no further notifications will // happen from this class. ~UniqueNotifier(); + UniqueNotifier& operator=(const UniqueNotifier&) = delete; + // Schedule a notification to be run. If another notification is already // pending, then only one notification will take place. void Schedule(); @@ -47,8 +49,6 @@ bool notification_pending_; base::WeakPtrFactory<UniqueNotifier> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(UniqueNotifier); }; } // namespace cc
diff --git a/cc/benchmarks/benchmark_instrumentation.h b/cc/benchmarks/benchmark_instrumentation.h index d946c6e6..d2bc0627d 100644 --- a/cc/benchmarks/benchmark_instrumentation.h +++ b/cc/benchmarks/benchmark_instrumentation.h
@@ -5,7 +5,6 @@ #ifndef CC_BENCHMARKS_BENCHMARK_INSTRUMENTATION_H_ #define CC_BENCHMARKS_BENCHMARK_INSTRUMENTATION_H_ -#include "base/macros.h" #include "base/trace_event/trace_event.h" #include "cc/cc_export.h" #include "cc/debug/rendering_stats.h" @@ -38,14 +37,15 @@ TRACE_EVENT_BEGIN1(internal::Category(), event_name_, internal::kBeginFrameId, begin_frame_id); } + ScopedBeginFrameTask(const ScopedBeginFrameTask&) = delete; ~ScopedBeginFrameTask() { TRACE_EVENT_END0(internal::Category(), event_name_); } + ScopedBeginFrameTask& operator=(const ScopedBeginFrameTask&) = delete; + private: const char* event_name_; - - DISALLOW_COPY_AND_ASSIGN(ScopedBeginFrameTask); }; void IssueImplThreadRenderingStatsEvent(const RenderingStats& stats);
diff --git a/cc/benchmarks/micro_benchmark_controller.h b/cc/benchmarks/micro_benchmark_controller.h index e5eb7b27..ab5ce66f 100644 --- a/cc/benchmarks/micro_benchmark_controller.h +++ b/cc/benchmarks/micro_benchmark_controller.h
@@ -9,7 +9,6 @@ #include <vector> #include "base/callback.h" -#include "base/macros.h" #include "cc/benchmarks/micro_benchmark.h" namespace base { @@ -24,8 +23,11 @@ class CC_EXPORT MicroBenchmarkController { public: explicit MicroBenchmarkController(LayerTreeHost* host); + MicroBenchmarkController(const MicroBenchmarkController&) = delete; ~MicroBenchmarkController(); + MicroBenchmarkController& operator=(const MicroBenchmarkController&) = delete; + void DidUpdateLayers(); // Returns the id of the benchmark on success, 0 otherwise. @@ -45,8 +47,6 @@ std::vector<std::unique_ptr<MicroBenchmark>> benchmarks_; static int next_id_; scoped_refptr<base::SingleThreadTaskRunner> main_controller_task_runner_; - - DISALLOW_COPY_AND_ASSIGN(MicroBenchmarkController); }; } // namespace cc
diff --git a/cc/benchmarks/micro_benchmark_controller_impl.h b/cc/benchmarks/micro_benchmark_controller_impl.h index 7948243..fc1b91c 100644 --- a/cc/benchmarks/micro_benchmark_controller_impl.h +++ b/cc/benchmarks/micro_benchmark_controller_impl.h
@@ -8,7 +8,6 @@ #include <string> #include <vector> -#include "base/macros.h" #include "cc/benchmarks/micro_benchmark_impl.h" namespace cc { @@ -17,8 +16,12 @@ class CC_EXPORT MicroBenchmarkControllerImpl { public: explicit MicroBenchmarkControllerImpl(LayerTreeHostImpl* host); + MicroBenchmarkControllerImpl(const MicroBenchmarkControllerImpl&) = delete; ~MicroBenchmarkControllerImpl(); + MicroBenchmarkControllerImpl& operator=(const MicroBenchmarkControllerImpl&) = + delete; + void DidCompleteCommit(); void ScheduleRun(std::unique_ptr<MicroBenchmarkImpl> benchmark); @@ -28,8 +31,6 @@ LayerTreeHostImpl* host_; std::vector<std::unique_ptr<MicroBenchmarkImpl>> benchmarks_; - - DISALLOW_COPY_AND_ASSIGN(MicroBenchmarkControllerImpl); }; } // namespace cc
diff --git a/cc/benchmarks/rasterize_and_record_benchmark_impl.cc b/cc/benchmarks/rasterize_and_record_benchmark_impl.cc index cf7f706..6f2da14 100644 --- a/cc/benchmarks/rasterize_and_record_benchmark_impl.cc +++ b/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
@@ -71,8 +71,7 @@ settings.image_provider = &image_provider; raster_source->PlaybackToCanvas( - &canvas, gfx::ColorSpace(), - raster_source->GetContentSize(contents_scale), content_rect, + &canvas, raster_source->GetContentSize(contents_scale), content_rect, content_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), settings);
diff --git a/cc/debug/debug_colors.cc b/cc/debug/debug_colors.cc index eef3fcb7..d8fc52a 100644 --- a/cc/debug/debug_colors.cc +++ b/cc/debug/debug_colors.cc
@@ -3,7 +3,6 @@ // found in the LICENSE file. #include "base/logging.h" -#include "base/macros.h" #include "cc/debug/debug_colors.h"
diff --git a/cc/debug/debug_colors.h b/cc/debug/debug_colors.h index d45e0dc..69a73b1 100644 --- a/cc/debug/debug_colors.h +++ b/cc/debug/debug_colors.h
@@ -6,7 +6,6 @@ #define CC_DEBUG_DEBUG_COLORS_H_ #include "base/containers/span.h" -#include "base/macros.h" #include "cc/debug/debug_export.h" #include "third_party/skia/include/core/SkColor.h" @@ -14,6 +13,8 @@ class CC_DEBUG_EXPORT DebugColors { public: + DebugColors() = delete; + static SkColor TiledContentLayerBorderColor(); static int TiledContentLayerBorderWidth(float device_scale_factor); @@ -119,9 +120,6 @@ static SkColor FPSDisplayTextAndGraphColor(); static SkColor MemoryDisplayTextColor(); static SkColor PaintTimeDisplayTextAndGraphColor(); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(DebugColors); }; } // namespace cc
diff --git a/cc/debug/rendering_stats_instrumentation.h b/cc/debug/rendering_stats_instrumentation.h index 3f656dbe..98ba79b 100644 --- a/cc/debug/rendering_stats_instrumentation.h +++ b/cc/debug/rendering_stats_instrumentation.h
@@ -9,7 +9,6 @@ #include <memory> -#include "base/macros.h" #include "base/synchronization/lock.h" #include "cc/debug/rendering_stats.h" @@ -20,8 +19,12 @@ class CC_DEBUG_EXPORT RenderingStatsInstrumentation { public: static std::unique_ptr<RenderingStatsInstrumentation> Create(); + RenderingStatsInstrumentation(const RenderingStatsInstrumentation&) = delete; virtual ~RenderingStatsInstrumentation(); + RenderingStatsInstrumentation& operator=( + const RenderingStatsInstrumentation&) = delete; + // Return copy of current impl thread rendering stats, and resets the current // stats. RenderingStats TakeImplThreadRenderingStats(); @@ -58,8 +61,6 @@ bool record_rendering_stats_; base::Lock lock_; - - DISALLOW_COPY_AND_ASSIGN(RenderingStatsInstrumentation); }; } // namespace cc
diff --git a/cc/input/browser_controls_offset_manager.h b/cc/input/browser_controls_offset_manager.h index 8d0435d2..af00d33 100644 --- a/cc/input/browser_controls_offset_manager.h +++ b/cc/input/browser_controls_offset_manager.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "base/time/time.h" #include "cc/input/browser_controls_state.h" #include "cc/layers/layer_impl.h" @@ -27,8 +26,12 @@ BrowserControlsOffsetManagerClient* client, float controls_show_threshold, float controls_hide_threshold); + BrowserControlsOffsetManager(const BrowserControlsOffsetManager&) = delete; virtual ~BrowserControlsOffsetManager(); + BrowserControlsOffsetManager& operator=(const BrowserControlsOffsetManager&) = + delete; + // The offset from the window top to the top edge of the controls. Runs from 0 // (controls fully shown) to negative values (down is positive). float ControlsTopOffset() const; @@ -115,8 +118,6 @@ // Used to track whether the constraint has changed and we need up reflect // the changes to Blink. bool constraint_changed_since_commit_; - - DISALLOW_COPY_AND_ASSIGN(BrowserControlsOffsetManager); }; } // namespace cc
diff --git a/cc/input/input_handler.h b/cc/input/input_handler.h index e8626f8..0aea723a 100644 --- a/cc/input/input_handler.h +++ b/cc/input/input_handler.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "base/time/time.h" #include "cc/cc_export.h" #include "cc/input/event_listener_properties.h" @@ -59,7 +58,10 @@ class CC_EXPORT InputHandlerClient { public: - virtual ~InputHandlerClient() {} + InputHandlerClient(const InputHandlerClient&) = delete; + virtual ~InputHandlerClient() = default; + + InputHandlerClient& operator=(const InputHandlerClient&) = delete; virtual void WillShutdown() = 0; virtual void Animate(base::TimeTicks time) = 0; @@ -74,10 +76,7 @@ virtual void DeliverInputForBeginFrame() = 0; protected: - InputHandlerClient() {} - - private: - DISALLOW_COPY_AND_ASSIGN(InputHandlerClient); + InputHandlerClient() = default; }; // The InputHandler is a way for the embedders to interact with the impl thread @@ -96,6 +95,9 @@ LAST_SCROLL_STATUS = SCROLL_UNKNOWN }; + InputHandler(const InputHandler&) = delete; + InputHandler& operator=(const InputHandler&) = delete; + struct ScrollStatus { ScrollStatus() : thread(SCROLL_ON_IMPL_THREAD), @@ -244,11 +246,8 @@ gfx::Vector2dF* target_offset) const = 0; protected: - InputHandler() {} - virtual ~InputHandler() {} - - private: - DISALLOW_COPY_AND_ASSIGN(InputHandler); + InputHandler() = default; + virtual ~InputHandler() = default; }; } // namespace cc
diff --git a/cc/input/page_scale_animation.h b/cc/input/page_scale_animation.h index 9d66923e..be4515a 100644 --- a/cc/input/page_scale_animation.h +++ b/cc/input/page_scale_animation.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "base/time/time.h" #include "cc/cc_export.h" #include "ui/gfx/geometry/cubic_bezier.h" @@ -51,8 +50,11 @@ const gfx::SizeF& viewport_size, const gfx::SizeF& root_layer_size); + PageScaleAnimation(const PageScaleAnimation&) = delete; ~PageScaleAnimation(); + PageScaleAnimation& operator=(const PageScaleAnimation&) = delete; + // The following methods initialize the animation. Call one of them // immediately after construction to set the final scroll and page scale. @@ -123,8 +125,6 @@ base::TimeDelta duration_; const gfx::CubicBezier timing_function_; - - DISALLOW_COPY_AND_ASSIGN(PageScaleAnimation); }; } // namespace cc
diff --git a/cc/input/single_scrollbar_animation_controller_thinning.h b/cc/input/single_scrollbar_animation_controller_thinning.h index 20c06835..80a267d 100644 --- a/cc/input/single_scrollbar_animation_controller_thinning.h +++ b/cc/input/single_scrollbar_animation_controller_thinning.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "base/time/time.h" #include "cc/cc_export.h" #include "cc/input/scrollbar.h" @@ -31,7 +30,12 @@ ScrollbarAnimationControllerClient* client, base::TimeDelta thinning_duration); - ~SingleScrollbarAnimationControllerThinning() {} + SingleScrollbarAnimationControllerThinning( + const SingleScrollbarAnimationControllerThinning&) = delete; + ~SingleScrollbarAnimationControllerThinning() = default; + + SingleScrollbarAnimationControllerThinning& operator=( + const SingleScrollbarAnimationControllerThinning&) = delete; bool mouse_is_over_scrollbar_thumb() const { return mouse_is_over_scrollbar_thumb_; @@ -96,8 +100,6 @@ AnimationChange thickness_change_; base::TimeDelta thinning_duration_; - - DISALLOW_COPY_AND_ASSIGN(SingleScrollbarAnimationControllerThinning); }; } // namespace cc
diff --git a/cc/input/snap_fling_controller.h b/cc/input/snap_fling_controller.h index eb07106..c5ad511 100644 --- a/cc/input/snap_fling_controller.h +++ b/cc/input/snap_fling_controller.h
@@ -53,8 +53,11 @@ SnapFlingClient* client, std::unique_ptr<SnapFlingCurve> curve); + SnapFlingController(const SnapFlingController&) = delete; ~SnapFlingController(); + SnapFlingController& operator=(const SnapFlingController&) = delete; + // Returns true if the event should be consumed for snapping and should not be // processed further. bool FilterEventForSnap(GestureScrollType gesture_scroll_type); @@ -97,8 +100,6 @@ SnapFlingClient* client_; State state_ = State::kIdle; std::unique_ptr<SnapFlingCurve> curve_; - - DISALLOW_COPY_AND_ASSIGN(SnapFlingController); }; } // namespace cc
diff --git a/cc/layers/deadline_policy.h b/cc/layers/deadline_policy.h index 268ca23..6c3b006 100644 --- a/cc/layers/deadline_policy.h +++ b/cc/layers/deadline_policy.h
@@ -8,7 +8,6 @@ #include <cstdint> #include "base/logging.h" -#include "base/macros.h" #include "base/optional.h" #include "cc/cc_export.h"
diff --git a/cc/layers/heads_up_display_layer.h b/cc/layers/heads_up_display_layer.h index 2936a975..1337fb6 100644 --- a/cc/layers/heads_up_display_layer.h +++ b/cc/layers/heads_up_display_layer.h
@@ -8,7 +8,6 @@ #include <memory> #include <string> -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/layers/layer.h" #include "third_party/skia/include/core/SkRefCnt.h" @@ -20,6 +19,9 @@ public: static scoped_refptr<HeadsUpDisplayLayer> Create(); + HeadsUpDisplayLayer(const HeadsUpDisplayLayer&) = delete; + HeadsUpDisplayLayer& operator=(const HeadsUpDisplayLayer&) = delete; + void UpdateLocationAndSize(const gfx::Size& device_viewport, float device_scale_factor); @@ -36,8 +38,6 @@ ~HeadsUpDisplayLayer() override; sk_sp<SkTypeface> typeface_; - - DISALLOW_COPY_AND_ASSIGN(HeadsUpDisplayLayer); }; } // namespace cc
diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc index 6d317814..366013e 100644 --- a/cc/layers/heads_up_display_layer_impl.cc +++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -375,7 +375,8 @@ { ScopedGpuRaster gpu_raster(context_provider); viz::ClientResourceProvider::ScopedSkSurface scoped_surface( - context_provider->GrContext(), mailbox_texture_id, + context_provider->GrContext(), + pool_resource.color_space().ToSkColorSpace(), mailbox_texture_id, backing->texture_target, pool_resource.size(), pool_resource.format(), false /* can_use_lcd_text */, 0 /* msaa_sample_count */);
diff --git a/cc/layers/heads_up_display_layer_impl.h b/cc/layers/heads_up_display_layer_impl.h index 0315c2c..7f209eb 100644 --- a/cc/layers/heads_up_display_layer_impl.h +++ b/cc/layers/heads_up_display_layer_impl.h
@@ -9,7 +9,6 @@ #include <string> #include <vector> -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/time/time.h" #include "cc/cc_export.h" @@ -41,8 +40,11 @@ int id) { return base::WrapUnique(new HeadsUpDisplayLayerImpl(tree_impl, id)); } + HeadsUpDisplayLayerImpl(const HeadsUpDisplayLayerImpl&) = delete; ~HeadsUpDisplayLayerImpl() override; + HeadsUpDisplayLayerImpl& operator=(const HeadsUpDisplayLayerImpl&) = delete; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; bool WillDraw(DrawMode draw_mode, @@ -157,8 +159,6 @@ std::vector<DebugRect> paint_rects_; base::TimeTicks time_of_last_graph_update_; - - DISALLOW_COPY_AND_ASSIGN(HeadsUpDisplayLayerImpl); }; } // namespace cc
diff --git a/cc/layers/layer.h b/cc/layers/layer.h index 0bfbffc..772e066 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h
@@ -15,7 +15,6 @@ #include <vector> #include "base/callback.h" -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/observer_list.h" #include "cc/base/region.h" @@ -84,6 +83,9 @@ // Factory to create a new Layer, with a unique id. static scoped_refptr<Layer> Create(); + Layer(const Layer&) = delete; + Layer& operator=(const Layer&) = delete; + // Sets an optional client on this layer, that will be called when relevant // events happen. The client is a WeakPtr so it can be destroyed without // unsetting itself as the client. @@ -1043,8 +1045,6 @@ int owner_node_id_; std::unique_ptr<std::set<Layer*>> clip_children_; - - DISALLOW_COPY_AND_ASSIGN(Layer); }; } // namespace cc
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index b036dd80..092d9c1 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -139,9 +139,10 @@ bool contents_opaque) const { EffectNode* effect_node = GetEffectTree().Node(effect_tree_index_); state->SetAll(draw_properties_.target_space_transform, gfx::Rect(bounds()), - draw_properties_.visible_layer_rect, draw_properties_.clip_rect, - draw_properties_.is_clipped, contents_opaque, - draw_properties_.opacity, + draw_properties_.visible_layer_rect, + draw_properties_.rounded_corner_bounds, + draw_properties_.clip_rect, draw_properties_.is_clipped, + contents_opaque, draw_properties_.opacity, effect_node->has_render_surface ? SkBlendMode::kSrcOver : effect_node->blend_mode, GetSortingContextId()); @@ -163,9 +164,10 @@ EffectNode* effect_node = GetEffectTree().Node(effect_tree_index_); state->SetAll(scaled_draw_transform, gfx::Rect(scaled_bounds), - scaled_visible_layer_rect, draw_properties().clip_rect, - draw_properties().is_clipped, contents_opaque, - draw_properties().opacity, + scaled_visible_layer_rect, + draw_properties().rounded_corner_bounds, + draw_properties().clip_rect, draw_properties().is_clipped, + contents_opaque, draw_properties().opacity, effect_node->has_render_surface ? SkBlendMode::kSrcOver : effect_node->blend_mode, GetSortingContextId());
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index d3f3d6e..8e6dd6c7 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h
@@ -15,7 +15,6 @@ #include <vector> #include "base/logging.h" -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/values.h" #include "cc/base/region.h" @@ -79,8 +78,11 @@ return base::WrapUnique(new LayerImpl(tree_impl, id)); } + LayerImpl(const LayerImpl&) = delete; virtual ~LayerImpl(); + LayerImpl& operator=(const LayerImpl&) = delete; + int id() const { return layer_id_; } // Whether this layer is on the active tree, return false if it's on the @@ -604,8 +606,6 @@ bool raster_even_if_not_drawn_ : 1; bool has_transform_node_ : 1; - - DISALLOW_COPY_AND_ASSIGN(LayerImpl); }; } // namespace cc
diff --git a/cc/layers/nine_patch_generator.h b/cc/layers/nine_patch_generator.h index f413e4f..afdcb27bf 100644 --- a/cc/layers/nine_patch_generator.h +++ b/cc/layers/nine_patch_generator.h
@@ -8,7 +8,6 @@ #include <string> #include <vector> -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/resources/ui_resource_client.h" #include "ui/gfx/geometry/rect.h"
diff --git a/cc/layers/nine_patch_layer.h b/cc/layers/nine_patch_layer.h index ca9fb92..f492e6e 100644 --- a/cc/layers/nine_patch_layer.h +++ b/cc/layers/nine_patch_layer.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/layers/layer.h" #include "cc/layers/ui_resource_layer.h" @@ -20,6 +19,9 @@ public: static scoped_refptr<NinePatchLayer> Create(); + NinePatchLayer(const NinePatchLayer&) = delete; + NinePatchLayer& operator=(const NinePatchLayer&) = delete; + void PushPropertiesTo(LayerImpl* layer) override; // |border| is the space around the center rectangular region in layer space @@ -60,8 +62,6 @@ // The occluded region in layer space set by SetLayerOcclusion. It is // usually larger than |image_aperture_|. gfx::Rect layer_occlusion_; - - DISALLOW_COPY_AND_ASSIGN(NinePatchLayer); }; } // namespace cc
diff --git a/cc/layers/nine_patch_layer_impl.h b/cc/layers/nine_patch_layer_impl.h index 5e01501d..d63163d 100644 --- a/cc/layers/nine_patch_layer_impl.h +++ b/cc/layers/nine_patch_layer_impl.h
@@ -7,7 +7,6 @@ #include <string> -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "cc/cc_export.h" #include "cc/layers/layer_impl.h" @@ -29,8 +28,11 @@ int id) { return base::WrapUnique(new NinePatchLayerImpl(tree_impl, id)); } + NinePatchLayerImpl(const NinePatchLayerImpl&) = delete; ~NinePatchLayerImpl() override; + NinePatchLayerImpl& operator=(const NinePatchLayerImpl&) = delete; + // For parameter meanings, see the declaration of NinePatchGenerator. void SetLayout(const gfx::Rect& image_aperture, const gfx::Rect& border, @@ -53,8 +55,6 @@ const char* LayerTypeAsString() const override; NinePatchGenerator quad_generator_; - - DISALLOW_COPY_AND_ASSIGN(NinePatchLayerImpl); }; } // namespace cc
diff --git a/cc/layers/painted_overlay_scrollbar_layer.h b/cc/layers/painted_overlay_scrollbar_layer.h index 674a7266..931d96c 100644 --- a/cc/layers/painted_overlay_scrollbar_layer.h +++ b/cc/layers/painted_overlay_scrollbar_layer.h
@@ -5,7 +5,6 @@ #ifndef CC_LAYERS_PAINTED_OVERLAY_SCROLLBAR_LAYER_H_ #define CC_LAYERS_PAINTED_OVERLAY_SCROLLBAR_LAYER_H_ -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/input/scrollbar.h" #include "cc/layers/layer.h" @@ -20,6 +19,9 @@ public: std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; + PaintedOverlayScrollbarLayer(const PaintedOverlayScrollbarLayer&) = delete; + PaintedOverlayScrollbarLayer& operator=(const PaintedOverlayScrollbarLayer&) = + delete; static scoped_refptr<PaintedOverlayScrollbarLayer> Create( std::unique_ptr<Scrollbar> scrollbar, ElementId scroll_element_id = ElementId()); @@ -66,8 +68,6 @@ std::unique_ptr<ScopedUIResource> thumb_resource_; std::unique_ptr<ScopedUIResource> track_resource_; - - DISALLOW_COPY_AND_ASSIGN(PaintedOverlayScrollbarLayer); }; } // namespace cc
diff --git a/cc/layers/painted_overlay_scrollbar_layer_impl.h b/cc/layers/painted_overlay_scrollbar_layer_impl.h index 37bdce9..36b2900 100644 --- a/cc/layers/painted_overlay_scrollbar_layer_impl.h +++ b/cc/layers/painted_overlay_scrollbar_layer_impl.h
@@ -5,7 +5,6 @@ #ifndef CC_LAYERS_PAINTED_OVERLAY_SCROLLBAR_LAYER_IMPL_H_ #define CC_LAYERS_PAINTED_OVERLAY_SCROLLBAR_LAYER_IMPL_H_ -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/input/scrollbar.h" #include "cc/layers/nine_patch_generator.h" @@ -24,6 +23,10 @@ int id, ScrollbarOrientation orientation, bool is_left_side_vertical_scrollbar); + PaintedOverlayScrollbarLayerImpl(const PaintedOverlayScrollbarLayerImpl&) = + delete; + PaintedOverlayScrollbarLayerImpl& operator=( + const PaintedOverlayScrollbarLayerImpl&) = delete; ~PaintedOverlayScrollbarLayerImpl() override; // LayerImpl implementation. @@ -89,8 +92,6 @@ gfx::Rect aperture_; NinePatchGenerator quad_generator_; - - DISALLOW_COPY_AND_ASSIGN(PaintedOverlayScrollbarLayerImpl); }; } // namespace cc
diff --git a/cc/layers/painted_scrollbar_layer.h b/cc/layers/painted_scrollbar_layer.h index 6f293bf5..eac5321 100644 --- a/cc/layers/painted_scrollbar_layer.h +++ b/cc/layers/painted_scrollbar_layer.h
@@ -5,7 +5,6 @@ #ifndef CC_LAYERS_PAINTED_SCROLLBAR_LAYER_H_ #define CC_LAYERS_PAINTED_SCROLLBAR_LAYER_H_ -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/input/scrollbar.h" #include "cc/layers/layer.h" @@ -24,6 +23,9 @@ std::unique_ptr<Scrollbar> scrollbar, ElementId element_id = ElementId()); + PaintedScrollbarLayer(const PaintedScrollbarLayer&) = delete; + PaintedScrollbarLayer& operator=(const PaintedScrollbarLayer&) = delete; + bool OpacityCanAnimateOnImplThread() const override; // ScrollbarLayerInterface @@ -89,8 +91,6 @@ std::unique_ptr<ScopedUIResource> thumb_resource_; float thumb_opacity_; - - DISALLOW_COPY_AND_ASSIGN(PaintedScrollbarLayer); }; } // namespace cc
diff --git a/cc/layers/painted_scrollbar_layer_impl.h b/cc/layers/painted_scrollbar_layer_impl.h index a76b642..ad4daae0 100644 --- a/cc/layers/painted_scrollbar_layer_impl.h +++ b/cc/layers/painted_scrollbar_layer_impl.h
@@ -5,7 +5,6 @@ #ifndef CC_LAYERS_PAINTED_SCROLLBAR_LAYER_IMPL_H_ #define CC_LAYERS_PAINTED_SCROLLBAR_LAYER_IMPL_H_ -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/input/scrollbar.h" #include "cc/layers/scrollbar_layer_impl_base.h" @@ -23,8 +22,12 @@ ScrollbarOrientation orientation, bool is_left_side_vertical_scrollbar, bool is_overlay); + PaintedScrollbarLayerImpl(const PaintedScrollbarLayerImpl&) = delete; ~PaintedScrollbarLayerImpl() override; + PaintedScrollbarLayerImpl& operator=(const PaintedScrollbarLayerImpl&) = + delete; + // LayerImpl implementation. std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void PushPropertiesTo(LayerImpl* layer) override; @@ -87,8 +90,6 @@ int thumb_length_; int track_start_; int track_length_; - - DISALLOW_COPY_AND_ASSIGN(PaintedScrollbarLayerImpl); }; } // namespace cc
diff --git a/cc/layers/picture_image_layer.h b/cc/layers/picture_image_layer.h index c51da8b..b9a424f 100644 --- a/cc/layers/picture_image_layer.h +++ b/cc/layers/picture_image_layer.h
@@ -7,7 +7,6 @@ #include <stddef.h> -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/layers/content_layer_client.h" #include "cc/layers/picture_layer.h" @@ -21,6 +20,9 @@ public: static scoped_refptr<PictureImageLayer> Create(); + PictureImageLayer(const PictureImageLayer&) = delete; + PictureImageLayer& operator=(const PictureImageLayer&) = delete; + void SetImage(PaintImage image, const SkMatrix& matrix, bool uses_width_as_height); @@ -46,8 +48,6 @@ PaintImage image_; SkMatrix matrix_; bool uses_width_as_height_; - - DISALLOW_COPY_AND_ASSIGN(PictureImageLayer); }; } // namespace cc
diff --git a/cc/layers/picture_layer.h b/cc/layers/picture_layer.h index dc53696..48ea872 100644 --- a/cc/layers/picture_layer.h +++ b/cc/layers/picture_layer.h
@@ -7,7 +7,6 @@ #include <vector> -#include "base/macros.h" #include "cc/base/devtools_instrumentation.h" #include "cc/base/invalidation_region.h" #include "cc/benchmarks/micro_benchmark_controller.h" @@ -23,6 +22,9 @@ public: static scoped_refptr<PictureLayer> Create(ContentLayerClient* client); + PictureLayer(const PictureLayer&) = delete; + PictureLayer& operator=(const PictureLayer&) = delete; + void ClearClient(); void SetNearestNeighbor(bool nearest_neighbor); @@ -98,8 +100,6 @@ int update_source_frame_number_; LayerMaskType mask_type_; - - DISALLOW_COPY_AND_ASSIGN(PictureLayer); }; } // namespace cc
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h index 6f85085..82309bd 100644 --- a/cc/layers/picture_layer_impl.h +++ b/cc/layers/picture_layer_impl.h
@@ -11,7 +11,6 @@ #include <string> #include <vector> -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "cc/cc_export.h" #include "cc/layers/layer.h" @@ -37,8 +36,11 @@ Create(LayerTreeImpl* tree_impl, int id, Layer::LayerMaskType mask_type) { return base::WrapUnique(new PictureLayerImpl(tree_impl, id, mask_type)); } + PictureLayerImpl(const PictureLayerImpl&) = delete; ~PictureLayerImpl() override; + PictureLayerImpl& operator=(const PictureLayerImpl&) = delete; + Layer::LayerMaskType mask_type() const { return mask_type_; } void SetLayerMaskType(Layer::LayerMaskType type); @@ -205,8 +207,6 @@ // of comparing pointers, since objects pointed to are not guaranteed to // exist. std::vector<PictureLayerTiling*> last_append_quads_tilings_; - - DISALLOW_COPY_AND_ASSIGN(PictureLayerImpl); }; } // namespace cc
diff --git a/cc/layers/picture_layer_impl_perftest.cc b/cc/layers/picture_layer_impl_perftest.cc index 281beab..443203e0a 100644 --- a/cc/layers/picture_layer_impl_perftest.cc +++ b/cc/layers/picture_layer_impl_perftest.cc
@@ -4,7 +4,6 @@ #include "cc/layers/picture_layer_impl.h" -#include "base/macros.h" #include "base/threading/thread_task_runner_handle.h" #include "base/timer/lap_timer.h" #include "cc/test/fake_impl_task_runner_provider.h" @@ -50,6 +49,9 @@ base::TimeDelta::FromMilliseconds(kTimeLimitMillis), kTimeCheckInterval) {} + PictureLayerImplPerfTest(const PictureLayerImplPerfTest&) = delete; + PictureLayerImplPerfTest& operator=(const PictureLayerImplPerfTest&) = delete; + void SetUp() override { host_impl_.SetVisible(true); host_impl_.InitializeFrameSink(layer_tree_frame_sink_.get()); @@ -175,9 +177,6 @@ FakeLayerTreeHostImpl host_impl_; FakePictureLayerImpl* pending_layer_; base::LapTimer timer_; - - private: - DISALLOW_COPY_AND_ASSIGN(PictureLayerImplPerfTest); }; TEST_F(PictureLayerImplPerfTest, TilingSetRasterQueueConstructAndIterate) {
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index 00cbffe..2af18ee 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -12,7 +12,6 @@ #include <utility> #include "base/location.h" -#include "base/macros.h" #include "base/stl_util.h" #include "base/threading/thread_task_runner_handle.h" #include "cc/animation/animation_host.h"
diff --git a/cc/layers/recording_source.h b/cc/layers/recording_source.h index 7469a11..a67d51b 100644 --- a/cc/layers/recording_source.h +++ b/cc/layers/recording_source.h
@@ -9,7 +9,6 @@ #include <memory> -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "cc/base/invalidation_region.h" #include "cc/cc_export.h" @@ -36,8 +35,11 @@ }; RecordingSource(); + RecordingSource(const RecordingSource&) = delete; virtual ~RecordingSource(); + RecordingSource& operator=(const RecordingSource&) = delete; + bool UpdateAndExpandInvalidation(Region* invalidation, const gfx::Size& layer_size, const gfx::Rect& new_recorded_viewport); @@ -82,8 +84,6 @@ void DetermineIfSolidColor(); InvalidationRegion invalidation_; - - DISALLOW_COPY_AND_ASSIGN(RecordingSource); }; } // namespace cc
diff --git a/cc/layers/render_surface_impl.cc b/cc/layers/render_surface_impl.cc index 6272461..ea81934 100644 --- a/cc/layers/render_surface_impl.cc +++ b/cc/layers/render_surface_impl.cc
@@ -403,7 +403,7 @@ viz::SharedQuadState* shared_quad_state = render_pass->CreateAndAppendSharedQuadState(); shared_quad_state->SetAll( - draw_transform(), content_rect(), content_rect(), + draw_transform(), content_rect(), content_rect(), rounded_corner_bounds(), draw_properties_.clip_rect, draw_properties_.is_clipped, contents_opaque, draw_properties_.draw_opacity, BlendMode(), sorting_context_id);
diff --git a/cc/layers/render_surface_impl.h b/cc/layers/render_surface_impl.h index b63fc7f..15dd8c9 100644 --- a/cc/layers/render_surface_impl.h +++ b/cc/layers/render_surface_impl.h
@@ -11,7 +11,6 @@ #include <string> #include <vector> -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/layers/draw_mode.h" #include "cc/layers/layer_collections.h" @@ -35,8 +34,11 @@ class CC_EXPORT RenderSurfaceImpl { public: RenderSurfaceImpl(LayerTreeImpl* layer_tree_impl, uint64_t stable_id); + RenderSurfaceImpl(const RenderSurfaceImpl&) = delete; virtual ~RenderSurfaceImpl(); + RenderSurfaceImpl& operator=(const RenderSurfaceImpl&) = delete; + // Returns the RenderSurfaceImpl that this render surface contributes to. Root // render surface's render_target is itself. RenderSurfaceImpl* render_target(); @@ -252,8 +254,6 @@ const RenderSurfaceImpl* nearest_occlusion_immune_ancestor_; std::unique_ptr<DamageTracker> damage_tracker_; - - DISALLOW_COPY_AND_ASSIGN(RenderSurfaceImpl); }; } // namespace cc
diff --git a/cc/layers/scrollbar_layer_impl_base.h b/cc/layers/scrollbar_layer_impl_base.h index 8c38e0e..b3cae4b 100644 --- a/cc/layers/scrollbar_layer_impl_base.h +++ b/cc/layers/scrollbar_layer_impl_base.h
@@ -6,7 +6,6 @@ #define CC_LAYERS_SCROLLBAR_LAYER_IMPL_BASE_H_ #include "base/containers/flat_set.h" -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/input/scrollbar.h" #include "cc/layers/layer.h" @@ -19,6 +18,9 @@ class CC_EXPORT ScrollbarLayerImplBase : public LayerImpl { public: + ScrollbarLayerImplBase(const ScrollbarLayerImplBase&) = delete; + ScrollbarLayerImplBase& operator=(const ScrollbarLayerImplBase&) = delete; + ElementId scroll_element_id() const { return scroll_element_id_; } void SetScrollElementId(ElementId scroll_element_id); @@ -103,8 +105,6 @@ FRIEND_TEST_ALL_PREFIXES(ScrollbarLayerTest, ScrollElementIdPushedAcrossCommit); - - DISALLOW_COPY_AND_ASSIGN(ScrollbarLayerImplBase); }; using ScrollbarSet = base::flat_set<ScrollbarLayerImplBase*>;
diff --git a/cc/layers/scrollbar_layer_interface.h b/cc/layers/scrollbar_layer_interface.h index a246fca9..661028e4 100644 --- a/cc/layers/scrollbar_layer_interface.h +++ b/cc/layers/scrollbar_layer_interface.h
@@ -5,7 +5,6 @@ #ifndef CC_LAYERS_SCROLLBAR_LAYER_INTERFACE_H_ #define CC_LAYERS_SCROLLBAR_LAYER_INTERFACE_H_ -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/input/scrollbar.h" @@ -13,14 +12,14 @@ class CC_EXPORT ScrollbarLayerInterface { public: + ScrollbarLayerInterface(const ScrollbarLayerInterface&) = delete; + ScrollbarLayerInterface& operator=(const ScrollbarLayerInterface&) = delete; + virtual void SetScrollElementId(ElementId element_id) = 0; protected: ScrollbarLayerInterface() {} virtual ~ScrollbarLayerInterface() {} - - private: - DISALLOW_COPY_AND_ASSIGN(ScrollbarLayerInterface); }; } // namespace cc
diff --git a/cc/layers/solid_color_layer.h b/cc/layers/solid_color_layer.h index 653dd8a..7b97ac046 100644 --- a/cc/layers/solid_color_layer.h +++ b/cc/layers/solid_color_layer.h
@@ -6,7 +6,6 @@ #ifndef CC_LAYERS_SOLID_COLOR_LAYER_H_ #define CC_LAYERS_SOLID_COLOR_LAYER_H_ -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/layers/layer.h" @@ -18,6 +17,9 @@ public: static scoped_refptr<SolidColorLayer> Create(); + SolidColorLayer(const SolidColorLayer&) = delete; + SolidColorLayer& operator=(const SolidColorLayer&) = delete; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void SetBackgroundColor(SkColor color) override; @@ -27,8 +29,6 @@ private: ~SolidColorLayer() override; - - DISALLOW_COPY_AND_ASSIGN(SolidColorLayer); }; } // namespace cc
diff --git a/cc/layers/solid_color_layer_impl.h b/cc/layers/solid_color_layer_impl.h index 78a35a4..68d1e1a 100644 --- a/cc/layers/solid_color_layer_impl.h +++ b/cc/layers/solid_color_layer_impl.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "cc/cc_export.h" #include "cc/layers/layer_impl.h" @@ -21,6 +20,9 @@ return base::WrapUnique(new SolidColorLayerImpl(tree_impl, id)); } + SolidColorLayerImpl(const SolidColorLayerImpl&) = delete; + SolidColorLayerImpl& operator=(const SolidColorLayerImpl&) = delete; + static void AppendSolidQuads(viz::RenderPass* render_pass, const Occlusion& occlusion_in_layer_space, viz::SharedQuadState* shared_quad_state, @@ -42,8 +44,6 @@ private: const char* LayerTypeAsString() const override; - - DISALLOW_COPY_AND_ASSIGN(SolidColorLayerImpl); }; } // namespace cc
diff --git a/cc/layers/solid_color_scrollbar_layer.h b/cc/layers/solid_color_scrollbar_layer.h index 69bcc4f..67c4adb2 100644 --- a/cc/layers/solid_color_scrollbar_layer.h +++ b/cc/layers/solid_color_scrollbar_layer.h
@@ -5,7 +5,6 @@ #ifndef CC_LAYERS_SOLID_COLOR_SCROLLBAR_LAYER_H_ #define CC_LAYERS_SOLID_COLOR_SCROLLBAR_LAYER_H_ -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/layers/layer.h" #include "cc/layers/scrollbar_layer_interface.h" @@ -24,6 +23,9 @@ bool is_left_side_vertical_scrollbar, ElementId scroll_element_id); + SolidColorScrollbarLayer(const SolidColorScrollbarLayer&) = delete; + SolidColorScrollbarLayer& operator=(const SolidColorScrollbarLayer&) = delete; + // Layer overrides. bool OpacityCanAnimateOnImplThread() const override; @@ -63,8 +65,6 @@ }; SolidColorScrollbarLayerInputs solid_color_scrollbar_layer_inputs_; - - DISALLOW_COPY_AND_ASSIGN(SolidColorScrollbarLayer); }; } // namespace cc
diff --git a/cc/layers/surface_layer.cc b/cc/layers/surface_layer.cc index afe7d8e..0bc24a03 100644 --- a/cc/layers/surface_layer.cc +++ b/cc/layers/surface_layer.cc
@@ -6,7 +6,6 @@ #include <stdint.h> -#include "base/macros.h" #include "base/trace_event/trace_event.h" #include "cc/layers/surface_layer_impl.h" #include "cc/trees/layer_tree_host.h"
diff --git a/cc/layers/surface_layer.h b/cc/layers/surface_layer.h index 61c7830..9d15812 100644 --- a/cc/layers/surface_layer.h +++ b/cc/layers/surface_layer.h
@@ -5,7 +5,6 @@ #ifndef CC_LAYERS_SURFACE_LAYER_H_ #define CC_LAYERS_SURFACE_LAYER_H_ -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/layers/deadline_policy.h" #include "cc/layers/layer.h" @@ -27,6 +26,9 @@ static scoped_refptr<SurfaceLayer> Create(); static scoped_refptr<SurfaceLayer> Create(UpdateSubmissionStateCB); + SurfaceLayer(const SurfaceLayer&) = delete; + SurfaceLayer& operator=(const SurfaceLayer&) = delete; + void SetSurfaceId(const viz::SurfaceId& surface_id, const DeadlinePolicy& deadline_policy); void SetOldestAcceptableFallback(const viz::SurfaceId& surface_id); @@ -88,8 +90,6 @@ // TODO(sunxd): consider renaming it to oopif_has_pointer_events_none_ for // disambiguation. bool has_pointer_events_none_ = false; - - DISALLOW_COPY_AND_ASSIGN(SurfaceLayer); }; } // namespace cc
diff --git a/cc/layers/surface_layer_impl.h b/cc/layers/surface_layer_impl.h index d00a8ba..4daa923 100644 --- a/cc/layers/surface_layer_impl.h +++ b/cc/layers/surface_layer_impl.h
@@ -8,7 +8,6 @@ #include <memory> #include "base/bind.h" -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "cc/cc_export.h" #include "cc/layers/layer_impl.h" @@ -38,8 +37,11 @@ new SurfaceLayerImpl(tree_impl, id, base::BindRepeating([](bool) {}))); } + SurfaceLayerImpl(const SurfaceLayerImpl&) = delete; ~SurfaceLayerImpl() override; + SurfaceLayerImpl& operator=(const SurfaceLayerImpl&) = delete; + void SetRange(const viz::SurfaceRange& surface_range, base::Optional<uint32_t> deadline_in_frames); const viz::SurfaceRange& range() const { return surface_range_; } @@ -92,8 +94,6 @@ bool surface_hit_testable_ = false; bool has_pointer_events_none_ = false; bool will_draw_ = false; - - DISALLOW_COPY_AND_ASSIGN(SurfaceLayerImpl); }; } // namespace cc
diff --git a/cc/layers/texture_layer.h b/cc/layers/texture_layer.h index b5d59931..dc9bd63 100644 --- a/cc/layers/texture_layer.h +++ b/cc/layers/texture_layer.h
@@ -8,7 +8,6 @@ #include <string> #include "base/callback.h" -#include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" @@ -43,14 +42,21 @@ class CC_EXPORT MainThreadReference { public: explicit MainThreadReference(TransferableResourceHolder* holder); + MainThreadReference(const MainThreadReference&) = delete; ~MainThreadReference(); + + MainThreadReference& operator=(const MainThreadReference&) = delete; + TransferableResourceHolder* holder() { return holder_.get(); } private: scoped_refptr<TransferableResourceHolder> holder_; - DISALLOW_COPY_AND_ASSIGN(MainThreadReference); }; + TransferableResourceHolder(const TransferableResourceHolder&) = delete; + TransferableResourceHolder& operator=(const TransferableResourceHolder&) = + delete; + const viz::TransferableResource& resource() const { return resource_; } void Return(const gpu::SyncToken& sync_token, bool is_lost); @@ -102,13 +108,15 @@ gpu::SyncToken sync_token_; bool is_lost_ = false; base::ThreadChecker main_thread_checker_; - DISALLOW_COPY_AND_ASSIGN(TransferableResourceHolder); }; // Used when mailbox names are specified instead of texture IDs. static scoped_refptr<TextureLayer> CreateForMailbox( TextureLayerClient* client); + TextureLayer(const TextureLayer&) = delete; + TextureLayer& operator=(const TextureLayer&) = delete; + // Resets the client, which also resets the texture. void ClearClient(); @@ -215,8 +223,6 @@ std::vector<viz::SharedBitmapId> to_unregister_bitmap_ids_; base::WeakPtrFactory<TextureLayer> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(TextureLayer); }; } // namespace cc
diff --git a/cc/layers/texture_layer_impl.h b/cc/layers/texture_layer_impl.h index 51da8cd..d2ae0db 100644 --- a/cc/layers/texture_layer_impl.h +++ b/cc/layers/texture_layer_impl.h
@@ -9,7 +9,6 @@ #include "base/callback.h" #include "base/containers/flat_map.h" -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "cc/cc_export.h" #include "cc/layers/layer_impl.h" @@ -28,8 +27,11 @@ int id) { return base::WrapUnique(new TextureLayerImpl(tree_impl, id)); } + TextureLayerImpl(const TextureLayerImpl&) = delete; ~TextureLayerImpl() override; + TextureLayerImpl& operator=(const TextureLayerImpl&) = delete; + std::unique_ptr<LayerImpl> CreateLayerImpl( LayerTreeImpl* layer_tree_impl) override; bool IsSnappedToPixelGridInTarget() override; @@ -123,8 +125,6 @@ // As a pending layer, the set of SharedBitmapIds that the active layer should // unregister. std::vector<viz::SharedBitmapId> to_unregister_bitmap_ids_; - - DISALLOW_COPY_AND_ASSIGN(TextureLayerImpl); }; } // namespace cc
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc index c85b89e9..64697a6c 100644 --- a/cc/layers/texture_layer_unittest.cc +++ b/cc/layers/texture_layer_unittest.cc
@@ -13,7 +13,6 @@ #include "base/bind.h" #include "base/callback.h" #include "base/location.h" -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h"
diff --git a/cc/layers/ui_resource_layer.h b/cc/layers/ui_resource_layer.h index 57d2f03..529ef85 100644 --- a/cc/layers/ui_resource_layer.h +++ b/cc/layers/ui_resource_layer.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/layers/layer.h" #include "cc/resources/ui_resource_client.h" @@ -21,6 +20,9 @@ public: static scoped_refptr<UIResourceLayer> Create(); + UIResourceLayer(const UIResourceLayer&) = delete; + UIResourceLayer& operator=(const UIResourceLayer&) = delete; + void PushPropertiesTo(LayerImpl* layer) override; void SetLayerTreeHost(LayerTreeHost* host) override; @@ -66,8 +68,6 @@ gfx::PointF uv_top_left_; gfx::PointF uv_bottom_right_; float vertex_opacity_[4]; - - DISALLOW_COPY_AND_ASSIGN(UIResourceLayer); }; } // namespace cc
diff --git a/cc/layers/ui_resource_layer_impl.h b/cc/layers/ui_resource_layer_impl.h index 1283a23..f1ad51d0 100644 --- a/cc/layers/ui_resource_layer_impl.h +++ b/cc/layers/ui_resource_layer_impl.h
@@ -7,7 +7,6 @@ #include <string> -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "cc/cc_export.h" #include "cc/layers/layer_impl.h" @@ -31,8 +30,11 @@ int id) { return base::WrapUnique(new UIResourceLayerImpl(tree_impl, id)); } + UIResourceLayerImpl(const UIResourceLayerImpl&) = delete; ~UIResourceLayerImpl() override; + UIResourceLayerImpl& operator=(const UIResourceLayerImpl&) = delete; + void SetUIResourceId(UIResourceId uid); void SetImageBounds(const gfx::Size& image_bounds); @@ -68,8 +70,6 @@ private: const char* LayerTypeAsString() const override; - - DISALLOW_COPY_AND_ASSIGN(UIResourceLayerImpl); }; } // namespace cc
diff --git a/cc/layers/video_frame_provider_client_impl.h b/cc/layers/video_frame_provider_client_impl.h index 6c11f72..2798dd01 100644 --- a/cc/layers/video_frame_provider_client_impl.h +++ b/cc/layers/video_frame_provider_client_impl.h
@@ -5,7 +5,6 @@ #ifndef CC_LAYERS_VIDEO_FRAME_PROVIDER_CLIENT_IMPL_H_ #define CC_LAYERS_VIDEO_FRAME_PROVIDER_CLIENT_IMPL_H_ -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" #include "base/threading/thread_checker.h" @@ -33,6 +32,10 @@ VideoFrameProvider* provider, VideoFrameControllerClient* client); + VideoFrameProviderClientImpl(const VideoFrameProviderClientImpl&) = delete; + VideoFrameProviderClientImpl& operator=(const VideoFrameProviderClientImpl&) = + delete; + VideoLayerImpl* ActiveVideoLayer() const; void SetActiveVideoLayer(VideoLayerImpl* video_layer); @@ -82,8 +85,6 @@ // from returning until the frame controller is done using the frame. base::Lock provider_lock_; base::ThreadChecker thread_checker_; - - DISALLOW_COPY_AND_ASSIGN(VideoFrameProviderClientImpl); }; } // namespace cc
diff --git a/cc/layers/video_frame_provider_client_impl_unittest.cc b/cc/layers/video_frame_provider_client_impl_unittest.cc index 32627b8..5d03c67 100644 --- a/cc/layers/video_frame_provider_client_impl_unittest.cc +++ b/cc/layers/video_frame_provider_client_impl_unittest.cc
@@ -3,7 +3,6 @@ // found in the LICENSE file. #include "cc/layers/video_frame_provider_client_impl.h" -#include "base/macros.h" #include "cc/layers/video_layer_impl.h" #include "cc/test/fake_video_frame_provider.h" #include "cc/test/layer_test_common.h" @@ -40,6 +39,8 @@ base::TimeDelta())) { DebugSetImplThreadAndMainThreadBlocked(impl_.task_runner_provider()); } + VideoFrameProviderClientImplTest(const VideoFrameProviderClientImplTest&) = + delete; ~VideoFrameProviderClientImplTest() override { if (!client_impl_->Stopped()) { @@ -51,6 +52,9 @@ provider_.SetVideoFrameProviderClient(nullptr); } + VideoFrameProviderClientImplTest& operator=( + const VideoFrameProviderClientImplTest&) = delete; + void StartRendering() { EXPECT_CALL(*this, AddVideoFrameController(_)); client_impl_->StartRendering(); @@ -92,9 +96,6 @@ scoped_refptr<VideoFrameProviderClientImpl> client_impl_; VideoLayerImpl* video_layer_impl_; scoped_refptr<media::VideoFrame> test_frame_; - - private: - DISALLOW_COPY_AND_ASSIGN(VideoFrameProviderClientImplTest); }; TEST_F(VideoFrameProviderClientImplTest, StartStopRendering) {
diff --git a/cc/layers/video_layer.h b/cc/layers/video_layer.h index 02919b1..0ae52c8 100644 --- a/cc/layers/video_layer.h +++ b/cc/layers/video_layer.h
@@ -6,7 +6,6 @@ #define CC_LAYERS_VIDEO_LAYER_H_ #include "base/callback.h" -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/layers/layer.h" #include "media/base/video_rotation.h" @@ -24,6 +23,9 @@ static scoped_refptr<VideoLayer> Create(VideoFrameProvider* provider, media::VideoRotation video_rotation); + VideoLayer(const VideoLayer&) = delete; + VideoLayer& operator=(const VideoLayer&) = delete; + std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; bool Update() override; @@ -40,8 +42,6 @@ VideoFrameProvider* provider_; media::VideoRotation video_rotation_; - - DISALLOW_COPY_AND_ASSIGN(VideoLayer); }; } // namespace cc
diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc index eab1e6a..b76baeb 100644 --- a/cc/layers/video_layer_impl.cc +++ b/cc/layers/video_layer_impl.cc
@@ -159,8 +159,9 @@ return; updater_->AppendQuads( - render_pass, frame_, transform, quad_rect, visible_quad_rect, clip_rect(), - is_clipped(), contents_opaque(), draw_opacity(), GetSortingContextId()); + render_pass, frame_, transform, quad_rect, visible_quad_rect, + draw_properties().rounded_corner_bounds, clip_rect(), is_clipped(), + contents_opaque(), draw_opacity(), GetSortingContextId()); } void VideoLayerImpl::DidDraw(viz::ClientResourceProvider* resource_provider) {
diff --git a/cc/layers/video_layer_impl.h b/cc/layers/video_layer_impl.h index 4b3646b..0f715c7 100644 --- a/cc/layers/video_layer_impl.h +++ b/cc/layers/video_layer_impl.h
@@ -7,7 +7,6 @@ #include <vector> -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/layers/layer_impl.h" #include "components/viz/common/resources/release_callback.h" @@ -31,8 +30,11 @@ int id, VideoFrameProvider* provider, media::VideoRotation video_rotation); + VideoLayerImpl(const VideoLayerImpl&) = delete; ~VideoLayerImpl() override; + VideoLayerImpl& operator=(const VideoLayerImpl&) = delete; + // LayerImpl implementation. std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; bool WillDraw(DrawMode draw_mode, @@ -63,8 +65,6 @@ media::VideoRotation video_rotation_; std::unique_ptr<media::VideoResourceUpdater> updater_; - - DISALLOW_COPY_AND_ASSIGN(VideoLayerImpl); }; } // namespace cc
diff --git a/cc/layers/viewport.h b/cc/layers/viewport.h index 275e826..5abe67d 100644 --- a/cc/layers/viewport.h +++ b/cc/layers/viewport.h
@@ -8,7 +8,6 @@ #include <memory> #include "base/gtest_prod_util.h" -#include "base/macros.h" #include "cc/layers/layer_impl.h" #include "ui/gfx/geometry/vector2d_f.h" @@ -38,6 +37,9 @@ static std::unique_ptr<Viewport> Create(LayerTreeHostImpl* host_impl); + Viewport(const Viewport&) = delete; + Viewport& operator=(const Viewport&) = delete; + // Differs from scrolling in that only the visual viewport is moved, without // affecting the browser controls or outer viewport. void Pan(const gfx::Vector2dF& delta); @@ -103,8 +105,6 @@ gfx::Vector2d pinch_anchor_adjustment_; FRIEND_TEST_ALL_PREFIXES(ViewportTest, ShouldAnimateViewport); - - DISALLOW_COPY_AND_ASSIGN(Viewport); }; } // namespace cc
diff --git a/cc/mojo_embedder/async_layer_tree_frame_sink.h b/cc/mojo_embedder/async_layer_tree_frame_sink.h index 91bf450..5ed49023 100644 --- a/cc/mojo_embedder/async_layer_tree_frame_sink.h +++ b/cc/mojo_embedder/async_layer_tree_frame_sink.h
@@ -9,7 +9,6 @@ #include <string> #include <vector> -#include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" #include "cc/mojo_embedder/mojo_embedder_export.h" @@ -103,9 +102,11 @@ scoped_refptr<viz::ContextProvider> context_provider, scoped_refptr<viz::RasterContextProvider> worker_context_provider, InitParams* params); - + AsyncLayerTreeFrameSink(const AsyncLayerTreeFrameSink&) = delete; ~AsyncLayerTreeFrameSink() override; + AsyncLayerTreeFrameSink& operator=(const AsyncLayerTreeFrameSink&) = delete; + const viz::HitTestDataProvider* hit_test_data_provider() const { return hit_test_data_provider_.get(); } @@ -187,8 +188,6 @@ // GraphicsPipeline.ClientName.SubmitCompositorFrameAfterBeginFrame base::HistogramBase* const submit_begin_frame_histogram_; base::WeakPtrFactory<AsyncLayerTreeFrameSink> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(AsyncLayerTreeFrameSink); }; } // namespace mojo_embedder
diff --git a/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc b/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc index cc49361e..0a6f1d6c 100644 --- a/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc +++ b/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc
@@ -39,8 +39,13 @@ base::PlatformThreadId* called_thread_id, base::RunLoop* run_loop) : called_thread_id_(called_thread_id), run_loop_(run_loop) {} + ThreadTrackingLayerTreeFrameSinkClient( + const ThreadTrackingLayerTreeFrameSinkClient&) = delete; ~ThreadTrackingLayerTreeFrameSinkClient() override = default; + ThreadTrackingLayerTreeFrameSinkClient& operator=( + const ThreadTrackingLayerTreeFrameSinkClient&) = delete; + // FakeLayerTreeFrameSinkClient: void DidLoseLayerTreeFrameSink() override { EXPECT_FALSE(did_lose_layer_tree_frame_sink_called()); @@ -52,8 +57,6 @@ private: base::PlatformThreadId* called_thread_id_; base::RunLoop* run_loop_; - - DISALLOW_COPY_AND_ASSIGN(ThreadTrackingLayerTreeFrameSinkClient); }; TEST(AsyncLayerTreeFrameSinkTest, @@ -190,7 +193,8 @@ gfx::Rect rect1(display_rect_); shared_quad_state1->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect1, - /*visible_quad_layer_rect=*/rect1, /*clip_rect=*/rect1, + /*visible_quad_layer_rect=*/rect1, + /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect1, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad1 = @@ -211,7 +215,8 @@ gfx::Rect rect2(display_rect_); shared_quad_state2->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect2, - /*visible_quad_layer_rect=*/rect2, /*clip_rect=*/rect2, + /*visible_quad_layer_rect=*/rect2, + /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect2, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad2 = @@ -239,7 +244,8 @@ transform3_0.Translate(-200, -100); shared_quad_state3_0->SetAll( transform3_0, /*quad_layer_rect=*/rect3_0, - /*visible_quad_layer_rect=*/rect3_0, /*clip_rect=*/rect3_0, + /*visible_quad_layer_rect=*/rect3_0, + /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect3_0, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad3_0 = @@ -259,7 +265,8 @@ gfx::Rect rect3_1(display_rect_); shared_quad_state3_1->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect3_1, - /*visible_quad_layer_rect=*/rect3_1, /*clip_rect=*/rect3_1, + /*visible_quad_layer_rect=*/rect3_1, + /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect3_1, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad3_1 = @@ -276,7 +283,8 @@ gfx::Rect rect3_root(display_rect_); shared_quad_state3_root->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect3_root, - /*visible_quad_layer_rect=*/rect3_root, /*clip_rect=*/rect3_root, + /*visible_quad_layer_rect=*/rect3_root, + /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect3_root, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad3_root_1 = @@ -313,7 +321,8 @@ gfx::Rect rect1(display_rect_); shared_quad_state1->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect1, - /*visible_quad_layer_rect=*/rect1, /*clip_rect=*/rect1, + /*visible_quad_layer_rect=*/rect1, + /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect1, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad1 = @@ -339,7 +348,8 @@ transform2_0.Translate(-200, -100); shared_quad_state2_0->SetAll( transform2_0, /*quad_layer_rect=*/rect2_0, - /*visible_quad_layer_rect=*/rect2_0, /*clip_rect=*/rect2_0, + /*visible_quad_layer_rect=*/rect2_0, + /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect2_0, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad2_0 = @@ -359,7 +369,8 @@ gfx::Rect rect2_1(display_rect_); shared_quad_state2_1->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect2_1, - /*visible_quad_layer_rect=*/rect2_1, /*clip_rect=*/rect2_1, + /*visible_quad_layer_rect=*/rect2_1, + /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect2_1, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad2_1 = @@ -376,7 +387,8 @@ gfx::Rect rect2_root(display_rect_); shared_quad_state2_root->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect2_root, - /*visible_quad_layer_rect=*/rect2_root, /*clip_rect=*/rect2_root, + /*visible_quad_layer_rect=*/rect2_root, + /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect2_root, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad2_root_1 = @@ -411,7 +423,8 @@ gfx::Rect rect3(display_rect_); shared_quad_state3->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect3, - /*visible_quad_layer_rect=*/rect3, /*clip_rect=*/rect3, + /*visible_quad_layer_rect=*/rect3, + /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect3, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad3 =
diff --git a/cc/paint/decode_stashing_image_provider.h b/cc/paint/decode_stashing_image_provider.h index 99a45d9..e638d03 100644 --- a/cc/paint/decode_stashing_image_provider.h +++ b/cc/paint/decode_stashing_image_provider.h
@@ -17,8 +17,12 @@ public: // |source_provider| must outlive this class. explicit DecodeStashingImageProvider(ImageProvider* source_provider); + DecodeStashingImageProvider(const DecodeStashingImageProvider&) = delete; ~DecodeStashingImageProvider() override; + DecodeStashingImageProvider& operator=(const DecodeStashingImageProvider&) = + delete; + // ImageProvider implementation. ImageProvider::ScopedResult GetRasterContent( const DrawImage& draw_image) override; @@ -30,8 +34,6 @@ private: ImageProvider* source_provider_; base::StackVector<ScopedResult, 1> decoded_images_; - - DISALLOW_COPY_AND_ASSIGN(DecodeStashingImageProvider); }; } // namespace cc
diff --git a/cc/paint/display_item_list.h b/cc/paint/display_item_list.h index a61ed5c..1eb89208 100644 --- a/cc/paint/display_item_list.h +++ b/cc/paint/display_item_list.h
@@ -12,7 +12,6 @@ #include <vector> #include "base/gtest_prod_util.h" -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/trace_event/trace_event.h" #include "cc/base/rtree.h" @@ -58,6 +57,8 @@ enum UsageHint { kTopLevelDisplayItemList, kToBeReleasedAsPaintOpBuffer }; explicit DisplayItemList(UsageHint = kTopLevelDisplayItemList); + DisplayItemList(const DisplayItemList&) = delete; + DisplayItemList& operator=(const DisplayItemList&) = delete; void Raster(SkCanvas* canvas, ImageProvider* image_provider = nullptr) const; @@ -247,7 +248,6 @@ friend class base::RefCountedThreadSafe<DisplayItemList>; FRIEND_TEST_ALL_PREFIXES(DisplayItemListTest, BytesUsed); - DISALLOW_COPY_AND_ASSIGN(DisplayItemList); }; } // namespace cc
diff --git a/cc/paint/image_provider.h b/cc/paint/image_provider.h index 9ec5b3b..6ffd8978 100644 --- a/cc/paint/image_provider.h +++ b/cc/paint/image_provider.h
@@ -28,9 +28,11 @@ explicit ScopedResult(DecodedDrawImage image); ScopedResult(DecodedDrawImage image, DestructionCallback callback); ScopedResult(const PaintRecord* record, DestructionCallback callback); + ScopedResult(const ScopedResult&) = delete; + ScopedResult(ScopedResult&& other); ~ScopedResult(); - ScopedResult(ScopedResult&& other); + ScopedResult& operator=(const ScopedResult&) = delete; ScopedResult& operator=(ScopedResult&& other); operator bool() const { return image_ || record_; } @@ -47,8 +49,6 @@ DecodedDrawImage image_; const PaintRecord* record_ = nullptr; DestructionCallback destruction_callback_; - - DISALLOW_COPY_AND_ASSIGN(ScopedResult); }; virtual ~ImageProvider() {}
diff --git a/cc/paint/oop_pixeltest.cc b/cc/paint/oop_pixeltest.cc index 2ac24c2..3e90ba7 100644 --- a/cc/paint/oop_pixeltest.cc +++ b/cc/paint/oop_pixeltest.cc
@@ -295,7 +295,8 @@ SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType); } SkImageInfo image_info = SkImageInfo::MakeN32Premul( - options.resource_size.width(), options.resource_size.height()); + options.resource_size.width(), options.resource_size.height(), + options.color_space.ToSkColorSpace()); auto surface = SkSurface::MakeRenderTarget( gles2_context_provider_->GrContext(), SkBudgeted::kYes, image_info); SkCanvas* canvas = surface->getCanvas(); @@ -307,9 +308,8 @@ gfx::AxisTransform2d raster_transform(options.post_scale, options.post_translate); raster_source->PlaybackToCanvas( - canvas, options.color_space, options.content_size, - options.full_raster_rect, options.playback_rect, raster_transform, - settings); + canvas, options.content_size, options.full_raster_rect, + options.playback_rect, raster_transform, settings); surface->prepareForExternalIO(); EXPECT_EQ(gles2_context_provider_->ContextGL()->GetError(), static_cast<unsigned>(GL_NO_ERROR));
diff --git a/cc/paint/paint_cache.h b/cc/paint/paint_cache.h index 3413f43..f4467014 100644 --- a/cc/paint/paint_cache.h +++ b/cc/paint/paint_cache.h
@@ -50,8 +50,11 @@ class CC_PAINT_EXPORT ClientPaintCache { public: explicit ClientPaintCache(size_t max_budget_bytes); + ClientPaintCache(const ClientPaintCache&) = delete; ~ClientPaintCache(); + ClientPaintCache& operator=(const ClientPaintCache&) = delete; + bool Get(PaintCacheDataType type, PaintCacheId id); void Put(PaintCacheDataType type, PaintCacheId id, size_t size); @@ -89,8 +92,6 @@ // send them to the service-side cache. This is necessary to ensure we // maintain an accurate mirror of the service-side state. base::StackVector<CacheKey, 1> pending_entries_; - - DISALLOW_COPY_AND_ASSIGN(ClientPaintCache); }; class CC_PAINT_EXPORT ServicePaintCache {
diff --git a/cc/paint/paint_canvas.h b/cc/paint/paint_canvas.h index 342e20e4..0f0c694e 100644 --- a/cc/paint/paint_canvas.h +++ b/cc/paint/paint_canvas.h
@@ -6,7 +6,6 @@ #define CC_PAINT_PAINT_CANVAS_H_ #include "base/compiler_specific.h" -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "build/build_config.h" #include "cc/paint/paint_export.h" @@ -42,8 +41,11 @@ // from SkCanvas to PaintCanvas or from SkPicture back into PaintRecord. class CC_PAINT_EXPORT PaintCanvas { public: - PaintCanvas() {} - virtual ~PaintCanvas() {} + PaintCanvas() = default; + PaintCanvas(const PaintCanvas&) = delete; + virtual ~PaintCanvas() = default; + + PaintCanvas& operator=(const PaintCanvas&) = delete; // TODO(enne): this only appears to mostly be used to determine if this is // recording or not, so could be simplified or removed. @@ -193,8 +195,6 @@ private: printing::MetafileSkia* metafile_ = nullptr; - - DISALLOW_COPY_AND_ASSIGN(PaintCanvas); }; class CC_PAINT_EXPORT PaintCanvasAutoRestore {
diff --git a/cc/paint/paint_filter.h b/cc/paint/paint_filter.h index 7710d501..bdf724a 100644 --- a/cc/paint/paint_filter.h +++ b/cc/paint/paint_filter.h
@@ -72,8 +72,11 @@ using MapDirection = SkImageFilter::MapDirection; using CropRect = SkImageFilter::CropRect; + PaintFilter(const PaintFilter&) = delete; ~PaintFilter() override; + PaintFilter& operator=(const PaintFilter&) = delete; + static std::string TypeToString(Type type); // Returns the size required to serialize the |filter|. Note that |filter| can @@ -156,8 +159,6 @@ const bool has_discardable_images_; ImageAnalysisState image_analysis_state_ = ImageAnalysisState::kNoAnalysis; - - DISALLOW_COPY_AND_ASSIGN(PaintFilter); }; class CC_PAINT_EXPORT ColorFilterPaintFilter final : public PaintFilter {
diff --git a/cc/paint/paint_image_generator.h b/cc/paint/paint_image_generator.h index d0ce1c7..db33427 100644 --- a/cc/paint/paint_image_generator.h +++ b/cc/paint/paint_image_generator.h
@@ -7,7 +7,6 @@ #include <vector> -#include "base/macros.h" #include "cc/paint/frame_metadata.h" #include "cc/paint/paint_export.h" #include "cc/paint/paint_image.h" @@ -25,8 +24,11 @@ // be called from any thread. class CC_PAINT_EXPORT PaintImageGenerator : public SkRefCnt { public: + PaintImageGenerator(const PaintImageGenerator&) = delete; ~PaintImageGenerator() override; + PaintImageGenerator& operator=(const PaintImageGenerator&) = delete; + // Returns a reference to the encoded content of this image. virtual sk_sp<SkData> GetEncodedData() const = 0; @@ -87,8 +89,6 @@ const SkImageInfo info_; const PaintImage::ContentId generator_content_id_; const std::vector<FrameMetadata> frames_; - - DISALLOW_COPY_AND_ASSIGN(PaintImageGenerator); }; } // namespace cc
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc index 8ab8147..99dcf00 100644 --- a/cc/paint/paint_op_buffer.cc +++ b/cc/paint/paint_op_buffer.cc
@@ -2245,7 +2245,7 @@ Reset(); } -void PaintOpBuffer::operator=(PaintOpBuffer&& other) { +PaintOpBuffer& PaintOpBuffer::operator=(PaintOpBuffer&& other) { data_ = std::move(other.data_); used_ = other.used_; reserved_ = other.reserved_; @@ -2260,6 +2260,7 @@ other.used_ = 0; other.op_count_ = 0; other.reserved_ = 0; + return *this; } void PaintOpBuffer::Reset() {
diff --git a/cc/paint/paint_op_buffer.h b/cc/paint/paint_op_buffer.h index e7e36a5..54725c8 100644 --- a/cc/paint/paint_op_buffer.h +++ b/cc/paint/paint_op_buffer.h
@@ -920,10 +920,12 @@ } PaintOpBuffer(); + PaintOpBuffer(const PaintOpBuffer&) = delete; PaintOpBuffer(PaintOpBuffer&& other); ~PaintOpBuffer() override; - void operator=(PaintOpBuffer&& other); + PaintOpBuffer& operator=(const PaintOpBuffer&) = delete; + PaintOpBuffer& operator=(PaintOpBuffer&& other); void Reset(); @@ -1230,8 +1232,6 @@ bool has_non_aa_paint_ : 1; bool has_discardable_images_ : 1; - - DISALLOW_COPY_AND_ASSIGN(PaintOpBuffer); }; } // namespace cc
diff --git a/cc/paint/paint_recorder.h b/cc/paint/paint_recorder.h index c8f1c8a..58b26fa3 100644 --- a/cc/paint/paint_recorder.h +++ b/cc/paint/paint_recorder.h
@@ -6,7 +6,6 @@ #define CC_PAINT_PAINT_RECORDER_H_ #include "base/compiler_specific.h" -#include "base/macros.h" #include "base/optional.h" #include "cc/paint/paint_record.h" #include "cc/paint/record_paint_canvas.h" @@ -18,8 +17,11 @@ class CC_PAINT_EXPORT PaintRecorder { public: PaintRecorder(); + PaintRecorder(const PaintRecorder&) = delete; ~PaintRecorder(); + PaintRecorder& operator=(const PaintRecorder&) = delete; + PaintCanvas* beginRecording(const SkRect& bounds); // TODO(enne): should make everything go through the non-rect version. @@ -38,7 +40,6 @@ private: scoped_refptr<DisplayItemList> display_item_list_; base::Optional<RecordPaintCanvas> canvas_; - DISALLOW_COPY_AND_ASSIGN(PaintRecorder); }; } // namespace cc
diff --git a/cc/paint/paint_shader.h b/cc/paint/paint_shader.h index 17cbd1f..0f715bc 100644 --- a/cc/paint/paint_shader.h +++ b/cc/paint/paint_shader.h
@@ -112,8 +112,11 @@ static size_t GetSerializedSize(const PaintShader* shader); + PaintShader(const PaintShader&) = delete; ~PaintShader() override; + PaintShader& operator=(const PaintShader&) = delete; + void set_has_animated_images(bool has_animated_images) { image_analysis_state_ = has_animated_images ? ImageAnalysisState::kAnimatedImages @@ -244,8 +247,6 @@ sk_sp<SkShader> cached_shader_; ImageAnalysisState image_analysis_state_ = ImageAnalysisState::kNoAnalysis; - - DISALLOW_COPY_AND_ASSIGN(PaintShader); }; } // namespace cc
diff --git a/cc/paint/record_paint_canvas.h b/cc/paint/record_paint_canvas.h index b0a75cc7..c32547f2 100644 --- a/cc/paint/record_paint_canvas.h +++ b/cc/paint/record_paint_canvas.h
@@ -9,7 +9,6 @@ #include "base/compiler_specific.h" #include "base/logging.h" -#include "base/macros.h" #include "base/optional.h" #include "build/build_config.h" #include "cc/paint/paint_canvas.h" @@ -25,8 +24,11 @@ class CC_PAINT_EXPORT RecordPaintCanvas final : public PaintCanvas { public: RecordPaintCanvas(DisplayItemList* list, const SkRect& bounds); + RecordPaintCanvas(const RecordPaintCanvas&) = delete; ~RecordPaintCanvas() override; + RecordPaintCanvas& operator=(const RecordPaintCanvas&) = delete; + SkImageInfo imageInfo() const override; void flush() override; @@ -130,8 +132,6 @@ // lazy initialize the canvas can still be const. mutable base::Optional<SkNoDrawCanvas> canvas_; SkRect recording_bounds_; - - DISALLOW_COPY_AND_ASSIGN(RecordPaintCanvas); }; } // namespace cc
diff --git a/cc/paint/render_surface_filters.h b/cc/paint/render_surface_filters.h index 903ae21..1ca44be5 100644 --- a/cc/paint/render_surface_filters.h +++ b/cc/paint/render_surface_filters.h
@@ -5,7 +5,6 @@ #ifndef CC_PAINT_RENDER_SURFACE_FILTERS_H_ #define CC_PAINT_RENDER_SURFACE_FILTERS_H_ -#include "base/macros.h" #include "cc/paint/paint_export.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "ui/gfx/geometry/vector2d_f.h" @@ -20,13 +19,12 @@ class CC_PAINT_EXPORT RenderSurfaceFilters { public: + RenderSurfaceFilters() = delete; + static sk_sp<PaintFilter> BuildImageFilter( const FilterOperations& filters, const gfx::SizeF& size, const gfx::Vector2dF& offset = gfx::Vector2dF(0, 0)); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(RenderSurfaceFilters); }; } // namespace cc
diff --git a/cc/paint/scoped_raster_flags.h b/cc/paint/scoped_raster_flags.h index 91a6b871..53b4b38 100644 --- a/cc/paint/scoped_raster_flags.h +++ b/cc/paint/scoped_raster_flags.h
@@ -6,7 +6,6 @@ #define CC_PAINT_SCOPED_RASTER_FLAGS_H_ #include "base/containers/stack_container.h" -#include "base/macros.h" #include "cc/paint/decode_stashing_image_provider.h" #include "cc/paint/paint_export.h" #include "cc/paint/paint_flags.h" @@ -22,8 +21,11 @@ ImageProvider* image_provider, const SkMatrix& ctm, uint8_t alpha); + ScopedRasterFlags(const ScopedRasterFlags&) = delete; ~ScopedRasterFlags(); + ScopedRasterFlags& operator=(const ScopedRasterFlags&) = delete; + // The usage of these flags should not extend beyond the lifetime of this // object. const PaintFlags* flags() const { @@ -50,8 +52,6 @@ base::Optional<PaintFlags> modified_flags_; base::Optional<DecodeStashingImageProvider> decode_stashing_image_provider_; bool decode_failed_ = false; - - DISALLOW_COPY_AND_ASSIGN(ScopedRasterFlags); }; } // namespace cc
diff --git a/cc/paint/skia_paint_canvas.h b/cc/paint/skia_paint_canvas.h index b3f665a..3f32da0 100644 --- a/cc/paint/skia_paint_canvas.h +++ b/cc/paint/skia_paint_canvas.h
@@ -9,7 +9,6 @@ #include "base/compiler_specific.h" #include "base/logging.h" -#include "base/macros.h" #include "build/build_config.h" #include "cc/paint/paint_canvas.h" #include "cc/paint/paint_flags.h" @@ -44,8 +43,11 @@ sk_sp<SkColorSpace> target_color_space, ImageProvider* image_provider = nullptr, ContextFlushes context_flushes = ContextFlushes()); + SkiaPaintCanvas(const SkiaPaintCanvas&) = delete; ~SkiaPaintCanvas() override; + SkiaPaintCanvas& operator=(const SkiaPaintCanvas&) = delete; + void reset_image_provider() { image_provider_ = nullptr; } SkImageInfo imageInfo() const override; @@ -152,8 +154,6 @@ const ContextFlushes context_flushes_; int num_of_ops_ = 0; - - DISALLOW_COPY_AND_ASSIGN(SkiaPaintCanvas); }; } // namespace cc
diff --git a/cc/paint/skia_paint_image_generator.h b/cc/paint/skia_paint_image_generator.h index 55068c2..a3c2ced 100644 --- a/cc/paint/skia_paint_image_generator.h +++ b/cc/paint/skia_paint_image_generator.h
@@ -5,7 +5,6 @@ #ifndef CC_PAINT_SKIA_PAINT_IMAGE_GENERATOR_H_ #define CC_PAINT_SKIA_PAINT_IMAGE_GENERATOR_H_ -#include "base/macros.h" #include "cc/paint/paint_export.h" #include "cc/paint/paint_image.h" #include "third_party/skia/include/core/SkImageGenerator.h" @@ -18,8 +17,11 @@ SkiaPaintImageGenerator(sk_sp<PaintImageGenerator> paint_image_generator, size_t frame_index, PaintImage::GeneratorClientId client_id); + SkiaPaintImageGenerator(const SkiaPaintImageGenerator&) = delete; ~SkiaPaintImageGenerator() override; + SkiaPaintImageGenerator& operator=(const SkiaPaintImageGenerator&) = delete; + sk_sp<SkData> onRefEncodedData() override; bool onGetPixels(const SkImageInfo&, void* pixels, @@ -36,8 +38,6 @@ sk_sp<PaintImageGenerator> paint_image_generator_; const size_t frame_index_; const PaintImage::GeneratorClientId client_id_; - - DISALLOW_COPY_AND_ASSIGN(SkiaPaintImageGenerator); }; } // namespace cc
diff --git a/cc/paint/skottie_wrapper.h b/cc/paint/skottie_wrapper.h index f4e312e..7690059 100644 --- a/cc/paint/skottie_wrapper.h +++ b/cc/paint/skottie_wrapper.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" #include "cc/paint/paint_export.h" @@ -32,6 +31,9 @@ explicit SkottieWrapper( const scoped_refptr<base::RefCountedMemory>& data_stream); explicit SkottieWrapper(std::unique_ptr<SkMemoryStream> stream); + SkottieWrapper(const SkottieWrapper&) = delete; + + SkottieWrapper& operator=(const SkottieWrapper&) = delete; // A thread safe call that will draw an image with bounds |rect| for the // frame at normalized time instant |t| onto the |canvas|. @@ -46,8 +48,6 @@ base::Lock lock_; sk_sp<skottie::Animation> animation_; - - DISALLOW_COPY_AND_ASSIGN(SkottieWrapper); }; } // namespace cc
diff --git a/cc/raster/bitmap_raster_buffer_provider.cc b/cc/raster/bitmap_raster_buffer_provider.cc index e2713a24..f94e220c 100644 --- a/cc/raster/bitmap_raster_buffer_provider.cc +++ b/cc/raster/bitmap_raster_buffer_provider.cc
@@ -9,7 +9,6 @@ #include <algorithm> -#include "base/macros.h" #include "base/strings/stringprintf.h" #include "base/trace_event/process_memory_dump.h" #include "base/trace_event/trace_event.h" @@ -54,6 +53,8 @@ resource_has_previous_content_( resource_content_id && resource_content_id == previous_content_id) { } + BitmapRasterBufferImpl(const BitmapRasterBufferImpl&) = delete; + BitmapRasterBufferImpl& operator=(const BitmapRasterBufferImpl&) = delete; // Overridden from RasterBuffer: void Playback(const RasterSource* raster_source, @@ -83,8 +84,6 @@ const gfx::ColorSpace color_space_; void* const pixels_; bool resource_has_previous_content_; - - DISALLOW_COPY_AND_ASSIGN(BitmapRasterBufferImpl); }; } // namespace
diff --git a/cc/raster/bitmap_raster_buffer_provider.h b/cc/raster/bitmap_raster_buffer_provider.h index f9c1b9e..e91ac1a4 100644 --- a/cc/raster/bitmap_raster_buffer_provider.h +++ b/cc/raster/bitmap_raster_buffer_provider.h
@@ -7,7 +7,6 @@ #include <stdint.h> -#include "base/macros.h" #include "base/values.h" #include "cc/raster/raster_buffer_provider.h" @@ -22,8 +21,12 @@ class CC_EXPORT BitmapRasterBufferProvider : public RasterBufferProvider { public: + BitmapRasterBufferProvider(const BitmapRasterBufferProvider&) = delete; ~BitmapRasterBufferProvider() override; + BitmapRasterBufferProvider& operator=(const BitmapRasterBufferProvider&) = + delete; + explicit BitmapRasterBufferProvider(LayerTreeFrameSink* frame_sink); // Overridden from RasterBufferProvider: @@ -50,8 +53,6 @@ const; LayerTreeFrameSink* const frame_sink_; - - DISALLOW_COPY_AND_ASSIGN(BitmapRasterBufferProvider); }; } // namespace cc
diff --git a/cc/raster/gpu_raster_buffer_provider.cc b/cc/raster/gpu_raster_buffer_provider.cc index c6677e1..bef3681 100644 --- a/cc/raster/gpu_raster_buffer_provider.cc +++ b/cc/raster/gpu_raster_buffer_provider.cc
@@ -7,8 +7,8 @@ #include <stdint.h> #include <algorithm> +#include <utility> -#include "base/macros.h" #include "base/metrics/histogram_macros.h" #include "base/rand_util.h" #include "base/strings/stringprintf.h" @@ -45,6 +45,7 @@ public: ScopedSkSurfaceForUnpremultiplyAndDither( viz::RasterContextProvider* context_provider, + sk_sp<SkColorSpace> color_space, const gfx::Rect& playback_rect, const gfx::Rect& raster_full_rect, const gfx::Size& max_tile_size, @@ -72,8 +73,9 @@ // Allocate a 32-bit surface for raster. We will copy from that into our // actual surface in destruction. - SkImageInfo n32Info = SkImageInfo::MakeN32Premul( - intermediate_size.width(), intermediate_size.height()); + SkImageInfo n32Info = SkImageInfo::MakeN32Premul(intermediate_size.width(), + intermediate_size.height(), + std::move(color_space)); SkSurfaceProps surface_props = viz::ClientResourceProvider::ScopedSkSurface::ComputeSurfaceProps( can_use_lcd_text); @@ -207,16 +209,18 @@ base::Optional<ScopedSkSurfaceForUnpremultiplyAndDither> scoped_dither_surface; SkSurface* surface; + sk_sp<SkColorSpace> sk_color_space = color_space.ToSkColorSpace(); if (!unpremultiply_and_dither) { - scoped_surface.emplace(context_provider->GrContext(), texture_id, - texture_target, resource_size, resource_format, - playback_settings.use_lcd_text, msaa_sample_count); + scoped_surface.emplace(context_provider->GrContext(), sk_color_space, + texture_id, texture_target, resource_size, + resource_format, playback_settings.use_lcd_text, + msaa_sample_count); surface = scoped_surface->surface(); } else { scoped_dither_surface.emplace( - context_provider, playback_rect, raster_full_rect, max_tile_size, - texture_id, resource_size, playback_settings.use_lcd_text, - msaa_sample_count); + context_provider, sk_color_space, playback_rect, raster_full_rect, + max_tile_size, texture_id, resource_size, + playback_settings.use_lcd_text, msaa_sample_count); surface = scoped_dither_surface->surface(); } @@ -234,8 +238,8 @@ canvas->discard(); gfx::Size content_size = raster_source->GetContentSize(transform.scale()); - raster_source->PlaybackToCanvas(canvas, color_space, content_size, - raster_full_rect, playback_rect, transform, + raster_source->PlaybackToCanvas(canvas, content_size, raster_full_rect, + playback_rect, transform, playback_settings); }
diff --git a/cc/raster/gpu_raster_buffer_provider.h b/cc/raster/gpu_raster_buffer_provider.h index cf72686..52fb765 100644 --- a/cc/raster/gpu_raster_buffer_provider.h +++ b/cc/raster/gpu_raster_buffer_provider.h
@@ -8,7 +8,6 @@ #include <stdint.h> #include <random> -#include "base/macros.h" #include "cc/raster/raster_buffer_provider.h" #include "gpu/command_buffer/common/sync_token.h" @@ -37,8 +36,11 @@ bool unpremultiply_and_dither_low_bit_depth_tiles, bool enable_oop_rasterization, int raster_metric_frequency = kRasterMetricFrequency); + GpuRasterBufferProvider(const GpuRasterBufferProvider&) = delete; ~GpuRasterBufferProvider() override; + GpuRasterBufferProvider& operator=(const GpuRasterBufferProvider&) = delete; + // Overridden from RasterBufferProvider: std::unique_ptr<RasterBuffer> AcquireBufferForRaster( const ResourcePool::InUsePoolResource& resource, @@ -84,8 +86,11 @@ const ResourcePool::InUsePoolResource& in_use_resource, GpuRasterBacking* backing, bool resource_has_previous_content); + RasterBufferImpl(const RasterBufferImpl&) = delete; ~RasterBufferImpl() override; + RasterBufferImpl& operator=(const RasterBufferImpl&) = delete; + // Overridden from RasterBuffer: void Playback(const RasterSource* raster_source, const gfx::Rect& raster_full_rect, @@ -113,8 +118,6 @@ // A SyncToken to be returned from the worker thread, and waited on before // using the rastered resource. gpu::SyncToken after_raster_sync_token_; - - DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl); }; struct PendingRasterQuery { @@ -163,8 +166,6 @@ // Accessed with the worker context lock acquired. std::mt19937 random_generator_; std::uniform_int_distribution<int> uniform_distribution_; - - DISALLOW_COPY_AND_ASSIGN(GpuRasterBufferProvider); }; } // namespace cc
diff --git a/cc/raster/one_copy_raster_buffer_provider.cc b/cc/raster/one_copy_raster_buffer_provider.cc index f16e9083..bbdf3744 100644 --- a/cc/raster/one_copy_raster_buffer_provider.cc +++ b/cc/raster/one_copy_raster_buffer_provider.cc
@@ -11,7 +11,6 @@ #include <utility> #include "base/debug/alias.h" -#include "base/macros.h" #include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" #include "base/trace_event/process_memory_dump.h"
diff --git a/cc/raster/one_copy_raster_buffer_provider.h b/cc/raster/one_copy_raster_buffer_provider.h index c2dec8e7..40aaf1d 100644 --- a/cc/raster/one_copy_raster_buffer_provider.h +++ b/cc/raster/one_copy_raster_buffer_provider.h
@@ -7,7 +7,6 @@ #include <stdint.h> -#include "base/macros.h" #include "base/sequenced_task_runner.h" #include "cc/raster/raster_buffer_provider.h" #include "cc/raster/staging_buffer_pool.h" @@ -39,8 +38,12 @@ bool use_gpu_memory_buffer_resources, int max_staging_buffer_usage_in_bytes, viz::ResourceFormat tile_format); + OneCopyRasterBufferProvider(const OneCopyRasterBufferProvider&) = delete; ~OneCopyRasterBufferProvider() override; + OneCopyRasterBufferProvider& operator=(const OneCopyRasterBufferProvider&) = + delete; + // Overridden from RasterBufferProvider: std::unique_ptr<RasterBuffer> AcquireBufferForRaster( const ResourcePool::InUsePoolResource& resource, @@ -87,8 +90,11 @@ const ResourcePool::InUsePoolResource& in_use_resource, OneCopyGpuBacking* backing, uint64_t previous_content_id); + RasterBufferImpl(const RasterBufferImpl&) = delete; ~RasterBufferImpl() override; + RasterBufferImpl& operator=(const RasterBufferImpl&) = delete; + // Overridden from RasterBuffer: void Playback(const RasterSource* raster_source, const gfx::Rect& raster_full_rect, @@ -115,8 +121,6 @@ // A SyncToken to be returned from the worker thread, and waited on before // using the rastered resource. gpu::SyncToken after_raster_sync_token_; - - DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl); }; void PlaybackToStagingBuffer( @@ -154,8 +158,6 @@ const viz::ResourceFormat tile_format_; StagingBufferPool staging_pool_; - - DISALLOW_COPY_AND_ASSIGN(OneCopyRasterBufferProvider); }; } // namespace cc
diff --git a/cc/raster/paint_worklet_image_provider.h b/cc/raster/paint_worklet_image_provider.h index fe67887..866a348 100644 --- a/cc/raster/paint_worklet_image_provider.h +++ b/cc/raster/paint_worklet_image_provider.h
@@ -17,17 +17,18 @@ class CC_EXPORT PaintWorkletImageProvider { public: explicit PaintWorkletImageProvider(PaintWorkletImageCache* cache); + PaintWorkletImageProvider(const PaintWorkletImageProvider&) = delete; + PaintWorkletImageProvider(PaintWorkletImageProvider&& other); ~PaintWorkletImageProvider(); - PaintWorkletImageProvider(PaintWorkletImageProvider&& other); + PaintWorkletImageProvider& operator=(const PaintWorkletImageProvider&) = + delete; PaintWorkletImageProvider& operator=(PaintWorkletImageProvider&& other); ImageProvider::ScopedResult GetPaintRecordResult(PaintWorkletInput* input); private: PaintWorkletImageCache* cache_; - - DISALLOW_COPY_AND_ASSIGN(PaintWorkletImageProvider); }; } // namespace cc
diff --git a/cc/raster/playback_image_provider.h b/cc/raster/playback_image_provider.h index 5e76746e..864ec25 100644 --- a/cc/raster/playback_image_provider.h +++ b/cc/raster/playback_image_provider.h
@@ -23,6 +23,8 @@ Settings(const Settings&) = delete; Settings(Settings&&); ~Settings(); + + Settings& operator=(const Settings&) = delete; Settings& operator=(Settings&&); // The set of image ids to skip during raster. @@ -36,9 +38,11 @@ // If no settings are provided, all images are skipped during rasterization. PlaybackImageProvider(ImageDecodeCache* cache, base::Optional<Settings>&& settings); + PlaybackImageProvider(const PlaybackImageProvider&) = delete; + PlaybackImageProvider(PlaybackImageProvider&& other); ~PlaybackImageProvider() override; - PlaybackImageProvider(PlaybackImageProvider&& other); + PlaybackImageProvider& operator=(const PlaybackImageProvider&) = delete; PlaybackImageProvider& operator=(PlaybackImageProvider&& other); // ImageProvider implementation. @@ -48,8 +52,6 @@ private: ImageDecodeCache* cache_; base::Optional<Settings> settings_; - - DISALLOW_COPY_AND_ASSIGN(PlaybackImageProvider); }; } // namespace cc
diff --git a/cc/raster/raster_buffer_provider.cc b/cc/raster/raster_buffer_provider.cc index 0e7d1c71..f5935e2 100644 --- a/cc/raster/raster_buffer_provider.cc +++ b/cc/raster/raster_buffer_provider.cc
@@ -74,7 +74,8 @@ // Uses kPremul_SkAlphaType since the result is not known to be opaque. SkImageInfo info = - SkImageInfo::MakeN32(size.width(), size.height(), kPremul_SkAlphaType); + SkImageInfo::MakeN32(size.width(), size.height(), kPremul_SkAlphaType, + target_color_space.ToSkColorSpace()); // Use unknown pixel geometry to disable LCD text. SkSurfaceProps surface_props(0, kUnknown_SkPixelGeometry); @@ -100,19 +101,18 @@ // invalid content, just crash the renderer and try again. // See: http://crbug.com/721744. CHECK(surface); - raster_source->PlaybackToCanvas(surface->getCanvas(), target_color_space, - content_size, canvas_bitmap_rect, - canvas_playback_rect, transform, - playback_settings); + raster_source->PlaybackToCanvas(surface->getCanvas(), content_size, + canvas_bitmap_rect, canvas_playback_rect, + transform, playback_settings); return; } case viz::RGBA_4444: { sk_sp<SkSurface> surface = SkSurface::MakeRaster(info, &surface_props); // TODO(reveman): Improve partial raster support by reducing the size of // playback rect passed to PlaybackToCanvas. crbug.com/519070 - raster_source->PlaybackToCanvas( - surface->getCanvas(), target_color_space, content_size, - canvas_bitmap_rect, canvas_bitmap_rect, transform, playback_settings); + raster_source->PlaybackToCanvas(surface->getCanvas(), content_size, + canvas_bitmap_rect, canvas_bitmap_rect, + transform, playback_settings); TRACE_EVENT0("cc", "RasterBufferProvider::PlaybackToMemory::ConvertRGBA4444");
diff --git a/cc/raster/raster_buffer_provider_perftest.cc b/cc/raster/raster_buffer_provider_perftest.cc index 6eb36031..b6c14bd 100644 --- a/cc/raster/raster_buffer_provider_perftest.cc +++ b/cc/raster/raster_buffer_provider_perftest.cc
@@ -5,7 +5,6 @@ #include <stddef.h> #include <stdint.h> -#include "base/macros.h" #include "base/test/test_simple_task_runner.h" #include "base/time/time.h" #include "base/timer/lap_timer.h" @@ -182,6 +181,9 @@ class PerfImageDecodeTaskImpl : public PerfTileTask { public: PerfImageDecodeTaskImpl() = default; + PerfImageDecodeTaskImpl(const PerfImageDecodeTaskImpl&) = delete; + + PerfImageDecodeTaskImpl& operator=(const PerfImageDecodeTaskImpl&) = delete; // Overridden from Task: void RunOnWorkerThread() override {} @@ -191,9 +193,6 @@ protected: ~PerfImageDecodeTaskImpl() override = default; - - private: - DISALLOW_COPY_AND_ASSIGN(PerfImageDecodeTaskImpl); }; class PerfRasterBufferProviderHelper { @@ -214,6 +213,8 @@ pool_(pool), resource_(std::move(in_use_resource)), raster_buffer_(std::move(raster_buffer)) {} + PerfRasterTaskImpl(const PerfRasterTaskImpl&) = delete; + PerfRasterTaskImpl& operator=(const PerfRasterTaskImpl&) = delete; // Overridden from Task: void RunOnWorkerThread() override {} @@ -236,8 +237,6 @@ ResourcePool* const pool_; ResourcePool::InUsePoolResource resource_; std::unique_ptr<RasterBuffer> raster_buffer_; - - DISALLOW_COPY_AND_ASSIGN(PerfRasterTaskImpl); }; class RasterBufferProviderPerfTestBase {
diff --git a/cc/raster/raster_buffer_provider_unittest.cc b/cc/raster/raster_buffer_provider_unittest.cc index 89332a7c..df22550 100644 --- a/cc/raster/raster_buffer_provider_unittest.cc +++ b/cc/raster/raster_buffer_provider_unittest.cc
@@ -15,7 +15,6 @@ #include "base/bind_helpers.h" #include "base/cancelable_callback.h" #include "base/location.h" -#include "base/macros.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/test/metrics/histogram_tester.h" @@ -72,6 +71,8 @@ id_(id), raster_buffer_(std::move(raster_buffer)), raster_source_(FakeRasterSource::CreateFilled(gfx::Size(1, 1))) {} + TestRasterTaskImpl(const TestRasterTaskImpl&) = delete; + TestRasterTaskImpl& operator=(const TestRasterTaskImpl&) = delete; // Overridden from Task: void RunOnWorkerThread() override { @@ -98,8 +99,6 @@ std::unique_ptr<RasterBuffer> raster_buffer_; scoped_refptr<RasterSource> raster_source_; GURL url_; - - DISALLOW_COPY_AND_ASSIGN(TestRasterTaskImpl); }; class BlockingTestRasterTaskImpl : public TestRasterTaskImpl { @@ -115,6 +114,9 @@ std::move(raster_buffer), dependencies), lock_(lock) {} + BlockingTestRasterTaskImpl(const BlockingTestRasterTaskImpl&) = delete; + BlockingTestRasterTaskImpl& operator=(const BlockingTestRasterTaskImpl&) = + delete; // Overridden from Task: void RunOnWorkerThread() override { @@ -127,8 +129,6 @@ private: base::Lock* lock_; - - DISALLOW_COPY_AND_ASSIGN(BlockingTestRasterTaskImpl); }; class RasterBufferProviderTest
diff --git a/cc/raster/raster_source.cc b/cc/raster/raster_source.cc index 8f510fa..8c490e48 100644 --- a/cc/raster/raster_source.cc +++ b/cc/raster/raster_source.cc
@@ -16,7 +16,6 @@ #include "cc/paint/skia_paint_canvas.h" #include "components/viz/common/traced_value.h" #include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkColorSpaceXformCanvas.h" #include "third_party/skia/include/core/SkPictureRecorder.h" #include "ui/gfx/geometry/axis_transform2d.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -111,8 +110,7 @@ } void RasterSource::PlaybackToCanvas( - SkCanvas* input_canvas, - const gfx::ColorSpace& target_color_space, + SkCanvas* raster_canvas, const gfx::Size& content_size, const gfx::Rect& canvas_bitmap_rect, const gfx::Rect& canvas_playback_rect, @@ -125,15 +123,6 @@ // Treat all subnormal values as zero for performance. ScopedSubnormalFloatDisabler disabler; - // TODO(enne): color transform needs to be replicated in gles2_cmd_decoder - SkCanvas* raster_canvas = input_canvas; - std::unique_ptr<SkCanvas> color_transform_canvas; - if (target_color_space.IsValid()) { - color_transform_canvas = SkCreateColorSpaceXformCanvas( - input_canvas, target_color_space.ToSkColorSpace()); - raster_canvas = color_transform_canvas.get(); - } - bool is_partial_raster = canvas_bitmap_rect != canvas_playback_rect; if (!requires_clear_) { // Clear opaque raster sources. Opaque rasters sources guarantee that all
diff --git a/cc/raster/raster_source.h b/cc/raster/raster_source.h index d4d45ff5..43ec5f3 100644 --- a/cc/raster/raster_source.h +++ b/cc/raster/raster_source.h
@@ -10,7 +10,6 @@ #include <memory> #include <vector> -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/debug/rendering_stats_instrumentation.h" #include "cc/layers/recording_source.h" @@ -41,6 +40,9 @@ ImageProvider* image_provider = nullptr; }; + RasterSource(const RasterSource&) = delete; + RasterSource& operator=(const RasterSource&) = delete; + // Helper function to apply a few common operations before passing the canvas // to the shorter version. This is useful for rastering into tiles. // canvas is expected to be backed by a tile, with a default state. @@ -51,7 +53,6 @@ // canvas_playback_rect can be used to replay only part of the recording in, // the content space, so only a sub-rect of the tile gets rastered. void PlaybackToCanvas(SkCanvas* canvas, - const gfx::ColorSpace& target_color_space, const gfx::Size& content_size, const gfx::Rect& canvas_bitmap_rect, const gfx::Rect& canvas_playback_rect, @@ -145,8 +146,6 @@ const gfx::Size size_; const int slow_down_raster_scale_factor_for_debug_; const float recording_scale_factor_; - - DISALLOW_COPY_AND_ASSIGN(RasterSource); }; } // namespace cc
diff --git a/cc/raster/raster_source_unittest.cc b/cc/raster/raster_source_unittest.cc index c694083..21338cf 100644 --- a/cc/raster/raster_source_unittest.cc +++ b/cc/raster/raster_source_unittest.cc
@@ -30,10 +30,6 @@ namespace cc { namespace { -gfx::ColorSpace ColorSpaceForTesting() { - return gfx::ColorSpace(); -} - TEST(RasterSourceTest, AnalyzeIsSolidUnscaled) { gfx::Size layer_bounds(400, 400); @@ -346,8 +342,8 @@ canvas.clear(SK_ColorTRANSPARENT); raster->PlaybackToCanvas( - &canvas, ColorSpaceForTesting(), content_bounds, canvas_rect, - canvas_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), + &canvas, content_bounds, canvas_rect, canvas_rect, + gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), RasterSource::PlaybackSettings()); SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); @@ -398,8 +394,8 @@ gfx::Rect raster_full_rect(content_bounds); gfx::Rect playback_rect(content_bounds); raster->PlaybackToCanvas( - &canvas, ColorSpaceForTesting(), content_bounds, raster_full_rect, - playback_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), + &canvas, content_bounds, raster_full_rect, playback_rect, + gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), RasterSource::PlaybackSettings()); { @@ -430,8 +426,8 @@ // that touches the edge pixels of the recording. playback_rect.Inset(1, 2, 0, 1); raster->PlaybackToCanvas( - &canvas, ColorSpaceForTesting(), content_bounds, raster_full_rect, - playback_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), + &canvas, content_bounds, raster_full_rect, playback_rect, + gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), RasterSource::PlaybackSettings()); SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); @@ -495,8 +491,8 @@ gfx::Rect raster_full_rect(content_bounds); gfx::Rect playback_rect(content_bounds); raster->PlaybackToCanvas( - &canvas, ColorSpaceForTesting(), content_bounds, raster_full_rect, - playback_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), + &canvas, content_bounds, raster_full_rect, playback_rect, + gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), RasterSource::PlaybackSettings()); { @@ -535,8 +531,8 @@ playback_rect = gfx::Rect(gfx::ScaleToCeiledSize(partial_bounds, contents_scale)); raster->PlaybackToCanvas( - &canvas, ColorSpaceForTesting(), content_bounds, raster_full_rect, - playback_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), + &canvas, content_bounds, raster_full_rect, playback_rect, + gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), RasterSource::PlaybackSettings()); // Test that the whole playback_rect was cleared and repainted with new alpha. @@ -576,7 +572,7 @@ SkCanvas canvas(bitmap); raster->PlaybackToCanvas( - &canvas, ColorSpaceForTesting(), content_bounds, canvas_rect, canvas_rect, + &canvas, content_bounds, canvas_rect, canvas_rect, gfx::AxisTransform2d(contents_scale, gfx::Vector2dF()), RasterSource::PlaybackSettings()); @@ -623,9 +619,8 @@ EXPECT_CALL(mock_canvas, willRestore()).InSequence(s); gfx::Size small_size(50, 50); - raster_source->PlaybackToCanvas(&mock_canvas, ColorSpaceForTesting(), size, - gfx::Rect(small_size), gfx::Rect(small_size), - gfx::AxisTransform2d(), + raster_source->PlaybackToCanvas(&mock_canvas, size, gfx::Rect(small_size), + gfx::Rect(small_size), gfx::AxisTransform2d(), RasterSource::PlaybackSettings()); }
diff --git a/cc/raster/scoped_gpu_raster.h b/cc/raster/scoped_gpu_raster.h index 9f4e0c84..0ccd91c 100644 --- a/cc/raster/scoped_gpu_raster.h +++ b/cc/raster/scoped_gpu_raster.h
@@ -8,7 +8,6 @@ #include <memory> #include "base/logging.h" -#include "base/macros.h" #include "cc/cc_export.h" namespace viz { @@ -23,15 +22,16 @@ class CC_EXPORT ScopedGpuRaster { public: explicit ScopedGpuRaster(viz::ContextProvider* context_provider); + ScopedGpuRaster(const ScopedGpuRaster&) = delete; ~ScopedGpuRaster(); + ScopedGpuRaster& operator=(const ScopedGpuRaster&) = delete; + private: void BeginGpuRaster(); void EndGpuRaster(); viz::ContextProvider* context_provider_; - - DISALLOW_COPY_AND_ASSIGN(ScopedGpuRaster); }; } // namespace cc
diff --git a/cc/raster/staging_buffer_pool.h b/cc/raster/staging_buffer_pool.h index d3331323..4b2953b 100644 --- a/cc/raster/staging_buffer_pool.h +++ b/cc/raster/staging_buffer_pool.h
@@ -11,7 +11,6 @@ #include <set> #include "base/containers/circular_deque.h" -#include "base/macros.h" #include "base/memory/memory_pressure_listener.h" #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner.h" @@ -81,12 +80,15 @@ class CC_EXPORT StagingBufferPool : public base::trace_event::MemoryDumpProvider { public: - ~StagingBufferPool() final; - StagingBufferPool(scoped_refptr<base::SequencedTaskRunner> task_runner, viz::RasterContextProvider* worker_context_provider, bool use_partial_raster, int max_staging_buffer_usage_in_bytes); + StagingBufferPool(const StagingBufferPool&) = delete; + ~StagingBufferPool() final; + + StagingBufferPool& operator=(const StagingBufferPool&) = delete; + void Shutdown(); // Overridden from base::trace_event::MemoryDumpProvider: @@ -141,8 +143,6 @@ std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; base::WeakPtrFactory<StagingBufferPool> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(StagingBufferPool); }; } // namespace cc
diff --git a/cc/raster/task.h b/cc/raster/task.h index d67cb7a..5369543 100644 --- a/cc/raster/task.h +++ b/cc/raster/task.h
@@ -112,18 +112,17 @@ uint16_t category, uint16_t priority, uint32_t dependencies); + Node(const Node&) = delete; Node(Node&& other); ~Node(); + Node& operator=(const Node&) = delete; Node& operator=(Node&& other) = default; scoped_refptr<Task> task; uint16_t category; uint16_t priority; uint32_t dependencies; - - private: - DISALLOW_COPY_AND_ASSIGN(Node); }; struct Edge { @@ -137,17 +136,18 @@ }; TaskGraph(); + TaskGraph(const TaskGraph&) = delete; TaskGraph(TaskGraph&& other); ~TaskGraph(); + TaskGraph& operator=(const TaskGraph&) = delete; + TaskGraph& operator=(TaskGraph&&) = default; + void Swap(TaskGraph* other); void Reset(); Node::Vector nodes; Edge::Vector edges; - - private: - DISALLOW_COPY_AND_ASSIGN(TaskGraph); }; } // namespace cc
diff --git a/cc/raster/task_graph_runner_perftest.cc b/cc/raster/task_graph_runner_perftest.cc index 36ee90fa..d7f35a0 100644 --- a/cc/raster/task_graph_runner_perftest.cc +++ b/cc/raster/task_graph_runner_perftest.cc
@@ -8,7 +8,6 @@ #include <memory> #include <vector> -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/time/time.h" #include "base/timer/lap_timer.h" @@ -29,6 +28,8 @@ typedef std::vector<scoped_refptr<PerfTaskImpl>> Vector; PerfTaskImpl() = default; + PerfTaskImpl(const PerfTaskImpl&) = delete; + PerfTaskImpl& operator=(const PerfTaskImpl&) = delete; // Overridden from Task: void RunOnWorkerThread() override {} @@ -37,8 +38,6 @@ private: ~PerfTaskImpl() override = default; - - DISALLOW_COPY_AND_ASSIGN(PerfTaskImpl); }; class TaskGraphRunnerPerfTest : public testing::Test {
diff --git a/cc/raster/task_graph_work_queue.h b/cc/raster/task_graph_work_queue.h index b1bbce8..3b739f72 100644 --- a/cc/raster/task_graph_work_queue.h +++ b/cc/raster/task_graph_work_queue.h
@@ -35,18 +35,17 @@ TaskNamespace* task_namespace, uint16_t category, uint16_t priority); + PrioritizedTask(const PrioritizedTask&) = delete; PrioritizedTask(PrioritizedTask&& other); ~PrioritizedTask(); + PrioritizedTask& operator=(const PrioritizedTask&) = delete; PrioritizedTask& operator=(PrioritizedTask&& other) = default; scoped_refptr<Task> task; TaskNamespace* task_namespace; uint16_t category; uint16_t priority; - - private: - DISALLOW_COPY_AND_ASSIGN(PrioritizedTask); }; using CategorizedTask = std::pair<uint16_t, scoped_refptr<Task>>; @@ -56,9 +55,13 @@ typedef std::vector<TaskNamespace*> Vector; TaskNamespace(); + TaskNamespace(const TaskNamespace&) = delete; TaskNamespace(TaskNamespace&& other); ~TaskNamespace(); + TaskNamespace& operator=(const TaskNamespace&) = delete; + TaskNamespace& operator=(TaskNamespace&&) = default; + // Current task graph. TaskGraph graph; @@ -71,14 +74,14 @@ // This set contains all currently running tasks. std::vector<CategorizedTask> running_tasks; - - private: - DISALLOW_COPY_AND_ASSIGN(TaskNamespace); }; TaskGraphWorkQueue(); + TaskGraphWorkQueue(const TaskGraphWorkQueue&) = delete; virtual ~TaskGraphWorkQueue(); + TaskGraphWorkQueue& operator=(const TaskGraphWorkQueue&) = delete; + // Generates a NamespaceToken which is guaranteed to be unique within this // TaskGraphWorkQueue. NamespaceToken GenerateNamespaceToken(); @@ -192,8 +195,6 @@ // Provides a unique id to each NamespaceToken. int next_namespace_id_; - - DISALLOW_COPY_AND_ASSIGN(TaskGraphWorkQueue); }; } // namespace cc
diff --git a/cc/raster/task_graph_work_queue_unittest.cc b/cc/raster/task_graph_work_queue_unittest.cc index 93455db..ac78a6d 100644 --- a/cc/raster/task_graph_work_queue_unittest.cc +++ b/cc/raster/task_graph_work_queue_unittest.cc
@@ -13,13 +13,15 @@ class FakeTaskImpl : public Task { public: FakeTaskImpl() = default; + FakeTaskImpl(const FakeTaskImpl&) = delete; + + FakeTaskImpl& operator=(const FakeTaskImpl&) = delete; // Overridden from Task: void RunOnWorkerThread() override {} private: ~FakeTaskImpl() override = default; - DISALLOW_COPY_AND_ASSIGN(FakeTaskImpl); }; TEST(TaskGraphWorkQueueTest, TestChangingDependency) {
diff --git a/cc/raster/zero_copy_raster_buffer_provider.cc b/cc/raster/zero_copy_raster_buffer_provider.cc index 8e5eb1c..6f491eb7 100644 --- a/cc/raster/zero_copy_raster_buffer_provider.cc +++ b/cc/raster/zero_copy_raster_buffer_provider.cc
@@ -8,7 +8,6 @@ #include <algorithm> -#include "base/macros.h" #include "base/trace_event/process_memory_dump.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/traced_value.h" @@ -75,6 +74,7 @@ resource_format_(in_use_resource.format()), resource_color_space_(in_use_resource.color_space()), gpu_memory_buffer_(std::move(backing_->gpu_memory_buffer)) {} + ZeroCopyRasterBufferImpl(const ZeroCopyRasterBufferImpl&) = delete; ~ZeroCopyRasterBufferImpl() override { // If GpuMemoryBuffer allocation failed (https://crbug.com/554541), then @@ -107,6 +107,8 @@ backing_->gpu_memory_buffer = std::move(gpu_memory_buffer_); } + ZeroCopyRasterBufferImpl& operator=(const ZeroCopyRasterBufferImpl&) = delete; + // Overridden from RasterBuffer: void Playback(const RasterSource* raster_source, const gfx::Rect& raster_full_rect, @@ -154,8 +156,6 @@ viz::ResourceFormat resource_format_; gfx::ColorSpace resource_color_space_; std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_; - - DISALLOW_COPY_AND_ASSIGN(ZeroCopyRasterBufferImpl); }; } // namespace
diff --git a/cc/raster/zero_copy_raster_buffer_provider.h b/cc/raster/zero_copy_raster_buffer_provider.h index 680d6b0..6bb0e33 100644 --- a/cc/raster/zero_copy_raster_buffer_provider.h +++ b/cc/raster/zero_copy_raster_buffer_provider.h
@@ -7,7 +7,6 @@ #include <stdint.h> -#include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/values.h" #include "cc/raster/raster_buffer_provider.h" @@ -30,8 +29,12 @@ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, viz::ContextProvider* compositor_context_provider, viz::ResourceFormat tile_format); + ZeroCopyRasterBufferProvider(const ZeroCopyRasterBufferProvider&) = delete; ~ZeroCopyRasterBufferProvider() override; + ZeroCopyRasterBufferProvider& operator=(const ZeroCopyRasterBufferProvider&) = + delete; + // Overridden from RasterBufferProvider: std::unique_ptr<RasterBuffer> AcquireBufferForRaster( const ResourcePool::InUsePoolResource& resource, @@ -58,8 +61,6 @@ gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_; viz::ContextProvider* compositor_context_provider_; viz::ResourceFormat tile_format_; - - DISALLOW_COPY_AND_ASSIGN(ZeroCopyRasterBufferProvider); }; } // namespace cc
diff --git a/cc/resources/memory_history.h b/cc/resources/memory_history.h index 14a2fbb..f5a7e9c8 100644 --- a/cc/resources/memory_history.h +++ b/cc/resources/memory_history.h
@@ -11,7 +11,6 @@ #include <memory> #include "base/containers/ring_buffer.h" -#include "base/macros.h" #include "base/time/time.h" namespace cc { @@ -21,6 +20,9 @@ public: static std::unique_ptr<MemoryHistory> Create(); + MemoryHistory(const MemoryHistory&) = delete; + MemoryHistory& operator=(const MemoryHistory&) = delete; + size_t HistorySize() const { return ring_buffer_.BufferSize(); } struct Entry { @@ -44,8 +46,6 @@ MemoryHistory(); RingBufferType ring_buffer_; - - DISALLOW_COPY_AND_ASSIGN(MemoryHistory); }; } // namespace cc
diff --git a/cc/resources/resource_pool.h b/cc/resources/resource_pool.h index cd72eb84..b7f2f8d 100644 --- a/cc/resources/resource_pool.h +++ b/cc/resources/resource_pool.h
@@ -12,7 +12,6 @@ #include <memory> #include "base/containers/circular_deque.h" -#include "base/macros.h" #include "base/memory/memory_pressure_listener.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" @@ -199,8 +198,11 @@ const base::TimeDelta& expiration_delay, bool disallow_non_exact_reuse); + ResourcePool(const ResourcePool&) = delete; ~ResourcePool() override; + ResourcePool& operator=(const ResourcePool&) = delete; + // Tries to reuse a resource. If none are available, makes a new one. InUsePoolResource AcquireResource(const gfx::Size& size, viz::ResourceFormat format, @@ -407,8 +409,6 @@ const base::TickClock* clock_; base::WeakPtrFactory<ResourcePool> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(ResourcePool); }; } // namespace cc
diff --git a/cc/resources/scoped_ui_resource.h b/cc/resources/scoped_ui_resource.h index 8b11f7e..e12dabd 100644 --- a/cc/resources/scoped_ui_resource.h +++ b/cc/resources/scoped_ui_resource.h
@@ -5,7 +5,6 @@ #ifndef CC_RESOURCES_SCOPED_UI_RESOURCE_H_ #define CC_RESOURCES_SCOPED_UI_RESOURCE_H_ -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "cc/cc_export.h" #include "cc/resources/ui_resource_bitmap.h" @@ -26,8 +25,11 @@ static std::unique_ptr<ScopedUIResource> Create( UIResourceManager* ui_resource_manager, const UIResourceBitmap& bitmap); + ScopedUIResource(const ScopedUIResource&) = delete; ~ScopedUIResource() override; + ScopedUIResource& operator=(const ScopedUIResource&) = delete; + // UIResourceClient implementation. UIResourceBitmap GetBitmap(UIResourceId uid, bool resource_lost) override; UIResourceId id() { return id_; } @@ -42,9 +44,6 @@ UIResourceBitmap bitmap_; UIResourceManager* ui_resource_manager_; UIResourceId id_; - - private: - DISALLOW_COPY_AND_ASSIGN(ScopedUIResource); }; } // namespace cc
diff --git a/cc/resources/shared_bitmap_id_registrar.h b/cc/resources/shared_bitmap_id_registrar.h index b3533def..6abb30e 100644 --- a/cc/resources/shared_bitmap_id_registrar.h +++ b/cc/resources/shared_bitmap_id_registrar.h
@@ -49,9 +49,12 @@ class CC_EXPORT SharedBitmapIdRegistration { public: SharedBitmapIdRegistration(); + SharedBitmapIdRegistration(const SharedBitmapIdRegistration&) = delete; + SharedBitmapIdRegistration(SharedBitmapIdRegistration&&); ~SharedBitmapIdRegistration(); - SharedBitmapIdRegistration(SharedBitmapIdRegistration&&); + SharedBitmapIdRegistration& operator=(const SharedBitmapIdRegistration&) = + delete; SharedBitmapIdRegistration& operator=(SharedBitmapIdRegistration&&); private: @@ -63,8 +66,6 @@ base::WeakPtr<TextureLayer> layer_ptr_; viz::SharedBitmapId id_; - - DISALLOW_COPY_AND_ASSIGN(SharedBitmapIdRegistration); }; } // namespace cc
diff --git a/cc/resources/ui_resource_manager.h b/cc/resources/ui_resource_manager.h index 7f29ba61f..e3e51204 100644 --- a/cc/resources/ui_resource_manager.h +++ b/cc/resources/ui_resource_manager.h
@@ -8,7 +8,6 @@ #include <unordered_map> #include <vector> -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/resources/ui_resource_request.h" @@ -18,8 +17,11 @@ class CC_EXPORT UIResourceManager { public: UIResourceManager(); + UIResourceManager(const UIResourceManager&) = delete; virtual ~UIResourceManager(); + UIResourceManager& operator=(const UIResourceManager&) = delete; + // CreateUIResource creates a resource given a bitmap. The bitmap is // generated via an interface function, which is called when initializing the // resource and when the resource has been lost (due to lost context). The @@ -65,8 +67,6 @@ // DeleteUIResource). std::unordered_map<SkPixelRef*, std::unique_ptr<ScopedUIResource>> owned_shared_resources_; - - DISALLOW_COPY_AND_ASSIGN(UIResourceManager); }; } // namespace cc
diff --git a/cc/scheduler/compositor_timing_history.h b/cc/scheduler/compositor_timing_history.h index 842583f1..f9559bd 100644 --- a/cc/scheduler/compositor_timing_history.h +++ b/cc/scheduler/compositor_timing_history.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "cc/base/rolling_time_delta_history.h" #include "cc/cc_export.h" #include "cc/tiles/tile_priority.h" @@ -36,8 +35,11 @@ bool using_synchronous_renderer_compositor, UMACategory uma_category, RenderingStatsInstrumentation* rendering_stats_instrumentation); + CompositorTimingHistory(const CompositorTimingHistory&) = delete; virtual ~CompositorTimingHistory(); + CompositorTimingHistory& operator=(const CompositorTimingHistory&) = delete; + void AsValueInto(base::trace_event::TracedValue* state) const; // The main thread responsiveness depends heavily on whether or not the @@ -166,9 +168,6 @@ bool previous_frame_had_raf_ = false; TreePriority tree_priority_ = SAME_PRIORITY_FOR_BOTH_TREES; - - private: - DISALLOW_COPY_AND_ASSIGN(CompositorTimingHistory); }; } // namespace cc
diff --git a/cc/scheduler/compositor_timing_history_unittest.cc b/cc/scheduler/compositor_timing_history_unittest.cc index a5e8387..c7fd357 100644 --- a/cc/scheduler/compositor_timing_history_unittest.cc +++ b/cc/scheduler/compositor_timing_history_unittest.cc
@@ -4,7 +4,6 @@ #include "cc/scheduler/compositor_timing_history.h" -#include "base/macros.h" #include "base/test/metrics/histogram_tester.h" #include "cc/debug/rendering_stats_instrumentation.h" #include "testing/gtest/include/gtest/gtest.h" @@ -20,14 +19,14 @@ RenderingStatsInstrumentation* rendering_stats) : CompositorTimingHistory(false, RENDERER_UMA, rendering_stats), test_(test) {} + TestCompositorTimingHistory(const TestCompositorTimingHistory&) = delete; + TestCompositorTimingHistory& operator=(const TestCompositorTimingHistory&) = + delete; protected: base::TimeTicks Now() const override; CompositorTimingHistoryTest* test_; - - private: - DISALLOW_COPY_AND_ASSIGN(TestCompositorTimingHistory); }; class CompositorTimingHistoryTest : public testing::Test {
diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h index 292a0f5..a84943e 100644 --- a/cc/scheduler/scheduler.h +++ b/cc/scheduler/scheduler.h
@@ -9,7 +9,6 @@ #include <string> #include "base/cancelable_callback.h" -#include "base/macros.h" #include "base/time/time.h" #include "cc/cc_export.h" #include "cc/scheduler/begin_frame_tracker.h" @@ -78,8 +77,11 @@ int layer_tree_host_id, base::SingleThreadTaskRunner* task_runner, std::unique_ptr<CompositorTimingHistory> compositor_timing_history); + Scheduler(const Scheduler&) = delete; ~Scheduler() override; + Scheduler& operator=(const Scheduler&) = delete; + // This is needed so that the scheduler doesn't perform spurious actions while // the compositor is being torn down. void Stop(); @@ -322,8 +324,6 @@ bool IsInsideAction(SchedulerStateMachine::Action action) { return inside_action_ == action; } - - DISALLOW_COPY_AND_ASSIGN(Scheduler); }; } // namespace cc
diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h index f683e52..76f3c18 100644 --- a/cc/scheduler/scheduler_state_machine.h +++ b/cc/scheduler/scheduler_state_machine.h
@@ -10,7 +10,6 @@ #include <memory> #include <string> -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/scheduler/commit_earlyout_reason.h" #include "cc/scheduler/draw_result.h" @@ -48,8 +47,11 @@ public: // settings must be valid for the lifetime of this class. explicit SchedulerStateMachine(const SchedulerSettings& settings); + SchedulerStateMachine(const SchedulerStateMachine&) = delete; ~SchedulerStateMachine(); + SchedulerStateMachine& operator=(const SchedulerStateMachine&) = delete; + enum class LayerTreeFrameSinkState { NONE, ACTIVE, @@ -457,9 +459,6 @@ // If set to true, the pending tree must be drawn at least once after // activation before a new tree can be activated. bool pending_tree_needs_first_draw_on_activation_ = false; - - private: - DISALLOW_COPY_AND_ASSIGN(SchedulerStateMachine); }; } // namespace cc
diff --git a/cc/test/cc_test_suite.h b/cc/test/cc_test_suite.h index 4e0a114..eef4c273 100644 --- a/cc/test/cc_test_suite.h +++ b/cc/test/cc_test_suite.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "base/test/test_discardable_memory_allocator.h" #include "base/test/test_suite.h" @@ -20,8 +19,11 @@ class CCTestSuite : public base::TestSuite { public: CCTestSuite(int argc, char** argv); + CCTestSuite(const CCTestSuite&) = delete; ~CCTestSuite() override; + CCTestSuite& operator=(const CCTestSuite&) = delete; + protected: // Overridden from base::TestSuite: void Initialize() override; @@ -31,7 +33,6 @@ std::unique_ptr<base::MessageLoop> message_loop_; base::TestDiscardableMemoryAllocator discardable_memory_allocator_; - DISALLOW_COPY_AND_ASSIGN(CCTestSuite); }; } // namespace cc
diff --git a/cc/test/fake_paint_image_generator.h b/cc/test/fake_paint_image_generator.h index e34ab446..8a18535 100644 --- a/cc/test/fake_paint_image_generator.h +++ b/cc/test/fake_paint_image_generator.h
@@ -8,7 +8,6 @@ #include <vector> #include "base/containers/flat_map.h" -#include "base/macros.h" // For DISALLOW_COPY_AND_ASSIGN #include "cc/paint/paint_image_generator.h" namespace cc { @@ -28,8 +27,11 @@ std::vector<FrameMetadata> frames = {FrameMetadata()}, bool allocate_discardable_memory = true, std::vector<SkISize> supported_sizes = {}); + FakePaintImageGenerator(const FakePaintImageGenerator&) = delete; ~FakePaintImageGenerator() override; + FakePaintImageGenerator& operator=(const FakePaintImageGenerator&) = delete; + // PaintImageGenerator implementation. sk_sp<SkData> GetEncodedData() const override; bool GetPixels(const SkImageInfo& info, @@ -70,8 +72,6 @@ // planes and after Chrome implements it, we should no longer expect RGB // fallback. bool expect_fallback_to_rgb_ = false; - - DISALLOW_COPY_AND_ASSIGN(FakePaintImageGenerator); }; } // namespace cc
diff --git a/cc/test/fake_scrollbar.h b/cc/test/fake_scrollbar.h index 56ed6de..e4d7e9c0 100644 --- a/cc/test/fake_scrollbar.h +++ b/cc/test/fake_scrollbar.h
@@ -6,7 +6,6 @@ #define CC_TEST_FAKE_SCROLLBAR_H_ #include "base/compiler_specific.h" -#include "base/macros.h" #include "cc/input/scrollbar.h" #include "third_party/skia/include/core/SkColor.h" @@ -21,8 +20,11 @@ ScrollbarOrientation orientation, bool is_left_side_vertical_scrollbar, bool is_overlay); + FakeScrollbar(const FakeScrollbar&) = delete; ~FakeScrollbar() override; + FakeScrollbar& operator=(const FakeScrollbar&) = delete; + // Scrollbar implementation. ScrollbarOrientation Orientation() const override; bool IsLeftSideVerticalScrollbar() const override; @@ -75,8 +77,6 @@ gfx::Point location_; gfx::Rect track_rect_; SkColor fill_color_; - - DISALLOW_COPY_AND_ASSIGN(FakeScrollbar); }; } // namespace cc
diff --git a/cc/test/mock_layer_client.h b/cc/test/mock_layer_client.h index e5ab750d..0850d24a 100644 --- a/cc/test/mock_layer_client.h +++ b/cc/test/mock_layer_client.h
@@ -5,7 +5,6 @@ #ifndef CC_TEST_MOCK_LAYER_CLIENT_H_ #define CC_TEST_MOCK_LAYER_CLIENT_H_ -#include "base/macros.h" #include "base/trace_event/trace_event_impl.h" #include "base/trace_event/traced_value.h" #include "cc/layers/layer_client.h" @@ -16,14 +15,14 @@ class MockLayerClient : public LayerClient { public: MockLayerClient(); + MockLayerClient(const MockLayerClient&) = delete; ~MockLayerClient() override; + MockLayerClient& operator=(const MockLayerClient&) = delete; + MOCK_METHOD1(TakeDebugInfo, std::unique_ptr<base::trace_event::TracedValue>(Layer*)); MOCK_METHOD1(didChangeScrollbarsHiddenIfOverlay, void(bool)); - - private: - DISALLOW_COPY_AND_ASSIGN(MockLayerClient); }; } // namespace cc
diff --git a/cc/test/mock_occlusion_tracker.h b/cc/test/mock_occlusion_tracker.h index 47f1f0e..18512bb 100644 --- a/cc/test/mock_occlusion_tracker.h +++ b/cc/test/mock_occlusion_tracker.h
@@ -5,7 +5,6 @@ #ifndef CC_TEST_MOCK_OCCLUSION_TRACKER_H_ #define CC_TEST_MOCK_OCCLUSION_TRACKER_H_ -#include "base/macros.h" #include "cc/trees/occlusion_tracker.h" namespace cc { @@ -28,6 +27,9 @@ OcclusionTracker::stack_.push_back(stack_obj); OcclusionTracker::stack_.push_back(stack_obj); } + MockOcclusionTracker(const MockOcclusionTracker&) = delete; + + MockOcclusionTracker& operator=(const MockOcclusionTracker&) = delete; void set_occluded_target_rect(const gfx::Rect& occluded) { OcclusionTracker::stack_.back().occlusion_from_inside_target = occluded; @@ -38,9 +40,6 @@ OcclusionTracker::stack_[OcclusionTracker::stack_.size() - 2] .occlusion_from_inside_target = occluded; } - - private: - DISALLOW_COPY_AND_ASSIGN(MockOcclusionTracker); }; } // namespace cc
diff --git a/cc/test/push_properties_counting_layer.h b/cc/test/push_properties_counting_layer.h index 97e71898..d1a9cc4 100644 --- a/cc/test/push_properties_counting_layer.h +++ b/cc/test/push_properties_counting_layer.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "cc/layers/layer.h" @@ -20,6 +19,10 @@ public: static scoped_refptr<PushPropertiesCountingLayer> Create(); + PushPropertiesCountingLayer(const PushPropertiesCountingLayer&) = delete; + PushPropertiesCountingLayer& operator=(const PushPropertiesCountingLayer&) = + delete; + // Layer implementation. void PushPropertiesTo(LayerImpl* layer) override; std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; @@ -37,8 +40,6 @@ void AddPushPropertiesCount(); size_t push_properties_count_ = 0; - - DISALLOW_COPY_AND_ASSIGN(PushPropertiesCountingLayer); }; } // namespace cc
diff --git a/cc/test/push_properties_counting_layer_impl.h b/cc/test/push_properties_counting_layer_impl.h index cd79397..2a94002c 100644 --- a/cc/test/push_properties_counting_layer_impl.h +++ b/cc/test/push_properties_counting_layer_impl.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "cc/layers/layer_impl.h" namespace cc { @@ -19,8 +18,13 @@ static std::unique_ptr<PushPropertiesCountingLayerImpl> Create( LayerTreeImpl* tree_impl, int id); + PushPropertiesCountingLayerImpl(const PushPropertiesCountingLayerImpl&) = + delete; ~PushPropertiesCountingLayerImpl() override; + PushPropertiesCountingLayerImpl& operator=( + const PushPropertiesCountingLayerImpl&) = delete; + // LayerImpl implementation. void PushPropertiesTo(LayerImpl* layer) override; std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; @@ -32,8 +36,6 @@ PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id); size_t push_properties_count_; - - DISALLOW_COPY_AND_ASSIGN(PushPropertiesCountingLayerImpl); }; } // namespace cc
diff --git a/cc/test/render_pass_test_utils.cc b/cc/test/render_pass_test_utils.cc index b3a07b0..b43730d 100644 --- a/cc/test/render_pass_test_utils.cc +++ b/cc/test/render_pass_test_utils.cc
@@ -73,8 +73,8 @@ const gfx::Rect& rect, SkColor color) { viz::SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), rect, rect, rect, false, false, 1, - SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, false, + false, 1, SkBlendMode::kSrcOver, 0); auto* quad = pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>(); quad->SetNew(shared_state, rect, rect, color, false); return quad; @@ -84,8 +84,8 @@ const gfx::Rect& rect, SkColor color) { viz::SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), rect, rect, rect, true, false, 1, - SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, true, + false, 1, SkBlendMode::kSrcOver, 0); auto* quad = pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>(); quad->SetNew(shared_state, rect, rect, color, false); return quad; @@ -96,7 +96,8 @@ SkColor color, const gfx::Transform& transform) { viz::SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(transform, rect, rect, rect, false, false, 1, + shared_state->SetAll(transform, rect, rect, gfx::RRectF(), rect, false, false, + 1, SkBlendMode::kSrcOver, 0); auto* quad = pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>(); @@ -109,8 +110,9 @@ gfx::Rect output_rect = contributing_pass->output_rect; viz::SharedQuadState* shared_state = to_pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), output_rect, output_rect, output_rect, - false, false, 1, SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), output_rect, output_rect, + gfx::RRectF(), output_rect, false, false, 1, + SkBlendMode::kSrcOver, 0); auto* quad = to_pass->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>(); quad->SetNew(shared_state, output_rect, output_rect, contributing_pass->id, 0, gfx::RectF(), gfx::Size(), gfx::Vector2dF(), gfx::PointF(), @@ -125,8 +127,8 @@ gfx::Rect output_rect = contributing_pass->output_rect; viz::SharedQuadState* shared_state = to_pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(transform, output_rect, output_rect, output_rect, false, - false, 1, blend_mode, 0); + shared_state->SetAll(transform, output_rect, output_rect, gfx::RRectF(), + output_rect, false, false, 1, blend_mode, 0); auto* quad = to_pass->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>(); gfx::Size arbitrary_nonzero_size(1, 1); quad->SetNew(shared_state, output_rect, output_rect, contributing_pass->id, @@ -171,8 +173,8 @@ viz::SharedQuadState* shared_state = to_pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), rect, rect, rect, false, false, 1, - SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, false, + false, 1, SkBlendMode::kSrcOver, 0); auto* debug_border_quad = to_pass->CreateAndAppendDrawQuad<viz::DebugBorderDrawQuad>(); @@ -233,8 +235,8 @@ viz::SharedQuadState* shared_state2 = to_pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), rect, rect, rect, false, false, 1, - SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, false, + false, 1, SkBlendMode::kSrcOver, 0); auto* tile_quad = to_pass->CreateAndAppendDrawQuad<viz::TileDrawQuad>(); tile_quad->SetNew(shared_state2, rect, visible_rect, needs_blending, @@ -349,8 +351,8 @@ viz::SharedQuadState* shared_state = to_pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), rect, rect, rect, false, false, 1, - SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, false, + false, 1, SkBlendMode::kSrcOver, 0); viz::DebugBorderDrawQuad* debug_border_quad = to_pass->CreateAndAppendDrawQuad<viz::DebugBorderDrawQuad>(); @@ -411,8 +413,8 @@ viz::SharedQuadState* shared_state2 = to_pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), rect, rect, rect, false, false, 1, - SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, false, + false, 1, SkBlendMode::kSrcOver, 0); viz::TileDrawQuad* tile_quad = to_pass->CreateAndAppendDrawQuad<viz::TileDrawQuad>();
diff --git a/cc/test/scheduler_test_common.h b/cc/test/scheduler_test_common.h index 1ac2f04..4a539c7 100644 --- a/cc/test/scheduler_test_common.h +++ b/cc/test/scheduler_test_common.h
@@ -10,7 +10,6 @@ #include <memory> #include <string> -#include "base/macros.h" #include "base/time/time.h" #include "cc/scheduler/compositor_timing_history.h" #include "cc/scheduler/scheduler.h" @@ -28,8 +27,12 @@ public: static std::unique_ptr<FakeCompositorTimingHistory> Create( bool using_synchronous_renderer_compositor); + FakeCompositorTimingHistory(const FakeCompositorTimingHistory&) = delete; ~FakeCompositorTimingHistory() override; + FakeCompositorTimingHistory& operator=(const FakeCompositorTimingHistory&) = + delete; + void SetAllEstimatesTo(base::TimeDelta duration); void SetBeginMainFrameQueueDurationCriticalEstimate(base::TimeDelta duration); @@ -70,9 +73,6 @@ base::TimeDelta prepare_tiles_duration_; base::TimeDelta activate_duration_; base::TimeDelta draw_duration_; - - private: - DISALLOW_COPY_AND_ASSIGN(FakeCompositorTimingHistory); }; class TestScheduler : public Scheduler { @@ -84,6 +84,9 @@ int layer_tree_host_id, base::SingleThreadTaskRunner* task_runner, std::unique_ptr<CompositorTimingHistory> compositor_timing_history); + TestScheduler(const TestScheduler&) = delete; + + TestScheduler& operator=(const TestScheduler&) = delete; bool IsDrawThrottled() const { return state_machine_.IsDrawThrottled(); } @@ -137,8 +140,6 @@ private: const base::TickClock* now_src_; - - DISALLOW_COPY_AND_ASSIGN(TestScheduler); }; } // namespace cc
diff --git a/cc/test/task_graph_runner_test_template.h b/cc/test/task_graph_runner_test_template.h index 0384fea1..362eff4 100644 --- a/cc/test/task_graph_runner_test_template.h +++ b/cc/test/task_graph_runner_test_template.h
@@ -59,6 +59,9 @@ public: FakeTaskImpl(TaskGraphRunnerTestBase* test, int namespace_index, int id) : test_(test), namespace_index_(namespace_index), id_(id) {} + FakeTaskImpl(const FakeTaskImpl&) = delete; + + FakeTaskImpl& operator=(const FakeTaskImpl&) = delete; // Overridden from Task: void RunOnWorkerThread() override; @@ -72,8 +75,6 @@ TaskGraphRunnerTestBase* test_; int namespace_index_; int id_; - - DISALLOW_COPY_AND_ASSIGN(FakeTaskImpl); }; class FakeDependentTaskImpl : public FakeTaskImpl { @@ -82,14 +83,15 @@ int namespace_index, int id) : FakeTaskImpl(test, namespace_index, id) {} + FakeDependentTaskImpl(const FakeDependentTaskImpl&) = delete; + + FakeDependentTaskImpl& operator=(const FakeDependentTaskImpl&) = delete; // Overridden from FakeTaskImpl: void OnTaskCompleted() override {} private: ~FakeDependentTaskImpl() override {} - - DISALLOW_COPY_AND_ASSIGN(FakeDependentTaskImpl); }; TaskGraphRunner* task_graph_runner_;
diff --git a/cc/test/test_hooks.h b/cc/test/test_hooks.h index 73f32ba..c4af687 100644 --- a/cc/test/test_hooks.h +++ b/cc/test/test_hooks.h
@@ -5,7 +5,6 @@ #ifndef CC_TEST_TEST_HOOKS_H_ #define CC_TEST_TEST_HOOKS_H_ -#include "base/macros.h" #include "cc/animation/animation_delegate.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_host_impl.h"
diff --git a/cc/test/test_image_factory.h b/cc/test/test_image_factory.h index 749c4c7..9178b7b2 100644 --- a/cc/test/test_image_factory.h +++ b/cc/test/test_image_factory.h
@@ -5,7 +5,6 @@ #ifndef CC_TEST_TEST_IMAGE_FACTORY_H_ #define CC_TEST_TEST_IMAGE_FACTORY_H_ -#include "base/macros.h" #include "gpu/command_buffer/service/image_factory.h" namespace cc { @@ -13,8 +12,11 @@ class TestImageFactory : public gpu::ImageFactory { public: TestImageFactory(); + TestImageFactory(const TestImageFactory&) = delete; ~TestImageFactory() override; + TestImageFactory& operator=(const TestImageFactory&) = delete; + // Overridden from gpu::ImageFactory: scoped_refptr<gl::GLImage> CreateImageForGpuMemoryBuffer( gfx::GpuMemoryBufferHandle handle, @@ -22,9 +24,6 @@ gfx::BufferFormat format, int client_id, gpu::SurfaceHandle surface_handle) override; - - private: - DISALLOW_COPY_AND_ASSIGN(TestImageFactory); }; } // namespace cc
diff --git a/cc/test/test_in_process_context_provider.cc b/cc/test/test_in_process_context_provider.cc index 8254b3b..8600b3b 100644 --- a/cc/test/test_in_process_context_provider.cc +++ b/cc/test/test_in_process_context_provider.cc
@@ -8,7 +8,6 @@ #include <utility> #include "base/lazy_instance.h" -#include "base/macros.h" #include "base/stl_util.h" #include "base/threading/thread_task_runner_handle.h" #include "components/viz/common/gpu/context_cache_controller.h"
diff --git a/cc/test/test_task_graph_runner.h b/cc/test/test_task_graph_runner.h index b0e9bc40..3389269 100644 --- a/cc/test/test_task_graph_runner.h +++ b/cc/test/test_task_graph_runner.h
@@ -5,7 +5,6 @@ #ifndef CC_TEST_TEST_TASK_GRAPH_RUNNER_H_ #define CC_TEST_TEST_TASK_GRAPH_RUNNER_H_ -#include "base/macros.h" #include "base/threading/simple_thread.h" #include "cc/raster/single_thread_task_graph_runner.h" @@ -14,10 +13,10 @@ class TestTaskGraphRunner : public SingleThreadTaskGraphRunner { public: TestTaskGraphRunner(); + TestTaskGraphRunner(const TestTaskGraphRunner&) = delete; ~TestTaskGraphRunner() override; - private: - DISALLOW_COPY_AND_ASSIGN(TestTaskGraphRunner); + TestTaskGraphRunner& operator=(const TestTaskGraphRunner&) = delete; }; } // namespace cc
diff --git a/cc/tiles/checker_image_tracker.h b/cc/tiles/checker_image_tracker.h index 1a8229fe..f59f5a2 100644 --- a/cc/tiles/checker_image_tracker.h +++ b/cc/tiles/checker_image_tracker.h
@@ -55,8 +55,11 @@ CheckerImageTrackerClient* client, bool enable_checker_imaging, size_t min_image_bytes_to_checker); + CheckerImageTracker(const CheckerImageTracker&) = delete; ~CheckerImageTracker(); + CheckerImageTracker& operator=(const CheckerImageTracker&) = delete; + // Returns true if the decode for |image| will be deferred to the image decode // service and it should be be skipped during raster. bool ShouldCheckerImage(const DrawImage& image, WhichTree tree); @@ -146,13 +149,14 @@ ScopedDecodeHolder(ImageController* controller, ImageController::ImageDecodeRequestId request_id) : controller_(controller), request_id_(request_id) {} + ScopedDecodeHolder(const ScopedDecodeHolder&) = delete; ~ScopedDecodeHolder() { controller_->UnlockImageDecode(request_id_); } + ScopedDecodeHolder& operator=(const ScopedDecodeHolder&) = delete; + private: ImageController* controller_; ImageController::ImageDecodeRequestId request_id_; - - DISALLOW_COPY_AND_ASSIGN(ScopedDecodeHolder); }; void DidFinishImageDecode(PaintImage::Id image_id, @@ -204,8 +208,6 @@ base::flat_map<PaintImage::Id, PaintImage::DecodingMode> decoding_mode_map_; base::WeakPtrFactory<CheckerImageTracker> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(CheckerImageTracker); }; } // namespace cc
diff --git a/cc/tiles/decoded_image_tracker.h b/cc/tiles/decoded_image_tracker.h index c88bd2b..a5f99ab 100644 --- a/cc/tiles/decoded_image_tracker.h +++ b/cc/tiles/decoded_image_tracker.h
@@ -29,8 +29,11 @@ explicit DecodedImageTracker( ImageController* controller, scoped_refptr<base::SequencedTaskRunner> task_runner); + DecodedImageTracker(const DecodedImageTracker&) = delete; ~DecodedImageTracker(); + DecodedImageTracker& operator=(const DecodedImageTracker&) = delete; + // Request that the given image be decoded. This issues a callback upon // completion. The callback takes a bool indicating whether the decode was // successful or not. @@ -71,14 +74,16 @@ ImageLock(DecodedImageTracker* tracker, ImageController::ImageDecodeRequestId request_id, base::TimeTicks lock_time); + ImageLock(const ImageLock&) = delete; ~ImageLock(); + + ImageLock& operator=(const ImageLock&) = delete; base::TimeTicks lock_time() const { return lock_time_; } private: DecodedImageTracker* tracker_; ImageController::ImageDecodeRequestId request_id_; base::TimeTicks lock_time_; - DISALLOW_COPY_AND_ASSIGN(ImageLock); }; base::flat_map<PaintImage::Id, std::unique_ptr<ImageLock>> locked_images_; bool timeout_pending_ = false; @@ -88,8 +93,6 @@ const base::TickClock* tick_clock_; base::WeakPtrFactory<DecodedImageTracker> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(DecodedImageTracker); }; } // namespace cc
diff --git a/cc/tiles/eviction_tile_priority_queue.h b/cc/tiles/eviction_tile_priority_queue.h index 2e76ee8..49ee3ef8 100644 --- a/cc/tiles/eviction_tile_priority_queue.h +++ b/cc/tiles/eviction_tile_priority_queue.h
@@ -9,7 +9,6 @@ #include <utility> #include <vector> -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/layers/picture_layer_impl.h" #include "cc/tiles/tile_priority.h" @@ -21,8 +20,12 @@ class CC_EXPORT EvictionTilePriorityQueue { public: EvictionTilePriorityQueue(); + EvictionTilePriorityQueue(const EvictionTilePriorityQueue&) = delete; ~EvictionTilePriorityQueue(); + EvictionTilePriorityQueue& operator=(const EvictionTilePriorityQueue&) = + delete; + void Build(const std::vector<PictureLayerImpl*>& active_layers, const std::vector<PictureLayerImpl*>& pending_layers, TreePriority tree_priority); @@ -39,8 +42,6 @@ std::vector<std::unique_ptr<TilingSetEvictionQueue>> active_queues_; std::vector<std::unique_ptr<TilingSetEvictionQueue>> pending_queues_; TreePriority tree_priority_; - - DISALLOW_COPY_AND_ASSIGN(EvictionTilePriorityQueue); }; } // namespace cc
diff --git a/cc/tiles/frame_viewer_instrumentation.h b/cc/tiles/frame_viewer_instrumentation.h index 2f389be..7c4ad9d 100644 --- a/cc/tiles/frame_viewer_instrumentation.h +++ b/cc/tiles/frame_viewer_instrumentation.h
@@ -5,7 +5,6 @@ #ifndef CC_TILES_FRAME_VIEWER_INSTRUMENTATION_H_ #define CC_TILES_FRAME_VIEWER_INSTRUMENTATION_H_ -#include "base/macros.h" #include "base/trace_event/trace_event.h" #include "cc/tiles/tile_priority.h" @@ -25,10 +24,10 @@ TileResolution tile_resolution, int source_frame_number, int layer_id); + ScopedAnalyzeTask(const ScopedAnalyzeTask&) = delete; ~ScopedAnalyzeTask(); - private: - DISALLOW_COPY_AND_ASSIGN(ScopedAnalyzeTask); + ScopedAnalyzeTask& operator=(const ScopedAnalyzeTask&) = delete; }; class ScopedRasterTask { @@ -37,10 +36,10 @@ TileResolution tile_resolution, int source_frame_number, int layer_id); + ScopedRasterTask(const ScopedRasterTask&) = delete; ~ScopedRasterTask(); - private: - DISALLOW_COPY_AND_ASSIGN(ScopedRasterTask); + ScopedRasterTask& operator=(const ScopedRasterTask&) = delete; }; bool IsTracingLayerTreeSnapshots();
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc index 89fc519..4f583e1e 100644 --- a/cc/tiles/gpu_image_decode_cache.cc +++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -477,6 +477,9 @@ task_type_(task_type) { DCHECK(!SkipImage(draw_image)); } + GpuImageDecodeTaskImpl(const GpuImageDecodeTaskImpl&) = delete; + + GpuImageDecodeTaskImpl& operator=(const GpuImageDecodeTaskImpl&) = delete; // Overridden from Task: void RunOnWorkerThread() override { @@ -503,8 +506,6 @@ DrawImage image_; const ImageDecodeCache::TracingInfo tracing_info_; const GpuImageDecodeCache::DecodeTaskType task_type_; - - DISALLOW_COPY_AND_ASSIGN(GpuImageDecodeTaskImpl); }; // Task which creates an image from decoded data. Typically this involves @@ -526,6 +527,9 @@ if (decode_dependency) dependencies_.push_back(std::move(decode_dependency)); } + ImageUploadTaskImpl(const ImageUploadTaskImpl&) = delete; + + ImageUploadTaskImpl& operator=(const ImageUploadTaskImpl&) = delete; // Override from Task: void RunOnWorkerThread() override { @@ -546,8 +550,6 @@ GpuImageDecodeCache* cache_; DrawImage image_; const ImageDecodeCache::TracingInfo tracing_info_; - - DISALLOW_COPY_AND_ASSIGN(ImageUploadTaskImpl); }; GpuImageDecodeCache::ImageDataBase::ImageDataBase() = default;
diff --git a/cc/tiles/image_controller.h b/cc/tiles/image_controller.h index d554010..2533b6e 100644 --- a/cc/tiles/image_controller.h +++ b/cc/tiles/image_controller.h
@@ -10,7 +10,6 @@ #include "base/callback.h" #include "base/containers/flat_map.h" -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner.h" @@ -34,8 +33,11 @@ explicit ImageController( base::SequencedTaskRunner* origin_task_runner, scoped_refptr<base::SequencedTaskRunner> worker_task_runner); + ImageController(const ImageController&) = delete; virtual ~ImageController(); + ImageController& operator=(const ImageController&) = delete; + void SetImageDecodeCache(ImageDecodeCache* cache); void SetPaintWorkletLayerPainter( std::unique_ptr<PaintWorkletLayerPainter> painter); @@ -150,8 +152,6 @@ std::vector<ImageDecodeRequest> orphaned_decode_requests_; base::WeakPtrFactory<ImageController> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(ImageController); }; } // namespace cc
diff --git a/cc/tiles/image_controller_unittest.cc b/cc/tiles/image_controller_unittest.cc index ba11ee8..05c82a4 100644 --- a/cc/tiles/image_controller_unittest.cc +++ b/cc/tiles/image_controller_unittest.cc
@@ -161,6 +161,9 @@ SimpleTask() : TileTask(true /* supports_concurrent_execution */) { EXPECT_TRUE(thread_checker_.CalledOnValidThread()); } + SimpleTask(const SimpleTask&) = delete; + + SimpleTask& operator=(const SimpleTask&) = delete; void RunOnWorkerThread() override { EXPECT_FALSE(HasCompleted()); @@ -177,8 +180,6 @@ base::ThreadChecker thread_checker_; bool has_run_ = false; - - DISALLOW_COPY_AND_ASSIGN(SimpleTask); }; // A task that blocks until instructed otherwise. @@ -188,6 +189,9 @@ : TileTask(true /* supports_concurrent_execution */), run_cv_(&lock_) { EXPECT_TRUE(thread_checker_.CalledOnValidThread()); } + BlockingTask(const BlockingTask&) = delete; + + BlockingTask& operator=(const BlockingTask&) = delete; void RunOnWorkerThread() override { EXPECT_FALSE(HasCompleted()); @@ -219,8 +223,6 @@ base::Lock lock_; base::ConditionVariable run_cv_; bool can_run_ = false; - - DISALLOW_COPY_AND_ASSIGN(BlockingTask); }; // For tests that exercise image controller's thread, this is the timeout value
diff --git a/cc/tiles/paint_worklet_image_cache.cc b/cc/tiles/paint_worklet_image_cache.cc index fc37da4a..9eecf2b 100644 --- a/cc/tiles/paint_worklet_image_cache.cc +++ b/cc/tiles/paint_worklet_image_cache.cc
@@ -14,6 +14,9 @@ PaintWorkletTaskImpl(PaintWorkletImageCache* cache, const PaintImage& paint_image) : TileTask(true), cache_(cache), paint_image_(paint_image) {} + PaintWorkletTaskImpl(const PaintWorkletTaskImpl&) = delete; + + PaintWorkletTaskImpl& operator=(const PaintWorkletTaskImpl&) = delete; // Overridden from Task: void RunOnWorkerThread() override { cache_->PaintImageInTask(paint_image_); } @@ -27,8 +30,6 @@ private: PaintWorkletImageCache* cache_; PaintImage paint_image_; - - DISALLOW_COPY_AND_ASSIGN(PaintWorkletTaskImpl); }; PaintWorkletImageCache::PaintWorkletImageCache() {}
diff --git a/cc/tiles/picture_layer_tiling.h b/cc/tiles/picture_layer_tiling.h index d9c33a0..4f66d99 100644 --- a/cc/tiles/picture_layer_tiling.h +++ b/cc/tiles/picture_layer_tiling.h
@@ -14,7 +14,6 @@ #include <utility> #include <vector> -#include "base/macros.h" #include "cc/base/region.h" #include "cc/base/tiling_data.h" #include "cc/cc_export.h" @@ -95,8 +94,11 @@ PictureLayerTilingClient* client, float min_preraster_distance, float max_preraster_distance); + PictureLayerTiling(const PictureLayerTiling&) = delete; ~PictureLayerTiling(); + PictureLayerTiling& operator=(const PictureLayerTiling&) = delete; + PictureLayerTilingClient* client() const { return client_; } void SetRasterSourceAndResize(scoped_refptr<RasterSource> raster_source); @@ -392,9 +394,6 @@ bool has_soon_border_rect_tiles_ = false; bool has_eventually_rect_tiles_ = false; bool all_tiles_done_ = true; - - private: - DISALLOW_COPY_AND_ASSIGN(PictureLayerTiling); }; } // namespace cc
diff --git a/cc/tiles/picture_layer_tiling_set.h b/cc/tiles/picture_layer_tiling_set.h index 78e426e..b5b9c453 100644 --- a/cc/tiles/picture_layer_tiling_set.h +++ b/cc/tiles/picture_layer_tiling_set.h
@@ -11,7 +11,6 @@ #include <set> #include <vector> -#include "base/macros.h" #include "cc/base/region.h" #include "cc/tiles/picture_layer_tiling.h" #include "ui/gfx/geometry/size.h" @@ -48,8 +47,11 @@ int skewport_extrapolation_limit_in_screen_pixels, float max_preraster_distance); + PictureLayerTilingSet(const PictureLayerTilingSet&) = delete; ~PictureLayerTilingSet(); + PictureLayerTilingSet& operator=(const PictureLayerTilingSet&) = delete; + const PictureLayerTilingClient* client() const { return client_; } void CleanUpTilings(float min_acceptable_high_res_scale_key, @@ -262,9 +264,6 @@ gfx::Rect eventually_rect_in_layer_space_; friend class Iterator; - - private: - DISALLOW_COPY_AND_ASSIGN(PictureLayerTilingSet); }; } // namespace cc
diff --git a/cc/tiles/picture_layer_tiling_unittest.cc b/cc/tiles/picture_layer_tiling_unittest.cc index 4a98325e..424dc99 100644 --- a/cc/tiles/picture_layer_tiling_unittest.cc +++ b/cc/tiles/picture_layer_tiling_unittest.cc
@@ -10,7 +10,6 @@ #include <set> #include "base/bind.h" -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "cc/base/math_util.h" #include "cc/test/fake_output_surface_client.h" @@ -90,8 +89,13 @@ base::RepeatingCallback<void(Tile* tile, const gfx::Rect& geometry_rect)>; PictureLayerTilingIteratorTest() = default; + PictureLayerTilingIteratorTest(const PictureLayerTilingIteratorTest&) = + delete; ~PictureLayerTilingIteratorTest() override = default; + PictureLayerTilingIteratorTest& operator=( + const PictureLayerTilingIteratorTest&) = delete; + void Initialize(const gfx::Size& tile_size, float contents_scale, const gfx::Size& layer_bounds) { @@ -218,9 +222,6 @@ FakePictureLayerTilingClient client_; std::unique_ptr<TestablePictureLayerTiling> tiling_; bool loose_texel_extent_check_ = false; - - private: - DISALLOW_COPY_AND_ASSIGN(PictureLayerTilingIteratorTest); }; TEST_F(PictureLayerTilingIteratorTest, ResizeDeletesTiles) {
diff --git a/cc/tiles/raster_tile_priority_queue.h b/cc/tiles/raster_tile_priority_queue.h index 9886076..7bfc229 100644 --- a/cc/tiles/raster_tile_priority_queue.h +++ b/cc/tiles/raster_tile_priority_queue.h
@@ -7,7 +7,6 @@ #include <vector> -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/layers/picture_layer_impl.h" #include "cc/tiles/tile_priority.h" @@ -26,6 +25,9 @@ Type type); virtual ~RasterTilePriorityQueue() {} + RasterTilePriorityQueue(const RasterTilePriorityQueue&) = delete; + + RasterTilePriorityQueue& operator=(const RasterTilePriorityQueue&) = delete; virtual bool IsEmpty() const = 0; virtual const PrioritizedTile& Top() const = 0; @@ -33,9 +35,6 @@ protected: RasterTilePriorityQueue() {} - - private: - DISALLOW_COPY_AND_ASSIGN(RasterTilePriorityQueue); }; } // namespace cc
diff --git a/cc/tiles/raster_tile_priority_queue_all.h b/cc/tiles/raster_tile_priority_queue_all.h index 698dfe0..5aa6caf 100644 --- a/cc/tiles/raster_tile_priority_queue_all.h +++ b/cc/tiles/raster_tile_priority_queue_all.h
@@ -9,7 +9,6 @@ #include <utility> #include <vector> -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/layers/picture_layer_impl.h" #include "cc/tiles/raster_tile_priority_queue.h" @@ -21,8 +20,12 @@ class CC_EXPORT RasterTilePriorityQueueAll : public RasterTilePriorityQueue { public: RasterTilePriorityQueueAll(); + RasterTilePriorityQueueAll(const RasterTilePriorityQueueAll&) = delete; ~RasterTilePriorityQueueAll() override; + RasterTilePriorityQueueAll& operator=(const RasterTilePriorityQueueAll&) = + delete; + bool IsEmpty() const override; const PrioritizedTile& Top() const override; void Pop() override; @@ -41,8 +44,6 @@ std::vector<std::unique_ptr<TilingSetRasterQueueAll>> active_queues_; std::vector<std::unique_ptr<TilingSetRasterQueueAll>> pending_queues_; TreePriority tree_priority_; - - DISALLOW_COPY_AND_ASSIGN(RasterTilePriorityQueueAll); }; } // namespace cc
diff --git a/cc/tiles/raster_tile_priority_queue_required.h b/cc/tiles/raster_tile_priority_queue_required.h index a45a4ba..c405e25 100644 --- a/cc/tiles/raster_tile_priority_queue_required.h +++ b/cc/tiles/raster_tile_priority_queue_required.h
@@ -7,7 +7,6 @@ #include <vector> -#include "base/macros.h" #include "cc/layers/picture_layer_impl.h" #include "cc/tiles/raster_tile_priority_queue.h" #include "cc/tiles/tiling_set_raster_queue_required.h" @@ -18,8 +17,13 @@ class RasterTilePriorityQueueRequired : public RasterTilePriorityQueue { public: RasterTilePriorityQueueRequired(); + RasterTilePriorityQueueRequired(const RasterTilePriorityQueueRequired&) = + delete; ~RasterTilePriorityQueueRequired() override; + RasterTilePriorityQueueRequired& operator=( + const RasterTilePriorityQueueRequired&) = delete; + bool IsEmpty() const override; const PrioritizedTile& Top() const override; void Pop() override; @@ -37,8 +41,6 @@ const std::vector<PictureLayerImpl*>& pending_layers); std::vector<std::unique_ptr<TilingSetRasterQueueRequired>> tiling_set_queues_; - - DISALLOW_COPY_AND_ASSIGN(RasterTilePriorityQueueRequired); }; } // namespace cc
diff --git a/cc/tiles/software_image_decode_cache.cc b/cc/tiles/software_image_decode_cache.cc index 126cb37b..c2bb32f6 100644 --- a/cc/tiles/software_image_decode_cache.cc +++ b/cc/tiles/software_image_decode_cache.cc
@@ -8,7 +8,6 @@ #include "base/bind.h" #include "base/format_macros.h" -#include "base/macros.h" #include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" @@ -64,6 +63,10 @@ paint_image_(paint_image), task_type_(task_type), tracing_info_(tracing_info) {} + SoftwareImageDecodeTaskImpl(const SoftwareImageDecodeTaskImpl&) = delete; + + SoftwareImageDecodeTaskImpl& operator=(const SoftwareImageDecodeTaskImpl&) = + delete; // Overridden from Task: void RunOnWorkerThread() override { @@ -91,8 +94,6 @@ PaintImage paint_image_; SoftwareImageDecodeCache::DecodeTaskType task_type_; const ImageDecodeCache::TracingInfo tracing_info_; - - DISALLOW_COPY_AND_ASSIGN(SoftwareImageDecodeTaskImpl); }; SkSize GetScaleAdjustment(const SoftwareImageDecodeCache::CacheKey& key) {
diff --git a/cc/tiles/tile.h b/cc/tiles/tile.h index d413c3c0..84f68cb 100644 --- a/cc/tiles/tile.h +++ b/cc/tiles/tile.h
@@ -8,7 +8,6 @@ #include <stddef.h> #include <stdint.h> -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "cc/paint/draw_image.h" #include "cc/raster/tile_task.h" @@ -51,8 +50,11 @@ typedef uint64_t Id; + Tile(const Tile&) = delete; ~Tile(); + Tile& operator=(const Tile&) = delete; + Id id() const { return id_; } @@ -180,8 +182,6 @@ // rasterize a resource with checker images. bool raster_task_scheduled_with_checker_images_ = false; scoped_refptr<TileTask> raster_task_; - - DISALLOW_COPY_AND_ASSIGN(Tile); }; } // namespace cc
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc index 43d282e6..e797e6db 100644 --- a/cc/tiles/tile_manager.cc +++ b/cc/tiles/tile_manager.cc
@@ -14,7 +14,6 @@ #include "base/bind.h" #include "base/json/json_writer.h" #include "base/logging.h" -#include "base/macros.h" #include "base/metrics/histogram.h" #include "base/numerics/safe_conversions.h" #include "base/optional.h" @@ -83,8 +82,11 @@ : playback_image_provider_(std::move(playback_image_provider)), paint_worklet_image_provider_(std::move(paint_worklet_image_provider)) { } + DispatchingImageProvider(const DispatchingImageProvider&) = delete; ~DispatchingImageProvider() override = default; + DispatchingImageProvider& operator=(const DispatchingImageProvider&) = delete; + DispatchingImageProvider(DispatchingImageProvider&& other) = default; ImageProvider::ScopedResult GetRasterContent( @@ -98,8 +100,6 @@ private: PlaybackImageProvider playback_image_provider_; PaintWorkletImageProvider paint_worklet_image_provider_; - - DISALLOW_COPY_AND_ASSIGN(DispatchingImageProvider); }; class RasterTaskImpl : public TileTask { @@ -139,6 +139,8 @@ DCHECK(origin_thread_checker_.CalledOnValidThread()); playback_settings_.image_provider = &image_provider_; } + RasterTaskImpl(const RasterTaskImpl&) = delete; + RasterTaskImpl& operator=(const RasterTaskImpl&) = delete; // Overridden from Task: void RunOnWorkerThread() override { @@ -205,8 +207,6 @@ std::unique_ptr<RasterBuffer> raster_buffer_; DispatchingImageProvider image_provider_; GURL url_; - - DISALLOW_COPY_AND_ASSIGN(RasterTaskImpl); }; TaskCategory TaskCategoryForTileTask(TileTask* task, @@ -334,6 +334,8 @@ task_runner_(task_runner), on_task_set_finished_callback_( std::move(on_task_set_finished_callback)) {} + TaskSetFinishedTaskImpl(const TaskSetFinishedTaskImpl&) = delete; + TaskSetFinishedTaskImpl& operator=(const TaskSetFinishedTaskImpl&) = delete; // Overridden from Task: void RunOnWorkerThread() override { @@ -354,8 +356,6 @@ private: base::SequencedTaskRunner* task_runner_; const base::RepeatingClosure on_task_set_finished_callback_; - - DISALLOW_COPY_AND_ASSIGN(TaskSetFinishedTaskImpl); }; class DidFinishRunningAllTilesTask : public TileTask {
diff --git a/cc/tiles/tile_manager.h b/cc/tiles/tile_manager.h index c4024e2..30d5590 100644 --- a/cc/tiles/tile_manager.h +++ b/cc/tiles/tile_manager.h
@@ -14,7 +14,6 @@ #include <utility> #include <vector> -#include "base/macros.h" #include "base/sequenced_task_runner.h" #include "base/values.h" #include "cc/base/unique_notifier.h" @@ -135,8 +134,12 @@ scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner, size_t scheduled_raster_task_limit, const TileManagerSettings& tile_manager_settings); + + TileManager(const TileManager&) = delete; ~TileManager() override; + TileManager& operator=(const TileManager&) = delete; + // Assigns tile memory and schedules work to prepare tiles for drawing. // This step occurs after Commit and at most once per BeginFrame. It can be // called on its own, that is, outside of Commit. @@ -470,8 +473,6 @@ base::WeakPtrFactory<TileManager> task_set_finished_weak_ptr_factory_; // The |ready_to_draw_callback_weak_ptr_factory_| is never invalidated. base::WeakPtrFactory<TileManager> ready_to_draw_callback_weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(TileManager); }; } // namespace cc
diff --git a/cc/tiles/tile_task_manager.h b/cc/tiles/tile_task_manager.h index 7f543c1..f77a460 100644 --- a/cc/tiles/tile_task_manager.h +++ b/cc/tiles/tile_task_manager.h
@@ -36,8 +36,11 @@ class CC_EXPORT TileTaskManagerImpl : public TileTaskManager { public: + TileTaskManagerImpl(const TileTaskManagerImpl&) = delete; ~TileTaskManagerImpl() override; + TileTaskManagerImpl& operator=(const TileTaskManagerImpl&) = delete; + static std::unique_ptr<TileTaskManagerImpl> Create( TaskGraphRunner* task_graph_runner); @@ -51,9 +54,6 @@ TaskGraphRunner* task_graph_runner_; const NamespaceToken namespace_token_; - - private: - DISALLOW_COPY_AND_ASSIGN(TileTaskManagerImpl); }; } // namespace cc
diff --git a/cc/tiles/tiling_set_raster_queue_all.h b/cc/tiles/tiling_set_raster_queue_all.h index e29736d..7e9149f3 100644 --- a/cc/tiles/tiling_set_raster_queue_all.h +++ b/cc/tiles/tiling_set_raster_queue_all.h
@@ -8,7 +8,6 @@ #include <stddef.h> #include "base/containers/stack_container.h" -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/tiles/picture_layer_tiling_set.h" #include "cc/tiles/prioritized_tile.h" @@ -24,8 +23,11 @@ TilingSetRasterQueueAll(PictureLayerTilingSet* tiling_set, bool prioritize_low_res, bool is_drawing_layer); + TilingSetRasterQueueAll(const TilingSetRasterQueueAll&) = delete; ~TilingSetRasterQueueAll(); + TilingSetRasterQueueAll& operator=(const TilingSetRasterQueueAll&) = delete; + const PrioritizedTile& Top() const; void Pop(); bool IsEmpty() const; @@ -193,8 +195,6 @@ base::StackVector<IterationStage, 6> stages_; TilingIterator iterators_[NUM_ITERATORS]; bool is_drawing_layer_ = false; - - DISALLOW_COPY_AND_ASSIGN(TilingSetRasterQueueAll); }; } // namespace cc
diff --git a/cc/trees/damage_tracker.h b/cc/trees/damage_tracker.h index c320db43..bda7579c 100644 --- a/cc/trees/damage_tracker.h +++ b/cc/trees/damage_tracker.h
@@ -8,7 +8,6 @@ #include <memory> #include <vector> -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/layers/layer_collections.h" #include "ui/gfx/geometry/rect.h" @@ -30,8 +29,11 @@ class CC_EXPORT DamageTracker { public: static std::unique_ptr<DamageTracker> Create(); + DamageTracker(const DamageTracker&) = delete; ~DamageTracker(); + DamageTracker& operator=(const DamageTracker&) = delete; + static void UpdateDamageTracking( LayerTreeImpl* layer_tree_impl, const RenderSurfaceList& render_surface_list); @@ -153,8 +155,6 @@ // Damage accumulated since the last call to PrepareForUpdate(). DamageAccumulator damage_for_this_update_; - - DISALLOW_COPY_AND_ASSIGN(DamageTracker); }; } // namespace cc
diff --git a/cc/trees/debug_rect_history.h b/cc/trees/debug_rect_history.h index fb6b9021..94d1ee9 100644 --- a/cc/trees/debug_rect_history.h +++ b/cc/trees/debug_rect_history.h
@@ -8,7 +8,6 @@ #include <memory> #include <vector> -#include "base/macros.h" #include "cc/input/touch_action.h" #include "cc/layers/layer_collections.h" #include "ui/gfx/geometry/rect.h" @@ -71,8 +70,11 @@ public: static std::unique_ptr<DebugRectHistory> Create(); + DebugRectHistory(const DebugRectHistory&) = delete; ~DebugRectHistory(); + DebugRectHistory& operator=(const DebugRectHistory&) = delete; + // Note: Saving debug rects must happen before layers' change tracking is // reset. void SaveDebugRectsForCurrentFrame( @@ -99,8 +101,6 @@ void SaveNonFastScrollableRectsCallback(LayerImpl* layer); std::vector<DebugRect> debug_rects_; - - DISALLOW_COPY_AND_ASSIGN(DebugRectHistory); }; } // namespace cc
diff --git a/cc/trees/frame_rate_counter.h b/cc/trees/frame_rate_counter.h index 2eadf84..8646150 100644 --- a/cc/trees/frame_rate_counter.h +++ b/cc/trees/frame_rate_counter.h
@@ -10,7 +10,6 @@ #include <memory> #include "base/containers/ring_buffer.h" -#include "base/macros.h" #include "base/time/time.h" namespace cc { @@ -21,6 +20,9 @@ public: static std::unique_ptr<FrameRateCounter> Create(bool has_impl_thread); + FrameRateCounter(const FrameRateCounter&) = delete; + FrameRateCounter& operator=(const FrameRateCounter&) = delete; + size_t current_frame_number() const { return ring_buffer_.CurrentIndex(); } int dropped_frame_count() const { return dropped_frame_count_; } size_t time_stamp_history_size() const { return ring_buffer_.BufferSize(); } @@ -51,8 +53,6 @@ bool has_impl_thread_; int dropped_frame_count_; - - DISALLOW_COPY_AND_ASSIGN(FrameRateCounter); }; } // namespace cc
diff --git a/cc/trees/image_animation_controller.h b/cc/trees/image_animation_controller.h index d6f6c3c..a95ec124 100644 --- a/cc/trees/image_animation_controller.h +++ b/cc/trees/image_animation_controller.h
@@ -133,10 +133,13 @@ class AnimationState { public: AnimationState(); + AnimationState(const AnimationState&) = delete; AnimationState(AnimationState&& other); - AnimationState& operator=(AnimationState&& other); ~AnimationState(); + AnimationState& operator=(const AnimationState&) = delete; + AnimationState& operator=(AnimationState&& other); + bool ShouldAnimate() const; bool AdvanceFrame(const viz::BeginFrameArgs& args, bool enable_image_animation_resync); @@ -224,8 +227,6 @@ // The number of frames skipped during catch-up the last time this animation // was advanced. size_t last_num_frames_skipped_ = 0u; - - DISALLOW_COPY_AND_ASSIGN(AnimationState); }; class InvalidationScheduler {
diff --git a/cc/trees/layer_tree_frame_sink.cc b/cc/trees/layer_tree_frame_sink.cc index 024981c..71ed277 100644 --- a/cc/trees/layer_tree_frame_sink.cc +++ b/cc/trees/layer_tree_frame_sink.cc
@@ -8,7 +8,6 @@ #include "base/bind.h" #include "base/location.h" -#include "base/macros.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "cc/trees/layer_tree_frame_sink_client.h" @@ -25,8 +24,11 @@ ContextLostForwarder(base::WeakPtr<LayerTreeFrameSink> frame_sink, scoped_refptr<base::SingleThreadTaskRunner> task_runner) : frame_sink_(frame_sink), task_runner_(std::move(task_runner)) {} + ContextLostForwarder(const ContextLostForwarder&) = delete; ~ContextLostForwarder() override = default; + ContextLostForwarder& operator=(const ContextLostForwarder&) = delete; + void OnContextLost() override { task_runner_->PostTask( FROM_HERE, @@ -36,7 +38,6 @@ private: base::WeakPtr<LayerTreeFrameSink> frame_sink_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - DISALLOW_COPY_AND_ASSIGN(ContextLostForwarder); }; LayerTreeFrameSink::LayerTreeFrameSink(
diff --git a/cc/trees/layer_tree_frame_sink.h b/cc/trees/layer_tree_frame_sink.h index 7ae114e3..76634a7 100644 --- a/cc/trees/layer_tree_frame_sink.h +++ b/cc/trees/layer_tree_frame_sink.h
@@ -8,7 +8,6 @@ #include <deque> #include <memory> -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" @@ -59,9 +58,12 @@ scoped_refptr<viz::RasterContextProvider> worker_context_provider, scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager); + LayerTreeFrameSink(const LayerTreeFrameSink&) = delete; ~LayerTreeFrameSink() override; + LayerTreeFrameSink& operator=(const LayerTreeFrameSink&) = delete; + base::WeakPtr<LayerTreeFrameSink> GetWeakPtr(); // Called by the compositor on the compositor thread. This is a place where @@ -153,7 +155,6 @@ private: THREAD_CHECKER(thread_checker_); base::WeakPtrFactory<LayerTreeFrameSink> weak_ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(LayerTreeFrameSink); }; } // namespace cc
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index ec6298d..3ec2655 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h
@@ -19,7 +19,6 @@ #include "base/cancelable_callback.h" #include "base/containers/flat_map.h" #include "base/containers/flat_set.h" -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" @@ -128,8 +127,11 @@ LayerTreeHostSingleThreadClient* single_thread_client, InitParams params); + LayerTreeHost(const LayerTreeHost&) = delete; virtual ~LayerTreeHost(); + LayerTreeHost& operator=(const LayerTreeHost&) = delete; + // Returns the process global unique identifier for this LayerTreeHost. int GetId() const; @@ -893,8 +895,6 @@ // Used to vend weak pointers to LayerTreeHost to ScopedDeferMainFrameUpdate // objects. base::WeakPtrFactory<LayerTreeHost> defer_main_frame_update_weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(LayerTreeHost); }; } // namespace cc
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h index 235910b..fab5e1eb 100644 --- a/cc/trees/layer_tree_host_common.h +++ b/cc/trees/layer_tree_host_common.h
@@ -11,7 +11,6 @@ #include <vector> #include "base/bind.h" -#include "base/macros.h" #include "base/memory/ref_counted.h" #include "cc/cc_export.h" #include "cc/input/browser_controls_state.h" @@ -158,8 +157,11 @@ struct CC_EXPORT ScrollAndScaleSet { ScrollAndScaleSet(); + ScrollAndScaleSet(const ScrollAndScaleSet&) = delete; ~ScrollAndScaleSet(); + ScrollAndScaleSet& operator=(const ScrollAndScaleSet&) = delete; + // The inner viewport scroll delta is kept separate since it's special. // Because the inner (visual) viewport's maximum offset depends on the // current page scale, the two must be committed at the same time to prevent @@ -192,9 +194,6 @@ // Set to true when a scroll gesture being handled on the compositor has // ended. bool scroll_gesture_did_end; - - private: - DISALLOW_COPY_AND_ASSIGN(ScrollAndScaleSet); }; template <typename Function>
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 0a875e9..e3c7641d 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -906,9 +906,9 @@ viz::SharedQuadState* shared_quad_state = target_render_pass->CreateAndAppendSharedQuadState(); shared_quad_state->SetAll(gfx::Transform(), root_target_rect, - root_target_rect, root_target_rect, false, - are_contents_opaque, opacity, SkBlendMode::kSrcOver, - sorting_context_id); + root_target_rect, gfx::RRectF(), root_target_rect, + false, are_contents_opaque, opacity, + SkBlendMode::kSrcOver, sorting_context_id); for (gfx::Rect screen_space_rect : fill_region) { gfx::Rect visible_screen_space_rect = screen_space_rect;
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 6f07f25..7cac46c 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -17,7 +17,6 @@ #include "base/callback.h" #include "base/containers/circular_deque.h" #include "base/containers/flat_map.h" -#include "base/macros.h" #include "base/memory/memory_pressure_listener.h" #include "base/sequenced_task_runner.h" #include "base/time/time.h" @@ -184,7 +183,10 @@ // or become part of the CompositorFrameMetadata. struct CC_EXPORT FrameData { FrameData(); + FrameData(const FrameData&) = delete; ~FrameData(); + + FrameData& operator=(const FrameData&) = delete; void AsValueInto(base::trace_event::TracedValue* value) const; std::vector<viz::SurfaceId> activation_dependencies; @@ -196,17 +198,17 @@ bool has_no_damage = false; bool may_contain_video = false; viz::BeginFrameAck begin_frame_ack; - - private: - DISALLOW_COPY_AND_ASSIGN(FrameData); }; // A struct of data for a single UIResource, including the backing // pixels, and metadata about it. struct CC_EXPORT UIResourceData { UIResourceData(); - ~UIResourceData(); + UIResourceData(const UIResourceData&) = delete; UIResourceData(UIResourceData&&) noexcept; + ~UIResourceData(); + + UIResourceData& operator=(const UIResourceData&) = delete; UIResourceData& operator=(UIResourceData&&); bool opaque; @@ -221,9 +223,6 @@ // The name with which to refer to the resource in frames submitted to the // display compositor. viz::ResourceId resource_id_for_export; - - private: - DISALLOW_COPY_AND_ASSIGN(UIResourceData); }; static std::unique_ptr<LayerTreeHostImpl> Create( @@ -235,8 +234,11 @@ std::unique_ptr<MutatorHost> mutator_host, int id, scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner); + LayerTreeHostImpl(const LayerTreeHostImpl&) = delete; ~LayerTreeHostImpl() override; + LayerTreeHostImpl& operator=(const LayerTreeHostImpl&) = delete; + // InputHandler implementation void BindToClient(InputHandlerClient* client) override; InputHandler::ScrollStatus ScrollBegin( @@ -1114,9 +1116,13 @@ uint32_t token, base::TimeTicks cc_frame_time, std::vector<LayerTreeHost::PresentationTimeCallback> callbacks); + FrameTokenInfo(const FrameTokenInfo&) = delete; FrameTokenInfo(FrameTokenInfo&&); ~FrameTokenInfo(); + FrameTokenInfo& operator=(const FrameTokenInfo&) = delete; + FrameTokenInfo& operator=(FrameTokenInfo&&) = default; + uint32_t token; // The compositor frame time used to produce the frame. @@ -1124,8 +1130,6 @@ // The callbacks to send back to the main thread. std::vector<LayerTreeHost::PresentationTimeCallback> callbacks; - - DISALLOW_COPY_AND_ASSIGN(FrameTokenInfo); }; base::circular_deque<FrameTokenInfo> frame_token_infos_; @@ -1143,8 +1147,6 @@ // Set in ScrollEnd before clearing the currently scrolling node. This is // used to send the scrollend DOM event when scrolling has happened on CC. ElementId last_scroller_element_id_; - - DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl); }; } // namespace cc
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 3c91b797..d0d2a54 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -13879,8 +13879,13 @@ public: explicit TestRenderFrameMetadataObserver(bool increment_counter) : increment_counter_(increment_counter) {} + TestRenderFrameMetadataObserver(const TestRenderFrameMetadataObserver&) = + delete; ~TestRenderFrameMetadataObserver() override {} + TestRenderFrameMetadataObserver& operator=( + const TestRenderFrameMetadataObserver&) = delete; + void BindToCurrentThread() override {} void OnRenderFrameSubmission( const RenderFrameMetadata& render_frame_metadata, @@ -13898,8 +13903,6 @@ private: bool increment_counter_; base::Optional<RenderFrameMetadata> last_metadata_; - - DISALLOW_COPY_AND_ASSIGN(TestRenderFrameMetadataObserver); }; TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) {
diff --git a/cc/trees/layer_tree_host_unittest_proxy.cc b/cc/trees/layer_tree_host_unittest_proxy.cc index 1443be7..399b68f 100644 --- a/cc/trees/layer_tree_host_unittest_proxy.cc +++ b/cc/trees/layer_tree_host_unittest_proxy.cc
@@ -4,7 +4,6 @@ #include "base/bind.h" #include "base/compiler_specific.h" -#include "base/macros.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_picture_layer.h" #include "cc/test/layer_tree_test.h" @@ -39,8 +38,13 @@ class LayerTreeHostProxyTestSetNeedsCommit : public LayerTreeHostProxyTest { protected: LayerTreeHostProxyTestSetNeedsCommit() = default; + LayerTreeHostProxyTestSetNeedsCommit( + const LayerTreeHostProxyTestSetNeedsCommit&) = delete; ~LayerTreeHostProxyTestSetNeedsCommit() override = default; + LayerTreeHostProxyTestSetNeedsCommit& operator=( + const LayerTreeHostProxyTestSetNeedsCommit&) = delete; + void BeginTest() override { EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->max_requested_pipeline_stage()); @@ -66,9 +70,6 @@ } void AfterTest() override {} - - private: - DISALLOW_COPY_AND_ASSIGN(LayerTreeHostProxyTestSetNeedsCommit); }; MULTI_THREAD_TEST_F(LayerTreeHostProxyTestSetNeedsCommit); @@ -76,8 +77,13 @@ class LayerTreeHostProxyTestSetNeedsAnimate : public LayerTreeHostProxyTest { protected: LayerTreeHostProxyTestSetNeedsAnimate() = default; + LayerTreeHostProxyTestSetNeedsAnimate( + const LayerTreeHostProxyTestSetNeedsAnimate&) = delete; ~LayerTreeHostProxyTestSetNeedsAnimate() override = default; + LayerTreeHostProxyTestSetNeedsAnimate& operator=( + const LayerTreeHostProxyTestSetNeedsAnimate&) = delete; + void BeginTest() override { EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->max_requested_pipeline_stage()); @@ -101,9 +107,6 @@ } void AfterTest() override {} - - private: - DISALLOW_COPY_AND_ASSIGN(LayerTreeHostProxyTestSetNeedsAnimate); }; MULTI_THREAD_TEST_F(LayerTreeHostProxyTestSetNeedsAnimate); @@ -112,8 +115,13 @@ : public LayerTreeHostProxyTest { protected: LayerTreeHostProxyTestSetNeedsUpdateLayers() = default; + LayerTreeHostProxyTestSetNeedsUpdateLayers( + const LayerTreeHostProxyTestSetNeedsUpdateLayers&) = delete; ~LayerTreeHostProxyTestSetNeedsUpdateLayers() override = default; + LayerTreeHostProxyTestSetNeedsUpdateLayers& operator=( + const LayerTreeHostProxyTestSetNeedsUpdateLayers&) = delete; + void BeginTest() override { EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->max_requested_pipeline_stage()); @@ -137,9 +145,6 @@ } void AfterTest() override {} - - private: - DISALLOW_COPY_AND_ASSIGN(LayerTreeHostProxyTestSetNeedsUpdateLayers); }; MULTI_THREAD_TEST_F(LayerTreeHostProxyTestSetNeedsUpdateLayers); @@ -148,9 +153,14 @@ : public LayerTreeHostProxyTest { protected: LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating() = default; + LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating( + const LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating&) = delete; ~LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating() override = default; + LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating& operator=( + const LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating&) = delete; + void BeginTest() override { proxy()->SetNeedsAnimate(); } void WillBeginMainFrame() override { @@ -182,10 +192,6 @@ } void AfterTest() override {} - - private: - DISALLOW_COPY_AND_ASSIGN( - LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating); }; MULTI_THREAD_TEST_F(LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating); @@ -194,8 +200,13 @@ : public LayerTreeHostProxyTest { protected: LayerTreeHostProxyTestSetNeedsCommitWhileAnimating() = default; + LayerTreeHostProxyTestSetNeedsCommitWhileAnimating( + const LayerTreeHostProxyTestSetNeedsCommitWhileAnimating&) = delete; ~LayerTreeHostProxyTestSetNeedsCommitWhileAnimating() override = default; + LayerTreeHostProxyTestSetNeedsCommitWhileAnimating& operator=( + const LayerTreeHostProxyTestSetNeedsCommitWhileAnimating&) = delete; + void BeginTest() override { proxy()->SetNeedsAnimate(); } void WillBeginMainFrame() override { @@ -227,9 +238,6 @@ } void AfterTest() override {} - - private: - DISALLOW_COPY_AND_ASSIGN(LayerTreeHostProxyTestSetNeedsCommitWhileAnimating); }; MULTI_THREAD_TEST_F(LayerTreeHostProxyTestSetNeedsCommitWhileAnimating); @@ -238,6 +246,11 @@ : public LayerTreeHostProxyTest { protected: LayerTreeHostProxyTestCommitWaitsForActivation() = default; + LayerTreeHostProxyTestCommitWaitsForActivation( + const LayerTreeHostProxyTestCommitWaitsForActivation&) = delete; + + LayerTreeHostProxyTestCommitWaitsForActivation& operator=( + const LayerTreeHostProxyTestCommitWaitsForActivation&) = delete; void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -314,8 +327,6 @@ private: base::Lock activate_blocked_lock_; bool activate_blocked_ = false; - - DISALLOW_COPY_AND_ASSIGN(LayerTreeHostProxyTestCommitWaitsForActivation); }; MULTI_THREAD_TEST_F(LayerTreeHostProxyTestCommitWaitsForActivation); @@ -328,6 +339,11 @@ : public LayerTreeHostProxyTest { protected: LayerTreeHostProxyTestCommitWaitsForActivationMFBA() = default; + LayerTreeHostProxyTestCommitWaitsForActivationMFBA( + const LayerTreeHostProxyTestCommitWaitsForActivationMFBA&) = delete; + + LayerTreeHostProxyTestCommitWaitsForActivationMFBA& operator=( + const LayerTreeHostProxyTestCommitWaitsForActivationMFBA&) = delete; void InitializeSettings(LayerTreeSettings* settings) override { settings->main_frame_before_activation_enabled = true; @@ -419,8 +435,6 @@ private: base::Lock activate_blocked_lock_; bool activate_blocked_ = false; - - DISALLOW_COPY_AND_ASSIGN(LayerTreeHostProxyTestCommitWaitsForActivationMFBA); }; MULTI_THREAD_TEST_F(LayerTreeHostProxyTestCommitWaitsForActivationMFBA); @@ -431,6 +445,10 @@ : public LayerTreeHostProxyTest { protected: LayerTreeHostProxyTestImplFrameCausesAnimatePending() = default; + LayerTreeHostProxyTestImplFrameCausesAnimatePending( + const LayerTreeHostProxyTestImplFrameCausesAnimatePending&) = delete; + LayerTreeHostProxyTestImplFrameCausesAnimatePending& operator=( + const LayerTreeHostProxyTestImplFrameCausesAnimatePending&) = delete; void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -453,9 +471,6 @@ } void AfterTest() override {} - - private: - DISALLOW_COPY_AND_ASSIGN(LayerTreeHostProxyTestImplFrameCausesAnimatePending); }; SINGLE_THREAD_TEST_F(LayerTreeHostProxyTestImplFrameCausesAnimatePending); @@ -466,6 +481,10 @@ : public LayerTreeHostProxyTest { protected: LayerTreeHostProxyTestNeedsCommitFromImpl() = default; + LayerTreeHostProxyTestNeedsCommitFromImpl( + const LayerTreeHostProxyTestNeedsCommitFromImpl&) = delete; + LayerTreeHostProxyTestNeedsCommitFromImpl& operator=( + const LayerTreeHostProxyTestNeedsCommitFromImpl&) = delete; void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -500,9 +519,6 @@ } void AfterTest() override {} - - private: - DISALLOW_COPY_AND_ASSIGN(LayerTreeHostProxyTestNeedsCommitFromImpl); }; SINGLE_THREAD_TEST_F(LayerTreeHostProxyTestNeedsCommitFromImpl); @@ -514,8 +530,13 @@ : public LayerTreeHostProxyTest { protected: LayerTreeHostProxyTestDelayedCommitDueToVisibility() = default; + LayerTreeHostProxyTestDelayedCommitDueToVisibility( + const LayerTreeHostProxyTestDelayedCommitDueToVisibility&) = delete; ~LayerTreeHostProxyTestDelayedCommitDueToVisibility() override = default; + LayerTreeHostProxyTestDelayedCommitDueToVisibility& operator=( + const LayerTreeHostProxyTestDelayedCommitDueToVisibility&) = delete; + void BeginTest() override { PostSetNeedsCommitToMainThread(); } void WillSendBeginMainFrameOnThread(LayerTreeHostImpl*) override { @@ -537,8 +558,6 @@ private: bool set_invisible_once_ = false; - - DISALLOW_COPY_AND_ASSIGN(LayerTreeHostProxyTestDelayedCommitDueToVisibility); }; SINGLE_AND_MULTI_THREAD_TEST_F(
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h index a42e2153..b6f7921 100644 --- a/cc/trees/layer_tree_impl.h +++ b/cc/trees/layer_tree_impl.h
@@ -12,7 +12,6 @@ #include <vector> #include "base/containers/flat_set.h" -#include "base/macros.h" #include "base/time/time.h" #include "base/values.h" #include "cc/base/synced_property.h" @@ -99,8 +98,11 @@ scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor, scoped_refptr<SyncedBrowserControls> top_controls_shown_ratio, scoped_refptr<SyncedElasticOverscroll> elastic_overscroll); + LayerTreeImpl(const LayerTreeImpl&) = delete; virtual ~LayerTreeImpl(); + LayerTreeImpl& operator=(const LayerTreeImpl&) = delete; + void Shutdown(); void ReleaseResources(); void OnPurgeMemory(); @@ -803,8 +805,6 @@ LayerTreeLifecycle lifecycle_; std::vector<LayerTreeHost::PresentationTimeCallback> presentation_callbacks_; - - DISALLOW_COPY_AND_ASSIGN(LayerTreeImpl); }; } // namespace cc
diff --git a/cc/trees/layer_tree_impl_unittest.cc b/cc/trees/layer_tree_impl_unittest.cc index 5c8054c..c752ebca 100644 --- a/cc/trees/layer_tree_impl_unittest.cc +++ b/cc/trees/layer_tree_impl_unittest.cc
@@ -4,7 +4,6 @@ #include "cc/trees/layer_tree_impl.h" -#include "base/macros.h" #include "cc/layers/heads_up_display_layer_impl.h" #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/geometry_test_utils.h"
diff --git a/cc/trees/layer_tree_mutator.h b/cc/trees/layer_tree_mutator.h index a25f40c..58e8aa4 100644 --- a/cc/trees/layer_tree_mutator.h +++ b/cc/trees/layer_tree_mutator.h
@@ -79,20 +79,25 @@ std::vector<WorkletAnimationId> peeked_animations; AnimationWorkletInput(); + AnimationWorkletInput(const AnimationWorkletInput&) = delete; ~AnimationWorkletInput(); + AnimationWorkletInput& operator=(const AnimationWorkletInput&) = delete; + #if DCHECK_IS_ON() // Verifies all animation states have the expected worklet id. bool ValidateId(int worklet_id) const; #endif - DISALLOW_COPY_AND_ASSIGN(AnimationWorkletInput); }; class CC_EXPORT MutatorInputState { public: MutatorInputState(); + MutatorInputState(const MutatorInputState&) = delete; ~MutatorInputState(); + MutatorInputState& operator=(const MutatorInputState&) = delete; + bool IsEmpty() const; void Add(AnimationWorkletInput::AddAndUpdateState&& state); void Update(AnimationWorkletInput::UpdateState&& state); @@ -119,8 +124,6 @@ // Returns iterator pointing to the entry in |inputs_| map whose key is id. It // inserts a new entry if none exists. AnimationWorkletInput& EnsureWorkletEntry(int id); - - DISALLOW_COPY_AND_ASSIGN(MutatorInputState); }; struct CC_EXPORT AnimationWorkletOutput {
diff --git a/cc/trees/occlusion_tracker.h b/cc/trees/occlusion_tracker.h index 0f360f39..09c7aec 100644 --- a/cc/trees/occlusion_tracker.h +++ b/cc/trees/occlusion_tracker.h
@@ -7,7 +7,6 @@ #include <vector> -#include "base/macros.h" #include "cc/base/simple_enclosed_region.h" #include "cc/cc_export.h" #include "cc/layers/effect_tree_layer_list_iterator.h" @@ -31,8 +30,11 @@ class CC_EXPORT OcclusionTracker { public: explicit OcclusionTracker(const gfx::Rect& screen_space_clip_rect); + OcclusionTracker(const OcclusionTracker&) = delete; ~OcclusionTracker(); + OcclusionTracker& operator=(const OcclusionTracker&) = delete; + // Return an occlusion that retains the current state of the tracker // and can be used outside of a layer walk to check occlusion. Occlusion GetCurrentOcclusionForLayer( @@ -102,8 +104,6 @@ gfx::Rect screen_space_clip_rect_; gfx::Size minimum_tracking_size_; - - DISALLOW_COPY_AND_ASSIGN(OcclusionTracker); }; } // namespace cc
diff --git a/cc/trees/proxy_impl.cc b/cc/trees/proxy_impl.cc index 672f1c3..0a49df13 100644 --- a/cc/trees/proxy_impl.cc +++ b/cc/trees/proxy_impl.cc
@@ -46,11 +46,13 @@ class ScopedCompletionEvent { public: explicit ScopedCompletionEvent(CompletionEvent* event) : event_(event) {} + ScopedCompletionEvent(const ScopedCompletionEvent&) = delete; ~ScopedCompletionEvent() { event_->Signal(); } + ScopedCompletionEvent& operator=(const ScopedCompletionEvent&) = delete; + private: CompletionEvent* const event_; - DISALLOW_COPY_AND_ASSIGN(ScopedCompletionEvent); }; ProxyImpl::ProxyImpl(base::WeakPtr<ProxyMain> proxy_main_weak_ptr,
diff --git a/cc/trees/proxy_impl.h b/cc/trees/proxy_impl.h index 21090c9..1f6f4be 100644 --- a/cc/trees/proxy_impl.h +++ b/cc/trees/proxy_impl.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "base/memory/weak_ptr.h" #include "cc/base/completion_event.h" #include "cc/base/delayed_unique_notifier.h" @@ -31,8 +30,11 @@ ProxyImpl(base::WeakPtr<ProxyMain> proxy_main_weak_ptr, LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider); + ProxyImpl(const ProxyImpl&) = delete; ~ProxyImpl() override; + ProxyImpl& operator=(const ProxyImpl&) = delete; + void UpdateBrowserControlsStateOnImpl(BrowserControlsState constraints, BrowserControlsState current, bool animate); @@ -184,8 +186,6 @@ // A weak pointer to ProxyMain that is invalidated when LayerTreeFrameSink is // released. base::WeakPtr<ProxyMain> proxy_main_frame_sink_bound_weak_ptr_; - - DISALLOW_COPY_AND_ASSIGN(ProxyImpl); }; } // namespace cc
diff --git a/cc/trees/proxy_main.h b/cc/trees/proxy_main.h index 468bad8..76ee5de 100644 --- a/cc/trees/proxy_main.h +++ b/cc/trees/proxy_main.h
@@ -5,7 +5,6 @@ #ifndef CC_TREES_PROXY_MAIN_H_ #define CC_TREES_PROXY_MAIN_H_ -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/input/browser_controls_state.h" #include "cc/trees/proxy.h" @@ -33,9 +32,11 @@ public: ProxyMain(LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider); - + ProxyMain(const ProxyMain&) = delete; ~ProxyMain() override; + ProxyMain& operator=(const ProxyMain&) = delete; + // Commits between the main and impl threads are processed through a pipeline // with the following stages. For efficiency we can early out at any stage if // we decide that no further processing is necessary. @@ -166,8 +167,6 @@ base::WeakPtrFactory<ProxyMain> frame_sink_bound_weak_factory_; base::WeakPtrFactory<ProxyMain> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(ProxyMain); }; } // namespace cc
diff --git a/cc/trees/render_frame_metadata_observer.h b/cc/trees/render_frame_metadata_observer.h index 13b0263..4b30e52 100644 --- a/cc/trees/render_frame_metadata_observer.h +++ b/cc/trees/render_frame_metadata_observer.h
@@ -5,7 +5,6 @@ #ifndef CC_TREES_RENDER_FRAME_METADATA_OBSERVER_H_ #define CC_TREES_RENDER_FRAME_METADATA_OBSERVER_H_ -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/trees/render_frame_metadata.h" @@ -22,8 +21,12 @@ class CC_EXPORT RenderFrameMetadataObserver { public: RenderFrameMetadataObserver() = default; + RenderFrameMetadataObserver(const RenderFrameMetadataObserver&) = delete; virtual ~RenderFrameMetadataObserver() = default; + RenderFrameMetadataObserver& operator=(const RenderFrameMetadataObserver&) = + delete; + // Binds on the current thread. This should only be called from the compositor // thread. virtual void BindToCurrentThread() = 0; @@ -34,9 +37,6 @@ const RenderFrameMetadata& render_frame_metadata, viz::CompositorFrameMetadata* compositor_frame_metadata, bool force_send) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(RenderFrameMetadataObserver); }; } // namespace cc
diff --git a/cc/trees/scoped_abort_remaining_swap_promises.h b/cc/trees/scoped_abort_remaining_swap_promises.h index b6c1197..af9cd79 100644 --- a/cc/trees/scoped_abort_remaining_swap_promises.h +++ b/cc/trees/scoped_abort_remaining_swap_promises.h
@@ -5,7 +5,6 @@ #ifndef CC_TREES_SCOPED_ABORT_REMAINING_SWAP_PROMISES_H_ #define CC_TREES_SCOPED_ABORT_REMAINING_SWAP_PROMISES_H_ -#include "base/macros.h" #include "cc/trees/swap_promise.h" #include "cc/trees/swap_promise_manager.h" @@ -16,15 +15,18 @@ explicit ScopedAbortRemainingSwapPromises( SwapPromiseManager* swap_promise_manager) : swap_promise_manager_(swap_promise_manager) {} + ScopedAbortRemainingSwapPromises(const ScopedAbortRemainingSwapPromises&) = + delete; ~ScopedAbortRemainingSwapPromises() { swap_promise_manager_->BreakSwapPromises(SwapPromise::COMMIT_FAILS); } + ScopedAbortRemainingSwapPromises& operator=( + const ScopedAbortRemainingSwapPromises&) = delete; + private: SwapPromiseManager* swap_promise_manager_; - - DISALLOW_COPY_AND_ASSIGN(ScopedAbortRemainingSwapPromises); }; } // namespace cc
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h index 107f91b2..e0f07ef9 100644 --- a/cc/trees/single_thread_proxy.h +++ b/cc/trees/single_thread_proxy.h
@@ -8,7 +8,6 @@ #include <limits> #include "base/cancelable_callback.h" -#include "base/macros.h" #include "base/time/time.h" #include "cc/scheduler/scheduler.h" #include "cc/trees/layer_tree_host_impl.h" @@ -35,8 +34,11 @@ LayerTreeHost* layer_tree_host, LayerTreeHostSingleThreadClient* client, TaskRunnerProvider* task_runner_provider); + SingleThreadProxy(const SingleThreadProxy&) = delete; ~SingleThreadProxy() override; + SingleThreadProxy& operator=(const SingleThreadProxy&) = delete; + // Proxy implementation bool IsStarted() const override; bool CommitToActiveTree() const override; @@ -211,8 +213,6 @@ base::WeakPtrFactory<SingleThreadProxy> frame_sink_bound_weak_factory_; base::WeakPtrFactory<SingleThreadProxy> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(SingleThreadProxy); }; // For use in the single-threaded case. In debug builds, it pretends that the @@ -229,19 +229,22 @@ explicit DebugScopedSetImplThread(TaskRunnerProvider* task_runner_provider) {} #endif + DebugScopedSetImplThread(const DebugScopedSetImplThread&) = delete; + ~DebugScopedSetImplThread() { #if DCHECK_IS_ON() task_runner_provider_->SetCurrentThreadIsImplThread(previous_value_); #endif } - private: + DebugScopedSetImplThread& operator=(const DebugScopedSetImplThread&) = delete; + #if DCHECK_IS_ON() + + private: bool previous_value_; TaskRunnerProvider* task_runner_provider_; #endif - - DISALLOW_COPY_AND_ASSIGN(DebugScopedSetImplThread); }; // For use in the single-threaded case. In debug builds, it pretends that the @@ -258,19 +261,22 @@ explicit DebugScopedSetMainThread(TaskRunnerProvider* task_runner_provider) {} #endif + DebugScopedSetMainThread(const DebugScopedSetMainThread&) = delete; + ~DebugScopedSetMainThread() { #if DCHECK_IS_ON() task_runner_provider_->SetCurrentThreadIsImplThread(previous_value_); #endif } - private: + DebugScopedSetMainThread& operator=(const DebugScopedSetMainThread&) = delete; + #if DCHECK_IS_ON() + + private: bool previous_value_; TaskRunnerProvider* task_runner_provider_; #endif - - DISALLOW_COPY_AND_ASSIGN(DebugScopedSetMainThread); }; // For use in the single-threaded case. In debug builds, it pretends that the @@ -282,12 +288,14 @@ TaskRunnerProvider* task_runner_provider) : impl_thread_(task_runner_provider), main_thread_blocked_(task_runner_provider) {} + DebugScopedSetImplThreadAndMainThreadBlocked( + const DebugScopedSetImplThreadAndMainThreadBlocked&) = delete; + DebugScopedSetImplThreadAndMainThreadBlocked& operator=( + const DebugScopedSetImplThreadAndMainThreadBlocked&) = delete; private: DebugScopedSetImplThread impl_thread_; DebugScopedSetMainThreadBlocked main_thread_blocked_; - - DISALLOW_COPY_AND_ASSIGN(DebugScopedSetImplThreadAndMainThreadBlocked); }; } // namespace cc
diff --git a/cc/trees/swap_promise_manager.h b/cc/trees/swap_promise_manager.h index da72a8ac..f2dc6e4 100644 --- a/cc/trees/swap_promise_manager.h +++ b/cc/trees/swap_promise_manager.h
@@ -8,7 +8,6 @@ #include <set> #include <vector> -#include "base/macros.h" #include "cc/cc_export.h" #include "cc/trees/swap_promise.h" @@ -19,8 +18,11 @@ class CC_EXPORT SwapPromiseManager { public: SwapPromiseManager(); + SwapPromiseManager(const SwapPromiseManager&) = delete; ~SwapPromiseManager(); + SwapPromiseManager& operator=(const SwapPromiseManager&) = delete; + // Call this function when you expect there to be a swap buffer. // See swap_promise.h for how to use SwapPromise. void QueueSwapPromise(std::unique_ptr<SwapPromise> swap_promise); @@ -49,8 +51,6 @@ private: std::vector<std::unique_ptr<SwapPromise>> swap_promise_list_; std::set<SwapPromiseMonitor*> swap_promise_monitors_; - - DISALLOW_COPY_AND_ASSIGN(SwapPromiseManager); }; } // namespace cc
diff --git a/cc/trees/task_runner_provider.h b/cc/trees/task_runner_provider.h index 42b0ed80..0bc19d3 100644 --- a/cc/trees/task_runner_provider.h +++ b/cc/trees/task_runner_provider.h
@@ -9,7 +9,6 @@ #include <string> #include "base/logging.h" -#include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "base/single_thread_task_runner.h" @@ -35,6 +34,9 @@ new TaskRunnerProvider(main_task_runner, impl_task_runner)); } + TaskRunnerProvider(const TaskRunnerProvider&) = delete; + TaskRunnerProvider& operator=(const TaskRunnerProvider&) = delete; + // TODO(vmpstr): Should these return scoped_refptr to task runners? Many // places turn them into scoped_refptrs. How many of them need to? base::SingleThreadTaskRunner* MainThreadTaskRunner() const; @@ -70,8 +72,6 @@ bool impl_thread_is_overridden_; bool is_main_thread_blocked_; #endif - - DISALLOW_COPY_AND_ASSIGN(TaskRunnerProvider); }; #if DCHECK_IS_ON() @@ -83,24 +83,30 @@ DCHECK(!task_runner_provider_->IsMainThreadBlocked()); task_runner_provider_->SetMainThreadBlocked(true); } + DebugScopedSetMainThreadBlocked(const DebugScopedSetMainThreadBlocked&) = + delete; ~DebugScopedSetMainThreadBlocked() { DCHECK(task_runner_provider_->IsMainThreadBlocked()); task_runner_provider_->SetMainThreadBlocked(false); } + DebugScopedSetMainThreadBlocked& operator=( + const DebugScopedSetMainThreadBlocked&) = delete; + private: TaskRunnerProvider* task_runner_provider_; - DISALLOW_COPY_AND_ASSIGN(DebugScopedSetMainThreadBlocked); }; #else class DebugScopedSetMainThreadBlocked { public: explicit DebugScopedSetMainThreadBlocked( TaskRunnerProvider* task_runner_provider) {} + DebugScopedSetMainThreadBlocked(const DebugScopedSetMainThreadBlocked&) = + delete; ~DebugScopedSetMainThreadBlocked() {} - private: - DISALLOW_COPY_AND_ASSIGN(DebugScopedSetMainThreadBlocked); + DebugScopedSetMainThreadBlocked& operator=( + const DebugScopedSetMainThreadBlocked&) = delete; }; #endif
diff --git a/cc/trees/tree_synchronizer.h b/cc/trees/tree_synchronizer.h index 1f0a1a1..81f1986 100644 --- a/cc/trees/tree_synchronizer.h +++ b/cc/trees/tree_synchronizer.h
@@ -7,7 +7,6 @@ #include <memory> -#include "base/macros.h" #include "cc/cc_export.h" namespace cc { @@ -19,6 +18,9 @@ class CC_EXPORT TreeSynchronizer { public: + // Not instantiable. + TreeSynchronizer() = delete; + // Accepts a Layer tree and returns a reference to a LayerImpl tree that // duplicates the structure of the Layer tree, reusing the LayerImpls in the // tree provided by old_layer_impl_root if possible. @@ -30,11 +32,6 @@ LayerTreeImpl* active_tree); static void PushLayerProperties(LayerTreeHost* host_tree, LayerTreeImpl* impl_tree); - - private: - TreeSynchronizer(); // Not instantiable. - - DISALLOW_COPY_AND_ASSIGN(TreeSynchronizer); }; } // namespace cc
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index ae5d423..ae6b1d8 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -118,10 +118,10 @@ "//components/strings:components_strings_grd", "//content/public/android:content_java_resources", "//third_party/android_data_chart:android_data_chart_java_resources", - "//third_party/android_deps:android_support_design_java", "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:android_support_v7_gridlayout_java", - "//third_party/android_deps:android_support_v7_recyclerview_java", + "//third_party/android_deps:com_android_support_design_java", + "//third_party/android_deps:com_android_support_gridlayout_v7_java", + "//third_party/android_deps:com_android_support_recyclerview_v7_java", ] custom_package = "org.chromium.chrome" } @@ -331,14 +331,14 @@ "//third_party/android_data_chart:android_data_chart_java", "//third_party/android_deps:android_arch_lifecycle_common_java", "//third_party/android_deps:android_arch_lifecycle_runtime_java", - "//third_party/android_deps:android_support_annotations_java", - "//third_party/android_deps:android_support_compat_java", - "//third_party/android_deps:android_support_design_java", - "//third_party/android_deps:android_support_v13_java", "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:android_support_v7_gridlayout_java", - "//third_party/android_deps:android_support_v7_mediarouter_java", - "//third_party/android_deps:android_support_v7_recyclerview_java", + "//third_party/android_deps:com_android_support_design_java", + "//third_party/android_deps:com_android_support_gridlayout_v7_java", + "//third_party/android_deps:com_android_support_mediarouter_v7_java", + "//third_party/android_deps:com_android_support_recyclerview_v7_java", + "//third_party/android_deps:com_android_support_support_annotations_java", + "//third_party/android_deps:com_android_support_support_compat_java", + "//third_party/android_deps:com_android_support_support_v13_java", "//third_party/android_deps:com_google_dagger_dagger_java", "//third_party/android_deps:com_google_protobuf_protobuf_lite_java", "//third_party/android_deps:javax_inject_javax_inject_java", @@ -616,10 +616,10 @@ "//net/android:net_java", "//services/media_session/public/cpp/android:media_session_java", "//third_party/android_deps:android_arch_lifecycle_common_java", - "//third_party/android_deps:android_support_annotations_java", "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:android_support_v7_mediarouter_java", - "//third_party/android_deps:android_support_v7_recyclerview_java", + "//third_party/android_deps:com_android_support_mediarouter_v7_java", + "//third_party/android_deps:com_android_support_recyclerview_v7_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/blink/public:android_mojo_bindings_java", "//third_party/blink/public:blink_headers_java", "//third_party/blink/public/mojom:android_mojo_bindings_java", @@ -756,10 +756,10 @@ "//services/service_manager/public/java:service_manager_java", "//third_party/android_data_chart:android_data_chart_java", "//third_party/android_deps:android_arch_lifecycle_common_java", - "//third_party/android_deps:android_support_annotations_java", - "//third_party/android_deps:android_support_design_java", "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:android_support_v7_recyclerview_java", + "//third_party/android_deps:com_android_support_design_java", + "//third_party/android_deps:com_android_support_recyclerview_v7_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/android_deps:com_google_ar_core_java", "//third_party/android_deps:com_google_protobuf_protobuf_lite_java", "//third_party/android_support_test_runner:rules_java", @@ -850,9 +850,9 @@ "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/android_deps:android_arch_lifecycle_common_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:android_support_v7_recyclerview_java", + "//third_party/android_deps:com_android_support_recyclerview_v7_java", "//third_party/custom_tabs_client:custom_tabs_support_java", "//third_party/junit", "//third_party/ub-uiautomator:ub_uiautomator_java",
diff --git a/chrome/android/features/autofill_assistant/BUILD.gn b/chrome/android/features/autofill_assistant/BUILD.gn index d4c02f3..bac2bd62 100644 --- a/chrome/android/features/autofill_assistant/BUILD.gn +++ b/chrome/android/features/autofill_assistant/BUILD.gn
@@ -13,7 +13,7 @@ "//chrome/android:chrome_java", "//components/url_formatter/android:url_formatter_java", "//content/public/android:content_java", - "//third_party/android_deps:android_support_design_java", + "//third_party/android_deps:com_android_support_design_java", "//third_party/android_deps:com_android_support_recyclerview_v7_java", "//third_party/android_deps:com_android_support_support_compat_java", "//third_party/android_deps:com_android_support_support_core_ui_java",
diff --git a/chrome/android/features/media_router/BUILD.gn b/chrome/android/features/media_router/BUILD.gn index 66d317f..ed861e05 100644 --- a/chrome/android/features/media_router/BUILD.gn +++ b/chrome/android/features/media_router/BUILD.gn
@@ -16,9 +16,9 @@ "//base:base_java", "//chrome/android:chrome_java", "//services/media_session/public/cpp/android:media_session_java", - "//third_party/android_deps:android_support_compat_java", "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:android_support_v7_mediarouter_java", + "//third_party/android_deps:com_android_support_mediarouter_v7_java", + "//third_party/android_deps:com_android_support_support_compat_java", "//third_party/android_media:android_media_java", ] java_files = [
diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn index 78854a9..13529d7 100644 --- a/chrome/android/features/tab_ui/BUILD.gn +++ b/chrome/android/features/tab_ui/BUILD.gn
@@ -48,11 +48,11 @@ "//content/public/android:content_java", "//third_party/android_deps:android_arch_lifecycle_common_java", "//third_party/android_deps:android_arch_lifecycle_runtime_java", - "//third_party/android_deps:android_support_annotations_java", - "//third_party/android_deps:android_support_compat_java", - "//third_party/android_deps:android_support_v13_java", + "//third_party/android_deps:com_android_support_support_annotations_java", + "//third_party/android_deps:com_android_support_support_compat_java", + "//third_party/android_deps:com_android_support_support_v13_java", "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:android_support_v7_recyclerview_java", + "//third_party/android_deps:com_android_support_recyclerview_v7_java", "//ui/android:ui_java", ] }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUi.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUi.java index b532812..2004074 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUi.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUi.java
@@ -5,11 +5,14 @@ package org.chromium.chrome.browser.tasks.tab_management; import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.toolbar.bottom.BottomControlsCoordinator; /** - * Interface for the Tab Groups related UI. + * Interface for the Tab Groups related UI. This UI manages its own visibility through {@link + * BottomControlsCoordinator.BottomControlsVisibilityController}. */ public interface TabGroupUi { - void initializeWithNative(ChromeActivity activity); + void initializeWithNative(ChromeActivity activity, + BottomControlsCoordinator.BottomControlsVisibilityController visibilityController); void destroy(); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java index 8ab604b..aec8f45 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java
@@ -8,10 +8,12 @@ import android.view.ViewGroup; import org.chromium.chrome.browser.ChromeActivity; +import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.lifecycle.Destroyable; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModelSelector; +import org.chromium.chrome.browser.toolbar.bottom.BottomControlsCoordinator; import org.chromium.ui.modelutil.PropertyModel; import java.util.List; @@ -45,7 +47,10 @@ * Handle any initialization that occurs once native has been loaded. */ @Override - public void initializeWithNative(ChromeActivity activity) { + public void initializeWithNative(ChromeActivity activity, + BottomControlsCoordinator.BottomControlsVisibilityController visibilityController) { + assert activity instanceof ChromeTabbedActivity; + TabModelSelector tabModelSelector = activity.getTabModelSelector(); TabContentManager tabContentManager = activity.getTabContentManager(); mTabStripCoordinator = new TabListCoordinator(TabListCoordinator.TabListMode.STRIP, @@ -55,7 +60,9 @@ mTabGridSheetCoordinator = new TabGridSheetCoordinator(mContext, activity.getBottomSheetController(), tabModelSelector, tabContentManager, activity); - mMediator = new TabGroupUiMediator(this, mTabStripToolbarModel, tabModelSelector, activity); + mMediator = new TabGroupUiMediator(visibilityController, this, mTabStripToolbarModel, + tabModelSelector, activity, + ((ChromeTabbedActivity) activity).getOverviewModeBehavior()); } /**
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java index 05cc81fb..9613412 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java
@@ -5,6 +5,8 @@ package org.chromium.chrome.browser.tasks.tab_management; import org.chromium.chrome.browser.UrlConstants; +import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver; +import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.lifecycle.Destroyable; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; @@ -13,6 +15,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabSelectionType; +import org.chromium.chrome.browser.toolbar.bottom.BottomControlsCoordinator; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.ui.modelutil.PropertyModel; @@ -50,28 +53,59 @@ private final ResetHandler mResetHandler; private final TabModelSelector mTabModelSelector; private final TabCreatorManager mTabCreatorManager; + private final OverviewModeBehavior mOverviewModeBehavior; + private final OverviewModeBehavior.OverviewModeObserver mOverviewModeObserver; + private final BottomControlsCoordinator + .BottomControlsVisibilityController mVisibilityController; - TabGroupUiMediator(ResetHandler resetHandler, PropertyModel toolbarPropertyModel, - TabModelSelector tabModelSelector, TabCreatorManager tabCreatorManager) { + TabGroupUiMediator( + BottomControlsCoordinator.BottomControlsVisibilityController visibilityController, + ResetHandler resetHandler, PropertyModel toolbarPropertyModel, + TabModelSelector tabModelSelector, TabCreatorManager tabCreatorManager, + OverviewModeBehavior overviewModeBehavior) { mResetHandler = resetHandler; mToolbarPropertyModel = toolbarPropertyModel; mTabModelSelector = tabModelSelector; mTabCreatorManager = tabCreatorManager; + mOverviewModeBehavior = overviewModeBehavior; + mVisibilityController = visibilityController; // register for tab model mTabModelObserver = new EmptyTabModelObserver() { @Override public void didSelectTab(Tab tab, @TabSelectionType int type, int lastId) { if (getRelatedTabsForId(lastId).contains(tab)) return; - mResetHandler.resetStripWithListOfTabs(getRelatedTabsForId(tab.getId())); + resetTabStripWithRelatedTabsForId(tab.getId()); + } + + @Override + public void didAddTab(Tab tab, int type) { + if (type == TabLaunchType.FROM_CHROME_UI) return; + resetTabStripWithRelatedTabsForId(tab.getId()); + } + }; + mOverviewModeObserver = new EmptyOverviewModeObserver() { + @Override + public void onOverviewModeStartedShowing(boolean showToolbar) { + resetTabStripWithRelatedTabsForId(Tab.INVALID_TAB_ID); + } + + @Override + public void onOverviewModeFinishedHiding() { + Tab tab = mTabModelSelector.getCurrentTab(); + if (tab == null) return; + resetTabStripWithRelatedTabsForId(tab.getId()); } }; mTabModelSelector.getTabModelFilterProvider().addTabModelFilterObserver(mTabModelObserver); + mOverviewModeBehavior.addOverviewModeObserver(mOverviewModeObserver); setupToolbarClickHandlers(); mToolbarPropertyModel.set(TabStripToolbarViewProperties.IS_MAIN_CONTENT_VISIBLE, true); - mResetHandler.resetStripWithListOfTabs( - getRelatedTabsForId(tabModelSelector.getCurrentTab().getId())); + Tab tab = mTabModelSelector.getCurrentTab(); + if (tab != null) { + resetTabStripWithRelatedTabsForId(tab.getId()); + } } private void setupToolbarClickHandlers() { @@ -88,6 +122,20 @@ }); } + private void resetTabStripWithRelatedTabsForId(int id) { + List<Tab> listOfTabs = mTabModelSelector.getTabModelFilterProvider() + .getCurrentTabModelFilter() + .getRelatedTabList(id); + + if (listOfTabs == null || listOfTabs.size() < 2) { + mResetHandler.resetStripWithListOfTabs(null); + mVisibilityController.setBottomControlsVisible(false); + } else { + mResetHandler.resetStripWithListOfTabs(listOfTabs); + mVisibilityController.setBottomControlsVisible(true); + } + } + private List<Tab> getRelatedTabsForId(int id) { return mTabModelSelector.getTabModelFilterProvider() .getCurrentTabModelFilter() @@ -100,5 +148,6 @@ mTabModelSelector.getTabModelFilterProvider().removeTabModelFilterObserver( mTabModelObserver); } + mOverviewModeBehavior.removeOverviewModeObserver(mOverviewModeObserver); } }
diff --git a/chrome/android/features/vr/BUILD.gn b/chrome/android/features/vr/BUILD.gn index 917275c..57b5e54c 100644 --- a/chrome/android/features/vr/BUILD.gn +++ b/chrome/android/features/vr/BUILD.gn
@@ -112,7 +112,7 @@ "//content/public/android:content_java", "//third_party/android_deps:android_arch_lifecycle_common_java", "//third_party/android_deps:android_arch_lifecycle_runtime_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/android_deps:android_support_v7_appcompat_java", "//third_party/gvr-android-keyboard:kb_java", "//ui/android:ui_full_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index 4343ac1..b10330c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -1213,7 +1213,8 @@ public void onOrientationChange() { if (mActionModeController != null) mActionModeController.showControlsOnOrientationChange(); - if (mBottomControlsCoordinator != null && FeatureUtilities.isAdaptiveToolbarEnabled()) { + if (mBottomControlsCoordinator != null && FeatureUtilities.isBottomToolbarEnabled() + && FeatureUtilities.isAdaptiveToolbarEnabled()) { mIsBottomToolbarVisible = mActivity.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE; mToolbar.onBottomToolbarVisibilityChanged(mIsBottomToolbarVisible);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java index 054838a1..69ece79 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom/BottomControlsCoordinator.java
@@ -38,6 +38,13 @@ * controls offset is 0. */ public class BottomControlsCoordinator { + /** + * Interface for the BottomControls component to hide and show itself. + */ + public interface BottomControlsVisibilityController { + void setBottomControlsVisible(boolean isVisible); + } + /** The mediator that handles events from outside the bottom controls. */ private final BottomControlsMediator mMediator; @@ -121,8 +128,7 @@ } if (mTabGroupUi != null) { - mTabGroupUi.initializeWithNative(chromeActivity); - mMediator.setBottomControlsVisible(true); + mTabGroupUi.initializeWithNative(chromeActivity, mMediator::setBottomControlsVisible); } } @@ -130,9 +136,6 @@ * @param isVisible Whether the bottom control is visible. */ public void setBottomControlsVisible(boolean isVisible) { - // TabGroupUi manages its own visibility - if (mTabGroupUi != null) return; - mMediator.setBottomControlsVisible(isVisible); if (mBottomToolbarCoordinator != null) { mBottomToolbarCoordinator.setBottomToolbarVisible(isVisible);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java index b4a046b..7160a2a5 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java
@@ -18,6 +18,7 @@ import android.os.Bundle; import org.junit.Before; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -529,6 +530,7 @@ * Test that the pending update file is deleted after update completes regardless of whether * update succeeded. */ + @Ignore("https://crbug.com/937109") @Test public void testPendingUpdateFileDeletedAfterUpdateCompletion() throws Exception { mClockRule.advance(WebappDataStorage.UPDATE_INTERVAL); @@ -554,6 +556,7 @@ * {@link WebApkUpdateManager#nativeStoreWebApkUpdateRequestToFile} creates the pending update * file but fails. */ + @Ignore("https://crbug.com/937109") @Test public void testFileDeletedIfStoreWebApkUpdateRequestToFileFails() throws Exception { mClockRule.advance(WebappDataStorage.UPDATE_INTERVAL);
diff --git a/chrome/android/webapk/libs/client/BUILD.gn b/chrome/android/webapk/libs/client/BUILD.gn index 92169504..84fb107 100644 --- a/chrome/android/webapk/libs/client/BUILD.gn +++ b/chrome/android/webapk/libs/client/BUILD.gn
@@ -19,7 +19,7 @@ "//base:base_java", "//chrome/android/webapk/libs/common:common_java", "//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] srcjar_deps = [ ":runtime_library_version_java" ] }
diff --git a/chrome/android/webapk/libs/common/BUILD.gn b/chrome/android/webapk/libs/common/BUILD.gn index 527f068..da53ae3 100644 --- a/chrome/android/webapk/libs/common/BUILD.gn +++ b/chrome/android/webapk/libs/common/BUILD.gn
@@ -18,7 +18,7 @@ java_files = [ "src/org/chromium/webapk/lib/common/splash/SplashLayout.java" ] deps = [ ":splash_resources", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] }
diff --git a/chrome/android/webapk/libs/runtime_library/BUILD.gn b/chrome/android/webapk/libs/runtime_library/BUILD.gn index 477d5f7..eef3a89 100644 --- a/chrome/android/webapk/libs/runtime_library/BUILD.gn +++ b/chrome/android/webapk/libs/runtime_library/BUILD.gn
@@ -35,7 +35,7 @@ [ "src/org/chromium/webapk/lib/runtime_library/WebApkServiceImpl.java" ] srcjar_deps = [ ":webapk_service_aidl" ] deps = [ - "//third_party/android_deps:android_support_compat_java", + "//third_party/android_deps:com_android_support_support_compat_java", ] } @@ -45,7 +45,7 @@ [ "src/org/chromium/webapk/lib/runtime_library/WebApkServiceImpl.java" ] deps = [ ":webapk_service_aidl_java", - "//third_party/android_deps:android_support_compat_java", + "//third_party/android_deps:com_android_support_support_compat_java", ] }
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 028f65d..d7b200ec 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -1648,9 +1648,12 @@ <message name="IDS_TERMS_OF_SERVICE_SCREEN_ACCEPT_BUTTON" desc="Text of the accept button on the Terms of Service screen."> Accept and continue </message> - <message name="IDS_CONTROLLED_SETTING_OWNER" desc="Text displayed in the controlled settings bubble when a setting's value can be edited only by the owner."> + <message name="IDS_CONTROLLED_SETTING_WITH_OWNER" desc="Text displayed in the controlled settings bubble when a setting's value can be edited only by the owner."> This setting is managed by the device owner, <ph name="OWNER_EMAIL">$1<ex>john@google.com</ex></ph>. </message> + <message name="IDS_CONTROLLED_SETTING_NO_OWNER" desc="Text displayed in the controlled settings bubble when a setting's value can be edited only by the owner."> + This setting is managed by the device owner. + </message> <message name="IDS_CONTROLLED_SETTING_SHARED" desc="Text displayed in the controlled settings bubble when a setting's value belongs to the primary user but can be edited."> This setting belongs to <ph name="OWNER_EMAIL">$1<ex>john@google.com</ex></ph>. </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 3d5a59e3..915a5eb 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -875,8 +875,6 @@ "net/proxy_config_monitor.h", "net/proxy_service_factory.cc", "net/proxy_service_factory.h", - "net/quota_policy_channel_id_store.cc", - "net/quota_policy_channel_id_store.h", "net/referrer.cc", "net/referrer.h", "net/reporting_permissions_checker.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index a350f6e..1d70726b 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -194,6 +194,10 @@ #include "chrome/browser/win/titlebar_config.h" #endif // OS_WIN +#if defined(TOOLKIT_VIEWS) +#include "ui/views/animation/installable_ink_drop.h" +#endif // defined(TOOLKIT_VIEWS) + using flags_ui::FeatureEntry; using flags_ui::kOsAndroid; using flags_ui::kOsCrOS; @@ -2914,9 +2918,6 @@ flag_descriptions::kEnableFullscreenHandwritingVirtualKeyboardDescription, kOsCrOS, FEATURE_VALUE_TYPE(features::kEnableFullscreenHandwritingVirtualKeyboard)}, - {"enable-per-user-timezone", flag_descriptions::kEnablePerUserTimezoneName, - flag_descriptions::kEnablePerUserTimezoneDescription, kOsCrOS, - SINGLE_DISABLE_VALUE_TYPE(chromeos::switches::kDisablePerUserTimezone)}, {"enable-virtual-keyboard-ukm", flag_descriptions::kEnableVirtualKeyboardUkmName, flag_descriptions::kEnableVirtualKeyboardUkmDescription, kOsCrOS, @@ -3487,8 +3488,9 @@ {"unsafely-treat-insecure-origin-as-secure", flag_descriptions::kTreatInsecureOriginAsSecureName, flag_descriptions::kTreatInsecureOriginAsSecureDescription, kOsAll, - ORIGIN_LIST_VALUE_TYPE(switches::kUnsafelyTreatInsecureOriginAsSecure, - "")}, + ORIGIN_LIST_VALUE_TYPE( + network::switches::kUnsafelyTreatInsecureOriginAsSecure, + "")}, #if defined(OS_CHROMEOS) {"enable-app-shortcut-search", @@ -4082,6 +4084,12 @@ FEATURE_VALUE_TYPE(features::kIntentPicker)}, #endif // !defined(OS_ANDROID) +#if defined(TOOLKIT_VIEWS) + {"installable-ink-drop", flag_descriptions::kInstallableInkDropName, + flag_descriptions::kInstallableInkDropDescription, kOsDesktop, + FEATURE_VALUE_TYPE(views::kInstallableInkDropFeature)}, +#endif // defined(TOOLKIT_VIEWS) + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/android/background_sync_launcher_android.cc b/chrome/browser/android/background_sync_launcher_android.cc index 8eaedf25..effc509 100644 --- a/chrome/browser/android/background_sync_launcher_android.cc +++ b/chrome/browser/android/background_sync_launcher_android.cc
@@ -8,6 +8,7 @@ #include "base/android/callback_android.h" #include "base/barrier_closure.h" +#include "base/bind.h" #include "base/feature_list.h" #include "chrome/browser/android/chrome_feature_list.h" #include "chrome/browser/profiles/profile_manager.h" @@ -52,12 +53,10 @@ } // static -void BackgroundSyncLauncherAndroid::LaunchBrowserIfStopped( - bool launch_when_next_online, - int64_t min_delay_ms) { +void BackgroundSyncLauncherAndroid::LaunchBrowserIfStopped() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - Get()->LaunchBrowserIfStoppedImpl(launch_when_next_online, min_delay_ms); + Get()->LaunchBrowserIfStoppedImpl(); } // static @@ -76,24 +75,38 @@ base::android::AttachCurrentThread()); } -void BackgroundSyncLauncherAndroid::LaunchBrowserIfStoppedImpl( - bool launch_when_next_online, - int64_t min_delay_ms) { +void BackgroundSyncLauncherAndroid::LaunchBrowserIfStoppedImpl() { DCHECK_CURRENTLY_ON(BrowserThread::UI); + auto* profile = ProfileManager::GetLastUsedProfile(); + DCHECK(profile); + + auto* storage_partition = + content::BrowserContext::GetDefaultStoragePartition(profile); + storage_partition->GetBackgroundSyncContext() + ->GetSoonestWakeupDeltaAcrossPartitions( + profile, + base::BindOnce( + &BackgroundSyncLauncherAndroid::LaunchBrowserWithWakeupDelta, + base::Unretained(this))); +} + +void BackgroundSyncLauncherAndroid::LaunchBrowserWithWakeupDelta( + base::TimeDelta soonest_wakeup_delta) { JNIEnv* env = base::android::AttachCurrentThread(); + int64_t min_delay_ms = soonest_wakeup_delta.InMilliseconds(); if (!base::FeatureList::IsEnabled( chrome::android::kBackgroundTaskSchedulerForBackgroundSync)) { Java_BackgroundSyncLauncher_launchBrowserIfStopped( - env, java_gcm_network_manager_launcher_, launch_when_next_online, + env, java_gcm_network_manager_launcher_, soonest_wakeup_delta.is_max(), min_delay_ms); return; } Java_BackgroundSyncBackgroundTaskScheduler_launchBrowserIfStopped( env, java_background_sync_background_task_scheduler_launcher_, - launch_when_next_online, min_delay_ms); + soonest_wakeup_delta.is_max(), min_delay_ms); } void BackgroundSyncLauncherAndroid::FireBackgroundSyncEvents( @@ -103,51 +116,12 @@ auto* profile = ProfileManager::GetLastUsedProfile(); DCHECK(profile); - int num_partitions = 0; - content::BrowserContext::ForEachStoragePartition( - profile, base::BindRepeating( - [](int* num_partitions, - content::StoragePartition* storage_partition) { - (*num_partitions)++; - }, - &num_partitions)); - - // This class is a singleton, which is only destructed on program exit. - // Therefore, use of base::Unretained(this) is safe. - base::RepeatingClosure done_closure = base::BarrierClosure( - num_partitions, - base::BindOnce(base::android::RunRunnableAndroid, - base::android::ScopedJavaGlobalRef<jobject>(j_runnable))); - - content::BrowserContext::ForEachStoragePartition( - profile, - base::BindRepeating(&BackgroundSyncLauncherAndroid:: - FireBackgroundSyncEventsForStoragePartition, - base::Unretained(this), done_closure)); + auto* storage_partition = + content::BrowserContext::GetDefaultStoragePartition(profile); + storage_partition->GetBackgroundSyncContext() + ->FireBackgroundSyncEventsAcrossPartitions(profile, j_runnable); } -void BackgroundSyncLauncherAndroid::FireBackgroundSyncEventsForStoragePartition( - base::OnceClosure done_closure, - content::StoragePartition* storage_partition) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - content::BackgroundSyncContext* sync_context = - storage_partition->GetBackgroundSyncContext(); - if (!sync_context) { - std::move(done_closure).Run(); - return; - } - - sync_context->FireBackgroundSyncEventsForStoragePartition( - storage_partition, std::move(done_closure)); -} - -void BackgroundSyncLauncherAndroid::OnFiredBackgroundSyncEvents( - base::android::ScopedJavaGlobalRef<jobject> j_runnable) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - base::android::RunRunnableAndroid(j_runnable); -} BackgroundSyncLauncherAndroid::BackgroundSyncLauncherAndroid() { DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/chrome/browser/android/background_sync_launcher_android.h b/chrome/browser/android/background_sync_launcher_android.h index 1afb9bae..25cfec2 100644 --- a/chrome/browser/android/background_sync_launcher_android.h +++ b/chrome/browser/android/background_sync_launcher_android.h
@@ -13,10 +13,7 @@ #include "base/callback_forward.h" #include "base/lazy_instance.h" #include "base/macros.h" - -namespace content { -class StoragePartition; -} // namespace content +#include "base/time/time.h" // The BackgroundSyncLauncherAndroid singleton owns the Java // BackgroundSyncLauncher object and is used to register interest in starting @@ -26,8 +23,12 @@ public: static BackgroundSyncLauncherAndroid* Get(); - static void LaunchBrowserIfStopped(bool launch_when_next_online, - int64_t min_delay_ms); + // Calculates the soonest wakeup time across all the storage + // partitions for the non-incognito profile and ensures that the browser + // is running when the device next goes online after that time has passed. + // If this time is set to base::TimeDelta::Max() across all storage + // partitions, the wake-up task is cancelled. + static void LaunchBrowserIfStopped(); static bool ShouldDisableBackgroundSync(); @@ -47,13 +48,8 @@ BackgroundSyncLauncherAndroid(); ~BackgroundSyncLauncherAndroid(); - void LaunchBrowserIfStoppedImpl(bool launch_when_next_online, - int64_t min_delay_ms); - void FireBackgroundSyncEventsForStoragePartition( - base::OnceClosure done_closure, - content::StoragePartition* storage_partition); - void OnFiredBackgroundSyncEvents( - base::android::ScopedJavaGlobalRef<jobject> j_runnable); + void LaunchBrowserIfStoppedImpl(); + void LaunchBrowserWithWakeupDelta(base::TimeDelta soonest_wakeup_delta); base::android::ScopedJavaGlobalRef<jobject> java_gcm_network_manager_launcher_;
diff --git a/chrome/browser/background_sync/background_sync_controller_impl.cc b/chrome/browser/background_sync/background_sync_controller_impl.cc index 40c86396..f73f95e2 100644 --- a/chrome/browser/background_sync/background_sync_controller_impl.cc +++ b/chrome/browser/background_sync/background_sync_controller_impl.cc
@@ -114,17 +114,13 @@ origin.GetURL()); } -void BackgroundSyncControllerImpl::RunInBackground(bool enabled, - int64_t min_ms) { +void BackgroundSyncControllerImpl::RunInBackground() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); if (profile_->IsOffTheRecord()) return; #if defined(OS_ANDROID) - BackgroundSyncLauncherAndroid::LaunchBrowserIfStopped(enabled, min_ms); -#else -// TODO(jkarlin): Use BackgroundModeManager to enter background mode. See -// https://crbug.com/484201. + BackgroundSyncLauncherAndroid::LaunchBrowserIfStopped(); #endif }
diff --git a/chrome/browser/background_sync/background_sync_controller_impl.h b/chrome/browser/background_sync/background_sync_controller_impl.h index 6446b77..e5739a39 100644 --- a/chrome/browser/background_sync/background_sync_controller_impl.h +++ b/chrome/browser/background_sync/background_sync_controller_impl.h
@@ -45,7 +45,7 @@ void GetParameterOverrides( content::BackgroundSyncParameters* parameters) const override; void NotifyBackgroundSyncRegistered(const url::Origin& origin) override; - void RunInBackground(bool enabled, int64_t min_ms) override; + void RunInBackground() override; protected: // Virtual for testing.
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 48ef94d..bc8af9d 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -327,6 +327,7 @@ #include "services/image_annotation/public/mojom/constants.mojom.h" #include "services/image_annotation/public/mojom/image_annotation.mojom.h" #include "services/network/public/cpp/features.h" +#include "services/network/public/cpp/network_switches.h" #include "services/network/public/cpp/resource_request.h" #include "services/preferences/public/cpp/in_process_service_factory.h" #include "services/preferences/public/mojom/preferences.mojom.h" @@ -2106,7 +2107,7 @@ if (prefs->HasPrefPath(prefs::kUnsafelyTreatInsecureOriginAsSecure)) { command_line->AppendSwitchASCII( - switches::kUnsafelyTreatInsecureOriginAsSecure, + network::switches::kUnsafelyTreatInsecureOriginAsSecure, prefs->GetString(prefs::kUnsafelyTreatInsecureOriginAsSecure)); }
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index 9fd16ba..5bf5279 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -57,9 +57,8 @@ #include "chrome/grit/browser_resources.h" #include "chromeos/audio/chromeos_sounds.h" #include "chromeos/constants/chromeos_switches.h" -#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/power_manager_client.h" -#include "chromeos/dbus/upstart_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" #include "components/language/core/browser/pref_names.h" #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" @@ -149,8 +148,7 @@ // stop followed by start ensures we both stop a started job, and also start // brltty. void RestartBrltty(const std::string& address) { - chromeos::UpstartClient* client = - chromeos::DBusThreadManager::Get()->GetUpstartClient(); + chromeos::UpstartClient* client = chromeos::UpstartClient::Get(); client->StopJob(kBrlttyUpstartJobName, EmptyVoidDBusMethodCallback()); std::vector<std::string> args; @@ -1345,8 +1343,8 @@ void AccessibilityManager::PostUnloadChromeVox() { // Do any teardown work needed immediately after ChromeVox actually unloads. // Stop brltty. - chromeos::DBusThreadManager::Get()->GetUpstartClient()->StopJob( - kBrlttyUpstartJobName, EmptyVoidDBusMethodCallback()); + chromeos::UpstartClient::Get()->StopJob(kBrlttyUpstartJobName, + EmptyVoidDBusMethodCallback()); PlayEarcon(SOUND_SPOKEN_FEEDBACK_DISABLED, PlaySoundOption::ALWAYS);
diff --git a/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler_unittest.cc b/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler_unittest.cc index 42d55b0b..3609ba1 100644 --- a/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler_unittest.cc +++ b/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler_unittest.cc
@@ -21,6 +21,7 @@ #include "chrome/test/base/testing_profile.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/fake_session_manager_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" #include "components/arc/arc_prefs.h" #include "components/arc/arc_session_runner.h" #include "components/arc/arc_util.h" @@ -54,6 +55,7 @@ chromeos::DBusThreadManager::GetSetterForTesting()->SetSessionManagerClient( std::make_unique<chromeos::FakeSessionManagerClient>()); chromeos::DBusThreadManager::Initialize(); + chromeos::UpstartClient::InitializeFake(); SetArcAvailableCommandLineForTesting( base::CommandLine::ForCurrentProcess()); @@ -90,6 +92,7 @@ arc_session_manager_.reset(); identity_test_env_profile_adaptor_.reset(); profile_.reset(); + chromeos::UpstartClient::Shutdown(); chromeos::DBusThreadManager::Shutdown(); }
diff --git a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc index d184c47..6f44589 100644 --- a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc +++ b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
@@ -43,6 +43,7 @@ #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/fake_session_manager_client.h" #include "chromeos/dbus/power_manager_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" #include "components/account_id/account_id.h" #include "components/arc/arc_features.h" #include "components/arc/arc_prefs.h" @@ -181,6 +182,7 @@ std::make_unique<chromeos::FakeSessionManagerClient>()); chromeos::PowerManagerClient::Initialize(); + chromeos::UpstartClient::InitializeFake(); SetArcAvailableCommandLineForTesting( base::CommandLine::ForCurrentProcess()); @@ -208,6 +210,7 @@ profile_.reset(); arc_session_manager_.reset(); arc_service_manager_.reset(); + chromeos::UpstartClient::Shutdown(); chromeos::PowerManagerClient::Shutdown(); chromeos::DBusThreadManager::Shutdown(); }
diff --git a/chrome/browser/chromeos/dbus/dbus_helper.cc b/chrome/browser/chromeos/dbus/dbus_helper.cc index 94afeab7..c251cb4 100644 --- a/chrome/browser/chromeos/dbus/dbus_helper.cc +++ b/chrome/browser/chromeos/dbus/dbus_helper.cc
@@ -10,6 +10,7 @@ #include "chromeos/dbus/hammerd/hammerd_client.h" #include "chromeos/dbus/power_manager_client.h" #include "chromeos/dbus/system_clock/system_clock_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" #include "chromeos/tpm/install_attributes.h" #include "ui/base/ui_base_features.h" @@ -33,6 +34,14 @@ PowerManagerClient::Initialize(bus); SystemClockClient::Initialize(bus); + // TODO(stevenjb): Modify PowerManagerClient and SystemClockClient to use + // the same pattern as UpstartClient. + if (bus) { + UpstartClient::Initialize(bus); + } else { + UpstartClient::InitializeFake(); + } + // Initialize the device settings service so that we'll take actions per // signals sent from the session manager. This needs to happen before // g_browser_process initializes BrowserPolicyConnector. @@ -41,6 +50,7 @@ } void ShutdownDBus() { + UpstartClient::Shutdown(); SystemClockClient::Shutdown(); PowerManagerClient::Shutdown();
diff --git a/chrome/browser/chromeos/login/active_directory_test_helper.cc b/chrome/browser/chromeos/login/active_directory_test_helper.cc index e7239c5..02c1839 100644 --- a/chrome/browser/chromeos/login/active_directory_test_helper.cc +++ b/chrome/browser/chromeos/login/active_directory_test_helper.cc
@@ -16,7 +16,7 @@ #include "chromeos/dbus/auth_policy_client.h" #include "chromeos/dbus/authpolicy/active_directory_info.pb.h" #include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/upstart_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" #include "chromeos/dbus/util/tpm_util.h" #include "chromeos/login/auth/authpolicy_login_helper.h" #include "testing/gtest/include/gtest/gtest.h" @@ -38,9 +38,7 @@ ASSERT_EQ(2u, user_and_domain.size()); // Start the D-Bus service. - chromeos::DBusThreadManager::Get() - ->GetUpstartClient() - ->StartAuthPolicyService(); + chromeos::UpstartClient::Get()->StartAuthPolicyService(); // Join the AD domain. chromeos::AuthPolicyLoginHelper helper;
diff --git a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc index be4ba4e..e98b2d4 100644 --- a/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc +++ b/chrome/browser/chromeos/login/enterprise_enrollment_browsertest.cc
@@ -25,7 +25,7 @@ #include "chromeos/dbus/constants/dbus_switches.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/fake_auth_policy_client.h" -#include "chromeos/dbus/upstart_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" @@ -511,9 +511,7 @@ enrollment_screen(), kAdUserDomain, std::string(), kDMToken); SubmitEnrollmentCredentials(); - chromeos::DBusThreadManager::Get() - ->GetUpstartClient() - ->StartAuthPolicyService(); + chromeos::UpstartClient::Get()->StartAuthPolicyService(); CheckActiveDirectoryCredentialsShown(); CheckConfigurationSelectionVisible(false); @@ -545,9 +543,7 @@ SubmitEnrollmentCredentials(); - chromeos::DBusThreadManager::Get() - ->GetUpstartClient() - ->StartAuthPolicyService(); + chromeos::UpstartClient::Get()->StartAuthPolicyService(); content::DOMMessageQueue message_queue; SetupActiveDirectoryJSNotifications(); @@ -582,9 +578,7 @@ enrollment_screen(), kAdUserDomain, std::string(), kDMToken); SubmitEnrollmentCredentials(); - chromeos::DBusThreadManager::Get() - ->GetUpstartClient() - ->StartAuthPolicyService(); + chromeos::UpstartClient::Get()->StartAuthPolicyService(); content::DOMMessageQueue message_queue; // Checking error in case of empty password. Whether password is not empty @@ -630,9 +624,7 @@ enrollment_screen(), kAdUserDomain, std::string(), kDMToken); SubmitEnrollmentCredentials(); - chromeos::DBusThreadManager::Get() - ->GetUpstartClient() - ->StartAuthPolicyService(); + chromeos::UpstartClient::Get()->StartAuthPolicyService(); content::DOMMessageQueue message_queue; SetupActiveDirectoryJSNotifications(); @@ -657,9 +649,7 @@ enrollment_screen(), kAdUserDomain, binary_config, kDMToken); SubmitEnrollmentCredentials(); - chromeos::DBusThreadManager::Get() - ->GetUpstartClient() - ->StartAuthPolicyService(); + chromeos::UpstartClient::Get()->StartAuthPolicyService(); ExecutePendingJavaScript(); content::DOMMessageQueue message_queue;
diff --git a/chrome/browser/chromeos/login/screens/mock_welcome_screen.cc b/chrome/browser/chromeos/login/screens/mock_welcome_screen.cc index 4785e65..65d2025 100644 --- a/chrome/browser/chromeos/login/screens/mock_welcome_screen.cc +++ b/chrome/browser/chromeos/login/screens/mock_welcome_screen.cc
@@ -7,10 +7,9 @@ namespace chromeos { MockWelcomeScreen::MockWelcomeScreen( - Delegate* delegate, WelcomeView* view, const base::RepeatingClosure& exit_callback) - : WelcomeScreen(delegate, view, exit_callback) {} + : WelcomeScreen(view, exit_callback) {} void MockWelcomeScreen::ExitScreen() { exit_callback()->Run();
diff --git a/chrome/browser/chromeos/login/screens/mock_welcome_screen.h b/chrome/browser/chromeos/login/screens/mock_welcome_screen.h index 6d39c05..6436b25 100644 --- a/chrome/browser/chromeos/login/screens/mock_welcome_screen.h +++ b/chrome/browser/chromeos/login/screens/mock_welcome_screen.h
@@ -16,8 +16,7 @@ class MockWelcomeScreen : public WelcomeScreen { public: - MockWelcomeScreen(Delegate* delegate, - WelcomeView* view, + MockWelcomeScreen(WelcomeView* view, const base::RepeatingClosure& exit_callback); ~MockWelcomeScreen() override;
diff --git a/chrome/browser/chromeos/login/screens/welcome_screen.cc b/chrome/browser/chromeos/login/screens/welcome_screen.cc index 6bcd29a..2309386 100644 --- a/chrome/browser/chromeos/login/screens/welcome_screen.cc +++ b/chrome/browser/chromeos/login/screens/welcome_screen.cc
@@ -36,8 +36,6 @@ namespace { constexpr char kUserActionContinueButtonClicked[] = "continue"; -constexpr char kUserActionConnectDebuggingFeaturesClicked[] = - "connect-debugging-features"; } // namespace @@ -52,12 +50,10 @@ manager->GetScreen(OobeScreen::SCREEN_OOBE_WELCOME)); } -WelcomeScreen::WelcomeScreen(Delegate* delegate, - WelcomeView* view, +WelcomeScreen::WelcomeScreen(WelcomeView* view, const base::RepeatingClosure& exit_callback) : BaseScreen(OobeScreen::SCREEN_OOBE_WELCOME), view_(view), - delegate_(delegate), exit_callback_(exit_callback), weak_factory_(this) { if (view_) @@ -205,9 +201,6 @@ void WelcomeScreen::OnUserAction(const std::string& action_id) { if (action_id == kUserActionContinueButtonClicked) { OnContinueButtonPressed(); - } else if (action_id == kUserActionConnectDebuggingFeaturesClicked) { - if (delegate_) - delegate_->OnEnableDebuggingScreenRequested(); } else { BaseScreen::OnUserAction(action_id); }
diff --git a/chrome/browser/chromeos/login/screens/welcome_screen.h b/chrome/browser/chromeos/login/screens/welcome_screen.h index 2842950..6eba275 100644 --- a/chrome/browser/chromeos/login/screens/welcome_screen.h +++ b/chrome/browser/chromeos/login/screens/welcome_screen.h
@@ -31,14 +31,6 @@ class WelcomeScreen : public BaseScreen, public input_method::InputMethodManager::Observer { public: - class Delegate { - public: - virtual ~Delegate() {} - - // Called when enable debugging screen is requested. - virtual void OnEnableDebuggingScreenRequested() = 0; - }; - class Observer { public: virtual ~Observer() {} @@ -47,9 +39,7 @@ virtual void OnLanguageListReloaded() = 0; }; - WelcomeScreen(Delegate* delegate, - WelcomeView* view, - const base::RepeatingClosure& exit_callback); + WelcomeScreen(WelcomeView* view, const base::RepeatingClosure& exit_callback); ~WelcomeScreen() override; static WelcomeScreen* Get(ScreenManager* manager); @@ -130,7 +120,6 @@ std::unique_ptr<CrosSettings::ObserverSubscription> timezone_subscription_; WelcomeView* view_ = nullptr; - Delegate* delegate_ = nullptr; base::RepeatingClosure exit_callback_; std::string input_method_;
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc index aace7b26..d976d792 100644 --- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc +++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
@@ -76,7 +76,7 @@ #include "chromeos/dbus/cryptohome/rpc.pb.h" #include "chromeos/dbus/dbus_method_call_status.h" #include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/upstart_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" #include "chromeos/login/login_state/login_state.h" #include "chromeos/network/proxy/proxy_config_service_impl.h" #include "chromeos/settings/cros_settings_names.h" @@ -212,8 +212,8 @@ const std::string board_name = board[0]; if (board_name != "eve" && board_name != "nocturne") return; - chromeos::DBusThreadManager::Get()->GetUpstartClient()->StartJob( - kBluetoothLoggingUpstartJob, {}, EmptyVoidDBusMethodCallback()); + chromeos::UpstartClient::Get()->StartJob(kBluetoothLoggingUpstartJob, {}, + EmptyVoidDBusMethodCallback()); } bool IsManagedSessionEnabled(policy::DeviceLocalAccountPolicyBroker* broker) {
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index ed4a9d56..d2bc4e9 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -69,6 +69,7 @@ #include "chrome/browser/chromeos/login/screens/sync_consent_screen.h" #include "chrome/browser/chromeos/login/screens/update_required_screen.h" #include "chrome/browser/chromeos/login/screens/update_screen.h" +#include "chrome/browser/chromeos/login/screens/welcome_screen.h" #include "chrome/browser/chromeos/login/screens/welcome_view.h" #include "chrome/browser/chromeos/login/screens/wrong_hwid_screen.h" #include "chrome/browser/chromeos/login/session/user_session_manager.h" @@ -374,7 +375,7 @@ if (screen == OobeScreen::SCREEN_OOBE_WELCOME) { return std::make_unique<WelcomeScreen>( - this, oobe_ui->GetWelcomeView(), + oobe_ui->GetWelcomeView(), base::BindRepeating(&WizardController::OnWelcomeScreenExit, weak_factory_.GetWeakPtr())); } else if (screen == OobeScreen::SCREEN_OOBE_NETWORK) { @@ -1552,11 +1553,6 @@ SetCurrentScreen(parent_screen); } -void WizardController::OnEnableDebuggingScreenRequested() { - if (!login_screen_started()) - AdvanceToScreen(OobeScreen::SCREEN_OOBE_ENABLE_DEBUGGING); -} - void WizardController::OnAccessibilityStatusChanged( const AccessibilityStatusEventDetails& details) { enum AccessibilityNotificationType type = details.notification_type;
diff --git a/chrome/browser/chromeos/login/wizard_controller.h b/chrome/browser/chromeos/login/wizard_controller.h index 3d7693b6..8b06156 100644 --- a/chrome/browser/chromeos/login/wizard_controller.h +++ b/chrome/browser/chromeos/login/wizard_controller.h
@@ -33,8 +33,8 @@ #include "chrome/browser/chromeos/login/screens/recommend_apps_screen.h" #include "chrome/browser/chromeos/login/screens/terms_of_service_screen.h" #include "chrome/browser/chromeos/login/screens/update_screen.h" -#include "chrome/browser/chromeos/login/screens/welcome_screen.h" #include "chrome/browser/chromeos/policy/enrollment_config.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" class PrefService; @@ -55,8 +55,7 @@ // Class that manages control flow between wizard screens. Wizard controller // interacts with screen controllers to move the user between screens. -class WizardController : public BaseScreenDelegate, - public WelcomeScreen::Delegate { +class WizardController : public BaseScreenDelegate { public: WizardController(); ~WizardController() override; @@ -267,9 +266,6 @@ void ShowErrorScreen() override; void HideErrorScreen(BaseScreen* parent_screen) override; - // Override from WelcomeScreen::Delegate: - void OnEnableDebuggingScreenRequested() override; - void OnHIDScreenNecessityCheck(bool screen_needed); // Notification of a change in the state of an accessibility setting.
diff --git a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc index 8ffa727..3000cc91 100644 --- a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc +++ b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
@@ -583,7 +583,7 @@ // Set up the mocks for all screens. mock_welcome_screen_ = MockScreenExpectLifecycle(std::make_unique<MockWelcomeScreen>( - wizard_controller, GetOobeUI()->GetWelcomeView(), + GetOobeUI()->GetWelcomeView(), base::BindRepeating(&WizardController::OnWelcomeScreenExit, base::Unretained(wizard_controller)))); @@ -2286,11 +2286,16 @@ EXPECT_CALL(*mock_welcome_screen_, SetConfiguration(IsNull(), _)).Times(1); EXPECT_CALL(*mock_enable_debugging_screen_, Show()).Times(1); + // Find the enable debugging link element (in the appropriate shadow root), + // and click it. ASSERT_TRUE( - JSExecute("chrome.send('login.WelcomeScreen.userActed', " - "['connect-debugging-features']);")); + JSExecute("(function() {" + " var root = ['oobe-welcome-md', 'welcomeScreen'].reduce(" + " (root, id) => root.getElementById(id).shadowRoot," + " document);" + " root.getElementById('enableDebuggingLink').click();" + "})();")); - // Let update screen smooth time process (time = 0ms). content::RunAllPendingInMessageLoop(); CheckCurrentScreen(OobeScreen::SCREEN_OOBE_ENABLE_DEBUGGING); @@ -2744,7 +2749,7 @@ ExpectBindUnbind(mock_welcome_view_.get()); mock_welcome_screen_ = MockScreenExpectLifecycle(std::make_unique<MockWelcomeScreen>( - wizard_controller, mock_welcome_view_.get(), + mock_welcome_view_.get(), base::BindRepeating(&WizardController::OnWelcomeScreenExit, base::Unretained(wizard_controller)))); @@ -2844,7 +2849,7 @@ mock_welcome_view_ = std::make_unique<MockWelcomeView>(); mock_welcome_screen_ = MockScreenExpectLifecycle(std::make_unique<MockWelcomeScreen>( - wizard_controller, mock_welcome_view_.get(), + mock_welcome_view_.get(), base::BindRepeating(&WizardController::OnWelcomeScreenExit, base::Unretained(wizard_controller)))); }
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc index 94776513d..a4eb63e 100644 --- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc +++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
@@ -51,7 +51,7 @@ #include "chromeos/cryptohome/system_salt_getter.h" #include "chromeos/dbus/cryptohome_client.h" #include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/upstart_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" #include "chromeos/network/network_cert_loader.h" #include "chromeos/network/network_handler.h" #include "chromeos/network/onc/onc_certificate_importer_impl.h" @@ -117,9 +117,7 @@ chromeos::InstallAttributes::Get(), GetBackgroundTaskRunner()); if (chromeos::InstallAttributes::Get()->IsActiveDirectoryManaged()) { - chromeos::DBusThreadManager::Get() - ->GetUpstartClient() - ->StartAuthPolicyService(); + chromeos::UpstartClient::Get()->StartAuthPolicyService(); device_active_directory_policy_manager_ = new DeviceActiveDirectoryPolicyManager(
diff --git a/chrome/browser/chromeos/policy/device_account_initializer.cc b/chrome/browser/chromeos/policy/device_account_initializer.cc index 980ec30..143bbd8 100644 --- a/chrome/browser/chromeos/policy/device_account_initializer.cc +++ b/chrome/browser/chromeos/policy/device_account_initializer.cc
@@ -33,7 +33,6 @@ #include "chromeos/dbus/auth_policy_client.h" #include "chromeos/dbus/cryptohome/rpc.pb.h" #include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/upstart_client.h" #include "components/policy/core/common/cloud/dm_auth.h" #include "components/policy/proto/chrome_device_policy.pb.h" #include "google_apis/gaia/gaia_auth_util.h"
diff --git a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc index 639e1cb..40746bf 100644 --- a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc +++ b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc
@@ -31,7 +31,7 @@ #include "chromeos/dbus/auth_policy_client.h" #include "chromeos/dbus/cryptohome/rpc.pb.h" #include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/upstart_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" #include "components/policy/core/common/cloud/dm_auth.h" #include "components/policy/proto/chrome_device_policy.pb.h" #include "google_apis/gaia/gaia_auth_util.h" @@ -351,9 +351,7 @@ // Do nothing. break; case DEVICE_MODE_ENTERPRISE_AD: - chromeos::DBusThreadManager::Get() - ->GetUpstartClient() - ->StartAuthPolicyService(); + chromeos::UpstartClient::Get()->StartAuthPolicyService(); break; default: LOG(ERROR) << "Supplied device mode is not supported:" << device_mode_;
diff --git a/chrome/browser/chromeos/policy/secondary_google_account_signin_policy_handler.cc b/chrome/browser/chromeos/policy/secondary_google_account_signin_policy_handler.cc index f66db98..d68d01c 100644 --- a/chrome/browser/chromeos/policy/secondary_google_account_signin_policy_handler.cc +++ b/chrome/browser/chromeos/policy/secondary_google_account_signin_policy_handler.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "chrome/browser/chromeos/policy/secondary_google_account_signin_policy_handler.h" +#include "chromeos/constants/chromeos_pref_names.h" #include "components/policy/core/common/policy_map.h" #include "components/policy/policy_constants.h" #include "components/prefs/pref_value_map.h" @@ -31,8 +32,14 @@ return; } - // Disallow secondary sign-in by enabling Mirror consistency. + // Disallow secondary sign-in by enabling Mirror consistency. If Chrome OS + // Account Manager is not available, this has the effect of disabling + // secondary account sign-ins within the content area. + // TODO(https://crbug.com/938835): Clean this up after releasing Chrome OS + // Account Manager. prefs->SetBoolean(prefs::kAccountConsistencyMirrorRequired, true); + prefs->SetBoolean(chromeos::prefs::kSecondaryGoogleAccountSigninAllowed, + false); } } // namespace policy
diff --git a/chrome/browser/chromeos/policy/secondary_google_account_signin_policy_handler_unittest.cc b/chrome/browser/chromeos/policy/secondary_google_account_signin_policy_handler_unittest.cc index 8f49a58d..de09538 100644 --- a/chrome/browser/chromeos/policy/secondary_google_account_signin_policy_handler_unittest.cc +++ b/chrome/browser/chromeos/policy/secondary_google_account_signin_policy_handler_unittest.cc
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "chrome/browser/chromeos/policy/secondary_google_account_signin_policy_handler.h" +#include "chromeos/constants/chromeos_pref_names.h" #include "components/policy/core/common/policy_map.h" #include "components/policy/core/common/policy_pref_names.h" #include "components/policy/policy_constants.h" @@ -24,7 +25,8 @@ void SetPolicy(std::unique_ptr<base::Value> value) { policies_.Set(key::kSecondaryGoogleAccountSigninAllowed, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, - POLICY_SOURCE_CLOUD, std::move(value), nullptr); + POLICY_SOURCE_CLOUD, std::move(value), + nullptr /* external_data_fetcher */); } void ApplyPolicySettings(bool value) { @@ -32,14 +34,31 @@ handler_.ApplyPolicySettings(policies_, &prefs_); } - bool GetAccountConsistencyPref(bool* pref) { - return prefs_.GetBoolean(prefs::kAccountConsistencyMirrorRequired, pref); + bool GetMirrorAccountConsistencyPref() { + bool pref = false; + bool success = + prefs_.GetBoolean(prefs::kAccountConsistencyMirrorRequired, &pref); + EXPECT_TRUE(success); + return pref; } void SetAccountConsistencyPref(bool pref) { prefs_.SetBoolean(prefs::kAccountConsistencyMirrorRequired, pref); } + bool GetSecondaryGoogleAccountSigninAllowedPref() { + bool pref = false; + bool success = prefs_.GetBoolean( + chromeos::prefs::kSecondaryGoogleAccountSigninAllowed, &pref); + EXPECT_TRUE(success); + return pref; + } + + void SetSecondaryGoogleAccountSigninPref(bool pref) { + prefs_.SetBoolean(chromeos::prefs::kSecondaryGoogleAccountSigninAllowed, + pref); + } + private: SecondaryGoogleAccountSigninPolicyHandler handler_; PolicyMap policies_; @@ -48,33 +67,50 @@ DISALLOW_COPY_AND_ASSIGN(SecondaryGoogleAccountSigninPolicyHandlerTest); }; +// If the policy is set to true, it should not override the default pref values +// (set to true in this test case). TEST_F(SecondaryGoogleAccountSigninPolicyHandlerTest, - CheckSigninAllowedDoesNotChangeDefaultTruePreference) { + SettingPolicyToTrueDoesNotChangeDefaultPreferencesSetToTrue) { + // Set prefs to |true|. SetAccountConsistencyPref(true); + SetSecondaryGoogleAccountSigninPref(true); + // Set policy to |true|. ApplyPolicySettings(true /* policy value */); - bool preference = false; - EXPECT_TRUE(GetAccountConsistencyPref(&preference)); - EXPECT_TRUE(preference); + // Test that the prefs should be set to |true|. + EXPECT_TRUE(GetMirrorAccountConsistencyPref()); + EXPECT_TRUE(GetSecondaryGoogleAccountSigninAllowedPref()); } +// If the policy is set to true, it should not override the default pref values +// (set to false in this test case). TEST_F(SecondaryGoogleAccountSigninPolicyHandlerTest, - CheckSigninAllowedDoesNotChangeDefaultFalsePreference) { + SettingPolicyToTrueDoesNotChangeDefaultPreferencesSetToFalse) { + // Set prefs to |false|. SetAccountConsistencyPref(false); + SetSecondaryGoogleAccountSigninPref(false); + // Set policy to |true|. ApplyPolicySettings(true /* policy value */); - bool preference = true; - EXPECT_TRUE(GetAccountConsistencyPref(&preference)); - EXPECT_FALSE(preference); + // Test that the prefs should be set to |false|. + EXPECT_FALSE(GetMirrorAccountConsistencyPref()); + EXPECT_FALSE(GetSecondaryGoogleAccountSigninAllowedPref()); } TEST_F(SecondaryGoogleAccountSigninPolicyHandlerTest, - CheckSigninDisallowedEnablesMirror) { + SettingPolicyToFalseEnablesMirror) { + SetAccountConsistencyPref(false); ApplyPolicySettings(false /* policy value */); - bool preference = false; - EXPECT_TRUE(GetAccountConsistencyPref(&preference)); - EXPECT_TRUE(preference); + EXPECT_TRUE(GetMirrorAccountConsistencyPref()); +} + +TEST_F(SecondaryGoogleAccountSigninPolicyHandlerTest, + SettingPolicyToFalseDisablesSecondaryAccountSignins) { + SetSecondaryGoogleAccountSigninPref(true); + ApplyPolicySettings(false /* policy value */); + + EXPECT_FALSE(GetSecondaryGoogleAccountSigninAllowedPref()); } } // namespace policy
diff --git a/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc b/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc index baa2e5cc..8b8f4a8fd 100644 --- a/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc +++ b/chrome/browser/chromeos/policy/user_affiliation_browsertest.cc
@@ -27,6 +27,7 @@ #include "chromeos/dbus/fake_cryptohome_client.h" #include "chromeos/dbus/fake_session_manager_client.h" #include "chromeos/dbus/session_manager_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" #include "components/account_id/account_id.h" #include "components/policy/core/common/cloud/device_management_service.h" #include "components/user_manager/user.h" @@ -164,6 +165,10 @@ chromeos::DBusThreadManager::GetSetterForTesting()->SetCryptohomeClient( std::make_unique<chromeos::FakeCryptohomeClient>()); + // Initialize UpstartClient here so that it is available for + // FakeAuthPolicyClient. It will be shutdown in ChromeBrowserMain. + chromeos::UpstartClient::InitializeFake(); + chromeos::FakeAuthPolicyClient* fake_auth_policy_client = nullptr; if (GetParam().active_directory) { auto fake_auth_policy_client_owned =
diff --git a/chrome/browser/chromeos/printing/zeroconf_printer_detector.cc b/chrome/browser/chromeos/printing/zeroconf_printer_detector.cc index 8dad42f5..650db39 100644 --- a/chrome/browser/chromeos/printing/zeroconf_printer_detector.cc +++ b/chrome/browser/chromeos/printing/zeroconf_printer_detector.cc
@@ -27,9 +27,9 @@ // IppEverywhere printers are also required to advertise these services. const char ZeroconfPrinterDetector::kIppEverywhereServiceName[] = - "_ipp._tcp.local,_print"; + "_print._sub._ipp._tcp.local"; const char ZeroconfPrinterDetector::kIppsEverywhereServiceName[] = - "_ipps._tcp.local,_print"; + "_print._sub._ipps._tcp.local"; namespace { @@ -127,7 +127,8 @@ // Attempt to fill |detected_printer| using the information in // |service_description| and |metadata|. Return true on success, false on // failure. -bool ConvertToPrinter(const ServiceDescription& service_description, +bool ConvertToPrinter(const std::string& service_type, + const ServiceDescription& service_description, const ParsedMetadata& metadata, PrinterDetector::DetectedPrinter* detected_printer) { // If we don't have the minimum information needed to attempt a setup, fail. @@ -145,7 +146,6 @@ printer.set_display_name(metadata.ty); printer.set_description(metadata.note); printer.set_make_and_model(metadata.product); - const std::string service_type = service_description.service_type(); const char* uri_protocol; if (service_type == ZeroconfPrinterDetector::kIppServiceName || service_type == ZeroconfPrinterDetector::kIppEverywhereServiceName) { @@ -173,13 +173,13 @@ service_description.address.port(), metadata.rp.c_str())); // Per the IPP Everywhere Standard 5100.14-2013, section 4.2.1, IPP - // everywhere-capable printers advertise services suffixed with ",_print" - // (possibly in addition to suffix-free versions). If we get a printer from a - // ,_print service type, it should be auto-configurable with IPP Everywhere. + // everywhere-capable printers advertise services prefixed with "_print" + // (possibly in addition to prefix-free versions). If we get a printer from a + // _print service type, it should be auto-configurable with IPP Everywhere. printer.mutable_ppd_reference()->autoconf = - base::StringPiece(service_type).ends_with(",_print"); + base::StringPiece(service_type).starts_with("_print._sub"); - // gather ppd identification candidates. + // Gather ppd identification candidates. detected_printer->ppd_search_data.discovery_type = PrinterSearchData::PrinterDiscoveryType::kZeroconf; if (!metadata.ty.empty()) { @@ -259,7 +259,8 @@ // We don't care if it was added or not; we generate an update either way. ParsedMetadata metadata(service_description); DetectedPrinter printer; - if (!ConvertToPrinter(service_description, metadata, &printer)) { + if (!ConvertToPrinter(service_type, service_description, metadata, + &printer)) { return; } base::AutoLock auto_lock(printers_lock_);
diff --git a/chrome/browser/conflicts/module_blacklist_cache_updater_win.cc b/chrome/browser/conflicts/module_blacklist_cache_updater_win.cc index 3f3c115d..69eccea 100644 --- a/chrome/browser/conflicts/module_blacklist_cache_updater_win.cc +++ b/chrome/browser/conflicts/module_blacklist_cache_updater_win.cc
@@ -176,9 +176,6 @@ } // namespace -// static -constexpr base::TimeDelta ModuleBlacklistCacheUpdater::kUpdateTimerDuration; - ModuleBlacklistCacheUpdater::ModuleBlacklistCacheUpdater( ModuleDatabaseEventSource* module_database_event_source, const CertificateInfo& exe_certificate_info, @@ -312,12 +309,6 @@ module_analysis_disabled_ = true; } -void ModuleBlacklistCacheUpdater::OnTimerExpired() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - StartModuleBlacklistCacheUpdate(); -} - ModuleBlacklistCacheUpdater::ModuleListState ModuleBlacklistCacheUpdater::DetermineModuleListState( const ModuleInfoKey& module_key,
diff --git a/chrome/browser/conflicts/module_blacklist_cache_updater_win.h b/chrome/browser/conflicts/module_blacklist_cache_updater_win.h index 03c709b..2054103 100644 --- a/chrome/browser/conflicts/module_blacklist_cache_updater_win.h +++ b/chrome/browser/conflicts/module_blacklist_cache_updater_win.h
@@ -7,6 +7,7 @@ #include <vector> +#include "base/callback.h" #include "base/containers/flat_map.h" #include "base/files/file_path.h" #include "base/macros.h" @@ -14,8 +15,6 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" -#include "base/time/time.h" -#include "base/timer/timer.h" #include "chrome/browser/conflicts/module_database_observer_win.h" #include "chrome/browser/conflicts/proto/module_list.pb.h" #include "chrome_elf/third_party_dlls/packed_list_format.h" @@ -31,15 +30,8 @@ // is used by chrome_elf.dll to determine which module to block from loading // into the process. // -// Two things can happen that requires an update to the cache: -// 1. The Module Database becomes idle and this class identified new -// blacklisted modules. They must be added to the cache. -// 2. The module load attempt log was drained and contained blocked entries. -// Their timestamp in the cache must be updated. -// -// To coalesce these events and reduce the number of updates, a timer is started -// when the load attempt log is drained. Once expired, an update is triggered -// unless one was already done because of newly blacklisted modules. +// The cache is updated everytime the module database becomes idle and at least +// one module must be added to the cache. // // // Additional implementation details about the module blacklist cache file: @@ -147,11 +139,6 @@ using OnCacheUpdatedCallback = base::RepeatingCallback<void(const CacheUpdateResult&)>; - // The amount of time the timer will run before triggering an update of the - // cache. - static constexpr base::TimeDelta kUpdateTimerDuration = - base::TimeDelta::FromMinutes(2); - // Creates an instance of the updater. The callback will be invoked every time // the cache is updated. // The parameters must outlive the lifetime of this class. @@ -207,8 +194,6 @@ kBlacklisted, }; - void OnTimerExpired(); - // Gets the state of a module with respect to the module list. ModuleListState DetermineModuleListState(const ModuleInfoKey& module_key, const ModuleInfoData& module_data); @@ -245,10 +230,6 @@ // until they are used to update the cache. std::vector<third_party_dlls::PackedListModule> blocked_modules_; - // Ensures that the cache is updated when new blocked modules arrives even if - // OnModuleDatabaseIdle() is never called again. - base::OneShotTimer timer_; - // Holds the blocking state for all known modules. base::flat_map<ModuleInfoKey, ModuleBlockingState> module_blocking_states_;
diff --git a/chrome/browser/devtools/chrome_devtools_session.cc b/chrome/browser/devtools/chrome_devtools_session.cc index 80388aa3..42b6cee6 100644 --- a/chrome/browser/devtools/chrome_devtools_session.cc +++ b/chrome/browser/devtools/chrome_devtools_session.cc
@@ -11,6 +11,7 @@ #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/devtools_agent_host_client.h" #include "content/public/browser/devtools_manager_delegate.h" +#include "content/public/common/content_switches.h" #if defined(OS_CHROMEOS) #include "chrome/browser/devtools/protocol/window_manager_handler.h" @@ -52,6 +53,12 @@ client_->DispatchProtocolMessage(agent_host_, message->serialize(binary)); } +static bool EnableInternalDevToolsBinaryProtocol() { + static bool enabled = base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableInternalDevToolsBinaryProtocol); + return enabled; +} + void ChromeDevToolsSession::HandleCommand( const std::string& method, const std::string& message, @@ -63,9 +70,14 @@ int call_id; std::string unused; + // We also check for --enable-internal-dev-tools-binary-protocol here, + // because if this flag is set, then content::DevToolsSession will + // send us binary even if the |client_| did not ask for it. + bool binary = + client_->UsesBinaryProtocol() || EnableInternalDevToolsBinaryProtocol(); std::unique_ptr<protocol::DictionaryValue> value = - protocol::DictionaryValue::cast(protocol::StringUtil::parseMessage( - message, client_->UsesBinaryProtocol())); + protocol::DictionaryValue::cast( + protocol::StringUtil::parseMessage(message, binary)); if (!dispatcher_->parseCommand(value.get(), &call_id, &unused)) return; pending_commands_[call_id] = std::move(callback);
diff --git a/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc b/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc index 16b2359..d5c1ecb 100644 --- a/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc +++ b/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc
@@ -14,7 +14,9 @@ #include "chrome/browser/extensions/api/declarative_net_request/dnr_test_base.h" #include "chrome/browser/extensions/chrome_test_extension_loader.h" #include "chrome/browser/extensions/extension_util.h" +#include "extensions/browser/api/declarative_net_request/composite_matcher.h" #include "extensions/browser/api/declarative_net_request/ruleset_matcher.h" +#include "extensions/browser/api/declarative_net_request/ruleset_source.h" #include "extensions/browser/api/declarative_net_request/test_utils.h" #include "extensions/browser/api/web_request/web_request_info.h" #include "extensions/browser/extension_prefs.h" @@ -45,11 +47,11 @@ protected: using Action = RulesetManager::Action; - // Helper to create a ruleset matcher instance for the given |rules|. + // Helper to create a composite matcher instance for the given |rules|. void CreateMatcherForRules( const std::vector<TestRule>& rules, const std::string& extension_dirname, - std::unique_ptr<RulesetMatcher>* matcher, + std::unique_ptr<CompositeMatcher>* matcher, const std::vector<std::string>& host_permissions = {}, bool has_background_script = false) { base::FilePath extension_dir = @@ -74,11 +76,12 @@ ->GetDNRRulesetChecksum(last_loaded_extension_->id(), &expected_checksum)); - EXPECT_EQ( - RulesetMatcher::kLoadSuccess, - RulesetMatcher::CreateVerifiedMatcher( - file_util::GetIndexedRulesetPath(last_loaded_extension_->path()), - expected_checksum, matcher)); + std::vector<std::unique_ptr<RulesetMatcher>> matchers(1); + EXPECT_EQ(RulesetMatcher::kLoadSuccess, + RulesetMatcher::CreateVerifiedMatcher( + RulesetSource::Create(*last_loaded_extension_), + expected_checksum, &matchers[0])); + *matcher = std::make_unique<CompositeMatcher>(std::move(matchers)); } void SetIncognitoEnabled(const Extension* extension, bool incognito_enabled) { @@ -155,7 +158,7 @@ // Add the required rulesets. if (mask & kEnableRulesetOne) { ++expected_matcher_count; - std::unique_ptr<RulesetMatcher> matcher; + std::unique_ptr<CompositeMatcher> matcher; ASSERT_NO_FATAL_FAILURE(CreateMatcherForRules( {rule_one}, std::to_string(mask) + "_one", &matcher)); extension_id_one = last_loaded_extension()->id(); @@ -164,7 +167,7 @@ } if (mask & kEnableRulesetTwo) { ++expected_matcher_count; - std::unique_ptr<RulesetMatcher> matcher; + std::unique_ptr<CompositeMatcher> matcher; ASSERT_NO_FATAL_FAILURE(CreateMatcherForRules( {rule_two}, std::to_string(mask) + "_two", &matcher)); extension_id_two = last_loaded_extension()->id(); @@ -197,7 +200,7 @@ // Add an extension ruleset blocking "example.com". TestRule rule_one = CreateGenericRule(); rule_one.condition->url_filter = std::string("example.com"); - std::unique_ptr<RulesetMatcher> matcher; + std::unique_ptr<CompositeMatcher> matcher; ASSERT_NO_FATAL_FAILURE( CreateMatcherForRules({rule_one}, "test_extension", &matcher)); manager->AddRuleset(last_loaded_extension()->id(), std::move(matcher), @@ -258,7 +261,7 @@ // Add an extension ruleset which blocks requests to "example.com". TestRule rule = CreateGenericRule(); rule.condition->url_filter = std::string("example.com"); - std::unique_ptr<RulesetMatcher> matcher; + std::unique_ptr<CompositeMatcher> matcher; ASSERT_NO_FATAL_FAILURE( CreateMatcherForRules({rule}, "test_extension", &matcher)); manager->AddRuleset(last_loaded_extension()->id(), std::move(matcher), @@ -288,7 +291,7 @@ rule.priority = kMinValidPriority; rule.action->type = std::string("redirect"); rule.action->redirect_url = std::string("http://google.com"); - std::unique_ptr<RulesetMatcher> matcher; + std::unique_ptr<CompositeMatcher> matcher; ASSERT_NO_FATAL_FAILURE( CreateMatcherForRules({rule}, "test_extension", &matcher, {"*://example.com/*", "*://abc.com/*"})); @@ -340,7 +343,7 @@ const Extension* extension_2 = nullptr; // Add an extension with a background page which blocks all requests. { - std::unique_ptr<RulesetMatcher> matcher; + std::unique_ptr<CompositeMatcher> matcher; TestRule rule = CreateGenericRule(); rule.condition->url_filter = std::string("*"); ASSERT_NO_FATAL_FAILURE(CreateMatcherForRules( @@ -354,7 +357,7 @@ // Add another extension with a background page which redirects all requests // to "http://google.com". { - std::unique_ptr<RulesetMatcher> matcher; + std::unique_ptr<CompositeMatcher> matcher; TestRule rule = CreateGenericRule(); rule.condition->url_filter = std::string("*"); rule.priority = kMinValidPriority; @@ -412,7 +415,7 @@ // Add an extension which blocks all requests except for requests from // http://google.com/allow* which are allowed. { - std::unique_ptr<RulesetMatcher> matcher; + std::unique_ptr<CompositeMatcher> matcher; // This blocks all subresource requests. By default the main-frame resource // type is excluded. @@ -575,7 +578,7 @@ // Add an extension which redirects all sub-resource and sub-frame requests // made to example.com, to foo.com. By default, the "main_frame" type is // excluded if no "resource_types" are specified. - std::unique_ptr<RulesetMatcher> redirect_matcher; + std::unique_ptr<CompositeMatcher> redirect_matcher; { TestRule rule = CreateGenericRule(); rule.id = kMinValidID; @@ -594,7 +597,7 @@ // Add an extension which blocks all sub-resource and sub-frame requests to // example.com. By default, the "main_frame" type is excluded if no // "resource_types" are specified. The extension has no host permissions. - std::unique_ptr<RulesetMatcher> blocking_matcher; + std::unique_ptr<CompositeMatcher> blocking_matcher; { TestRule rule = CreateGenericRule(); rule.id = kMinValidID;
diff --git a/chrome/browser/extensions/global_shortcut_listener_win.cc b/chrome/browser/extensions/global_shortcut_listener_win.cc index eb58c51..f5d0ac4 100644 --- a/chrome/browser/extensions/global_shortcut_listener_win.cc +++ b/chrome/browser/extensions/global_shortcut_listener_win.cc
@@ -93,12 +93,18 @@ return success; } + // Convert Accelerator modifiers to OS modifiers. + int modifiers = 0; + modifiers |= accelerator.IsShiftDown() ? MOD_SHIFT : 0; + modifiers |= accelerator.IsCtrlDown() ? MOD_CONTROL : 0; + modifiers |= accelerator.IsAltDown() ? MOD_ALT : 0; + // Create an observer that registers a hot key for |accelerator|. std::unique_ptr<gfx::SingletonHwndHotKeyObserver> observer = gfx::SingletonHwndHotKeyObserver::Create( base::BindRepeating(&GlobalShortcutListenerWin::OnWndProc, base::Unretained(this)), - accelerator.key_code(), accelerator.modifiers()); + accelerator.key_code(), modifiers); if (!observer) { // Most likely error: 1409 (Hotkey already registered).
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index d684f6b..a523b4a 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1323,8 +1323,8 @@ }, { "name": "enable-modal-permission-dialog-view", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "pavely" ], + "expiry_milestone": 75 }, { "name": "enable-myfiles-volume", @@ -1482,11 +1482,6 @@ "expiry_milestone": 76 }, { - "name": "enable-per-user-timezone", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "enable-physical-keyboard-autocorrect", // "owners": [ "your-team" ], "expiry_milestone": 76 @@ -2167,6 +2162,11 @@ "expiry_milestone": 76 }, { + "name": "installable-ink-drop", + "owners": [ "collinbaker", "pbos" ], + "expiry_milestone": 77 + }, + { "name": "instant-tethering", // "owners": [ "your-team" ], "expiry_milestone": 76
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index d3830f0..019e830f 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3202,11 +3202,6 @@ "Enable the Recommend Apps Screen in OOBE which allows user to install apps" "from other devices"; -const char kEnablePerUserTimezoneName[] = "Per-user time zone preferences."; -const char kEnablePerUserTimezoneDescription[] = - "Chrome OS system timezone preference is stored and handled for each user " - "individually."; - const char kEnablePlayStoreSearchName[] = "Enable Play Store search"; const char kEnablePlayStoreSearchDescription[] = "Enable Play Store search in launcher."; @@ -3463,6 +3458,17 @@ #endif // defined(OS_CHROMEOS) +// All views-based platforms -------------------------------------------------- + +#if defined(TOOLKIT_VIEWS) + +const char kInstallableInkDropName[] = "Use InstallableInkDrop where supported"; +const char kInstallableInkDropDescription[] = + "InstallableInkDrop is part of an InkDrop refactoring effort. This enables " + "the pilot implementation where available."; + +#endif // defined(TOOLKIT_VIEWS) + // Random platform combinations ----------------------------------------------- #if defined(OS_WIN) || defined(OS_LINUX)
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 21a601d..7177546 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1916,9 +1916,6 @@ extern const char kEnableOobeRecommendAppsScreenName[]; extern const char kEnableOobeRecommendAppsScreenDescription[]; -extern const char kEnablePerUserTimezoneName[]; -extern const char kEnablePerUserTimezoneDescription[]; - extern const char kEnablePlayStoreSearchName[]; extern const char kEnablePlayStoreSearchDescription[]; @@ -2073,6 +2070,15 @@ #endif // #if defined(OS_CHROMEOS) +// All views-based platforms -------------------------------------------------- + +#if defined(TOOLKIT_VIEWS) + +extern const char kInstallableInkDropName[]; +extern const char kInstallableInkDropDescription[]; + +#endif // defined(TOOLKIT_VIEWS) + // Random platform combinations ----------------------------------------------- #if defined(OS_WIN) || defined(OS_LINUX)
diff --git a/chrome/browser/gcm/gcm_profile_service_factory.cc b/chrome/browser/gcm/gcm_profile_service_factory.cc index 6d54d1db..27a212a 100644 --- a/chrome/browser/gcm/gcm_profile_service_factory.cc +++ b/chrome/browser/gcm/gcm_profile_service_factory.cc
@@ -155,7 +155,7 @@ offline_pages::PrefetchServiceFactory::GetForBrowserContext(context); if (prefetch_service != nullptr) { offline_pages::PrefetchGCMHandler* prefetch_gcm_handler = - prefetch_service->GetPrefetchGCMHandler(); + prefetch_service->GetOrCreatePrefetchGCMHandler(context); service->driver()->AddAppHandler(prefetch_gcm_handler->GetAppId(), prefetch_gcm_handler->AsGCMAppHandler()); }
diff --git a/chrome/browser/installable/installable_manager.cc b/chrome/browser/installable/installable_manager.cc index 5284576..8f95112 100644 --- a/chrome/browser/installable/installable_manager.cc +++ b/chrome/browser/installable/installable_manager.cc
@@ -21,6 +21,7 @@ #include "content/public/common/origin_util.h" #include "content/public/common/url_constants.h" #include "net/base/url_util.h" +#include "services/network/public/cpp/is_potentially_trustworthy.h" #include "third_party/blink/public/common/manifest/manifest_icon_selector.h" #include "third_party/blink/public/common/manifest/web_display_mode.h" #include "url/origin.h" @@ -83,7 +84,8 @@ // Check those explicitly, using the VisibleURL to match what // SecurityStateTabHelper looks at. if (net::IsLocalhost(url) || - content::IsWhitelistedAsSecureOrigin(url::Origin::Create(url))) { + network::IsAllowlistedAsSecureOrigin( + url::Origin::Create(url), network::GetSecureOriginAllowlist())) { return true; }
diff --git a/chrome/browser/net/DEPS b/chrome/browser/net/DEPS index 33ac7c87..35ecf445 100644 --- a/chrome/browser/net/DEPS +++ b/chrome/browser/net/DEPS
@@ -1,7 +1,3 @@ -include_rules = [ - "+services/network/session_cleanup_channel_id_store.h", -] - specific_include_rules = { '.*_[a-z]*test.*': [ "+services/network/test",
diff --git a/chrome/browser/net/quota_policy_channel_id_store.cc b/chrome/browser/net/quota_policy_channel_id_store.cc deleted file mode 100644 index d91bc69..0000000 --- a/chrome/browser/net/quota_policy_channel_id_store.cc +++ /dev/null
@@ -1,27 +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. - -#include "chrome/browser/net/quota_policy_channel_id_store.h" - -#include "base/bind.h" -#include "base/files/file_path.h" -#include "storage/browser/quota/special_storage_policy.h" - -QuotaPolicyChannelIDStore::QuotaPolicyChannelIDStore( - const base::FilePath& path, - const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, - const scoped_refptr<storage::SpecialStoragePolicy>& special_storage_policy) - : SessionCleanupChannelIDStore(path, background_task_runner), - special_storage_policy_(special_storage_policy) {} - -QuotaPolicyChannelIDStore::~QuotaPolicyChannelIDStore() { - if (!special_storage_policy_.get() || - !special_storage_policy_->HasSessionOnlyOrigins()) { - return; - } - - DeleteSessionChannelIDs( - base::BindRepeating(&storage::SpecialStoragePolicy::IsStorageSessionOnly, - special_storage_policy_)); -}
diff --git a/chrome/browser/net/quota_policy_channel_id_store.h b/chrome/browser/net/quota_policy_channel_id_store.h deleted file mode 100644 index 230da33..0000000 --- a/chrome/browser/net/quota_policy_channel_id_store.h +++ /dev/null
@@ -1,44 +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. - -#ifndef CHROME_BROWSER_NET_QUOTA_POLICY_CHANNEL_ID_STORE_H_ -#define CHROME_BROWSER_NET_QUOTA_POLICY_CHANNEL_ID_STORE_H_ - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "net/extras/sqlite/sqlite_channel_id_store.h" -#include "services/network/session_cleanup_channel_id_store.h" - -namespace base { -class FilePath; -class SequencedTaskRunner; -} - -namespace storage { -class SpecialStoragePolicy; -} - -// Persistent ChannelID Store that takes into account SpecialStoragePolicy and -// removes ChannelIDs that are StorageSessionOnly when store is closed. -class QuotaPolicyChannelIDStore : public network::SessionCleanupChannelIDStore { - public: - // Create or open persistent store in file |path|. All I/O tasks are performed - // in background using |background_task_runner|. If provided, a - // |special_storage_policy| is consulted when the store is closed to decide - // which certificates to keep. - QuotaPolicyChannelIDStore( - const base::FilePath& path, - const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, - const scoped_refptr<storage::SpecialStoragePolicy>& - special_storage_policy); - - private: - ~QuotaPolicyChannelIDStore() override; - - scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_; - - DISALLOW_COPY_AND_ASSIGN(QuotaPolicyChannelIDStore); -}; - -#endif // CHROME_BROWSER_NET_QUOTA_POLICY_CHANNEL_ID_STORE_H_
diff --git a/chrome/browser/net/quota_policy_channel_id_store_unittest.cc b/chrome/browser/net/quota_policy_channel_id_store_unittest.cc deleted file mode 100644 index f28647d..0000000 --- a/chrome/browser/net/quota_policy_channel_id_store_unittest.cc +++ /dev/null
@@ -1,192 +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. - -#include "chrome/browser/net/quota_policy_channel_id_store.h" - -#include <vector> - -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/memory/ref_counted.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/stl_util.h" -#include "base/test/scoped_task_environment.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/time/time.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "net/cookies/cookie_util.h" -#include "net/ssl/ssl_client_cert_type.h" -#include "net/test/cert_test_util.h" -#include "net/test/channel_id_test_util.h" -#include "net/test/test_data_directory.h" -#include "sql/statement.h" -#include "storage/browser/test/mock_special_storage_policy.h" -#include "testing/gtest/include/gtest/gtest.h" - -const base::FilePath::CharType kTestChannelIDFilename[] = - FILE_PATH_LITERAL("ChannelID"); - -class QuotaPolicyChannelIDStoreTest : public testing::Test { - public: - void Load(std::vector<std::unique_ptr<net::DefaultChannelIDStore::ChannelID>>* - channel_ids) { - base::RunLoop run_loop; - store_->Load(base::Bind(&QuotaPolicyChannelIDStoreTest::OnLoaded, - base::Unretained(this), - &run_loop)); - run_loop.Run(); - channel_ids->swap(channel_ids_); - channel_ids_.clear(); - } - - void OnLoaded( - base::RunLoop* run_loop, - std::unique_ptr< - std::vector<std::unique_ptr<net::DefaultChannelIDStore::ChannelID>>> - channel_ids) { - channel_ids_.swap(*channel_ids); - run_loop->Quit(); - } - - protected: - void SetUp() override { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - store_ = new QuotaPolicyChannelIDStore( - temp_dir_.GetPath().Append(kTestChannelIDFilename), - base::ThreadTaskRunnerHandle::Get(), NULL); - std::vector<std::unique_ptr<net::DefaultChannelIDStore::ChannelID>> - channel_ids; - Load(&channel_ids); - ASSERT_EQ(0u, channel_ids.size()); - } - - void TearDown() override { - store_ = NULL; - base::RunLoop().RunUntilIdle(); - } - - base::ScopedTempDir temp_dir_; - scoped_refptr<QuotaPolicyChannelIDStore> store_; - std::vector<std::unique_ptr<net::DefaultChannelIDStore::ChannelID>> - channel_ids_; - base::test::ScopedTaskEnvironment scoped_task_environment_; -}; - -// Test if data is stored as expected in the QuotaPolicy database. -TEST_F(QuotaPolicyChannelIDStoreTest, TestPersistence) { - std::unique_ptr<crypto::ECPrivateKey> goog_key( - crypto::ECPrivateKey::Create()); - std::unique_ptr<crypto::ECPrivateKey> foo_key(crypto::ECPrivateKey::Create()); - store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( - "google.com", base::Time::FromInternalValue(1), goog_key->Copy())); - store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( - "foo.com", base::Time::FromInternalValue(3), foo_key->Copy())); - - std::vector<std::unique_ptr<net::DefaultChannelIDStore::ChannelID>> - channel_ids; - // Replace the store effectively destroying the current one and forcing it - // to write its data to disk. Then we can see if after loading it again it - // is still there. - store_ = NULL; - // Make sure we wait until the destructor has run. - base::RunLoop().RunUntilIdle(); - store_ = new QuotaPolicyChannelIDStore( - temp_dir_.GetPath().Append(kTestChannelIDFilename), - base::ThreadTaskRunnerHandle::Get(), NULL); - - // Reload and test for persistence - Load(&channel_ids); - ASSERT_EQ(2U, channel_ids.size()); - net::DefaultChannelIDStore::ChannelID* goog_channel_id; - net::DefaultChannelIDStore::ChannelID* foo_channel_id; - if (channel_ids[0]->server_identifier() == "google.com") { - goog_channel_id = channel_ids[0].get(); - foo_channel_id = channel_ids[1].get(); - } else { - goog_channel_id = channel_ids[1].get(); - foo_channel_id = channel_ids[0].get(); - } - ASSERT_EQ("google.com", goog_channel_id->server_identifier()); - EXPECT_TRUE(net::KeysEqual(goog_key.get(), goog_channel_id->key())); - ASSERT_EQ(1, goog_channel_id->creation_time().ToInternalValue()); - ASSERT_EQ("foo.com", foo_channel_id->server_identifier()); - EXPECT_TRUE(net::KeysEqual(foo_key.get(), foo_channel_id->key())); - ASSERT_EQ(3, foo_channel_id->creation_time().ToInternalValue()); - - // Now delete the channel ID and check persistence again. - store_->DeleteChannelID(*channel_ids[0]); - store_->DeleteChannelID(*channel_ids[1]); - store_ = NULL; - // Make sure we wait until the destructor has run. - base::RunLoop().RunUntilIdle(); - channel_ids.clear(); - store_ = new QuotaPolicyChannelIDStore( - temp_dir_.GetPath().Append(kTestChannelIDFilename), - base::ThreadTaskRunnerHandle::Get(), NULL); - - // Reload and check if the channel ID has been removed. - Load(&channel_ids); - ASSERT_EQ(0U, channel_ids.size()); -} - -// Test if data is stored as expected in the QuotaPolicy database. -TEST_F(QuotaPolicyChannelIDStoreTest, TestPolicy) { - store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( - "google.com", base::Time::FromInternalValue(1), - crypto::ECPrivateKey::Create())); - store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( - "nonpersistent.com", base::Time::FromInternalValue(3), - crypto::ECPrivateKey::Create())); - - std::vector<std::unique_ptr<net::DefaultChannelIDStore::ChannelID>> - channel_ids; - // Replace the store effectively destroying the current one and forcing it - // to write its data to disk. Then we can see if after loading it again it - // is still there. - store_ = NULL; - // Make sure we wait until the destructor has run. - base::RunLoop().RunUntilIdle(); - // Specify storage policy that makes "nonpersistent.com" session only. - scoped_refptr<content::MockSpecialStoragePolicy> storage_policy = - new content::MockSpecialStoragePolicy(); - storage_policy->AddSessionOnly( - net::cookie_util::CookieOriginToURL("nonpersistent.com", true)); - // Reload store, it should still have both channel IDs. - store_ = new QuotaPolicyChannelIDStore( - temp_dir_.GetPath().Append(kTestChannelIDFilename), - base::ThreadTaskRunnerHandle::Get(), storage_policy); - Load(&channel_ids); - ASSERT_EQ(2U, channel_ids.size()); - - // Add another two channel IDs before closing the store. Because additions are - // delayed and committed to disk in batches, these will not be committed until - // the store is destroyed, which is after the policy is applied. The pending - // operation pruning logic should prevent the "nonpersistent.com" ID from - // being committed to disk. - store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( - "nonpersistent.com", base::Time::FromInternalValue(5), - crypto::ECPrivateKey::Create())); - store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( - "persistent.com", base::Time::FromInternalValue(7), - crypto::ECPrivateKey::Create())); - - // Now close the store, and the nonpersistent.com channel IDs should be - // deleted according to policy. - store_ = NULL; - // Make sure we wait until the destructor has run. - base::RunLoop().RunUntilIdle(); - channel_ids.clear(); - store_ = new QuotaPolicyChannelIDStore( - temp_dir_.GetPath().Append(kTestChannelIDFilename), - base::ThreadTaskRunnerHandle::Get(), NULL); - - // Reload and check that the nonpersistent.com channel IDs have been removed. - Load(&channel_ids); - ASSERT_EQ(2U, channel_ids.size()); - for (const auto& id : channel_ids) { - ASSERT_NE("nonpersistent.com", id->server_identifier()); - } -}
diff --git a/chrome/browser/offline_pages/prefetch/prefetch_service_factory.cc b/chrome/browser/offline_pages/prefetch/prefetch_service_factory.cc index 8c9693c..b95185e8 100644 --- a/chrome/browser/offline_pages/prefetch/prefetch_service_factory.cc +++ b/chrome/browser/offline_pages/prefetch/prefetch_service_factory.cc
@@ -41,6 +41,18 @@ namespace offline_pages { +namespace { + +std::unique_ptr<PrefetchGCMHandler> CreatePrefetchGCMHandler( + content::BrowserContext* context) { + DCHECK(context); + return std::make_unique<PrefetchGCMAppHandler>( + std::make_unique<PrefetchInstanceIDProxy>(kPrefetchingOfflinePagesAppId, + context)); +} + +} // namespace + PrefetchServiceFactory::PrefetchServiceFactory() : BrowserContextKeyedServiceFactory( "OfflinePagePrefetchService", @@ -80,9 +92,8 @@ auto prefetch_dispatcher = std::make_unique<PrefetchDispatcherImpl>(profile->GetPrefs()); - auto prefetch_gcm_app_handler = std::make_unique<PrefetchGCMAppHandler>( - std::make_unique<PrefetchInstanceIDProxy>(kPrefetchingOfflinePagesAppId, - context)); + auto create_prefetch_gcm_handler_closure = + base::BindOnce(&CreatePrefetchGCMHandler); auto prefetch_network_request_factory = std::make_unique<PrefetchNetworkRequestFactoryImpl>( @@ -126,7 +137,7 @@ return new PrefetchServiceImpl( std::move(offline_metrics_collector), std::move(prefetch_dispatcher), - std::move(prefetch_gcm_app_handler), + std::move(create_prefetch_gcm_handler_closure), std::move(prefetch_network_request_factory), offline_page_model, std::move(prefetch_store), std::move(suggested_articles_observer), std::move(prefetch_downloader), std::move(prefetch_importer),
diff --git a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc index e73f48e..0ec9c4a 100644 --- a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.cc
@@ -6,11 +6,16 @@ #include <cmath> #include <memory> +#include <vector> #include "chrome/browser/browser_process.h" #include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/page_load_metrics/observers/largest_contentful_paint_handler.h" #include "chrome/browser/page_load_metrics/page_load_metrics_util.h" +#include "chrome/browser/prerender/prerender_final_status.h" +#include "chrome/browser/prerender/prerender_manager.h" +#include "chrome/browser/prerender/prerender_manager_factory.h" +#include "chrome/browser/prerender/prerender_origin.h" #include "chrome/browser/profiles/profile.h" #include "components/metrics/net/network_metrics_provider.h" #include "content/public/browser/web_contents.h" @@ -136,6 +141,7 @@ was_cached_ = navigation_handle->WasResponseCached(); is_signed_exchange_inner_response_ = navigation_handle->IsSignedExchangeInnerResponse(); + RecordNoStatePrefetchMetrics(navigation_handle, source_id); return CONTINUE_OBSERVING; } @@ -521,3 +527,43 @@ largest_contentful_paint_handler_.RecordTiming(timing.paint_timing, subframe_rfh); } + +void UkmPageLoadMetricsObserver::RecordNoStatePrefetchMetrics( + content::NavigationHandle* navigation_handle, + ukm::SourceId source_id) { + prerender::PrerenderManager* const prerender_manager = + prerender::PrerenderManagerFactory::GetForBrowserContext( + navigation_handle->GetWebContents()->GetBrowserContext()); + if (!prerender_manager) + return; + + const std::vector<GURL>& redirects = navigation_handle->GetRedirectChain(); + + base::TimeDelta prefetch_age; + prerender::FinalStatus final_status; + prerender::Origin prefetch_origin; + + bool nostate_prefetch_entry_found = prerender_manager->GetPrefetchInformation( + navigation_handle->GetURL(), &prefetch_age, &final_status, + &prefetch_origin); + + // Try the URLs from the redirect chain. + if (!nostate_prefetch_entry_found) { + for (const auto& url : redirects) { + nostate_prefetch_entry_found = prerender_manager->GetPrefetchInformation( + url, &prefetch_age, &final_status, &prefetch_origin); + if (nostate_prefetch_entry_found) + break; + } + } + + if (!nostate_prefetch_entry_found) + return; + + ukm::builders::NoStatePrefetch builder(source_id); + builder.SetPrefetchedRecently_PrefetchAge( + ukm::GetExponentialBucketMinForUserTiming(prefetch_age.InMilliseconds())); + builder.SetPrefetchedRecently_FinalStatus(final_status); + builder.SetPrefetchedRecently_Origin(prefetch_origin); + builder.Record(ukm::UkmRecorder::Get()); +}
diff --git a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.h index adc490a..648e30a 100644 --- a/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/ukm_page_load_metrics_observer.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_UKM_PAGE_LOAD_METRICS_OBSERVER_H_ #include "base/macros.h" +#include "base/metrics/ukm_source_id.h" #include "base/optional.h" #include "base/time/time.h" #include "chrome/browser/page_load_metrics/observers/largest_contentful_paint_handler.h" @@ -101,6 +102,12 @@ base::Optional<int64_t> GetRoundedSiteEngagementScore( const page_load_metrics::PageLoadExtraInfo& info) const; + // Records the metrics for the nostate prefetch to an event with UKM source ID + // |source_id|. + void RecordNoStatePrefetchMetrics( + content::NavigationHandle* navigation_handle, + ukm::SourceId source_id); + // Guaranteed to be non-null during the lifetime of |this|. network::NetworkQualityTracker* network_quality_tracker_;
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc index ecfa326..dc490b2 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -34,8 +34,12 @@ #include "chrome/browser/page_load_metrics/page_load_metrics_test_waiter.h" #include "chrome/browser/page_load_metrics/page_load_tracker.h" #include "chrome/browser/prefs/session_startup_pref.h" +#include "chrome/browser/prerender/prerender_handle.h" #include "chrome/browser/prerender/prerender_histograms.h" +#include "chrome/browser/prerender/prerender_manager.h" +#include "chrome/browser/prerender/prerender_manager_factory.h" #include "chrome/browser/prerender/prerender_origin.h" +#include "chrome/browser/prerender/prerender_test_utils.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sessions/session_restore.h" #include "chrome/browser/sessions/session_restore_test_helper.h" @@ -83,12 +87,14 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/use_counter/css_property_id.mojom.h" #include "third_party/blink/public/mojom/web_feature/web_feature.mojom.h" +#include "ui/gfx/geometry/size.h" #include "url/gurl.h" using page_load_metrics::PageLoadMetricsTestWaiter; using TimingField = page_load_metrics::PageLoadMetricsTestWaiter::TimingField; using WebFeature = blink::mojom::WebFeature; using testing::UnorderedElementsAre; +using NoStatePrefetch = ukm::builders::NoStatePrefetch; namespace { @@ -181,6 +187,41 @@ return std::make_unique<PageLoadMetricsTestWaiter>(web_contents); } + // Triggers nostate prefetch of |url|. + void TriggerNoStatePrefetch(const GURL& url) { + prerender::PrerenderManager* prerender_manager = + prerender::PrerenderManagerFactory::GetForBrowserContext( + browser()->profile()); + ASSERT_TRUE(prerender_manager); + + prerender::test_utils::TestPrerenderContentsFactory* + prerender_contents_factory = + new prerender::test_utils::TestPrerenderContentsFactory(); + prerender_manager->SetPrerenderContentsFactoryForTest( + prerender_contents_factory); + + content::SessionStorageNamespace* storage_namespace = + browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetController() + .GetDefaultSessionStorageNamespace(); + ASSERT_TRUE(storage_namespace); + + std::unique_ptr<prerender::test_utils::TestPrerender> test_prerender = + prerender_contents_factory->ExpectPrerenderContents( + prerender::FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); + + std::unique_ptr<prerender::PrerenderHandle> prerender_handle = + prerender_manager->AddPrerenderFromOmnibox(url, storage_namespace, + gfx::Size(640, 480)); + ASSERT_EQ(prerender_handle->contents(), test_prerender->contents()); + + // The final status may be either FINAL_STATUS_NOSTATE_PREFETCH_FINISHED or + // FINAL_STATUS_RECENTLY_VISITED. + test_prerender->contents()->set_skip_final_checks(true); + } + base::test::ScopedFeatureList scoped_feature_list_; base::HistogramTester histogram_tester_; std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_ukm_recorder_; @@ -263,6 +304,50 @@ kv.second.get(), PageLoad::kSiteEngagementScoreName)); } + const auto& nostate_prefetch_entries = + test_ukm_recorder_->GetMergedEntriesByName(NoStatePrefetch::kEntryName); + EXPECT_EQ(0u, nostate_prefetch_entries.size()); + + // Verify that NoPageLoadMetricsRecorded returns false when PageLoad metrics + // have been recorded. + EXPECT_FALSE(NoPageLoadMetricsRecorded()); +} + +// Triggers nostate prefetch, and verifies that the UKM metrics related to +// nostate prefetch are recorded correctly. +IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, NoStatePrefetchMetrics) { + ASSERT_TRUE(embedded_test_server()->Start()); + + GURL url = embedded_test_server()->GetURL("/title1.html"); + + TriggerNoStatePrefetch(url); + + auto waiter = CreatePageLoadMetricsTestWaiter(); + waiter->AddPageExpectation(TimingField::kFirstPaint); + ui_test_utils::NavigateToURL(browser(), url); + waiter->Wait(); + + // Force navigation to another page, which should force logging of histograms + // persisted at the end of the page load lifetime. + NavigateToUntrackedUrl(); + histogram_tester_.ExpectTotalCount(internal::kHistogramPageLoadTotalBytes, 1); + histogram_tester_.ExpectTotalCount( + internal::kHistogramPageTimingForegroundDuration, 1); + + const auto& entries = + test_ukm_recorder_->GetMergedEntriesByName(NoStatePrefetch::kEntryName); + EXPECT_EQ(1u, entries.size()); + for (const auto& kv : entries) { + test_ukm_recorder_->ExpectEntrySourceHasUrl(kv.second.get(), url); + // UKM metrics related to attempted nostate prefetch should be recorded. + EXPECT_TRUE(test_ukm_recorder_->EntryHasMetric( + kv.second.get(), NoStatePrefetch::kPrefetchedRecently_FinalStatusName)); + EXPECT_TRUE(test_ukm_recorder_->EntryHasMetric( + kv.second.get(), NoStatePrefetch::kPrefetchedRecently_OriginName)); + EXPECT_TRUE(test_ukm_recorder_->EntryHasMetric( + kv.second.get(), NoStatePrefetch::kPrefetchedRecently_PrefetchAgeName)); + } + // Verify that NoPageLoadMetricsRecorded returns false when PageLoad metrics // have been recorded. EXPECT_FALSE(NoPageLoadMetricsRecorded());
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index c8f0bf2..a1cf6d1 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -288,6 +288,7 @@ #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" #include "chromeos/assistant/buildflags.h" #include "chromeos/audio/audio_devices_pref_handler_impl.h" +#include "chromeos/components/account_manager/account_manager.h" #include "chromeos/constants/chromeos_switches.h" #include "chromeos/network/fast_transition_observer.h" #include "chromeos/network/proxy/proxy_config_handler.h" @@ -749,6 +750,7 @@ #if defined(OS_CHROMEOS) arc::prefs::RegisterProfilePrefs(registry); certificate_manager::CertificatesHandler::RegisterProfilePrefs(registry); + chromeos::AccountManager::RegisterPrefs(registry); chromeos::CupsPrintersManager::RegisterProfilePrefs(registry); chromeos::first_run::RegisterProfilePrefs(registry); chromeos::file_system_provider::RegisterProfilePrefs(registry);
diff --git a/chrome/browser/prefs/chrome_command_line_pref_store.cc b/chrome/browser/prefs/chrome_command_line_pref_store.cc index c72aa73..4cdfaf7 100644 --- a/chrome/browser/prefs/chrome_command_line_pref_store.cc +++ b/chrome/browser/prefs/chrome_command_line_pref_store.cc
@@ -6,6 +6,7 @@ #include <stddef.h> +#include <memory> #include <string> #include <utility> #include <vector> @@ -48,7 +49,7 @@ {switches::kAuthAndroidNegotiateAccountType, prefs::kAuthAndroidNegotiateAccountType}, #endif - {switches::kUnsafelyTreatInsecureOriginAsSecure, + {network::switches::kUnsafelyTreatInsecureOriginAsSecure, prefs::kUnsafelyTreatInsecureOriginAsSecure}, // TODO(https://crbug.com/760761): This is not the ideal way to // implement this. Refactor enterprise policy and command line handling
diff --git a/chrome/browser/prerender/prerender_final_status.h b/chrome/browser/prerender/prerender_final_status.h index 3131cc46..9785d2b7 100644 --- a/chrome/browser/prerender/prerender_final_status.h +++ b/chrome/browser/prerender/prerender_final_status.h
@@ -11,6 +11,11 @@ // FinalStatus indicates whether |this| was used, or why it was cancelled. // NOTE: New values need to be appended, since they are used in histograms. + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. The values should remain +// synchronized with the enum PrerenderFinalStatus in +// //tools/metrics/histograms/enums.xml. enum FinalStatus { FINAL_STATUS_USED = 0, FINAL_STATUS_TIMED_OUT = 1,
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc index d6d856e..2e5a232 100644 --- a/chrome/browser/prerender/prerender_manager.cc +++ b/chrome/browser/prerender/prerender_manager.cc
@@ -491,7 +491,8 @@ base::TimeDelta time) { base::TimeDelta prefetch_age; Origin origin; - GetPrefetchInformation(url, &prefetch_age, &origin); + GetPrefetchInformation(url, &prefetch_age, nullptr /* final_status*/, + &origin); OnPrefetchUsed(url); histograms_->RecordPrefetchFirstContentfulPaintTime( @@ -782,7 +783,8 @@ if (IsNoStatePrefetchEnabled()) { base::TimeDelta prefetch_age; - GetPrefetchInformation(url, &prefetch_age, nullptr); + GetPrefetchInformation(url, &prefetch_age, nullptr /* final_status*/, + nullptr /* origin */); if (!prefetch_age.is_zero() && prefetch_age < base::TimeDelta::FromMinutes(net::HttpCache::kPrefetchReuseMins)) { @@ -1028,23 +1030,31 @@ old_web_contents_list_.clear(); } -void PrerenderManager::GetPrefetchInformation(const GURL& url, +bool PrerenderManager::GetPrefetchInformation(const GURL& url, base::TimeDelta* prefetch_age, + FinalStatus* final_status, Origin* origin) { - DCHECK(prefetch_age); CleanUpOldNavigations(&prefetches_, base::TimeDelta::FromMinutes(30)); - *prefetch_age = base::TimeDelta(); + if (prefetch_age) + *prefetch_age = base::TimeDelta(); + if (final_status) + *final_status = FINAL_STATUS_MAX; if (origin) *origin = ORIGIN_NONE; + for (auto it = prefetches_.crbegin(); it != prefetches_.crend(); ++it) { if (it->url == url) { - *prefetch_age = GetCurrentTimeTicks() - it->time; + if (prefetch_age) + *prefetch_age = GetCurrentTimeTicks() - it->time; + if (final_status) + *final_status = it->final_status; if (origin) *origin = it->origin; - break; + return true; } } + return false; } void PrerenderManager::SetPrefetchFinalStatusForUrl(const GURL& url,
diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h index b190bda..ad7429ee 100644 --- a/chrome/browser/prerender/prerender_manager.h +++ b/chrome/browser/prerender/prerender_manager.h
@@ -320,6 +320,15 @@ // content::RenderProcessHostObserver implementation. void RenderProcessHostDestroyed(content::RenderProcessHost* host) override; + // Cleans up the expired prefetches and then returns true if |url| was + // no-state prefetched recently. If so, |prefetch_age|, |final_status| and + // |origin| are set based on the no-state prefetch information if they are + // non-null. + bool GetPrefetchInformation(const GURL& url, + base::TimeDelta* prefetch_age, + FinalStatus* final_status, + Origin* origin); + void SetPrerenderContentsFactoryForTest( PrerenderContents::Factory* prerender_contents_factory); @@ -489,12 +498,6 @@ // so cannot immediately be deleted. void DeleteOldWebContents(); - // Get information associated with a possible prefetch of |url|. - // |origin| may be null, in which case the origin is not returned. - void GetPrefetchInformation(const GURL& url, - base::TimeDelta* prefetch_age, - Origin* origin); - // Called when PrerenderContents gets destroyed. Attaches the |final_status| // to the most recent prefetch matching the |url|. void SetPrefetchFinalStatusForUrl(const GURL& url, FinalStatus final_status);
diff --git a/chrome/browser/prerender/prerender_origin.h b/chrome/browser/prerender/prerender_origin.h index 5ff992e..78fa21e 100644 --- a/chrome/browser/prerender/prerender_origin.h +++ b/chrome/browser/prerender/prerender_origin.h
@@ -9,6 +9,11 @@ // Origin indicates what caused the prerender. // NOTE: New values need to be appended, since they are used in histograms. + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. The values should remain +// synchronized with the enum PrerenderOrigin in +// //tools/metrics/histograms/enums.xml. enum Origin { // Obsolete: ORIGIN_LINK_REL_PRERENDER = 0, // Obsolete: ORIGIN_OMNIBOX_ORIGINAL = 1,
diff --git a/chrome/browser/prerender/prerender_unittest.cc b/chrome/browser/prerender/prerender_unittest.cc index f5945a6..54b2dc1 100644 --- a/chrome/browser/prerender/prerender_unittest.cc +++ b/chrome/browser/prerender/prerender_unittest.cc
@@ -460,6 +460,12 @@ } TEST_F(PrerenderTest, FoundTest) { + base::TimeDelta prefetch_age; + FinalStatus final_status; + Origin origin; + + prerender_manager()->SetTickClockForTesting(tick_clock()); + GURL url("http://www.google.com/"); DummyPrerenderContents* prerender_contents = prerender_manager()->CreateNextPrerenderContents( @@ -470,6 +476,23 @@ std::unique_ptr<PrerenderContents> entry = prerender_manager()->FindAndUseEntry(url); ASSERT_EQ(prerender_contents, entry.get()); + + EXPECT_TRUE(prerender_manager()->GetPrefetchInformation( + url, &prefetch_age, &final_status, &origin)); + EXPECT_EQ(prerender::FINAL_STATUS_MAX, final_status); + EXPECT_EQ(prerender::ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN, origin); + + const base::TimeDelta advance_duration = TimeDelta::FromSeconds(1); + tick_clock()->Advance(advance_duration); + EXPECT_TRUE(prerender_manager()->GetPrefetchInformation( + url, &prefetch_age, &final_status, &origin)); + EXPECT_LE(advance_duration, prefetch_age); + EXPECT_EQ(prerender::FINAL_STATUS_MAX, final_status); + EXPECT_EQ(prerender::ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN, origin); + + prerender_manager()->ClearPrefetchInformationForTesting(); + EXPECT_FALSE(prerender_manager()->GetPrefetchInformation( + url, &prefetch_age, &final_status, &origin)); } // Make sure that if queue a request, and a second prerender request for the @@ -1510,6 +1533,10 @@ // should be blocked by max_concurrency; abandons both of them and waits to make // sure both are cleared from the PrerenderLinkManager. TEST_F(PrerenderTest, LinkManagerClearOnPendingAbandon) { + base::TimeDelta prefetch_age; + FinalStatus final_status; + Origin origin; + prerender_manager()->SetTickClockForTesting(tick_clock()); SetConcurrency(1); ASSERT_LT(prerender_manager()->config().abandon_time_to_live, @@ -1542,11 +1569,32 @@ prerender_link_manager()->OnAbandonPrerender(kDefaultChildId, second_prerender_id); - tick_clock()->Advance(prerender_manager()->config().abandon_time_to_live + - TimeDelta::FromSeconds(1)); + EXPECT_TRUE(prerender_manager()->GetPrefetchInformation( + first_url, &prefetch_age, &final_status, &origin)); + EXPECT_EQ(base::TimeDelta(), prefetch_age); + EXPECT_EQ(prerender::FINAL_STATUS_MAX, final_status); + EXPECT_EQ(prerender::ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN, origin); + + const base::TimeDelta advance_duration = + prerender_manager()->config().abandon_time_to_live + + TimeDelta::FromSeconds(1); + tick_clock()->Advance(advance_duration); EXPECT_FALSE(prerender_manager()->FindEntry(first_url)); EXPECT_FALSE(prerender_manager()->FindEntry(pending_url)); EXPECT_TRUE(IsEmptyPrerenderLinkManager()); + + EXPECT_TRUE(prerender_manager()->GetPrefetchInformation( + first_url, &prefetch_age, &final_status, &origin)); + EXPECT_EQ(advance_duration, prefetch_age); + EXPECT_EQ(prerender::FINAL_STATUS_TIMED_OUT, final_status); + EXPECT_EQ(prerender::ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN, origin); + + EXPECT_FALSE(prerender_manager()->GetPrefetchInformation( + pending_url, &prefetch_age, &final_status, &origin)); + + EXPECT_FALSE(prerender_manager()->GetPrefetchInformation( + GURL("https://not-prefetched.com/"), &prefetch_age, &final_status, + &origin)); } // Creates two prerenders, one of which should be blocked by the
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc index 35b1584..bf6fcd0 100644 --- a/chrome/browser/profiles/profile_impl_io_data.cc +++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -35,7 +35,6 @@ #include "chrome/browser/net/chrome_network_delegate.h" #include "chrome/browser/net/profile_network_context_service.h" #include "chrome/browser/net/profile_network_context_service_factory.h" -#include "chrome/browser/net/quota_policy_channel_id_store.h" #include "chrome/browser/net/reporting_permissions_checker.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_constants.h"
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index d66a0216..2583c010 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc
@@ -115,6 +115,11 @@ #include "chrome/browser/supervised_user/supervised_user_service_factory.h" #endif +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) +#include "chrome/browser/offline_pages/prefetch/prefetch_service_factory.h" +#include "components/offline_pages/core/prefetch/prefetch_service.h" +#endif + #if defined(OS_ANDROID) #include "chrome/browser/android/metrics/android_profile_session_durations_service_factory.h" #include "chrome/browser/ntp_snippets/content_suggestions_notifier_service_factory.h" @@ -1316,6 +1321,15 @@ } #endif +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) + // Make sure to precreate the PrefetchGCMHandler before GCMProfileService is + // created, otherwise leads to infinite recursion + offline_pages::PrefetchService* prefetch_service = + offline_pages::PrefetchServiceFactory::GetForBrowserContext(profile); + if (prefetch_service != nullptr) { + prefetch_service->GetOrCreatePrefetchGCMHandler(profile); + } +#endif #if BUILDFLAG(ENABLE_SUPERVISED_USERS) // Initialization needs to happen after extension system initialization (for // extension::ManagementPolicy) and InitProfileUserPrefs (for setting the
diff --git a/chrome/browser/resources/chromeos/login/apps_menu.css b/chrome/browser/resources/chromeos/login/apps_menu.css new file mode 100644 index 0000000..86ce3ba --- /dev/null +++ b/chrome/browser/resources/chromeos/login/apps_menu.css
@@ -0,0 +1,12 @@ +/* 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. */ + +.apps-menu-item { + background: no-repeat 4px 50%; + background-size: 16px; + overflow: hidden; + padding-inline-start: 24px; + text-overflow: ellipsis; + white-space: nowrap; +}
diff --git a/chrome/browser/resources/chromeos/login/md_login.html b/chrome/browser/resources/chromeos/login/md_login.html index a9b058a..8154b02e 100644 --- a/chrome/browser/resources/chromeos/login/md_login.html +++ b/chrome/browser/resources/chromeos/login/md_login.html
@@ -11,9 +11,15 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_components/chromeos/quick_unlock/pin_keyboard.html"> +<link rel="stylesheet" href="chrome://resources/css/butter_bar.css"> <link rel="stylesheet" href="chrome://resources/css/dialogs.css"> +<link rel="stylesheet" href="chrome://resources/css/list.css"> +<link rel="stylesheet" href="chrome://resources/css/menu_button.css"> +<link rel="stylesheet" href="chrome://resources/css/menu.css"> <link rel="stylesheet" href="chrome://resources/css/spinner.css"> <link rel="stylesheet" href="chrome://resources/css/throbber.css"> +<link rel="stylesheet" href="chrome://resources/css/widgets.css"> +<link rel="stylesheet" href="apps_menu.css"> <link rel="stylesheet" href="../../../../../ui/login/bubble.css"> <link rel="stylesheet" href="md_top_header_bar.css"> <link rel="stylesheet" href="../../../../../ui/login/oobe.css"> @@ -26,7 +32,19 @@ <script src="chrome://resources/js/event_tracker.js"></script> <script src="chrome://resources/js/cr/event_target.js"></script> <script src="chrome://resources/js/cr/ui.js"></script> +<script src="chrome://resources/js/cr/ui/touch_handler.js"></script> +<script src="chrome://resources/js/cr/ui/array_data_model.js"></script> <script src="chrome://resources/js/cr/ui/dialogs.js"></script> +<script src="chrome://resources/js/cr/ui/list_selection_controller.js"></script> +<script src="chrome://resources/js/cr/ui/list_selection_model.js"></script> +<script src="chrome://resources/js/cr/ui/list_single_selection_model.js"></script> +<script src="chrome://resources/js/cr/ui/list_item.js"></script> +<script src="chrome://resources/js/cr/ui/list.js"></script> +<script src="chrome://resources/js/cr/ui/grid.js"></script> +<script src="chrome://resources/js/cr/ui/position_util.js"></script> +<script src="chrome://resources/js/cr/ui/menu_item.js"></script> +<script src="chrome://resources/js/cr/ui/menu.js"></script> +<script src="chrome://resources/js/cr/ui/menu_button.js"></script> <script src="chrome://resources/js/load_time_data.js"></script> <script src="chrome://resources/js/promise_resolver.js"></script> <script src="chrome://resources/js/util.js"></script>
diff --git a/chrome/browser/resources/chromeos/login/oobe.html b/chrome/browser/resources/chromeos/login/oobe.html index ac3c843..8ef0b36 100644 --- a/chrome/browser/resources/chromeos/login/oobe.html +++ b/chrome/browser/resources/chromeos/login/oobe.html
@@ -12,10 +12,16 @@ <link rel="import" href="chrome://resources/cr_components/chromeos/quick_unlock/pin_keyboard.html"> +<link rel="stylesheet" href="chrome://resources/css/butter_bar.css"> <link rel="stylesheet" href="chrome://resources/css/dialogs.css"> +<link rel="stylesheet" href="chrome://resources/css/list.css"> +<link rel="stylesheet" href="chrome://resources/css/menu_button.css"> +<link rel="stylesheet" href="chrome://resources/css/menu.css"> <link rel="stylesheet" href="chrome://resources/css/spinner.css"> <link rel="stylesheet" href="chrome://resources/css/throbber.css"> +<link rel="stylesheet" href="chrome://resources/css/widgets.css"> +<link rel="stylesheet" href="apps_menu.css"> <link rel="stylesheet" href="../../../../../ui/login/bubble.css"> <link rel="stylesheet" href="md_top_header_bar.css"> <link rel="stylesheet" href="../../../../../ui/login/oobe.css"> @@ -30,7 +36,19 @@ <script src="chrome://resources/js/event_tracker.js"></script> <script src="chrome://resources/js/cr/event_target.js"></script> <script src="chrome://resources/js/cr/ui.js"></script> +<script src="chrome://resources/js/cr/ui/touch_handler.js"></script> +<script src="chrome://resources/js/cr/ui/array_data_model.js"></script> <script src="chrome://resources/js/cr/ui/dialogs.js"></script> +<script src="chrome://resources/js/cr/ui/list_selection_controller.js"></script> +<script src="chrome://resources/js/cr/ui/list_selection_model.js"></script> +<script src="chrome://resources/js/cr/ui/list_single_selection_model.js"></script> +<script src="chrome://resources/js/cr/ui/list_item.js"></script> +<script src="chrome://resources/js/cr/ui/list.js"></script> +<script src="chrome://resources/js/cr/ui/grid.js"></script> +<script src="chrome://resources/js/cr/ui/position_util.js"></script> +<script src="chrome://resources/js/cr/ui/menu_item.js"></script> +<script src="chrome://resources/js/cr/ui/menu.js"></script> +<script src="chrome://resources/js/cr/ui/menu_button.js"></script> <script src="chrome://resources/js/load_time_data.js"></script> <script src="chrome://resources/js/promise_resolver.js"></script> <script src="chrome://resources/js/util.js"></script> @@ -65,6 +83,7 @@ <script src="chrome://oobe/keyboard_utils.js"></script> +<link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://oobe/custom_elements.html"> <script src="chrome://oobe/oobe.js"></script> </head>
diff --git a/chrome/browser/resources/chromeos/login/oobe_welcome.html b/chrome/browser/resources/chromeos/login/oobe_welcome.html index 6c65e6b..0e746229 100644 --- a/chrome/browser/resources/chromeos/login/oobe_welcome.html +++ b/chrome/browser/resources/chromeos/login/oobe_welcome.html
@@ -64,6 +64,7 @@ on-accessibility-button-clicked="onWelcomeAccessibilityButtonClicked_" on-timezone-button-clicked="onWelcomeTimezoneButtonClicked_" on-next-button-clicked="onWelcomeNextButtonClicked_" + on-enable-debugging-clicked="onEnableDebuggingClicked_" on-launch-advanced-options="onWelcomeLaunchAdvancedOptions_" timezone-button-visible= "[[isTimezoneButtonVisible_(highlightStrength)]]"
diff --git a/chrome/browser/resources/chromeos/login/oobe_welcome.js b/chrome/browser/resources/chromeos/login/oobe_welcome.js index a9d0de6..a394b6e 100644 --- a/chrome/browser/resources/chromeos/login/oobe_welcome.js +++ b/chrome/browser/resources/chromeos/login/oobe_welcome.js
@@ -260,6 +260,15 @@ }, /** + * Handles "enable-debugging" link for "Welcome" screen. + * + * @private + */ + onEnableDebuggingClicked_: function() { + cr.ui.Oobe.handleAccelerator(ACCELERATOR_ENABLE_DEBBUGING); + }, + + /** * Handle "launch-advanced-options" button for "Welcome" screen. * * @private
diff --git a/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.html b/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.html index 804c5403..66abc083 100644 --- a/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.html +++ b/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.html
@@ -112,7 +112,7 @@ </if> </div> <div hidden="[[!debuggingLinkVisible]]"> - <a href="#" on-tap="onDebuggingLinkClicked_"> + <a href="#" on-tap="onDebuggingLinkClicked_" id="enableDebuggingLink"> [[i18nDynamic(locale, 'debuggingFeaturesLink')]] </a> </div>
diff --git a/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.js b/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.js index 4926033..052f6a6 100644 --- a/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.js +++ b/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.js
@@ -351,8 +351,7 @@ }, onDebuggingLinkClicked_: function() { - chrome.send( - 'login.WelcomeScreen.userActed', ['connect-debugging-features']); + this.fire('enable-debugging-clicked'); }, /*
diff --git a/chrome/browser/resources/safe_browsing/download_file_types.asciipb b/chrome/browser/resources/safe_browsing/download_file_types.asciipb index 4d608e4..1bc9016 100644 --- a/chrome/browser/resources/safe_browsing/download_file_types.asciipb +++ b/chrome/browser/resources/safe_browsing/download_file_types.asciipb
@@ -8,7 +8,7 @@ ## ## Top level settings ## -version_id: 32 +version_id: 33 sampled_ping_probability: 0.01 max_archived_binaries_to_report: 10 default_file_type { @@ -705,6 +705,9 @@ is_archive: true ping_setting: FULL_PING inspection_type: ZIP + platform_settings { + max_file_size_to_analyze: 52428800 # 50MB + } } file_types { extension: "zipx"
diff --git a/chrome/browser/resources/settings/settings_ui/settings_ui.js b/chrome/browser/resources/settings/settings_ui/settings_ui.js index 025e9262..14c3b80 100644 --- a/chrome/browser/resources/settings/settings_ui/settings_ui.js +++ b/chrome/browser/resources/settings/settings_ui/settings_ui.js
@@ -107,7 +107,10 @@ // <if expr="chromeos"> controlledSettingShared: loadTimeData.getString('controlledSettingShared'), - controlledSettingOwner: loadTimeData.getString('controlledSettingOwner'), + controlledSettingWithOwner: + loadTimeData.getString('controlledSettingWithOwner'), + controlledSettingNoOwner: + loadTimeData.getString('controlledSettingNoOwner'), // </if> };
diff --git a/chrome/browser/safe_browsing/download_protection/file_analyzer_unittest.cc b/chrome/browser/safe_browsing/download_protection/file_analyzer_unittest.cc index 53e35a2..256ec83 100644 --- a/chrome/browser/safe_browsing/download_protection/file_analyzer_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection/file_analyzer_unittest.cc
@@ -877,4 +877,47 @@ EXPECT_EQ(1, result_.directory_count); } +TEST_F(FileAnalyzerTest, LargeZipSkipsContentInspection) { + scoped_refptr<MockBinaryFeatureExtractor> extractor = + new testing::StrictMock<MockBinaryFeatureExtractor>(); + FileAnalyzer analyzer(extractor); + base::RunLoop run_loop; + + FileTypePoliciesTestOverlay overlay; + std::unique_ptr<DownloadFileTypeConfig> config = overlay.DuplicateConfig(); + for (DownloadFileType& file_type : *config->mutable_file_types()) { + if (file_type.extension() == "zip") { + // All archives will skip content inspection. + file_type.mutable_platform_settings(0)->set_max_file_size_to_analyze(0); + break; + } + } + overlay.SwapConfig(config); + + base::FilePath target_path(FILE_PATH_LITERAL("target.zip")); + base::FilePath tmp_path = + temp_dir_.GetPath().Append(FILE_PATH_LITERAL("tmp.crdownload")); + + base::ScopedTempDir zip_source_dir; + ASSERT_TRUE(zip_source_dir.CreateUniqueTempDir()); + std::string file_contents = "dummy file"; + ASSERT_EQ(static_cast<int>(file_contents.size()), + base::WriteFile( + zip_source_dir.GetPath().Append(FILE_PATH_LITERAL("file.exe")), + file_contents.data(), file_contents.size())); + ASSERT_TRUE(zip::Zip(zip_source_dir.GetPath(), tmp_path, + /* include_hidden_files= */ false)); + + analyzer.Start( + target_path, tmp_path, + base::BindOnce(&FileAnalyzerTest::DoneCallback, base::Unretained(this), + run_loop.QuitClosure())); + run_loop.Run(); + + ASSERT_TRUE(has_result_); + EXPECT_EQ(result_.type, ClientDownloadRequest::ZIPPED_EXECUTABLE); + EXPECT_EQ(result_.archive_is_valid, FileAnalyzer::ArchiveValid::VALID); + ASSERT_EQ(0, result_.archived_binaries.size()); +} + } // namespace safe_browsing
diff --git a/chrome/browser/secure_origin_whitelist_browsertest.cc b/chrome/browser/secure_origin_whitelist_browsertest.cc index 150294bb..fc04f66 100644 --- a/chrome/browser/secure_origin_whitelist_browsertest.cc +++ b/chrome/browser/secure_origin_whitelist_browsertest.cc
@@ -17,6 +17,7 @@ #include "components/security_state/core/features.h" #include "content/public/test/browser_test_utils.h" #include "net/dns/mock_host_resolver.h" +#include "services/network/public/cpp/network_switches.h" namespace { // SecureOriginWhitelistBrowsertests differ in the setup of the browser. Since @@ -58,7 +59,7 @@ return; command_line->AppendSwitchASCII( - switches::kUnsafelyTreatInsecureOriginAsSecure, BaseURL()); + network::switches::kUnsafelyTreatInsecureOriginAsSecure, BaseURL()); } void SetUpInProcessBrowserTestFixture() override {
diff --git a/chrome/browser/ssl/origin_util.cc b/chrome/browser/ssl/origin_util.cc index 0c975da..1ec4424 100644 --- a/chrome/browser/ssl/origin_util.cc +++ b/chrome/browser/ssl/origin_util.cc
@@ -9,37 +9,29 @@ #include "base/strings/pattern.h" #include "chrome/common/pref_names.h" -#include "chrome/common/secure_origin_whitelist.h" #include "components/prefs/pref_service.h" #include "content/public/common/origin_util.h" +#include "services/network/public/cpp/is_potentially_trustworthy.h" #include "url/gurl.h" namespace { -// Returns a vector containing all origins and patterns whitelisted as "Secure" +// Returns a vector containing all origins and patterns allowlisted as "Secure" // by the OverrideSecurityRestrictionsOnInsecureOrigin policy. std::vector<std::string> GetSecureOriginsAndPatterns(PrefService* prefs) { if (prefs->HasPrefPath(prefs::kUnsafelyTreatInsecureOriginAsSecure)) { - return secure_origin_whitelist::ParseWhitelist( + return network::ParseSecureOriginAllowlist( prefs->GetString(prefs::kUnsafelyTreatInsecureOriginAsSecure)); } return std::vector<std::string>(); } -// Returns true if |origin| matches an origin or pattern in the whitelist from +// Returns true if |origin| matches an origin or pattern in the allowlist from // the OverrideSecurityRestrictionsOnInsecureOrigin policy. bool IsPolicyWhitelistedAsSecureOrigin(const url::Origin& origin, PrefService* prefs) { - std::vector<std::string> whitelist = GetSecureOriginsAndPatterns(prefs); - if (base::ContainsValue(whitelist, origin.Serialize())) { - return true; - } - for (const auto& origin_or_pattern : whitelist) { - if (base::MatchPattern(origin.host(), origin_or_pattern)) { - return true; - } - } - return false; + std::vector<std::string> allowlist = GetSecureOriginsAndPatterns(prefs); + return network::IsAllowlistedAsSecureOrigin(origin, allowlist); } } // namespace
diff --git a/chrome/browser/ssl/security_state_tab_helper.cc b/chrome/browser/ssl/security_state_tab_helper.cc index 0066398..1ca339c 100644 --- a/chrome/browser/ssl/security_state_tab_helper.cc +++ b/chrome/browser/ssl/security_state_tab_helper.cc
@@ -34,6 +34,8 @@ #include "net/cert/x509_certificate.h" #include "net/ssl/ssl_cipher_suite_names.h" #include "net/ssl/ssl_connection_status_flags.h" +#include "services/network/public/cpp/is_potentially_trustworthy.h" +#include "services/network/public/cpp/network_switches.h" #include "third_party/boringssl/src/include/openssl/ssl.h" #include "url/origin.h" @@ -287,13 +289,14 @@ Profile::FromBrowserContext(web_contents()->GetBrowserContext()); PrefService* prefs = profile->GetPrefs(); std::string origins_str = ""; - if (command_line.HasSwitch(switches::kUnsafelyTreatInsecureOriginAsSecure)) { + if (command_line.HasSwitch( + network::switches::kUnsafelyTreatInsecureOriginAsSecure)) { origins_str = command_line.GetSwitchValueASCII( - switches::kUnsafelyTreatInsecureOriginAsSecure); + network::switches::kUnsafelyTreatInsecureOriginAsSecure); } else if (prefs->HasPrefPath(prefs::kUnsafelyTreatInsecureOriginAsSecure)) { origins_str = prefs->GetString(prefs::kUnsafelyTreatInsecureOriginAsSecure); } - return secure_origin_whitelist::ParseWhitelist(origins_str); + return network::ParseSecureOriginAllowlist(origins_str); } WEB_CONTENTS_USER_DATA_KEY_IMPL(SecurityStateTabHelper)
diff --git a/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc b/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc index fc6a58f..115ba79 100644 --- a/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc
@@ -22,6 +22,7 @@ #include "components/autofill/core/browser/payments/payments_customer_data.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/browser/personal_data_manager_observer.h" +#include "components/autofill/core/browser/test_autofill_clock.h" #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_prefs.h" #include "components/autofill/core/common/autofill_switches.h" @@ -65,6 +66,7 @@ const char kLocalGuidA[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44A"; const char kDifferentBillingAddressId[] = "another address entity ID"; +const base::Time kArbitraryDefaultTime = base::Time::FromDoubleT(25); template <class T> class AutofillWebDataServiceConsumer : public WebDataServiceConsumer { @@ -188,7 +190,10 @@ class SingleClientWalletSyncTest : public SyncTest { public: - SingleClientWalletSyncTest() : SyncTest(SINGLE_CLIENT) {} + SingleClientWalletSyncTest() : SyncTest(SINGLE_CLIENT) { + test_clock_.SetNow(kArbitraryDefaultTime); + } + ~SingleClientWalletSyncTest() override {} protected: @@ -256,8 +261,13 @@ 0); } + void AdvanceAutofillClockByOneDay() { + test_clock_.Advance(base::TimeDelta::FromDays(1)); + } + PersonalDataLoadedObserverMock personal_data_observer_; base::HistogramTester histogram_tester_; + autofill::TestAutofillClock test_clock_; private: DISALLOW_COPY_AND_ASSIGN(SingleClientWalletSyncTest); @@ -841,6 +851,61 @@ ExpectAddressesDiffInHistograms(/*added=*/0, /*removed=*/0); } +// Tests that we do report age metric on startup. +IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTestWithDefaultFeatures, + PRE_UseDateMetricReportedOnStartup) { + GetFakeServer()->SetWalletData( + {CreateSyncWalletCard(/*name=*/"card-1", /*last_four=*/"0001", + kDefaultBillingAddressID), + CreateSyncWalletAddress(/*name=*/"address-1", /*company=*/"Company-1"), + CreateDefaultSyncPaymentsCustomerData()}); + ASSERT_TRUE(SetupSync()); + + // Make sure the data is present on the client. + autofill::PersonalDataManager* pdm = GetPersonalDataManager(0); + ASSERT_EQ(1uL, pdm->GetCreditCards().size()); + ASSERT_EQ(1uL, pdm->GetServerProfiles().size()); + ASSERT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id); + + // Here, we would ideally test that no metrics get recorded during initial + // sync. Due to design differences between USS&Directory, we cannot make it + // work (the metadata syncable service has no reliable way to tell it is + // initial sync). +} + +IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTestWithDefaultFeatures, + UseDateMetricReportedOnStartup) { + // Advance the clock to get a reasonable value. + AdvanceAutofillClockByOneDay(); + + // Set the same data on the server so that we get an empty update (this is + // based on a hash of the data). + GetFakeServer()->SetWalletData( + {CreateSyncWalletCard(/*name=*/"card-1", /*last_four=*/"0001", + kDefaultBillingAddressID), + CreateSyncWalletAddress(/*name=*/"address-1", /*company=*/"Company-1"), + CreateDefaultSyncPaymentsCustomerData()}); + ASSERT_TRUE(SetupSync()); + + // Make sure the data is still present on the client. + autofill::PersonalDataManager* pdm = GetPersonalDataManager(0); + ASSERT_EQ(1uL, pdm->GetCreditCards().size()); + ASSERT_EQ(1uL, pdm->GetServerProfiles().size()); + ASSERT_EQ(kDefaultCustomerID, pdm->GetPaymentsCustomerData()->customer_id); + + // The metric gets recorded. + histogram_tester_.ExpectTotalCount("Autofill.WalletUseDate.Card", 1); + histogram_tester_.ExpectTimeBucketCount( + "Autofill.WalletUseDate.Card", + /*sample=*/base::TimeDelta::FromDays(1), + /*count=*/1); + histogram_tester_.ExpectTotalCount("Autofill.WalletUseDate.Address", 1); + histogram_tester_.ExpectTimeBucketCount( + "Autofill.WalletUseDate.Address", + /*sample=*/base::TimeDelta::FromDays(1), + /*count=*/1); +} + // Wallet data should get cleared from the database when the wallet sync type // flag is disabled. IN_PROC_BROWSER_TEST_P(SingleClientWalletSyncTestWithDefaultFeatures,
diff --git a/chrome/browser/ui/startup/bad_flags_prompt.cc b/chrome/browser/ui/startup/bad_flags_prompt.cc index 33125db..b8e5e35 100644 --- a/chrome/browser/ui/startup/bad_flags_prompt.cc +++ b/chrome/browser/ui/startup/bad_flags_prompt.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ui/startup/bad_flags_prompt.h" +#include <string> + #include "base/base_switches.h" #include "base/command_line.h" #include "base/feature_list.h" @@ -97,7 +99,7 @@ // This flag allows people to whitelist certain origins as secure, even // if they are not. - switches::kUnsafelyTreatInsecureOriginAsSecure, + network::switches::kUnsafelyTreatInsecureOriginAsSecure, // This flag allows sites to access the camera and microphone without // getting the user's permission.
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc index 8c1e486..c461815 100644 --- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc +++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
@@ -242,6 +242,7 @@ void ImmersiveModeControllerAsh::OnImmersiveRevealEnded() { UninstallEventRewriter(); visible_fraction_ = 0; + browser_view_->contents_web_view()->holder()->SetHitTestTopInset(0); for (Observer& observer : observers_) observer.OnImmersiveRevealEnded(); } @@ -250,6 +251,7 @@ void ImmersiveModeControllerAsh::OnImmersiveFullscreenExited() { UninstallEventRewriter(); + browser_view_->contents_web_view()->holder()->SetHitTestTopInset(0); for (Observer& observer : observers_) observer.OnImmersiveFullscreenExited(); }
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc index e29c1bc..6127fd2b0 100644 --- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc +++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash_unittest.cc
@@ -27,6 +27,7 @@ #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "ui/aura/window.h" #include "ui/events/event.h" +#include "ui/views/controls/native/native_view_host.h" #include "ui/views/controls/webview/webview.h" class ImmersiveModeControllerAshTest : public TestWithBrowserView { @@ -128,6 +129,8 @@ // By default, the tabstrip and toolbar should be visible. EXPECT_TRUE(tabstrip->visible()); EXPECT_TRUE(toolbar->visible()); + EXPECT_EQ( + 0, browser_view()->contents_web_view()->holder()->GetHitTestTopInset()); ToggleFullscreen(); EXPECT_TRUE(browser_view()->GetWidget()->IsFullscreen()); @@ -139,6 +142,8 @@ // Tabstrip and top container view should be completely offscreen. EXPECT_EQ(0, GetBoundsInWidget(tabstrip).bottom()); EXPECT_EQ(0, GetBoundsInWidget(browser_view()->top_container()).bottom()); + EXPECT_EQ( + 0, browser_view()->contents_web_view()->holder()->GetHitTestTopInset()); // Since the tab strip and tool bar are both hidden in immersive fullscreen // mode, the web contents should extend to the edge of screen. @@ -150,6 +155,8 @@ EXPECT_TRUE(controller()->IsRevealed()); EXPECT_TRUE(tabstrip->visible()); EXPECT_TRUE(toolbar->visible()); + EXPECT_NE( + 0, browser_view()->contents_web_view()->holder()->GetHitTestTopInset()); // The TopContainerView should be flush with the top edge of the widget. If // it is not flush with the top edge the immersive reveal animation looks @@ -189,6 +196,8 @@ // Exiting both immersive and tab fullscreen should show the tab strip and // toolbar. ToggleFullscreen(); + EXPECT_EQ( + 0, browser_view()->contents_web_view()->holder()->GetHitTestTopInset()); EXPECT_FALSE(browser_view()->GetWidget()->IsFullscreen()); EXPECT_FALSE(controller()->IsEnabled()); EXPECT_FALSE(controller()->IsRevealed());
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc b/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc index 837e33e7..58bef1e6 100644 --- a/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc +++ b/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc
@@ -17,6 +17,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "services/network/public/cpp/network_switches.h" namespace { @@ -46,7 +47,7 @@ InProcessBrowserTest::SetUpCommandLine(command_line); command_line->AppendSwitchASCII( - switches::kUnsafelyTreatInsecureOriginAsSecure, + network::switches::kUnsafelyTreatInsecureOriginAsSecure, GetInstallableAppURL().GetOrigin().spec()); }
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.cc b/chrome/browser/ui/views/toolbar/toolbar_button.cc index 9e5dac52..a9aaf0b 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_button.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_button.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/bind.h" +#include "base/feature_list.h" #include "base/location.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" @@ -26,6 +27,7 @@ #include "ui/gfx/color_utils.h" #include "ui/views/animation/ink_drop.h" #include "ui/views/animation/ink_drop_highlight.h" +#include "ui/views/animation/installable_ink_drop.h" #include "ui/views/background.h" #include "ui/views/controls/button/label_button_border.h" #include "ui/views/controls/menu/menu_item_view.h" @@ -48,6 +50,10 @@ show_menu_factory_(this) { set_has_ink_drop_action_on_click(true); set_context_menu_controller(this); + + if (base::FeatureList::IsEnabled(views::kInstallableInkDropFeature)) + installable_ink_drop_ = std::make_unique<views::InstallableInkDrop>(); + SetInkDropMode(InkDropMode::ON); // Make sure icons are flipped by default so that back, forward, etc. follows @@ -246,17 +252,33 @@ node_data->SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kPress); } +std::unique_ptr<views::InkDrop> ToolbarButton::CreateInkDrop() { + // Ensure this doesn't get called when InstallableInkDrops are enabled. + DCHECK(!base::FeatureList::IsEnabled(views::kInstallableInkDropFeature)); + return views::LabelButton::CreateInkDrop(); +} + std::unique_ptr<views::InkDropHighlight> ToolbarButton::CreateInkDropHighlight() const { + // Ensure this doesn't get called when InstallableInkDrops are enabled. + DCHECK(!base::FeatureList::IsEnabled(views::kInstallableInkDropFeature)); return CreateToolbarInkDropHighlight(this); } SkColor ToolbarButton::GetInkDropBaseColor() const { + // Ensure this doesn't get called when InstallableInkDrops are enabled. + DCHECK(!base::FeatureList::IsEnabled(views::kInstallableInkDropFeature)); if (highlight_color_) return *highlight_color_; return GetToolbarInkDropBaseColor(this); } +views::InkDrop* ToolbarButton::GetInkDrop() { + if (installable_ink_drop_) + return installable_ink_drop_.get(); + return views::LabelButton::GetInkDrop(); +} + void ToolbarButton::ShowContextMenuForViewImpl(View* source, const gfx::Point& point, ui::MenuSourceType source_type) {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.h b/chrome/browser/ui/views/toolbar/toolbar_button.h index b54a6a0..b86afc3 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_button.h +++ b/chrome/browser/ui/views/toolbar/toolbar_button.h
@@ -26,6 +26,7 @@ } namespace views { +class InstallableInkDrop; class MenuModelAdapter; class MenuRunner; } @@ -79,8 +80,10 @@ void OnMouseExited(const ui::MouseEvent& event) override; void OnGestureEvent(ui::GestureEvent* event) override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; + std::unique_ptr<views::InkDrop> CreateInkDrop() override; std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight() const override; + views::InkDrop* GetInkDrop() override; SkColor GetInkDropBaseColor() const override; // views::ContextMenuController: @@ -157,6 +160,10 @@ // default ToolbarButton ink drop. base::Optional<SkColor> highlight_color_; + // Used instead of the standard InkDrop implementation when + // |views::kInstallableInkDropFeature| is enabled. + std::unique_ptr<views::InstallableInkDrop> installable_ink_drop_; + // A factory for tasks that show the dropdown context menu for the button. base::WeakPtrFactory<ToolbarButton> show_menu_factory_;
diff --git a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc index 4316919..2418c18 100644 --- a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc
@@ -265,7 +265,6 @@ ProfileManager::GetActiveUserProfile()); connector->BindInterface(assistant::mojom::kServiceName, mojo::MakeRequest(&settings_manager_)); - client_binding_.Bind(mojo::MakeRequest(&client_ptr_)); if (initialized_) { SendGetSettingsRequest(); @@ -458,8 +457,11 @@ if (!prefs->GetBoolean(arc::prefs::kVoiceInteractionHotwordEnabled)) { prefs->SetBoolean(arc::prefs::kVoiceInteractionHotwordEnabled, true); } + + assistant::mojom::SpeakerIdEnrollmentClientPtr client_ptr; + client_binding_.Bind(mojo::MakeRequest(&client_ptr)); settings_manager_->StartSpeakerIdEnrollment(is_retrain_flow_, - std::move(client_ptr_)); + std::move(client_ptr)); } }
diff --git a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h index bbfedcd..3b9bf0e 100644 --- a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h
@@ -133,7 +133,6 @@ bool initialized_ = false; mojo::Binding<assistant::mojom::SpeakerIdEnrollmentClient> client_binding_; - assistant::mojom::SpeakerIdEnrollmentClientPtr client_ptr_; assistant::mojom::AssistantSettingsManagerPtr settings_manager_; base::WeakPtrFactory<AssistantOptInFlowScreenHandler> weak_factory_;
diff --git a/chrome/browser/ui/webui/policy_indicator_localized_strings_provider.cc b/chrome/browser/ui/webui/policy_indicator_localized_strings_provider.cc index e7e5f6e..cf11f3c0 100644 --- a/chrome/browser/ui/webui/policy_indicator_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/policy_indicator_localized_strings_provider.cc
@@ -32,7 +32,8 @@ IDS_CONTROLLED_SETTING_EXTENSION_WITHOUT_NAME}, #if defined(OS_CHROMEOS) {"controlledSettingShared", IDS_CONTROLLED_SETTING_SHARED}, - {"controlledSettingOwner", IDS_CONTROLLED_SETTING_OWNER}, + {"controlledSettingWithOwner", IDS_CONTROLLED_SETTING_WITH_OWNER}, + {"controlledSettingNoOwner", IDS_CONTROLLED_SETTING_NO_OWNER}, #endif }; AddLocalizedStringsBulk(html_source, localized_strings,
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index d3b62651..75bf966 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -126,6 +126,8 @@ "component_flash_hint_file_linux.h", "conflicts/module_watcher_win.cc", "conflicts/module_watcher_win.h", + "conflicts/remote_module_watcher_win.cc", + "conflicts/remote_module_watcher_win.h", "content_restriction.h", "crash_keys.cc", "crash_keys.h",
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc index 45f0aa9..40668377 100644 --- a/chrome/common/chrome_content_client.cc +++ b/chrome/common/chrome_content_client.cc
@@ -34,7 +34,6 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/crash_keys.h" #include "chrome/common/pepper_flash.h" -#include "chrome/common/secure_origin_whitelist.h" #include "chrome/common/url_constants.h" #include "chrome/grit/common_resources.h" #include "components/crash/core/common/crash_key.h" @@ -625,8 +624,6 @@ // with them by third parties. schemes->secure_schemes.push_back(extensions::kExtensionScheme); - schemes->secure_origins = secure_origin_whitelist::GetWhitelist(); - // chrome-native: is a scheme used for placeholder navigations that allow // UIs to be drawn with platform native widgets instead of HTML. These pages // should be treated as empty documents that can commit synchronously.
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index a3d7829..f7852fa 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -634,15 +634,6 @@ // apps/origins. This should be used only for testing purpose. const char kUnlimitedStorage[] = "unlimited-storage"; -// Treat given (insecure) origins as secure origins. Multiple origins can be -// supplied as a comma-separated list. For the definition of secure contexts, -// see https://w3c.github.io/webappsec-secure-contexts/ -// -// Example: -// --unsafely-treat-insecure-origin-as-secure=http://a.test,http://b.test -const char kUnsafelyTreatInsecureOriginAsSecure[] = - "unsafely-treat-insecure-origin-as-secure"; - // Pass the full https:// URL to PAC (Proxy Auto Config) scripts. As opposed to // the default behavior which strips path and query components before passing // to the PAC scripts.
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index dc3f4b6..04db70f 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -187,7 +187,6 @@ extern const char kTrustedDownloadSources[]; extern const char kTryChromeAgain[]; extern const char kUnlimitedStorage[]; -extern const char kUnsafelyTreatInsecureOriginAsSecure[]; extern const char kUnsafePacUrl[]; extern const char kUserAgent[]; extern const char kUserDataDir[];
diff --git a/chrome/common/conflicts/remote_module_watcher_win.cc b/chrome/common/conflicts/remote_module_watcher_win.cc new file mode 100644 index 0000000..ce00b786 --- /dev/null +++ b/chrome/common/conflicts/remote_module_watcher_win.cc
@@ -0,0 +1,70 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/conflicts/remote_module_watcher_win.h" + +#include "base/sequenced_task_runner.h" +#include "base/single_thread_task_runner.h" +#include "content/public/common/service_names.mojom.h" +#include "services/service_manager/public/cpp/connector.h" + +namespace { + +// Note: Can be called on any threads, even those not owned by the task +// scheduler. +void OnModuleEvent( + scoped_refptr<base::SequencedTaskRunner> task_runner, + const ModuleWatcher::OnModuleEventCallback& on_module_event_callback, + const ModuleWatcher::ModuleEvent& event) { + task_runner->PostTask(FROM_HERE, + base::BindOnce(on_module_event_callback, event)); +} + +} // namespace + +RemoteModuleWatcher::~RemoteModuleWatcher() = default; + +// static +RemoteModuleWatcher::UniquePtr RemoteModuleWatcher::Create( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + service_manager::Connector* connector) { + auto remote_module_watcher = + UniquePtr(new RemoteModuleWatcher(task_runner), + base::OnTaskRunnerDeleter(task_runner)); + + // Because |remote_module_watcher| will be sent for deletion on |task_runner|, + // using an unretained pointer to it is safe as the initialization is + // guaranteed to be run before the destructor. + task_runner->PostTask( + FROM_HERE, base::BindOnce(&RemoteModuleWatcher::InitializeOnTaskRunner, + base::Unretained(remote_module_watcher.get()), + connector->Clone())); + + return remote_module_watcher; +} + +RemoteModuleWatcher::RemoteModuleWatcher( + scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : task_runner_(task_runner), weak_ptr_factory_(this) {} + +void RemoteModuleWatcher::InitializeOnTaskRunner( + std::unique_ptr<service_manager::Connector> connector) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + + connector->BindInterface(content::mojom::kBrowserServiceName, + &module_event_sink_); + + module_watcher_ = ModuleWatcher::Create(base::BindRepeating( + &OnModuleEvent, task_runner_, + base::BindRepeating(&RemoteModuleWatcher::HandleModuleEvent, + weak_ptr_factory_.GetWeakPtr()))); +} + +void RemoteModuleWatcher::HandleModuleEvent( + const ModuleWatcher::ModuleEvent& event) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + + module_event_sink_->OnModuleEvent( + event.event_type, reinterpret_cast<uintptr_t>(event.module_load_address)); +}
diff --git a/chrome/common/conflicts/remote_module_watcher_win.h b/chrome/common/conflicts/remote_module_watcher_win.h new file mode 100644 index 0000000..c0e716a --- /dev/null +++ b/chrome/common/conflicts/remote_module_watcher_win.h
@@ -0,0 +1,71 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_COMMON_CONFLICTS_REMOTE_MODULE_WATCHER_WIN_H_ +#define CHROME_COMMON_CONFLICTS_REMOTE_MODULE_WATCHER_WIN_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" +#include "chrome/common/conflicts/module_event_sink_win.mojom.h" +#include "chrome/common/conflicts/module_watcher_win.h" +#include "mojo/public/cpp/bindings/interface_ptr.h" + +namespace base { +class SingleThreadTaskRunner; +struct OnTaskRunnerDeleter; +} // namespace base + +namespace service_manager { +class Connector; +} + +// This class is used to instantiate a ModuleWatcher instance in a child +// process that forwards all the module events to the browser process via the +// mojom::ModuleEventSink interface. +class RemoteModuleWatcher { + public: + // Provided for convenience. + using UniquePtr = + std::unique_ptr<RemoteModuleWatcher, base::OnTaskRunnerDeleter>; + + ~RemoteModuleWatcher(); + + // Creates a RemoteModuleWatcher instance and initializes it on |task_runner|. + // The instance lives on that task runner and will be destroyed there when the + // UniquePtr is destroyed. + static UniquePtr Create( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + service_manager::Connector* connector); + + private: + explicit RemoteModuleWatcher( + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + + // Initializes this instance by connecting the |module_event_sink_| instance + // and starting the |module_watcher_|. Called on |task_runner_|. + void InitializeOnTaskRunner( + std::unique_ptr<service_manager::Connector> connector); + + // Receives module load events from the |module_watcher_| and forwards them to + // the |module_event_sink_|. + void HandleModuleEvent(const ModuleWatcher::ModuleEvent& event); + + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + + // Module events from |module_watcher_| are forwarded to the browser process + // through this sink. + mojo::InterfacePtr<mojom::ModuleEventSink> module_event_sink_; + + // Observes module load events. + std::unique_ptr<ModuleWatcher> module_watcher_; + + base::WeakPtrFactory<RemoteModuleWatcher> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(RemoteModuleWatcher); +}; + +#endif // CHROME_COMMON_CONFLICTS_REMOTE_MODULE_WATCHER_WIN_H_
diff --git a/chrome/common/conflicts/remote_module_watcher_win_unittest.cc b/chrome/common/conflicts/remote_module_watcher_win_unittest.cc new file mode 100644 index 0000000..a47fb68 --- /dev/null +++ b/chrome/common/conflicts/remote_module_watcher_win_unittest.cc
@@ -0,0 +1,147 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/conflicts/remote_module_watcher_win.h" + +#include <windows.h> + +#include <memory> +#include <string> +#include <utility> + +#include "base/memory/scoped_refptr.h" +#include "base/task/post_task.h" +#include "base/test/scoped_task_environment.h" +#include "chrome/common/conflicts/module_event_sink_win.mojom.h" +#include "content/public/common/service_names.mojom.h" +#include "services/service_manager/public/cpp/binder_registry.h" +#include "services/service_manager/public/cpp/service.h" +#include "services/service_manager/public/cpp/service_binding.h" +#include "services/service_manager/public/cpp/test/test_connector_factory.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class RemoteModuleWatcherTest : public testing::Test, + public service_manager::Service, + public mojom::ModuleEventSink { + public: + RemoteModuleWatcherTest() + : service_binding_(this, + test_connector_factory_.RegisterInstance( + content::mojom::kBrowserServiceName)), + binding_(this) {} + + ~RemoteModuleWatcherTest() override = default; + + // service_manager::Service: + void OnStart() override { + registry_.AddInterface(base::BindRepeating( + &RemoteModuleWatcherTest::BindModuleEventSinkRequest, + base::Unretained(this))); + } + void OnBindInterface(const service_manager::BindSourceInfo& source_info, + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) override { + registry_.BindInterface(interface_name, std::move(interface_pipe)); + } + + // mojom::ModuleEventSink: + void OnModuleEvent(mojom::ModuleEventType event_type, + uint64_t load_address) override { + module_event_count_++; + } + + // Returns a connector that may be used to connect to a ModuleEventSink implementation. + service_manager::Connector* GetConnector() { + return test_connector_factory_.GetDefaultConnector(); + } + + void LoadModule() { + if (module_handle_) + return; + // This module should not be a static dependency of the unit-test + // executable, but should be a build-system dependency or a module that is + // present on any Windows machine. + static constexpr wchar_t kModuleName[] = L"conflicts_dll.dll"; + // The module should not already be loaded. + ASSERT_FALSE(::GetModuleHandle(kModuleName)); + // It should load successfully. + module_handle_ = ::LoadLibrary(kModuleName); + ASSERT_TRUE(module_handle_); + } + + void UnloadModule() { + if (!module_handle_) + return; + ::FreeLibrary(module_handle_); + module_handle_ = nullptr; + } + + // Runs the task scheduler until no tasks are running. + void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); } + + HMODULE module_handle() { return module_handle_; } + + int module_event_count() { return module_event_count_; } + + private: + void BindModuleEventSinkRequest(mojom::ModuleEventSinkRequest request) { + binding_.Bind(std::move(request)); + } + + // Must be first. + base::test::ScopedTaskEnvironment scoped_task_environment_; + + service_manager::TestConnectorFactory test_connector_factory_; + + // Used to implement |service_manager::Service|. + service_manager::ServiceBinding service_binding_; + service_manager::BinderRegistry registry_; + + // Binds a ModuleEventSinkRequest to this implementation of ModuleEventSink. + mojo::Binding<mojom::ModuleEventSink> binding_; + + // Holds a handle to a loaded module. + HMODULE module_handle_ = nullptr; + + // Total number of module events seen. + int module_event_count_ = 0; + + DISALLOW_COPY_AND_ASSIGN(RemoteModuleWatcherTest); +}; + +} // namespace + +TEST_F(RemoteModuleWatcherTest, ModuleEvents) { + auto task_runner = base::CreateSingleThreadTaskRunnerWithTraits({}); + + auto remote_module_watcher = + RemoteModuleWatcher::Create(task_runner, GetConnector()); + + // Wait until the watcher is initialized and a few module events are received. + RunUntilIdle(); + EXPECT_GT(module_event_count(), 0); + + // Dynamically load a module and ensure a notification is received for it. + int previous_module_event_count = module_event_count(); + LoadModule(); + RunUntilIdle(); + EXPECT_GT(module_event_count(), previous_module_event_count); + + UnloadModule(); + + // Destroy the module watcher. + remote_module_watcher = nullptr; + RunUntilIdle(); + + // Load the module and ensure no notification is received this time. + previous_module_event_count = module_event_count(); + LoadModule(); + RunUntilIdle(); + + EXPECT_EQ(module_event_count(), previous_module_event_count); + + UnloadModule(); +}
diff --git a/chrome/common/safe_browsing/zip_analyzer.cc b/chrome/common/safe_browsing/zip_analyzer.cc index 773f8bb..f499222 100644 --- a/chrome/common/safe_browsing/zip_analyzer.cc +++ b/chrome/common/safe_browsing/zip_analyzer.cc
@@ -13,6 +13,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/metrics/histogram_functions.h" +#include "base/metrics/histogram_macros.h" #include "base/numerics/ranges.h" #include "base/rand_util.h" #include "build/build_config.h" @@ -68,6 +69,16 @@ return; } + bool too_big_to_unpack = + base::checked_cast<uint64_t>(zip_file.GetLength()) > + FileTypePolicies::GetInstance()->GetMaxFileSizeToAnalyze("zip"); + UMA_HISTOGRAM_BOOLEAN("SBClientDownload.ZipTooBigToUnpack", + too_big_to_unpack); + if (too_big_to_unpack) { + results->success = true; + return; + } + bool contains_zip = false; bool advanced = true; int zip_entry_count = 0;
diff --git a/chrome/common/secure_origin_whitelist.cc b/chrome/common/secure_origin_whitelist.cc index b70d6ce..2f3d863 100644 --- a/chrome/common/secure_origin_whitelist.cc +++ b/chrome/common/secure_origin_whitelist.cc
@@ -4,163 +4,15 @@ #include "chrome/common/secure_origin_whitelist.h" -#include "base/command_line.h" -#include "base/metrics/histogram_macros.h" -#include "base/numerics/safe_conversions.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "chrome/common/chrome_switches.h" +#include <set> +#include <string> + #include "chrome/common/pref_names.h" #include "components/prefs/pref_registry_simple.h" #include "extensions/common/constants.h" -#include "net/base/registry_controlled_domains/registry_controlled_domain.h" -#include "url/gurl.h" -#include "url/origin.h" -#include "url/scheme_host_port.h" - -namespace { - -// Given a hostname pattern with a wildcard such as "*.foo.com", returns -// true if |hostname_pattern| meets both of these conditions: -// 1.) A string matching |hostname_pattern| is a valid hostname. -// 2.) Wildcards only appear beyond the eTLD+1. "*.foo.com" is considered -// valid but "*.com" is not. -bool IsValidWildcardPattern(const std::string& hostname_pattern) { - // Replace wildcards with dummy values to check whether a matching origin is - // valid. - std::string wildcards_replaced; - if (!base::ReplaceChars(hostname_pattern, "*", "a", &wildcards_replaced)) - return false; - // Construct a SchemeHostPort with a dummy scheme and port to check that the - // hostname is valid. - url::SchemeHostPort scheme_host_port( - GURL(base::StringPrintf("http://%s:80", wildcards_replaced.c_str()))); - if (scheme_host_port.IsInvalid()) - return false; - - // Check that wildcards only appear beyond the eTLD+1. - size_t registry_length = - net::registry_controlled_domains::PermissiveGetHostRegistryLength( - hostname_pattern, - net::registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES, - net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); - // std::string::npos should only be returned for empty inputs, which should be - // filtered out by the IsInvalid() check above. - CHECK(registry_length != std::string::npos); - // If there is no registrar portion, the pattern is considered invalid. - if (registry_length == 0) - return false; - // If there is no component before the registrar portion, or if the component - // immediately preceding the registrar portion contains a wildcard, the - // pattern is not considered valid. - std::string host_before_registrar = - hostname_pattern.substr(0, hostname_pattern.size() - registry_length); - std::vector<std::string> components = - base::SplitString(host_before_registrar, ".", base::KEEP_WHITESPACE, - base::SPLIT_WANT_NONEMPTY); - if (components.size() == 0) - return false; - if (components.back().find("*") != std::string::npos) - return false; - return true; -} - -// Canonicalizes each component of |hostname_pattern|, making no changes to -// wildcard components or components that fail canonicalization. For example, -// given a |hostname_pattern| of "TeSt.*.%46oo.com", the output will be -// "test.*.foo.com". -std::string CanonicalizePatternComponents(const std::string& hostname_pattern) { - std::string canonical_host; // Do not modify outside of canon_output. - canonical_host.reserve(hostname_pattern.length()); - url::StdStringCanonOutput canon_output(&canonical_host); - - for (size_t current = 0; current < hostname_pattern.length(); current++) { - size_t begin = current; - - // Advance to next "." or end. - current = hostname_pattern.find('.', begin); - if (current == std::string::npos) - current = hostname_pattern.length(); - - // Try to append the canonicalized version of this component. - int current_len = base::checked_cast<int>(current - begin); - if (hostname_pattern.substr(begin, current_len) == "*" || - !url::CanonicalizeHostSubstring( - hostname_pattern.data(), - url::Component(base::checked_cast<int>(begin), current_len), - &canon_output)) { - // Failed to canonicalize this component; append as-is. - canon_output.Append(hostname_pattern.substr(begin, current_len).data(), - current_len); - } - - if (current < hostname_pattern.length()) - canon_output.push_back('.'); - } - canon_output.Complete(); - return canonical_host; -} - -} // namespace namespace secure_origin_whitelist { -std::vector<std::string> ParseWhitelist(const std::string& origins_str) { - std::vector<std::string> origin_patterns; - for (const std::string& origin_str : base::SplitString( - origins_str, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { - if (origin_str.find("*") != std::string::npos) { - if (IsValidWildcardPattern(origin_str)) { - std::string canonicalized_pattern = - CanonicalizePatternComponents(origin_str); - if (!canonicalized_pattern.empty()) { - origin_patterns.push_back(canonicalized_pattern); - continue; - } - } - LOG(ERROR) << "Whitelisted secure origin pattern " << origin_str - << " is not valid; ignoring."; - continue; - } - - // Drop .unique() origins, as they are unequal to any other origins. - url::Origin origin(url::Origin::Create(GURL(origin_str))); - if (!origin.opaque()) - origin_patterns.push_back(origin.Serialize()); - } - - UMA_HISTOGRAM_COUNTS_100("Security.TreatInsecureOriginAsSecure", - origin_patterns.size()); - -#if defined(OS_CHROMEOS) - // For Crostini, we allow access to the default VM/container as a secure - // origin via the hostname penguin.linux.test. We are required to use a - // wildcard for the prefix because we do not know what the port number is. - // https://chromium.googlesource.com/chromiumos/docs/+/master/containers_and_vms.md - origin_patterns.push_back("*.linux.test"); -#endif - - return origin_patterns; -} - -std::vector<std::string> GetWhitelist() { - // If kUnsafelyTreatInsecureOriginAsSecure option is given, then treat the - // value as a comma-separated list of origins or origin patterns. Callers that - // need to also check the kUnsafelyTreatInsecureOriginAsSecure pref value must - // instead use ParseWhitelist directly (as there is no way for GetWhitelist() - // to access prefs). For renderer processes the pref and the switch will - // match, but for non-renderer processes the switch may not be set. - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - std::string origins_str = ""; - if (command_line.HasSwitch(switches::kUnsafelyTreatInsecureOriginAsSecure)) { - origins_str = command_line.GetSwitchValueASCII( - switches::kUnsafelyTreatInsecureOriginAsSecure); - } - return ParseWhitelist(origins_str); -} - std::set<std::string> GetSchemesBypassingSecureContextCheck() { std::set<std::string> schemes; schemes.insert(extensions::kExtensionScheme);
diff --git a/chrome/common/secure_origin_whitelist.h b/chrome/common/secure_origin_whitelist.h index 92b1fd9..65d7628 100644 --- a/chrome/common/secure_origin_whitelist.h +++ b/chrome/common/secure_origin_whitelist.h
@@ -7,35 +7,11 @@ #include <set> #include <string> -#include <vector> class PrefRegistrySimple; namespace secure_origin_whitelist { -// Return a whitelist of origins and hostname patterns that need to be -// considered trustworthy. The whitelist is given by -// kUnsafelyTreatInsecureOriginAsSecure command-line option. See -// https://www.w3.org/TR/powerful-features/#is-origin-trustworthy. -// -// The whitelist can contain origins and wildcard hostname patterns up to -// eTLD+1. For example, the list may contain "http://foo.com", -// "http://foo.com:8000", "*.foo.com", "*.foo.*.bar.com", and -// "http://*.foo.bar.com", but not "*.co.uk", "*.com", or "test.*.com". Hostname -// patterns must contain a wildcard somewhere (so "test.com" is not a valid -// pattern) and wildcards can only replace full components ("test*.foo.com" is -// not valid). -// -// Plain origins ("http://foo.com") are canonicalized when they are inserted -// into this list by converting to url::Origin and serializing. For hostname -// patterns, each component is individually canonicalized. -std::vector<std::string> GetWhitelist(); - -// Parses a comma-separated list of origins and wildcard hostname patterns. -// This separate function allows callers other than GetWhitelist() to -// explicitly pass a whitelist to be parsed. -std::vector<std::string> ParseWhitelist(const std::string& origins_str); - // Returns a whitelist of schemes that should bypass the Is Privileged Context // check. See http://www.w3.org/TR/powerful-features/#settings-privileged. std::set<std::string> GetSchemesBypassingSecureContextCheck();
diff --git a/chrome/common/secure_origin_whitelist_unittest.cc b/chrome/common/secure_origin_whitelist_unittest.cc deleted file mode 100644 index e71c9e1..0000000 --- a/chrome/common/secure_origin_whitelist_unittest.cc +++ /dev/null
@@ -1,93 +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 "base/command_line.h" -#include "base/test/scoped_command_line.h" -#include "chrome/common/chrome_switches.h" -#include "content/public/common/origin_util.h" -#include "content/public/test/test_utils.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -using content::IsOriginSecure; - -namespace chrome { - -class SecureOriginWhiteListTest : public testing::Test { - void TearDown() override { - // Ensure that we reset the whitelisted origins without any flags applied. - content::ResetSchemesAndOriginsWhitelist(); - } -}; - -TEST_F(SecureOriginWhiteListTest, UnsafelyTreatInsecureOriginAsSecure) { - EXPECT_FALSE(content::IsOriginSecure(GURL("http://example.com/a.html"))); - EXPECT_FALSE( - content::IsOriginSecure(GURL("http://127.example.com/a.html"))); - // Add http://example.com and http://127.example.com to whitelist by - // command-line and see if they are now considered secure origins. - // (The command line is applied via - // ChromeContentClient::AddSecureSchemesAndOrigins) - base::test::ScopedCommandLine scoped_command_line; - base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine(); - command_line->AppendSwitchASCII( - switches::kUnsafelyTreatInsecureOriginAsSecure, - "http://example.com,http://127.example.com"); - content::ResetSchemesAndOriginsWhitelist(); - - // They should be now white-listed. - EXPECT_TRUE(content::IsOriginSecure(GURL("http://example.com/a.html"))); - EXPECT_TRUE(content::IsOriginSecure(GURL("http://127.example.com/a.html"))); - - // Check that similarly named sites are not considered secure. - EXPECT_FALSE(content::IsOriginSecure(GURL("http://128.example.com/a.html"))); - EXPECT_FALSE(content::IsOriginSecure( - GURL("http://foobar.127.example.com/a.html"))); -} - -TEST_F(SecureOriginWhiteListTest, HostnamePatterns) { - const struct HostnamePatternCase { - const char* pattern; - const char* test_input; - bool expected_secure; - } kTestCases[] = { - {"*.foo.com", "http://bar.foo.com", true}, - {"*.foo.*.bar.com", "http://a.foo.b.bar.com:8000", true}, - // For parsing/canonicalization simplicity, wildcard patterns can be - // hostnames only, not full origins. - {"http://*.foo.com", "http://bar.foo.com", false}, - {"*://foo.com", "http://foo.com", false}, - // Wildcards must be beyond eTLD+1. - {"*.co.uk", "http://foo.co.uk", false}, - {"*.co.uk", "http://co.uk", false}, - {"*.baz", "http://foo.baz", false}, - {"foo.*.com", "http://foo.bar.com", false}, - {"*.foo.baz", "http://a.foo.baz", true}, - // Hostname patterns should be canonicalized. - {"*.FoO.com", "http://a.foo.com", true}, - {"%2A.foo.com", "http://a.foo.com", false}, - // Hostname patterns must contain a wildcard and a wildcard can only - // replace a component, not a part of a component. - {"foo.com", "http://foo.com", false}, - {"test*.foo.com", "http://testblah.foo.com", false}, - {"*foo.com", "http://testfoo.com", false}, - {"foo*.com", "http://footest.com", false}, - }; - - for (const auto& test : kTestCases) { - base::test::ScopedCommandLine scoped_command_line; - base::CommandLine* command_line = - scoped_command_line.GetProcessCommandLine(); - command_line->AppendSwitchASCII( - switches::kUnsafelyTreatInsecureOriginAsSecure, test.pattern); - content::ResetSchemesAndOriginsWhitelist(); - EXPECT_EQ(test.expected_secure, - content::IsOriginSecure(GURL(test.test_input))); - EXPECT_EQ(test.expected_secure, - content::IsPotentiallyTrustworthyOrigin( - url::Origin::Create(GURL(test.test_input)))); - } -} - -} // namespace chrome
diff --git a/chrome/credential_provider/gaiacp/associated_user_validator.cc b/chrome/credential_provider/gaiacp/associated_user_validator.cc index 44a9a9bd..c52eccf9 100644 --- a/chrome/credential_provider/gaiacp/associated_user_validator.cc +++ b/chrome/credential_provider/gaiacp/associated_user_validator.cc
@@ -279,7 +279,7 @@ HRESULT hr = UpdateAssociatedSids(nullptr); if (FAILED(hr)) { - LOGFN(ERROR) << "GetUserTokenHandles hr=" << putHR(hr); + LOGFN(ERROR) << "UpdateAssociatedSids hr=" << putHR(hr); return; } @@ -311,6 +311,26 @@ return S_OK; } +void AssociatedUserValidator::AllowSigninForAllAssociatedUsers( + CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus) { + if (!MdmEnrollmentEnabled() || + !CGaiaCredentialProvider::IsUsageScenarioSupported(cpus)) + return; + + std::map<base::string16, base::string16> sids_to_handle; + HRESULT hr = UpdateAssociatedSids(&sids_to_handle); + if (FAILED(hr)) { + LOGFN(ERROR) << "UpdateAssociatedSids hr=" << putHR(hr); + return; + } + + auto policy = ScopedLsaPolicy::Create(POLICY_ALL_ACCESS); + for (const auto& sid_to_handle : sids_to_handle) + ModifyUserAccess(policy, sid_to_handle.first, true); + + locked_user_sids_.clear(); +} + void AssociatedUserValidator::AllowSigninForUsersWithInvalidTokenHandles() { LOGFN(INFO); auto policy = ScopedLsaPolicy::Create(POLICY_ALL_ACCESS);
diff --git a/chrome/credential_provider/gaiacp/associated_user_validator.h b/chrome/credential_provider/gaiacp/associated_user_validator.h index 7818c1f..f2694874 100644 --- a/chrome/credential_provider/gaiacp/associated_user_validator.h +++ b/chrome/credential_provider/gaiacp/associated_user_validator.h
@@ -66,6 +66,12 @@ // token validator. void AllowSigninForUsersWithInvalidTokenHandles(); + // Restores access to all associated users. Regardless of their access + // state. This ensures that no user can be completely locked out due + // a bad computer state or crash. + void AllowSigninForAllAssociatedUsers( + CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus); + // Fills |associated_sids| with the sids of all valid associated users // found on this system. std::set<base::string16> GetUpdatedAssociatedSids();
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider_filter.cc b/chrome/credential_provider/gaiacp/gaia_credential_provider_filter.cc index 8cd1bb6..0516b58 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_provider_filter.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_provider_filter.cc
@@ -28,6 +28,9 @@ GUID* providers_clsids, BOOL* providers_allow, DWORD providers_count) { + // Re-enable all users in case internet has been lost or the computer + // crashed while users were locked out. + AssociatedUserValidator::Get()->AllowSigninForAllAssociatedUsers(cpus); // Check to see if any users need to have their access to this system // using the normal credential providers revoked. AssociatedUserValidator::Get()->DenySigninForUsersWithInvalidTokenHandles(
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 82ac3067..a838fabb 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -22,7 +22,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "base/values.h" -#include "build/build_config.h" #include "chrome/common/buildflags.h" #include "chrome/common/channel_info.h" #include "chrome/common/chrome_content_client.h" @@ -114,6 +113,7 @@ #include "ppapi/buildflags/buildflags.h" #include "ppapi/shared_impl/ppapi_switches.h" #include "printing/buildflags/buildflags.h" +#include "services/network/public/cpp/is_potentially_trustworthy.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" @@ -148,6 +148,9 @@ #include "chrome/renderer/searchbox/searchbox_extension.h" #endif +#if defined(OS_WIN) +#endif + #if defined(FULL_SAFE_BROWSING) #include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h" #endif @@ -293,52 +296,13 @@ DISALLOW_COPY_AND_ASSIGN(MediaLoadDeferrer); }; -#if defined(OS_WIN) -// Binds |module_event_sink| to the provided |interface_ptr_info|. This function -// is used to do the binding on the IO thread. -void BindModuleEventSink(mojom::ModuleEventSinkPtr* module_event_sink, - mojom::ModuleEventSinkPtrInfo interface_ptr_info) { - DCHECK(!module_event_sink->is_bound()); - - module_event_sink->Bind(std::move(interface_ptr_info)); -} - -// Dispatches a module |event| to the provided |module_event_sink| interface. -// It is expected that this only be called from the IO thread. This is only safe -// because the underlying |module_event_sink| object is never deleted, being -// owned by the leaked ChromeContentRendererClient object. If this ever changes -// then a WeakPtr mechanism would have to be used. -void HandleModuleEventOnIOThread( - const mojom::ModuleEventSinkPtr& module_event_sink, - const ModuleWatcher::ModuleEvent& event) { - DCHECK(module_event_sink.is_bound()); - - // Simply send the module load address. The browser can validate this and look - // up the module details on its own. - module_event_sink->OnModuleEvent( - event.event_type, reinterpret_cast<uintptr_t>(event.module_load_address)); -} - -// Receives notifications from the ModuleWatcher on any thread. Bounces these -// over to the provided |io_task_runner| where they are subsequently dispatched -// to the |module_event_sink| interface. -void OnModuleEvent(scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - const mojom::ModuleEventSinkPtr& module_event_sink, - const ModuleWatcher::ModuleEvent& event) { - // The Mojo interface can only be used from a single thread. Bounce tasks - // over to it. It is safe to pass an unretained pointer to - // |module_event_sink|: it is owned by a ChromeContentRendererClient, which is - // a leaked singleton in the process. - io_task_runner->PostTask(FROM_HERE, - base::BindOnce(&HandleModuleEventOnIOThread, - std::cref(module_event_sink), event)); -} -#endif - } // namespace ChromeContentRendererClient::ChromeContentRendererClient() : main_entry_time_(base::TimeTicks::Now()), +#if defined(OS_WIN) + remote_module_watcher_(nullptr, base::OnTaskRunnerDeleter(nullptr)), +#endif main_thread_profiler_(ThreadProfiler::CreateAndStartOnMainThread()) { #if BUILDFLAG(ENABLE_EXTENSIONS) EnsureExtensionsClientInitialized(); @@ -370,26 +334,8 @@ } #if defined(OS_WIN) - // Bind the ModuleEventSink interface. - thread->GetConnector()->BindInterface( - service_manager::ServiceFilter::ByName( - content::mojom::kBrowserServiceName), - &module_event_sink_); - - // Rebind the ModuleEventSink to the IO task runner. - // The use of base::Unretained() is safe here because |module_event_sink_| - // is never deleted and is only used on the IO task runner. - thread->GetIOTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&BindModuleEventSink, - base::Unretained(&module_event_sink_), - module_event_sink_.PassInterface())); - - // It is safe to pass an unretained pointer to |module_event_sink_|, as it - // is owned by the process singleton ChromeContentRendererClient, which is - // leaked. - module_watcher_ = ModuleWatcher::Create( - base::BindRepeating(&OnModuleEvent, thread->GetIOTaskRunner(), - std::cref(module_event_sink_))); + remote_module_watcher_ = RemoteModuleWatcher::Create( + thread->GetIOTaskRunner(), thread->GetConnector()); #endif chrome_observer_.reset(new ChromeRenderThreadObserver()); @@ -463,8 +409,7 @@ pdf::PepperPDFHost::SetPrintClient(pdf_print_client_.get()); #endif - for (auto& origin_or_hostname_pattern : - secure_origin_whitelist::GetWhitelist()) { + for (auto& origin_or_hostname_pattern : network::GetSecureOriginAllowlist()) { WebSecurityPolicy::AddOriginTrustworthyWhiteList( WebString::FromUTF8(origin_or_hostname_pattern)); }
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h index c9c7992..d64bb63 100644 --- a/chrome/renderer/chrome_content_renderer_client.h +++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -16,6 +16,7 @@ #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" #include "base/strings/string16.h" +#include "build/build_config.h" #include "chrome/common/plugin.mojom.h" #include "chrome/renderer/media/chrome_key_systems_provider.h" #include "components/nacl/common/buildflags.h" @@ -36,8 +37,7 @@ #include "v8/include/v8.h" #if defined(OS_WIN) -#include "chrome/common/conflicts/module_event_sink_win.mojom.h" -#include "chrome/common/conflicts/module_watcher_win.h" +#include "chrome/common/conflicts/remote_module_watcher_win.h" #endif class ChromeRenderThreadObserver; @@ -269,6 +269,13 @@ service_manager::Connector* GetConnector(); +#if defined(OS_WIN) + // Observes module load events and notifies the ModuleDatabase in the browser + // process. This instance is created on the main thread but then lives on the + // IO task runner. + RemoteModuleWatcher::UniquePtr remote_module_watcher_; +#endif + // Used to profile main thread. std::unique_ptr<ThreadProfiler> main_thread_profiler_; @@ -296,13 +303,6 @@ std::set<std::string> allowed_camera_device_origins_; #endif -#if defined(OS_WIN) - // Observes module load and unload events and notifies the ModuleDatabase in - // the browser process. - std::unique_ptr<ModuleWatcher> module_watcher_; - mojom::ModuleEventSinkPtr module_event_sink_; -#endif - service_manager::ServiceBinding service_binding_{this}; service_manager::BinderRegistry registry_;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index cacf16a..eef65e5 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2701,7 +2701,6 @@ "../browser/net/file_downloader_unittest.cc", "../browser/net/net_error_tab_helper_unittest.cc", "../browser/net/probe_message_unittest.cc", - "../browser/net/quota_policy_channel_id_store_unittest.cc", "../browser/net/reporting_permissions_checker_unittest.cc", "../browser/notifications/metrics/notification_metrics_logger_unittest.cc", "../browser/notifications/notification_channels_provider_android_unittest.cc", @@ -2954,6 +2953,7 @@ "../common/chrome_paths_unittest.cc", "../common/component_flash_hint_file_linux_unittest.cc", "../common/conflicts/module_watcher_win_unittest.cc", + "../common/conflicts/remote_module_watcher_win_unittest.cc", "../common/crash_keys_unittest.cc", "../common/heap_profiler_controller_unittest.cc", "../common/ini_parser_unittest.cc", @@ -2970,7 +2970,6 @@ "../common/page_load_metrics/test/weak_mock_timer.cc", "../common/page_load_metrics/test/weak_mock_timer.h", "../common/pref_names_util_unittest.cc", - "../common/secure_origin_whitelist_unittest.cc", "../common/thread_profiler_unittest.cc", "../renderer/chrome_content_renderer_client_unittest.cc", "../renderer/content_settings_observer_unittest.cc",
diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn index 1a82e9e..932b33d 100644 --- a/chrome/test/android/BUILD.gn +++ b/chrome/test/android/BUILD.gn
@@ -89,11 +89,11 @@ "//net/android:net_java_test_support", "//testing/android/reporter:reporter_java", "//third_party/android_deps:android_arch_lifecycle_common_java", - "//third_party/android_deps:android_support_annotations_java", - "//third_party/android_deps:android_support_compat_java", - "//third_party/android_deps:android_support_design_java", "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:android_support_v7_recyclerview_java", + "//third_party/android_deps:com_android_support_design_java", + "//third_party/android_deps:com_android_support_recyclerview_v7_java", + "//third_party/android_deps:com_android_support_support_annotations_java", + "//third_party/android_deps:com_android_support_support_compat_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/hamcrest:hamcrest_core_java",
diff --git a/chrome/test/android/cast_emulator/BUILD.gn b/chrome/test/android/cast_emulator/BUILD.gn index 78c1d04..251a13cb 100644 --- a/chrome/test/android/cast_emulator/BUILD.gn +++ b/chrome/test/android/cast_emulator/BUILD.gn
@@ -23,6 +23,6 @@ "$google_play_services_package:google_play_services_cast_java", "//base:base_java", "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:android_support_v7_mediarouter_java", + "//third_party/android_deps:com_android_support_mediarouter_v7_java", ] }
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_focus_test.js b/chrome/test/data/webui/cr_elements/cr_elements_focus_test.js index 5a6a890..4e523cc 100644 --- a/chrome/test/data/webui/cr_elements/cr_elements_focus_test.js +++ b/chrome/test/data/webui/cr_elements/cr_elements_focus_test.js
@@ -149,3 +149,29 @@ TEST_F('CrElementsIconButtonFocusTest', 'All', function() { mocha.run(); }); + + +/** + * @constructor + * @extends {CrElementsFocusTest} + */ +function CrElementsExpandButtonTest() {} + +CrElementsExpandButtonTest.prototype = { + __proto__: CrElementsFocusTest.prototype, + + /** @override */ + browsePreload: + 'chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html', + + /** @override */ + extraLibraries: CrElementsFocusTest.prototype.extraLibraries.concat([ + ROOT_PATH + 'ui/webui/resources/js/util.js', + '../settings/test_util.js', + 'cr_expand_button_focus_tests.js', + ]), +}; + +TEST_F('CrElementsExpandButtonTest', 'All', function() { + mocha.run(); +});
diff --git a/chrome/test/data/webui/cr_elements/cr_expand_button_focus_tests.js b/chrome/test/data/webui/cr_elements/cr_expand_button_focus_tests.js new file mode 100644 index 0000000..a6833230 --- /dev/null +++ b/chrome/test/data/webui/cr_elements/cr_expand_button_focus_tests.js
@@ -0,0 +1,120 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +suite('cr-expand-button-focus-tests', () => { + let button; + + /** @param {boolean} */ + function assertRippleState(rippleShown) { + assertEquals(button.$.icon, getDeepActiveElement()); + assertEquals(rippleShown, button.$.icon.getRipple().holdDown); + } + + function assertRipple() { + assertRippleState(true); + } + + function assertNoRipple() { + assertRippleState(false); + } + + /** @param {!Function} toggler */ + async function waitForExpansion(toggler) { + const wait = test_util.eventToPromise('expanded-changed', button); + toggler(); + await wait; + } + + async function click() { + await waitForExpansion(() => { + // This is used in cr.ui.focusWithoutInk to change mode into ink hidden + // when focused. + button.dispatchEvent(new PointerEvent('pointerdown')); + // Used to simulate releasing the mouse button. + button.$.icon.fire('up'); + // When the mouse is pressed and released, it will also emit a 'click' + // event which is used in cr-expand-button to toggle expansion. + button.fire('click'); + }); + } + + async function enter() { + await waitForExpansion(() => { + MockInteractions.pressAndReleaseKeyOn(button.$.icon, '', '', 'Enter'); + }); + } + + async function space() { + await waitForExpansion(() => { + MockInteractions.pressAndReleaseKeyOn(button.$.icon, '', '', ' '); + }); + } + + setup(() => { + document.body.innerHTML = '<cr-expand-button></cr-expand-button>'; + button = document.body.querySelector('cr-expand-button'); + }); + + test('focus, ripple', () => { + button.focus(); + assertRipple(); + }); + + test('click, no ripple', async () => { + await click(); + assertNoRipple(); + }); + + test('enter, ripple', async () => { + await enter(); + assertRipple(); + }); + + test('space, ripple', async () => { + await space(); + assertRipple(); + }); + + test('focus then click, no ripple', async () => { + button.focus(); + await click(); + assertNoRipple(); + }); + + test('click then enter, no ripple', async () => { + await click(); + await enter(); + assertNoRipple(); + }); + + test('click then space, no ripple', async () => { + await click(); + await space(); + assertNoRipple(); + }); + + test('enter then click, no ripple', async () => { + await enter(); + await click(); + assertNoRipple(); + }); + + test('space then click, no ripple', async () => { + await space(); + await click(); + assertNoRipple(); + }); + + test('focus then enter, ripple', async () => { + button.focus(); + await enter(); + assertRipple(); + }); + + test('focus then space, ripple', async () => { + button.focus(); + await space(); + assertRipple(); + }); +});
diff --git a/chrome/test/data/webui/cr_elements/cr_policy_strings.js b/chrome/test/data/webui/cr_elements/cr_policy_strings.js index a3b62793..5c1c966 100644 --- a/chrome/test/data/webui/cr_elements/cr_policy_strings.js +++ b/chrome/test/data/webui/cr_elements/cr_policy_strings.js
@@ -9,7 +9,8 @@ controlledSettingRecommendedMatches: 'matches', controlledSettingRecommendedDiffers: 'differs', controlledSettingShared: 'shared: $1', - controlledSettingOwner: 'owner: $1', + controlledSettingWithOwner: 'owner: $1', + controlledSettingNoOwner: 'owner', controlledSettingExtension: 'extension: $1', controlledSettingExtensionWithoutName: 'extension', };
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn index f777f46..75ce77a 100644 --- a/chromecast/browser/BUILD.gn +++ b/chromecast/browser/BUILD.gn
@@ -106,12 +106,6 @@ "media/media_caps_impl.h", "media/supported_codec_finder.cc", "media/supported_codec_finder.h", - "metrics/cast_metrics_prefs.cc", - "metrics/cast_metrics_prefs.h", - "metrics/cast_metrics_service_client.cc", - "metrics/cast_metrics_service_client.h", - "metrics/cast_stability_metrics_provider.cc", - "metrics/cast_stability_metrics_provider.h", "renderer_prelauncher.cc", "renderer_prelauncher.h", "service/cast_service_simple.cc", @@ -138,6 +132,7 @@ public_deps = [ ":prefs", ":public", + "//chromecast/browser/metrics", ] deps = [ @@ -226,14 +221,9 @@ "cast_memory_pressure_monitor.h", "memory_pressure_controller_impl.cc", "memory_pressure_controller_impl.h", - "metrics/external_metrics.cc", - "metrics/external_metrics.h", ] - deps += [ - "//components/metrics:serialization", - "//third_party/fontconfig", - ] + deps += [ "//third_party/fontconfig" ] } if (use_aura) {
diff --git a/chromecast/browser/android/BUILD.gn b/chromecast/browser/android/BUILD.gn index 93952de..05bb46f 100644 --- a/chromecast/browser/android/BUILD.gn +++ b/chromecast/browser/android/BUILD.gn
@@ -93,7 +93,7 @@ deps = [ "//base:base_java", "//chromecast/base:base_java", - "//third_party/android_deps:android_support_core_utils_java", + "//third_party/android_deps:com_android_support_support_core_utils_java", ] } @@ -149,7 +149,7 @@ "//net/android:net_java", # TODO(slan): We may need to pass this in as a parameter. - "//third_party/android_deps:android_support_core_utils_java", + "//third_party/android_deps:com_android_support_support_core_utils_java", "//ui/android:ui_java", ] @@ -210,7 +210,7 @@ "//base:base_junit_test_support", "//chromecast/base:cast_base_test_utils_java", "//content/public/android:content_java", - "//third_party/android_deps:android_support_core_utils_java", + "//third_party/android_deps:com_android_support_support_core_utils_java", "//third_party/hamcrest:hamcrest_java", ] }
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc index 17205215..4b6e811f 100644 --- a/chromecast/browser/cast_browser_main_parts.cc +++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -477,6 +477,7 @@ std::make_unique<CastBrowserContext>(url_request_context_factory_)); cast_browser_process_->SetMetricsServiceClient( std::make_unique<metrics::CastMetricsServiceClient>( + cast_browser_process_->browser_client(), cast_browser_process_->pref_service(), content::BrowserContext::GetDefaultStoragePartition( cast_browser_process_->browser_context())
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h index 1e1f5c26f..41da499 100644 --- a/chromecast/browser/cast_content_browser_client.h +++ b/chromecast/browser/cast_content_browser_client.h
@@ -15,6 +15,7 @@ #include "base/threading/thread.h" #include "build/build_config.h" #include "build/buildflag.h" +#include "chromecast/browser/metrics/cast_metrics_service_client.h" #include "chromecast/chromecast_buildflags.h" #include "content/public/browser/certificate_request_result_type.h" #include "content/public/browser/content_browser_client.h" @@ -67,7 +68,9 @@ class CastResourceDispatcherHostDelegate; class URLRequestContextFactory; -class CastContentBrowserClient : public content::ContentBrowserClient { +class CastContentBrowserClient + : public content::ContentBrowserClient, + public chromecast::metrics::CastMetricsServiceDelegate { public: // Creates an implementation of CastContentBrowserClient. Platform should // link in an implementation as needed. @@ -118,12 +121,10 @@ virtual base::WeakPtr<device::BluetoothAdapterCast> CreateBluetoothAdapter(); #endif // !defined(OS_ANDROID) && !defined(OS_FUCHSIA) - // Invoked when the metrics client ID changes. - virtual void SetMetricsClientId(const std::string& client_id); - - // Allows registration of extra metrics providers. - virtual void RegisterMetricsProviders( - ::metrics::MetricsService* metrics_service); + // chromecast::metrics::CastMetricsServiceDelegate implementation: + void SetMetricsClientId(const std::string& client_id) override; + void RegisterMetricsProviders( + ::metrics::MetricsService* metrics_service) override; // Returns whether or not the remote debugging service should be started // on browser startup.
diff --git a/chromecast/browser/cast_network_contexts.cc b/chromecast/browser/cast_network_contexts.cc index 169f0c2..58653a5 100644 --- a/chromecast/browser/cast_network_contexts.cc +++ b/chromecast/browser/cast_network_contexts.cc
@@ -126,6 +126,9 @@ CastNetworkContexts::~CastNetworkContexts() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (proxy_config_service_) + proxy_config_service_->RemoveObserver(this); + system_shared_url_loader_factory_->Shutdown(); }
diff --git a/chromecast/browser/metrics/BUILD.gn b/chromecast/browser/metrics/BUILD.gn index 9e037513..1055295 100644 --- a/chromecast/browser/metrics/BUILD.gn +++ b/chromecast/browser/metrics/BUILD.gn
@@ -18,13 +18,17 @@ "//base", "//base:i18n", "//chromecast/base", - "//chromecast/common", + "//chromecast/base:cast_sys_info", + "//chromecast/base:cast_version", "//components/metrics", "//components/metrics:gpu", "//components/metrics:net", + "//components/metrics:ui", "//components/prefs", "//content/public/browser", "//content/public/common", + "//services/network/public/cpp", + "//third_party/metrics_proto", ] if (is_linux) { @@ -33,6 +37,9 @@ "external_metrics.h", ] - deps += [ "//components/metrics:serialization" ] + deps += [ + "//chromecast/base/metrics", + "//components/metrics:serialization", + ] } }
diff --git a/chromecast/browser/metrics/cast_metrics_service_client.cc b/chromecast/browser/metrics/cast_metrics_service_client.cc index ab7cb3b..645835f 100644 --- a/chromecast/browser/metrics/cast_metrics_service_client.cc +++ b/chromecast/browser/metrics/cast_metrics_service_client.cc
@@ -18,8 +18,6 @@ #include "chromecast/base/path_utils.h" #include "chromecast/base/pref_names.h" #include "chromecast/base/version.h" -#include "chromecast/browser/cast_browser_process.h" -#include "chromecast/browser/cast_content_browser_client.h" #include "chromecast/browser/metrics/cast_stability_metrics_provider.h" #include "chromecast/public/cast_sys_info.h" #include "components/metrics/client_info.h" @@ -108,8 +106,8 @@ const std::string& client_id) { client_id_ = client_id; LOG(INFO) << "Metrics client ID set: " << client_id; - shell::CastBrowserProcess::GetInstance()->browser_client()-> - SetMetricsClientId(client_id); + if (delegate_) + delegate_->SetMetricsClientId(client_id); #if defined(OS_ANDROID) DumpstateWriter::AddDumpValue(kClientIdName, client_id); #endif @@ -276,9 +274,11 @@ } CastMetricsServiceClient::CastMetricsServiceClient( + CastMetricsServiceDelegate* delegate, PrefService* pref_service, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) - : pref_service_(pref_service), + : delegate_(delegate), + pref_service_(pref_service), client_info_loaded_(false), #if defined(OS_LINUX) external_metrics_(nullptr), @@ -340,7 +340,7 @@ SetMetricsClientId(metrics_state_manager_->client_id()); CastStabilityMetricsProvider* stability_provider = - new CastStabilityMetricsProvider(metrics_service_.get()); + new CastStabilityMetricsProvider(metrics_service_.get(), pref_service_); metrics_service_->RegisterMetricsProvider( std::unique_ptr<::metrics::MetricsProvider>(stability_provider)); @@ -359,8 +359,8 @@ metrics_service_->RegisterMetricsProvider( std::make_unique<::metrics::NetworkMetricsProvider>( content::CreateNetworkConnectionTrackerAsyncGetter())); - shell::CastBrowserProcess::GetInstance()->browser_client()-> - RegisterMetricsProviders(metrics_service_.get()); + if (delegate_) + delegate_->RegisterMetricsProviders(metrics_service_.get()); metrics_service_->InitializeMetricsRecordingState(); #if !defined(OS_ANDROID)
diff --git a/chromecast/browser/metrics/cast_metrics_service_client.h b/chromecast/browser/metrics/cast_metrics_service_client.h index 1fe3c5ba..0f056d3a 100644 --- a/chromecast/browser/metrics/cast_metrics_service_client.h +++ b/chromecast/browser/metrics/cast_metrics_service_client.h
@@ -37,12 +37,24 @@ namespace chromecast { namespace metrics { +class CastMetricsServiceDelegate { + public: + // Invoked when the metrics client ID changes. + virtual void SetMetricsClientId(const std::string& client_id) = 0; + // Allows registration of extra metrics providers. + virtual void RegisterMetricsProviders(::metrics::MetricsService* service) = 0; + + protected: + virtual ~CastMetricsServiceDelegate() = default; +}; + class ExternalMetrics; class CastMetricsServiceClient : public ::metrics::MetricsServiceClient, public ::metrics::EnabledStateProvider { public: CastMetricsServiceClient( + CastMetricsServiceDelegate* delegate, PrefService* pref_service, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); ~CastMetricsServiceClient() override; @@ -93,6 +105,7 @@ std::unique_ptr<::metrics::ClientInfo> LoadClientInfo(); void StoreClientInfo(const ::metrics::ClientInfo& client_info); + CastMetricsServiceDelegate* const delegate_; PrefService* const pref_service_; std::string client_id_; std::string force_client_id_;
diff --git a/chromecast/browser/metrics/cast_stability_metrics_provider.cc b/chromecast/browser/metrics/cast_stability_metrics_provider.cc index cd252b03..e22c89f 100644 --- a/chromecast/browser/metrics/cast_stability_metrics_provider.cc +++ b/chromecast/browser/metrics/cast_stability_metrics_provider.cc
@@ -10,7 +10,6 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "chromecast/base/pref_names.h" -#include "chromecast/browser/cast_browser_process.h" #include "chromecast/browser/metrics/cast_metrics_service_client.h" #include "components/metrics/metrics_service.h" #include "components/prefs/pref_registry_simple.h" @@ -37,13 +36,6 @@ RENDERER_TYPE_COUNT }; -void IncrementPrefValue(const char* path) { - PrefService* pref = shell::CastBrowserProcess::GetInstance()->pref_service(); - DCHECK(pref); - int value = pref->GetInteger(path); - pref->SetInteger(path, value + 1); -} - // Converts an exit code into something that can be inserted into our // histograms (which expect non-negative numbers less than MAX_INT). int MapCrashExitCodeForHistogram(int exit_code) { @@ -61,8 +53,10 @@ } CastStabilityMetricsProvider::CastStabilityMetricsProvider( - ::metrics::MetricsService* metrics_service) - : metrics_service_(metrics_service) { + ::metrics::MetricsService* metrics_service, + PrefService* pref_service) + : metrics_service_(metrics_service), pref_service_(pref_service) { + DCHECK(pref_service_); BrowserChildProcessObserver::Add(this); } @@ -85,32 +79,32 @@ void CastStabilityMetricsProvider::ProvideStabilityMetrics( ::metrics::SystemProfileProto* system_profile_proto) { - PrefService* pref = shell::CastBrowserProcess::GetInstance()->pref_service(); ::metrics::SystemProfileProto_Stability* stability_proto = system_profile_proto->mutable_stability(); - int count = pref->GetInteger(prefs::kStabilityChildProcessCrashCount); + int count = + pref_service_->GetInteger(prefs::kStabilityChildProcessCrashCount); if (count) { stability_proto->set_child_process_crash_count(count); - pref->SetInteger(prefs::kStabilityChildProcessCrashCount, 0); + pref_service_->SetInteger(prefs::kStabilityChildProcessCrashCount, 0); } - count = pref->GetInteger(prefs::kStabilityRendererCrashCount); + count = pref_service_->GetInteger(prefs::kStabilityRendererCrashCount); if (count) { stability_proto->set_renderer_crash_count(count); - pref->SetInteger(prefs::kStabilityRendererCrashCount, 0); + pref_service_->SetInteger(prefs::kStabilityRendererCrashCount, 0); } - count = pref->GetInteger(prefs::kStabilityRendererFailedLaunchCount); + count = pref_service_->GetInteger(prefs::kStabilityRendererFailedLaunchCount); if (count) { stability_proto->set_renderer_failed_launch_count(count); - pref->SetInteger(prefs::kStabilityRendererFailedLaunchCount, 0); + pref_service_->SetInteger(prefs::kStabilityRendererFailedLaunchCount, 0); } - count = pref->GetInteger(prefs::kStabilityRendererHangCount); + count = pref_service_->GetInteger(prefs::kStabilityRendererHangCount); if (count) { stability_proto->set_renderer_hang_count(count); - pref->SetInteger(prefs::kStabilityRendererHangCount, 0); + pref_service_->SetInteger(prefs::kStabilityRendererHangCount, 0); } } @@ -188,5 +182,10 @@ IncrementPrefValue(prefs::kStabilityRendererHangCount); } +void CastStabilityMetricsProvider::IncrementPrefValue(const char* path) { + int value = pref_service_->GetInteger(path); + pref_service_->SetInteger(path, value + 1); +} + } // namespace metrics } // namespace chromecast
diff --git a/chromecast/browser/metrics/cast_stability_metrics_provider.h b/chromecast/browser/metrics/cast_stability_metrics_provider.h index c4b2dee..966d647 100644 --- a/chromecast/browser/metrics/cast_stability_metrics_provider.h +++ b/chromecast/browser/metrics/cast_stability_metrics_provider.h
@@ -13,6 +13,7 @@ #include "content/public/browser/notification_registrar.h" class PrefRegistrySimple; +class PrefService; namespace content { class RenderProcessHost; @@ -35,8 +36,8 @@ // Registers local state prefs used by this class. static void RegisterPrefs(PrefRegistrySimple* registry); - explicit CastStabilityMetricsProvider( - ::metrics::MetricsService* metrics_service); + CastStabilityMetricsProvider(::metrics::MetricsService* metrics_service, + PrefService* pref_service); ~CastStabilityMetricsProvider() override; // metrics::MetricsDataProvider implementation: @@ -67,6 +68,9 @@ // Records a renderer process hang. void LogRendererHang(); + // Increments the specified pref by 1. + void IncrementPrefValue(const char* path); + // Registrar for receiving stability-related notifications. content::NotificationRegistrar registrar_; @@ -75,6 +79,8 @@ // CastStabilityMetricsProvider. ::metrics::MetricsService* metrics_service_; + PrefService* const pref_service_; + DISALLOW_COPY_AND_ASSIGN(CastStabilityMetricsProvider); };
diff --git a/chromecast/media/cma/backend/android/BUILD.gn b/chromecast/media/cma/backend/android/BUILD.gn index 96e8ead..b05a52da 100644 --- a/chromecast/media/cma/backend/android/BUILD.gn +++ b/chromecast/media/cma/backend/android/BUILD.gn
@@ -73,8 +73,8 @@ "//base:base_java", "//chromecast/base:base_java", "//chromecast/public:volume_control_enums_java", - "//third_party/android_deps:android_support_annotations_java", - "//third_party/android_deps:android_support_v13_java", + "//third_party/android_deps:com_android_support_support_annotations_java", + "//third_party/android_deps:com_android_support_support_v13_java", ] }
diff --git a/chromecast/public/BUILD.gn b/chromecast/public/BUILD.gn index 99730d0..d14f84d3 100644 --- a/chromecast/public/BUILD.gn +++ b/chromecast/public/BUILD.gn
@@ -50,7 +50,7 @@ android_library("volume_control_enums_java") { srcjar_deps = [ ":java_enums_volume_control" ] deps = [ - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] } }
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index b6ada5b5..2c0bbb31 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -11919.0.0 \ No newline at end of file +11921.0.0 \ No newline at end of file
diff --git a/chromeos/components/account_manager/BUILD.gn b/chromeos/components/account_manager/BUILD.gn index 8118946..04bdc5e 100644 --- a/chromeos/components/account_manager/BUILD.gn +++ b/chromeos/components/account_manager/BUILD.gn
@@ -20,6 +20,8 @@ deps = [ "//base", + "//chromeos/constants", + "//components/prefs:prefs", "//google_apis", "//net", "//services/network/public/cpp:cpp",
diff --git a/chromeos/components/account_manager/account_manager.cc b/chromeos/components/account_manager/account_manager.cc index 65e01726..4c01feb6 100644 --- a/chromeos/components/account_manager/account_manager.cc +++ b/chromeos/components/account_manager/account_manager.cc
@@ -17,6 +17,8 @@ #include "base/task/post_task.h" #include "base/task_runner_util.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "chromeos/constants/chromeos_pref_names.h" +#include "components/prefs/pref_registry_simple.h" #include "google_apis/gaia/gaia_auth_consumer.h" #include "google_apis/gaia/gaia_auth_fetcher.h" #include "google_apis/gaia/oauth2_access_token_fetcher_impl.h" @@ -127,6 +129,13 @@ AccountManager::AccountManager() : weak_factory_(this) {} +// static +void AccountManager::RegisterPrefs(PrefRegistrySimple* registry) { + registry->RegisterBooleanPref( + chromeos::prefs::kSecondaryGoogleAccountSigninAllowed, + true /* default_value */); +} + void AccountManager::Initialize( const base::FilePath& home_dir, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
diff --git a/chromeos/components/account_manager/account_manager.h b/chromeos/components/account_manager/account_manager.h index 1d29aaf..b0e106fd 100644 --- a/chromeos/components/account_manager/account_manager.h +++ b/chromeos/components/account_manager/account_manager.h
@@ -24,6 +24,7 @@ class OAuth2AccessTokenFetcher; class OAuth2AccessTokenConsumer; +class PrefRegistrySimple; namespace base { class SequencedTaskRunner; @@ -117,6 +118,8 @@ AccountManager(); virtual ~AccountManager(); + static void RegisterPrefs(PrefRegistrySimple* registry); + // |home_dir| is the path of the Device Account's home directory (root of the // user's cryptohome). // |request_context| is a non-owning pointer.
diff --git a/chromeos/constants/chromeos_pref_names.cc b/chromeos/constants/chromeos_pref_names.cc index 2ca159d9..dc0ff875 100644 --- a/chromeos/constants/chromeos_pref_names.cc +++ b/chromeos/constants/chromeos_pref_names.cc
@@ -46,5 +46,11 @@ const char kDeviceWiFiFastTransitionEnabled[] = "net.device_wifi_fast_transition_enabled"; +// A boolean pref to store if Secondary Google Account additions are allowed on +// Chrome OS Account Manager. The default value is |true|, i.e. Secondary Google +// Account additions are allowed by default. +const char kSecondaryGoogleAccountSigninAllowed[] = + "account_manager.secondary_google_account_signin_allowed"; + } // namespace prefs } // namespace chromeos
diff --git a/chromeos/constants/chromeos_pref_names.h b/chromeos/constants/chromeos_pref_names.h index 181ea3f..717a6cf 100644 --- a/chromeos/constants/chromeos_pref_names.h +++ b/chromeos/constants/chromeos_pref_names.h
@@ -21,6 +21,8 @@ extern const char kQuirksClientLastServerCheck[]; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const char kDeviceWiFiFastTransitionEnabled[]; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) +extern const char kSecondaryGoogleAccountSigninAllowed[]; } // namespace prefs } // namespace chromeos
diff --git a/chromeos/dbus/BUILD.gn b/chromeos/dbus/BUILD.gn index a09cbad..4ab6f83 100644 --- a/chromeos/dbus/BUILD.gn +++ b/chromeos/dbus/BUILD.gn
@@ -161,8 +161,6 @@ "fake_sms_client.h", "fake_update_engine_client.cc", "fake_update_engine_client.h", - "fake_upstart_client.cc", - "fake_upstart_client.h", "fake_virtual_file_provider_client.cc", "fake_virtual_file_provider_client.h", "gsm_sms_client.cc", @@ -221,8 +219,10 @@ "sms_client.h", "update_engine_client.cc", "update_engine_client.h", - "upstart_client.cc", - "upstart_client.h", + "upstart/fake_upstart_client.cc", + "upstart/fake_upstart_client.h", + "upstart/upstart_client.cc", + "upstart/upstart_client.h", "util/account_identifier_operators.cc", "util/account_identifier_operators.h", "util/tpm_util.cc",
diff --git a/chromeos/dbus/dbus_clients_common.cc b/chromeos/dbus/dbus_clients_common.cc index 8dca1ee..21907d53 100644 --- a/chromeos/dbus/dbus_clients_common.cc +++ b/chromeos/dbus/dbus_clients_common.cc
@@ -24,7 +24,6 @@ #include "chromeos/dbus/fake_shill_service_client.h" #include "chromeos/dbus/fake_shill_third_party_vpn_driver_client.h" #include "chromeos/dbus/fake_sms_client.h" -#include "chromeos/dbus/fake_upstart_client.h" #include "chromeos/dbus/gsm_sms_client.h" #include "chromeos/dbus/machine_learning_client.h" #include "chromeos/dbus/modem_messaging_client.h" @@ -38,7 +37,6 @@ #include "chromeos/dbus/shill_third_party_vpn_driver_client.h" #include "chromeos/dbus/sms_client.h" #include "chromeos/dbus/update_engine_client.h" -#include "chromeos/dbus/upstart_client.h" namespace chromeos { @@ -109,11 +107,6 @@ sms_client_.reset(new FakeSMSClient); update_engine_client_.reset(UpdateEngineClient::Create(client_impl_type)); - - if (use_real_clients) - upstart_client_.reset(UpstartClient::Create()); - else - upstart_client_.reset(new FakeUpstartClient); } DBusClientsCommon::~DBusClientsCommon() = default; @@ -138,7 +131,6 @@ shill_third_party_vpn_driver_client_->Init(system_bus); sms_client_->Init(system_bus); update_engine_client_->Init(system_bus); - upstart_client_->Init(system_bus); ShillManagerClient::TestInterface* manager = shill_manager_client_->GetTestInterface();
diff --git a/chromeos/dbus/dbus_clients_common.h b/chromeos/dbus/dbus_clients_common.h index 4f313593..69c9f0740 100644 --- a/chromeos/dbus/dbus_clients_common.h +++ b/chromeos/dbus/dbus_clients_common.h
@@ -33,7 +33,6 @@ class ShillThirdPartyVpnDriverClient; class SMSClient; class UpdateEngineClient; -class UpstartClient; // D-Bus clients used in multiple processes (e.g. ash, browser, mus). class COMPONENT_EXPORT(CHROMEOS_DBUS) DBusClientsCommon { @@ -68,7 +67,6 @@ std::unique_ptr<SMSClient> sms_client_; std::unique_ptr<SessionManagerClient> session_manager_client_; std::unique_ptr<UpdateEngineClient> update_engine_client_; - std::unique_ptr<UpstartClient> upstart_client_; DISALLOW_COPY_AND_ASSIGN(DBusClientsCommon); };
diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc index e47f197..990caad 100644 --- a/chromeos/dbus/dbus_thread_manager.cc +++ b/chromeos/dbus/dbus_thread_manager.cc
@@ -48,7 +48,6 @@ #include "chromeos/dbus/smb_provider_client.h" #include "chromeos/dbus/sms_client.h" #include "chromeos/dbus/update_engine_client.h" -#include "chromeos/dbus/upstart_client.h" #include "dbus/bus.h" #include "dbus/dbus_statistics.h" @@ -276,10 +275,6 @@ return clients_common_->update_engine_client_.get(); } -UpstartClient* DBusThreadManager::GetUpstartClient() { - return clients_common_ ? clients_common_->upstart_client_.get() : nullptr; -} - VirtualFileProviderClient* DBusThreadManager::GetVirtualFileProviderClient() { return clients_browser_ ? clients_browser_->virtual_file_provider_client_.get() @@ -505,10 +500,4 @@ std::move(client); } -void DBusThreadManagerSetter::SetUpstartClient( - std::unique_ptr<UpstartClient> client) { - DBusThreadManager::Get()->clients_common_->upstart_client_ = - std::move(client); -} - } // namespace chromeos
diff --git a/chromeos/dbus/dbus_thread_manager.h b/chromeos/dbus/dbus_thread_manager.h index 3dbbbdb1..25de2103 100644 --- a/chromeos/dbus/dbus_thread_manager.h +++ b/chromeos/dbus/dbus_thread_manager.h
@@ -63,7 +63,6 @@ class SmbProviderClient; class SMSClient; class UpdateEngineClient; -class UpstartClient; class VirtualFileProviderClient; // DBusThreadManager manages the D-Bus thread, the thread dedicated to @@ -169,7 +168,6 @@ SmbProviderClient* GetSmbProviderClient(); SMSClient* GetSMSClient(); UpdateEngineClient* GetUpdateEngineClient(); - UpstartClient* GetUpstartClient(); VirtualFileProviderClient* GetVirtualFileProviderClient(); private: @@ -229,7 +227,6 @@ std::unique_ptr<ShillThirdPartyVpnDriverClient> client); void SetSmbProviderClient(std::unique_ptr<SmbProviderClient> client); void SetUpdateEngineClient(std::unique_ptr<UpdateEngineClient> client); - void SetUpstartClient(std::unique_ptr<UpstartClient> client); private: friend class DBusThreadManager;
diff --git a/chromeos/dbus/fake_upstart_client.cc b/chromeos/dbus/upstart/fake_upstart_client.cc similarity index 87% rename from chromeos/dbus/fake_upstart_client.cc rename to chromeos/dbus/upstart/fake_upstart_client.cc index 056a9bb..43bebce 100644 --- a/chromeos/dbus/fake_upstart_client.cc +++ b/chromeos/dbus/upstart/fake_upstart_client.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/dbus/fake_upstart_client.h" +#include "chromeos/dbus/upstart/fake_upstart_client.h" #include "base/bind.h" #include "base/threading/thread_task_runner_handle.h" @@ -12,11 +12,25 @@ namespace chromeos { -FakeUpstartClient::FakeUpstartClient() = default; +namespace { +// Used to track the fake instance, mirrors the instance in the base class. +FakeUpstartClient* g_instance = nullptr; +} // namespace -FakeUpstartClient::~FakeUpstartClient() = default; +FakeUpstartClient::FakeUpstartClient() { + DCHECK(!g_instance); + g_instance = this; +} -void FakeUpstartClient::Init(dbus::Bus* bus) {} +FakeUpstartClient::~FakeUpstartClient() { + DCHECK_EQ(this, g_instance); + g_instance = nullptr; +} + +// static +FakeUpstartClient* FakeUpstartClient::Get() { + return g_instance; +} void FakeUpstartClient::StartJob(const std::string& job, const std::vector<std::string>& upstart_env,
diff --git a/chromeos/dbus/fake_upstart_client.h b/chromeos/dbus/upstart/fake_upstart_client.h similarity index 78% rename from chromeos/dbus/fake_upstart_client.h rename to chromeos/dbus/upstart/fake_upstart_client.h index 0c4bfb8..6501997 100644 --- a/chromeos/dbus/fake_upstart_client.h +++ b/chromeos/dbus/upstart/fake_upstart_client.h
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_DBUS_FAKE_UPSTART_CLIENT_H_ -#define CHROMEOS_DBUS_FAKE_UPSTART_CLIENT_H_ +#ifndef CHROMEOS_DBUS_UPSTART_FAKE_UPSTART_CLIENT_H_ +#define CHROMEOS_DBUS_UPSTART_FAKE_UPSTART_CLIENT_H_ #include "base/macros.h" -#include "chromeos/dbus/upstart_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" namespace chromeos { @@ -16,8 +16,8 @@ FakeUpstartClient(); ~FakeUpstartClient() override; - // DBusClient overrides. - void Init(dbus::Bus* bus) override; + // Returns the fake global instance if initialized. May return null. + static FakeUpstartClient* Get(); // UpstartClient overrides: void StartJob(const std::string& job, @@ -39,4 +39,4 @@ } // namespace chromeos -#endif // CHROMEOS_DBUS_FAKE_UPSTART_CLIENT_H_ +#endif // CHROMEOS_DBUS_UPSTART_FAKE_UPSTART_CLIENT_H_
diff --git a/chromeos/dbus/upstart_client.cc b/chromeos/dbus/upstart/upstart_client.cc similarity index 79% rename from chromeos/dbus/upstart_client.cc rename to chromeos/dbus/upstart/upstart_client.cc index 31de8f6d..b7de8ab 100644 --- a/chromeos/dbus/upstart_client.cc +++ b/chromeos/dbus/upstart/upstart_client.cc
@@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/dbus/upstart_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" #include "base/bind.h" #include "base/memory/weak_ptr.h" +#include "chromeos/dbus/upstart/fake_upstart_client.h" #include "dbus/bus.h" #include "dbus/message.h" #include "dbus/object_proxy.h" @@ -24,9 +25,12 @@ constexpr char kAuthPolicyJob[] = "authpolicyd"; constexpr char kMediaAnalyticsJob[] = "rtanalytics"; +UpstartClient* g_instance = nullptr; + class UpstartClientImpl : public UpstartClient { public: - UpstartClientImpl() : weak_ptr_factory_(this) {} + explicit UpstartClientImpl(dbus::Bus* bus) + : bus_(bus), weak_ptr_factory_(this) {} ~UpstartClientImpl() override = default; @@ -67,10 +71,6 @@ void StopMediaAnalytics(VoidDBusMethodCallback callback) override { StopJob(kMediaAnalyticsJob, std::move(callback)); } - protected: - void Init(dbus::Bus* bus) override { - bus_ = bus; - } private: void CallJobMethod(const std::string& job, @@ -104,13 +104,39 @@ } // namespace -UpstartClient::UpstartClient() = default; +UpstartClient::UpstartClient() { + DCHECK(!g_instance); + g_instance = this; +} -UpstartClient::~UpstartClient() = default; +UpstartClient::~UpstartClient() { + DCHECK_EQ(this, g_instance); + g_instance = nullptr; +} // static -UpstartClient* UpstartClient::Create() { - return new UpstartClientImpl(); +void UpstartClient::Initialize(dbus::Bus* bus) { + DCHECK(bus); + new UpstartClientImpl(bus); +} + +// static +void UpstartClient::InitializeFake() { + // Do not create a new fake if it was initialized early in a browser test (to + // allow test properties to be set). + if (!FakeUpstartClient::Get()) + new FakeUpstartClient(); +} + +// static +void UpstartClient::Shutdown() { + DCHECK(g_instance); + delete g_instance; +} + +// static +UpstartClient* UpstartClient::Get() { + return g_instance; } } // namespace chromeos
diff --git a/chromeos/dbus/upstart_client.h b/chromeos/dbus/upstart/upstart_client.h similarity index 74% rename from chromeos/dbus/upstart_client.h rename to chromeos/dbus/upstart/upstart_client.h index 8449b235..48eb2cd 100644 --- a/chromeos/dbus/upstart_client.h +++ b/chromeos/dbus/upstart/upstart_client.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROMEOS_DBUS_UPSTART_CLIENT_H_ -#define CHROMEOS_DBUS_UPSTART_CLIENT_H_ +#ifndef CHROMEOS_DBUS_UPSTART_UPSTART_CLIENT_H_ +#define CHROMEOS_DBUS_UPSTART_UPSTART_CLIENT_H_ #include <string> #include <vector> @@ -11,21 +11,32 @@ #include "base/callback.h" #include "base/component_export.h" #include "base/macros.h" -#include "chromeos/dbus/dbus_client.h" #include "chromeos/dbus/dbus_method_call_status.h" +namespace dbus { +class Bus; +} + namespace chromeos { // UpstartClient is used to communicate with the com.ubuntu.Upstart // sevice. All methods should be called from the origin thread (UI thread) which // initializes the DBusThreadManager instance. -class COMPONENT_EXPORT(CHROMEOS_DBUS) UpstartClient : public DBusClient { +class COMPONENT_EXPORT(CHROMEOS_DBUS) UpstartClient { public: - ~UpstartClient() override; + virtual ~UpstartClient(); - // Factory function, creates a new instance and returns ownership. - // For normal usage, access the singleton via DBusThreadManager::Get(). - static UpstartClient* Create(); + // Creates and initializes the global instance. |bus| must not be null. + static void Initialize(dbus::Bus* bus); + + // Creates and initializes a fake global instance if not already created. + static void InitializeFake(); + + // Destroys the global instance which must have been initialized. + static void Shutdown(); + + // Returns the global instance if initialized. May return null. + static UpstartClient* Get(); // Starts an Upstart job. // |job|: Name of Upstart job. @@ -62,8 +73,9 @@ // Provides an interface for stopping the media analytics process. virtual void StopMediaAnalytics(VoidDBusMethodCallback callback) = 0; + protected: - // Create() should be used instead. + // Initialize() should be used instead. UpstartClient(); private: @@ -72,4 +84,4 @@ } // namespace chromeos -#endif // CHROMEOS_DBUS_UPSTART_CLIENT_H_ +#endif // CHROMEOS_DBUS_UPSTART_UPSTART_CLIENT_H_
diff --git a/chromeos/login/auth/authpolicy_login_helper.cc b/chromeos/login/auth/authpolicy_login_helper.cc index cd96f3c..f577b6e 100644 --- a/chromeos/login/auth/authpolicy_login_helper.cc +++ b/chromeos/login/auth/authpolicy_login_helper.cc
@@ -12,7 +12,7 @@ #include "base/task/post_task.h" #include "chromeos/dbus/auth_policy_client.h" #include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/upstart_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" #include "chromeos/dbus/util/tpm_util.h" #include "crypto/encryptor.h" #include "crypto/hmac.h" @@ -153,9 +153,7 @@ // static void AuthPolicyLoginHelper::Restart() { - chromeos::DBusThreadManager::Get() - ->GetUpstartClient() - ->RestartAuthPolicyService(); + chromeos::UpstartClient::Get()->RestartAuthPolicyService(); } // static
diff --git a/components/arc/arc_data_remover.cc b/components/arc/arc_data_remover.cc index 8f80aa8..99a2e62 100644 --- a/components/arc/arc_data_remover.cc +++ b/components/arc/arc_data_remover.cc
@@ -9,8 +9,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/logging.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/upstart_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" #include "components/arc/arc_prefs.h" namespace arc { @@ -46,8 +45,12 @@ } VLOG(1) << "Starting ARC data removal"; - auto* upstart_client = chromeos::DBusThreadManager::Get()->GetUpstartClient(); - DCHECK(upstart_client); + auto* upstart_client = chromeos::UpstartClient::Get(); + if (!upstart_client) { + // May be null in tests + std::move(callback).Run(base::nullopt); + return; + } const std::string account_id = cryptohome::CreateAccountIdentifierFromIdentification(cryptohome_id_) .account_id();
diff --git a/components/arc/arc_data_remover_unittest.cc b/components/arc/arc_data_remover_unittest.cc index 13873a5..4e825f58 100644 --- a/components/arc/arc_data_remover_unittest.cc +++ b/components/arc/arc_data_remover_unittest.cc
@@ -12,7 +12,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "chromeos/cryptohome/cryptohome_parameters.h" #include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/fake_upstart_client.h" +#include "chromeos/dbus/upstart/fake_upstart_client.h" #include "components/account_id/account_id.h" #include "components/arc/arc_prefs.h" #include "components/prefs/testing_pref_service.h" @@ -46,14 +46,15 @@ ArcDataRemoverTest() = default; void SetUp() override { - chromeos::DBusThreadManager::GetSetterForTesting()->SetUpstartClient( - std::make_unique<TestUpstartClient>()); chromeos::DBusThreadManager::Initialize(); - + test_upstart_client_ = std::make_unique<TestUpstartClient>(); prefs::RegisterProfilePrefs(prefs_.registry()); } - void TearDown() override { chromeos::DBusThreadManager::Shutdown(); } + void TearDown() override { + test_upstart_client_.reset(); + chromeos::DBusThreadManager::Shutdown(); + } PrefService* prefs() { return &prefs_; } @@ -62,15 +63,14 @@ } TestUpstartClient* upstart_client() { - return static_cast<TestUpstartClient*>( - chromeos::DBusThreadManager::Get()->GetUpstartClient()); + return static_cast<TestUpstartClient*>(chromeos::UpstartClient::Get()); } private: TestingPrefServiceSimple prefs_; const cryptohome::Identification cryptohome_id_{EmptyAccountId()}; - base::test::ScopedTaskEnvironment scoped_task_environment_; + std::unique_ptr<TestUpstartClient> test_upstart_client_; DISALLOW_COPY_AND_ASSIGN(ArcDataRemoverTest); };
diff --git a/components/arc/arc_vm_client_adapter.cc b/components/arc/arc_vm_client_adapter.cc index 5aaec266..fc795c59 100644 --- a/components/arc/arc_vm_client_adapter.cc +++ b/components/arc/arc_vm_client_adapter.cc
@@ -13,9 +13,8 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/task/post_task.h" -#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/session_manager_client.h" -#include "chromeos/dbus/upstart_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" namespace arc { @@ -54,8 +53,7 @@ // TODO(yusukes): Consider doing the same as crostini rather than taking to // Upstart. VLOG(1) << "Starting arcvm"; - auto* upstart_client = - chromeos::DBusThreadManager::Get()->GetUpstartClient(); + auto* upstart_client = chromeos::UpstartClient::Get(); DCHECK(upstart_client); upstart_client->StartJob( kArcVmUpstartJob, @@ -72,8 +70,7 @@ // TODO(yusukes): Consider doing the same as crostini rather than taking to // Upstart. VLOG(1) << "Stopping arcvm"; - auto* upstart_client = - chromeos::DBusThreadManager::Get()->GetUpstartClient(); + auto* upstart_client = chromeos::UpstartClient::Get(); DCHECK(upstart_client); upstart_client->StopJob( kArcVmUpstartJob,
diff --git a/components/autofill/android/BUILD.gn b/components/autofill/android/BUILD.gn index bd2ac36..9540e8a 100644 --- a/components/autofill/android/BUILD.gn +++ b/components/autofill/android/BUILD.gn
@@ -107,7 +107,7 @@ deps = [ "//base:base_java", "//content/public/android:content_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] java_files = [ "java/src/org/chromium/components/autofill/AutofillProvider.java",
diff --git a/components/autofill/core/browser/payments/payments_client.cc b/components/autofill/core/browser/payments/payments_client.cc index 2a1c5eaf..eb228c3 100644 --- a/components/autofill/core/browser/payments/payments_client.cc +++ b/components/autofill/core/browser/payments/payments_client.cc
@@ -91,32 +91,6 @@ return GetBaseSecureUrl().Resolve(path); } -// Tries to get the string |out_value| from the |dictionary| with the given -// |key|. -// Returns true if the string value was found, false otherwise. -bool TryGetString(std::string key, - base::Value& dictionary, - std::string* out_value) { - base::Value* str_ptr = dictionary.FindKey(key); - if (str_ptr) { - *out_value = str_ptr->GetString(); - } - return str_ptr; -} - -// Tries to get the string |out_value| from the |dictionary| with the given -// |path|. -// Returns true if the string value was found, false otherwise. -bool TryGetStringByPath(std::initializer_list<base::StringPiece> path, - base::Value& dictionary, - std::string* out_value) { - base::Value* str_ptr = dictionary.FindPath(path); - if (str_ptr) { - *out_value = str_ptr->GetString(); - } - return str_ptr; -} - base::Value BuildCustomerContextDictionary(int64_t external_customer_id) { base::Value customer_context(base::Value::Type::DICTIONARY); customer_context.SetKey("external_customer_id", @@ -314,8 +288,9 @@ return request_content; } - void ParseResponse(base::Value response) override { - TryGetString("pan", response, &real_pan_); + void ParseResponse(const base::Value& response) override { + const auto* pan = response.FindStringKey("pan"); + real_pan_ = pan ? *pan : std::string(); } bool IsResponseComplete() override { return !real_pan_.empty(); } @@ -331,6 +306,8 @@ const std::string&)> callback_; std::string real_pan_; + + DISALLOW_COPY_AND_ASSIGN(UnmaskCardRequest); }; class GetUploadDetailsRequest : public PaymentsRequest { @@ -434,22 +411,23 @@ return request_content; } - void ParseResponse(base::Value response) override { - std::string context_token_utf8; - if (TryGetString("context_token", response, &context_token_utf8)) { - context_token_ = base::UTF8ToUTF16(context_token_utf8); - } + void ParseResponse(const base::Value& response) override { + const auto* context_token = response.FindStringKey("context_token"); + context_token_ = + context_token ? base::UTF8ToUTF16(*context_token) : base::string16(); - base::Value* dictionary_value = response.FindKey("legal_message"); + const base::Value* dictionary_value = + response.FindKeyOfType("legal_message", base::Value::Type::DICTIONARY); if (dictionary_value) legal_message_ = std::make_unique<base::Value>(dictionary_value->Clone()); - base::Value* list_ptr = response.FindKey("supported_card_bin_ranges"); - if (list_ptr && list_ptr->is_list()) { - for (base::Value& result : list_ptr->GetList()) { + const base::Value* list_ptr = response.FindKeyOfType( + "supported_card_bin_ranges", base::Value::Type::LIST); + if (list_ptr) { + for (const base::Value& result : list_ptr->GetList()) { DCHECK(result.is_dict()); - base::Optional<int> start = response.FindIntKey("start"); - base::Optional<int> end = response.FindIntKey("end"); + base::Optional<int> start = result.FindIntKey("start"); + base::Optional<int> end = result.FindIntKey("end"); supported_card_bin_ranges_.push_back(std::make_pair(*start, *end)); } } @@ -480,6 +458,8 @@ std::vector<std::pair<int, int>> supported_card_bin_ranges_; const int billable_service_number_; PaymentsClient::UploadCardSource upload_card_source_; + + DISALLOW_COPY_AND_ASSIGN(GetUploadDetailsRequest); }; class UploadCardRequest : public PaymentsRequest { @@ -575,8 +555,10 @@ return request_content; } - void ParseResponse(base::Value response) override { - TryGetString("credit_card_id", response, &server_id_); + void ParseResponse(const base::Value& response) override { + const std::string* credit_card_id = + response.FindStringKey("credit_card_id"); + server_id_ = credit_card_id ? *credit_card_id : std::string(); } bool IsResponseComplete() override { return true; } @@ -592,6 +574,8 @@ const std::string&)> callback_; std::string server_id_; + + DISALLOW_COPY_AND_ASSIGN(UploadCardRequest); }; class MigrateCardsRequest : public PaymentsRequest { @@ -666,26 +650,27 @@ return request_content; } - void ParseResponse(base::Value response) override { - base::Value* list_ptr = response.FindKey("save_result"); - if (!list_ptr || !list_ptr->is_list()) + void ParseResponse(const base::Value& response) override { + const auto* found_list = + response.FindKeyOfType("save_result", base::Value::Type::LIST); + if (!found_list) return; + save_result_ = std::make_unique<std::unordered_map<std::string, std::string>>(); - - for (base::Value& result : list_ptr->GetList()) { + for (const base::Value& result : found_list->GetList()) { if (result.is_dict()) { - std::string unique_id; - TryGetString("unique_id", result, &unique_id); - - std::string save_result; - TryGetString("status", result, &save_result); - - save_result_->insert(std::make_pair(unique_id, save_result)); + const std::string* unique_id = result.FindStringKey("unique_id"); + const std::string* status = result.FindStringKey("status"); + save_result_->insert( + std::make_pair(unique_id ? *unique_id : std::string(), + status ? *status : std::string())); } } - TryGetString("value_prop_display_text", response, &display_text_); + const std::string* display_text = + response.FindStringKey("value_prop_display_text"); + display_text_ = display_text ? *display_text : std::string(); } bool IsResponseComplete() override { @@ -720,6 +705,8 @@ MigrateCardsCallback callback_; std::unique_ptr<std::unordered_map<std::string, std::string>> save_result_; std::string display_text_; + + DISALLOW_COPY_AND_ASSIGN(MigrateCardsRequest); }; } // namespace @@ -895,8 +882,11 @@ std::string error_code; base::Optional<base::Value> message_value = base::JSONReader::Read(data); if (message_value && message_value->is_dict()) { - TryGetStringByPath({"error", "code"}, *message_value, &error_code); - request_->ParseResponse(*std::move(message_value)); + const auto* found = message_value->FindPathOfType( + {"error", "code"}, base::Value::Type::STRING); + if (found) + error_code = found->GetString(); + request_->ParseResponse(*message_value); } if (base::LowerCaseEqualsASCII(error_code, "internal"))
diff --git a/components/autofill/core/browser/payments/payments_request.h b/components/autofill/core/browser/payments/payments_request.h index e71d554..61916ad8 100644 --- a/components/autofill/core/browser/payments/payments_request.h +++ b/components/autofill/core/browser/payments/payments_request.h
@@ -28,7 +28,7 @@ virtual std::string GetRequestContent() = 0; // Parses the required elements of the HTTP response. - virtual void ParseResponse(base::Value response) = 0; + virtual void ParseResponse(const base::Value& response) = 0; // Returns true if all of the required elements were successfully retrieved by // a call to ParseResponse.
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc index 55d0a8a..ef98a6c 100644 --- a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc +++ b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc
@@ -11,6 +11,7 @@ #include "base/base64.h" #include "base/logging.h" +#include "base/metrics/histogram_macros.h" #include "base/optional.h" #include "base/pickle.h" #include "components/autofill/core/browser/autofill_metadata.h" @@ -20,6 +21,7 @@ #include "components/autofill/core/browser/webdata/autofill_table.h" #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" +#include "components/autofill/core/common/autofill_clock.h" #include "components/autofill/core/common/autofill_util.h" #include "components/sync/model/entity_data.h" #include "components/sync/model/mutable_data_batch.h" @@ -445,10 +447,22 @@ for (const auto& it : addresses_metadata) { cache_[GetStorageKeyForWalletMetadataTypeAndId( WalletMetadataSpecifics::ADDRESS, it.first)] = it.second; + UMA_HISTOGRAM_CUSTOM_TIMES( + "Autofill.WalletUseDate.Address", + /*sample=*/AutofillClock::Now() - it.second.use_date, + /*min=*/base::TimeDelta::FromMilliseconds(1), + /*max=*/base::TimeDelta::FromDays(365), + /*bucket_count=*/50); } for (const auto& it : cards_metadata) { cache_[GetStorageKeyForWalletMetadataTypeAndId( WalletMetadataSpecifics::CARD, it.first)] = it.second; + UMA_HISTOGRAM_CUSTOM_TIMES( + "Autofill.WalletUseDate.Card", + /*sample=*/AutofillClock::Now() - it.second.use_date, + /*min=*/base::TimeDelta::FromMilliseconds(1), + /*max=*/base::TimeDelta::FromDays(365), + /*bucket_count=*/50); } // Load the metadata and send to the processor.
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc b/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc index 7b88c1b8..df3a251 100644 --- a/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc +++ b/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc
@@ -13,6 +13,7 @@ #include "base/location.h" #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "base/metrics/histogram_macros.h" #include "base/numerics/safe_conversions.h" #include "base/time/time.h" #include "components/autofill/core/browser/autofill_data_model.h" @@ -22,6 +23,7 @@ #include "components/autofill/core/browser/webdata/autofill_table.h" #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" +#include "components/autofill/core/common/autofill_clock.h" #include "components/autofill/core/common/autofill_util.h" #include "components/sync/model/sync_change.h" #include "components/sync/model/sync_change_processor.h" @@ -383,6 +385,33 @@ result = MergeData(initial_sync_data); } + // Record ages for individual metadata entities to UMA. + for (const syncer::SyncData& data : cache_) { + const sync_pb::WalletMetadataSpecifics& specifics = + data.GetSpecifics().wallet_metadata(); + base::Time use_date = base::Time::FromDeltaSinceWindowsEpoch( + base::TimeDelta::FromMicroseconds(specifics.use_date())); + switch (specifics.type()) { + case sync_pb::WalletMetadataSpecifics::ADDRESS: + UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.WalletUseDate.Address", + /*sample=*/AutofillClock::Now() - use_date, + /*min=*/base::TimeDelta::FromMilliseconds(1), + /*max=*/base::TimeDelta::FromDays(365), + /*bucket_count=*/50); + break; + case sync_pb::WalletMetadataSpecifics::CARD: + UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.WalletUseDate.Card", + /*sample=*/AutofillClock::Now() - use_date, + /*min=*/base::TimeDelta::FromMilliseconds(1), + /*max=*/base::TimeDelta::FromDays(365), + /*bucket_count=*/50); + break; + case sync_pb::WalletMetadataSpecifics::UNKNOWN: + NOTREACHED(); + break; + } + } + // Notify that sync has started. This callback does not currently take into // account whether we're actually tracking wallet data. if (web_data_backend_)
diff --git a/components/background_task_scheduler/BUILD.gn b/components/background_task_scheduler/BUILD.gn index dea0bb6c..e89bd9d4 100644 --- a/components/background_task_scheduler/BUILD.gn +++ b/components/background_task_scheduler/BUILD.gn
@@ -56,7 +56,7 @@ "$google_play_services_package:google_play_services_gcm_java", "$google_play_services_package:google_play_services_tasks_java", "//base:base_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] }
diff --git a/components/bookmarks/common/android/BUILD.gn b/components/bookmarks/common/android/BUILD.gn index b53aeb5..4ac9ad97 100644 --- a/components/bookmarks/common/android/BUILD.gn +++ b/components/bookmarks/common/android/BUILD.gn
@@ -19,7 +19,7 @@ android_library("bookmarks_java") { deps = [ "//base:base_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] srcjar_deps = [ ":bookmark_type_javagen" ] java_files = [ "java/src/org/chromium/components/bookmarks/BookmarkId.java" ]
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn index e21e8b98..fff8f1dc 100644 --- a/components/cronet/android/BUILD.gn +++ b/components/cronet/android/BUILD.gn
@@ -255,7 +255,7 @@ deps = [ ":api_version", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] } @@ -295,7 +295,7 @@ deps = [ ":cronet_api_java", ":impl_version", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] deps += cronet_impl_common_java_deps_to_package @@ -316,7 +316,7 @@ ":cronet_api_java", ":cronet_impl_common_base_java", "//net/android:net_thread_stats_uid_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/jsr-305:jsr_305_javalib", ] } @@ -373,7 +373,7 @@ deps = [ ":cronet_api_java", ":cronet_impl_common_base_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/jsr-305:jsr_305_javalib", ] deps += cronet_impl_native_java_deps_to_package
diff --git a/components/download/public/common/BUILD.gn b/components/download/public/common/BUILD.gn index 5963bee..26a6dd0 100644 --- a/components/download/public/common/BUILD.gn +++ b/components/download/public/common/BUILD.gn
@@ -97,7 +97,7 @@ deps = [ "//base:base_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] }
diff --git a/components/download/public/task/BUILD.gn b/components/download/public/task/BUILD.gn index 4a53aa09..f98a9b2 100644 --- a/components/download/public/task/BUILD.gn +++ b/components/download/public/task/BUILD.gn
@@ -30,7 +30,7 @@ deps = [ "//base:base_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] }
diff --git a/components/embedder_support/android/BUILD.gn b/components/embedder_support/android/BUILD.gn index 7eb08dc7..5d300e8 100644 --- a/components/embedder_support/android/BUILD.gn +++ b/components/embedder_support/android/BUILD.gn
@@ -149,7 +149,7 @@ ":web_contents_delegate_java_resources", "//base:base_java", "//content/public/android:content_java", - "//third_party/android_deps:android_support_compat_java", + "//third_party/android_deps:com_android_support_support_compat_java", "//ui/android:ui_java", ] java_files = [
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index 6d72d41..6b29b75 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -944,10 +944,11 @@ viz::SharedQuadState* quad_state = render_pass->CreateAndAppendSharedQuadState(); quad_state->SetAll( - quad_to_target_transform, quad_rect /* quad_layer_rect */, - quad_rect /* visible_quad_layer_rect */, gfx::Rect() /* clip_rect */, - false /* is_clipped */, are_contents_opaque, state_.alpha /* opacity */, - SkBlendMode::kSrcOver /* blend_mode */, 0 /* sorting_context_id */); + quad_to_target_transform, quad_rect /*quad_layer_rect=*/, + quad_rect /*visible_quad_layer_rect=*/, + gfx::RRectF() /*rounded_corner_bounds=*/, gfx::Rect() /*clip_rect=*/, + false /*is_clipped=*/, are_contents_opaque, state_.alpha /*opacity=*/, + SkBlendMode::kSrcOver /*blend_mode=*/, 0 /*sorting_context_id=*/); if (current_resource_.id) { gfx::RectF uv_crop(gfx::SizeF(1, 1));
diff --git a/components/feature_engagement/internal/BUILD.gn b/components/feature_engagement/internal/BUILD.gn index 9c056121..498369dd 100644 --- a/components/feature_engagement/internal/BUILD.gn +++ b/components/feature_engagement/internal/BUILD.gn
@@ -141,7 +141,7 @@ deps = [ "//base:base_java", "//components/feature_engagement/public:public_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] }
diff --git a/components/feature_engagement/public/BUILD.gn b/components/feature_engagement/public/BUILD.gn index 95861e7..d5d000c 100644 --- a/components/feature_engagement/public/BUILD.gn +++ b/components/feature_engagement/public/BUILD.gn
@@ -39,7 +39,7 @@ deps = [ "//base:base_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] srcjar_deps = [ ":public_java_enums_srcjar" ]
diff --git a/components/gwp_asan/client/guarded_page_allocator.cc b/components/gwp_asan/client/guarded_page_allocator.cc index dbbf43a..63e99f8 100644 --- a/components/gwp_asan/client/guarded_page_allocator.cc +++ b/components/gwp_asan/client/guarded_page_allocator.cc
@@ -5,7 +5,6 @@ #include "components/gwp_asan/client/guarded_page_allocator.h" #include <algorithm> -#include <iterator> #include <memory> #include "base/bits.h" @@ -97,8 +96,9 @@ CHECK(base::bits::IsPowerOfTwo(align)); AllocatorState::SlotIdx free_slot; - if (!ReserveSlot(&free_slot)) - return nullptr; // All slots are reserved. + AllocatorState::MetadataIdx free_metadata; + if (!ReserveSlotAndMetadata(&free_slot, &free_metadata)) + return nullptr; uintptr_t free_page = state_.SlotToAddr(free_slot); MarkPageReadWrite(reinterpret_cast<void*>(free_page)); @@ -114,7 +114,7 @@ void* alloc = reinterpret_cast<void*>(free_page + offset); // Initialize slot metadata. - RecordAllocationMetadata(free_slot, size, alloc); + RecordAllocationMetadata(free_metadata, size, alloc); return alloc; } @@ -124,16 +124,17 @@ const uintptr_t addr = reinterpret_cast<uintptr_t>(ptr); AllocatorState::SlotIdx slot = state_.AddrToSlot(state_.GetPageAddr(addr)); + AllocatorState::MetadataIdx metadata_idx = slot; // Check for a call to free() with an incorrect pointer (e.g. the pointer does // not match the allocated pointer.) - if (addr != metadata_[slot].alloc_ptr) { + if (addr != metadata_[metadata_idx].alloc_ptr) { state_.free_invalid_address = addr; __builtin_trap(); } // Check for double free. - if (metadata_[slot].deallocation_occurred.exchange(true)) { + if (metadata_[metadata_idx].deallocation_occurred.exchange(true)) { state_.double_free_address = addr; // TODO(https://crbug.com/925447): The other thread may not be done writing // a stack trace so we could spin here until it's read; however, it's also @@ -145,27 +146,29 @@ // Record deallocation stack trace/thread id before marking the page // inaccessible in case a use-after-free occurs immediately. - RecordDeallocationMetadata(slot); + RecordDeallocationMetadata(metadata_idx); MarkPageInaccessible(reinterpret_cast<void*>(state_.GetPageAddr(addr))); - FreeSlot(slot); + FreeSlotAndMetadata(slot, metadata_idx); } size_t GuardedPageAllocator::GetRequestedSize(const void* ptr) const { CHECK(PointerIsMine(ptr)); const uintptr_t addr = reinterpret_cast<uintptr_t>(ptr); AllocatorState::SlotIdx slot = state_.AddrToSlot(state_.GetPageAddr(addr)); - DCHECK_EQ(addr, metadata_[slot].alloc_ptr); - return metadata_[slot].alloc_size; + AllocatorState::MetadataIdx metadata_idx = slot; + DCHECK_EQ(addr, metadata_[metadata_idx].alloc_ptr); + return metadata_[metadata_idx].alloc_size; } size_t GuardedPageAllocator::RegionSize() const { return (2 * state_.total_pages + 1) * state_.page_size; } -bool GuardedPageAllocator::ReserveSlot(AllocatorState::SlotIdx* slot) { +bool GuardedPageAllocator::ReserveSlotAndMetadata( + AllocatorState::SlotIdx* slot, + AllocatorState::MetadataIdx* metadata_idx) { base::AutoLock lock(lock_); - if (num_alloced_pages_ == max_alloced_pages_) return false; num_alloced_pages_++; @@ -178,10 +181,15 @@ free_slots_[rand] = free_slots_[free_slots_end_]; DCHECK_EQ(free_slots_end_, state_.total_pages - num_alloced_pages_); + *metadata_idx = *slot; + return true; } -void GuardedPageAllocator::FreeSlot(AllocatorState::SlotIdx slot) { +void GuardedPageAllocator::FreeSlotAndMetadata( + AllocatorState::SlotIdx slot, + AllocatorState::MetadataIdx metadata_idx) { + (void)metadata_idx; DCHECK_LT(slot, state_.total_pages); base::AutoLock lock(lock_); @@ -196,39 +204,39 @@ } void GuardedPageAllocator::RecordAllocationMetadata( - AllocatorState::SlotIdx slot, + AllocatorState::MetadataIdx metadata_idx, size_t size, void* ptr) { - metadata_[slot].alloc_size = size; - metadata_[slot].alloc_ptr = reinterpret_cast<uintptr_t>(ptr); + metadata_[metadata_idx].alloc_size = size; + metadata_[metadata_idx].alloc_ptr = reinterpret_cast<uintptr_t>(ptr); void* trace[AllocatorState::kMaxStackFrames]; size_t len = base::debug::CollectStackTrace(trace, AllocatorState::kMaxStackFrames); - metadata_[slot].alloc.trace_len = + metadata_[metadata_idx].alloc.trace_len = Pack(reinterpret_cast<uintptr_t*>(trace), len, - metadata_[slot].alloc.packed_trace, - sizeof(metadata_[slot].alloc.packed_trace)); - metadata_[slot].alloc.tid = ReportTid(); - metadata_[slot].alloc.trace_collected = true; + metadata_[metadata_idx].alloc.packed_trace, + sizeof(metadata_[metadata_idx].alloc.packed_trace)); + metadata_[metadata_idx].alloc.tid = ReportTid(); + metadata_[metadata_idx].alloc.trace_collected = true; - metadata_[slot].dealloc.tid = base::kInvalidThreadId; - metadata_[slot].dealloc.trace_len = 0; - metadata_[slot].dealloc.trace_collected = false; - metadata_[slot].deallocation_occurred = false; + metadata_[metadata_idx].dealloc.tid = base::kInvalidThreadId; + metadata_[metadata_idx].dealloc.trace_len = 0; + metadata_[metadata_idx].dealloc.trace_collected = false; + metadata_[metadata_idx].deallocation_occurred = false; } void GuardedPageAllocator::RecordDeallocationMetadata( - AllocatorState::SlotIdx slot) { + AllocatorState::MetadataIdx metadata_idx) { void* trace[AllocatorState::kMaxStackFrames]; size_t len = base::debug::CollectStackTrace(trace, AllocatorState::kMaxStackFrames); - metadata_[slot].dealloc.trace_len = + metadata_[metadata_idx].dealloc.trace_len = Pack(reinterpret_cast<uintptr_t*>(trace), len, - metadata_[slot].dealloc.packed_trace, - sizeof(metadata_[slot].dealloc.packed_trace)); - metadata_[slot].dealloc.tid = ReportTid(); - metadata_[slot].dealloc.trace_collected = true; + metadata_[metadata_idx].dealloc.packed_trace, + sizeof(metadata_[metadata_idx].dealloc.packed_trace)); + metadata_[metadata_idx].dealloc.tid = ReportTid(); + metadata_[metadata_idx].dealloc.trace_collected = true; } uintptr_t GuardedPageAllocator::GetCrashKeyAddress() const {
diff --git a/components/gwp_asan/client/guarded_page_allocator.h b/components/gwp_asan/client/guarded_page_allocator.h index 4f33026..d820079 100644 --- a/components/gwp_asan/client/guarded_page_allocator.h +++ b/components/gwp_asan/client/guarded_page_allocator.h
@@ -44,9 +44,7 @@ // It must be less than or equal to the allocation size. If it's left as zero // it will default to the default alignment the allocator chooses. // - // Preconditions: Init() must have been called, - // size <= page_size, - // align <= page_size + // Preconditions: Init() must have been called. void* Allocate(size_t size, size_t align = 0); // Deallocates memory pointed to by ptr. ptr must have been previously @@ -54,7 +52,7 @@ void Deallocate(void* ptr); // Returns the size requested when ptr was allocated. ptr must have been - // previously returned by a call to Allocate. + // previously returned by a call to Allocate, and not have been deallocated. size_t GetRequestedSize(const void* ptr) const; // Get the address of the GuardedPageAllocator crash key (the address of the @@ -84,21 +82,25 @@ // used by the quarantine. void MarkPageInaccessible(void*); - // On success, returns true and writes the reserved slot to |slot|. - // Otherwise returns false if no slots are available. - bool ReserveSlot(AllocatorState::SlotIdx* slot) LOCKS_EXCLUDED(lock_); + // On success, returns true and writes the reserved indices to |slot| and + // |metadata_idx|. Otherwise returns false if no allocations are available. + bool ReserveSlotAndMetadata(AllocatorState::SlotIdx* slot, + AllocatorState::MetadataIdx* metadata_idx) + LOCKS_EXCLUDED(lock_); - // Marks the specified slot as unreserved. - void FreeSlot(AllocatorState::SlotIdx slot) LOCKS_EXCLUDED(lock_); + // Marks the specified slot and metadata as unreserved. + void FreeSlotAndMetadata(AllocatorState::SlotIdx slot, + AllocatorState::MetadataIdx metadata_idx) + LOCKS_EXCLUDED(lock_); - // Record an allocation or deallocation for a given slot index. This - // encapsulates the logic for updating the stack traces and metadata for a - // given slot. + // Record the metadata for an allocation or deallocation for a given metadata + // index. ALWAYS_INLINE - void RecordAllocationMetadata(AllocatorState::SlotIdx slot, + void RecordAllocationMetadata(AllocatorState::MetadataIdx metadata_idx, size_t size, void* ptr); - ALWAYS_INLINE void RecordDeallocationMetadata(AllocatorState::SlotIdx slot); + ALWAYS_INLINE void RecordDeallocationMetadata( + AllocatorState::MetadataIdx metadata_idx); // Allocator state shared with with the crash analyzer. AllocatorState state_;
diff --git a/components/gwp_asan/common/allocator_state.h b/components/gwp_asan/common/allocator_state.h index 33ac4e2..7332fec 100644 --- a/components/gwp_asan/common/allocator_state.h +++ b/components/gwp_asan/common/allocator_state.h
@@ -37,6 +37,7 @@ class AllocatorState { public: + using MetadataIdx = uint8_t; using SlotIdx = uint8_t; // Maximum number of pages this class can allocate.
diff --git a/components/location/android/BUILD.gn b/components/location/android/BUILD.gn index 7e5ccfa..736114c5 100644 --- a/components/location/android/BUILD.gn +++ b/components/location/android/BUILD.gn
@@ -14,7 +14,7 @@ android_library("location_java") { deps = [ "//base:base_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//ui/android:ui_java", ] java_files =
diff --git a/components/minidump_uploader/BUILD.gn b/components/minidump_uploader/BUILD.gn index dbf3c437..0d7b0ee 100644 --- a/components/minidump_uploader/BUILD.gn +++ b/components/minidump_uploader/BUILD.gn
@@ -30,7 +30,7 @@ android_library("minidump_uploader_java") { deps = [ "//base:base_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] java_files = [
diff --git a/components/offline_items_collection/core/BUILD.gn b/components/offline_items_collection/core/BUILD.gn index e3a5122..917698f4 100644 --- a/components/offline_items_collection/core/BUILD.gn +++ b/components/offline_items_collection/core/BUILD.gn
@@ -92,7 +92,7 @@ deps = [ "//base:base_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] }
diff --git a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc index 7fae30bb..7e50bfec 100644 --- a/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc +++ b/components/offline_pages/core/prefetch/prefetch_dispatcher_impl.cc
@@ -250,8 +250,7 @@ std::unique_ptr<Task> generate_page_bundle_task = std::make_unique<GeneratePageBundleTask>( - this, service_->GetPrefetchStore(), service_->GetPrefetchGCMHandler(), - service_->GetCachedGCMToken(), + this, service_->GetPrefetchStore(), service_->GetCachedGCMToken(), service_->GetPrefetchNetworkRequestFactory(), base::BindOnce( &PrefetchDispatcherImpl::DidGenerateBundleOrGetOperationRequest,
diff --git a/components/offline_pages/core/prefetch/prefetch_service.h b/components/offline_pages/core/prefetch/prefetch_service.h index 0348dc8..96cb7da 100644 --- a/components/offline_pages/core/prefetch/prefetch_service.h +++ b/components/offline_pages/core/prefetch/prefetch_service.h
@@ -19,6 +19,9 @@ namespace ntp_snippets { class ContentSuggestionsService; } +namespace content { +class BrowserContext; +} namespace offline_pages { class OfflineEventLogger; @@ -82,7 +85,11 @@ // suggestion from the Prefetching pipeline and/or the Offline Pages database. virtual void RemoveSuggestion(GURL url) = 0; - virtual PrefetchGCMHandler* GetPrefetchGCMHandler() = 0; + // Returns a pointer to the PrefetchGCMHandler, if this is the first time the + // function is called, the PrefetchGCMHandler is created using the passed in + // context, then returned. + virtual PrefetchGCMHandler* GetOrCreatePrefetchGCMHandler( + content::BrowserContext* context) = 0; // Obtains the current GCM token from the PrefetchGCMHandler virtual void GetGCMToken(GCMTokenCallback callback) = 0;
diff --git a/components/offline_pages/core/prefetch/prefetch_service_impl.cc b/components/offline_pages/core/prefetch/prefetch_service_impl.cc index 4019ef5..4f6d23b 100644 --- a/components/offline_pages/core/prefetch/prefetch_service_impl.cc +++ b/components/offline_pages/core/prefetch/prefetch_service_impl.cc
@@ -7,10 +7,12 @@ #include <utility> #include "base/bind.h" +#include "base/bind_helpers.h" #include "base/logging.h" #include "components/image_fetcher/core/image_fetcher.h" #include "components/offline_pages/core/client_id.h" #include "components/offline_pages/core/client_namespace_constants.h" +#include "components/offline_pages/core/offline_page_feature.h" #include "components/offline_pages/core/prefetch/offline_metrics_collector.h" #include "components/offline_pages/core/prefetch/prefetch_background_task_handler.h" #include "components/offline_pages/core/prefetch/prefetch_dispatcher.h" @@ -28,7 +30,7 @@ PrefetchServiceImpl::PrefetchServiceImpl( std::unique_ptr<OfflineMetricsCollector> offline_metrics_collector, std::unique_ptr<PrefetchDispatcher> dispatcher, - std::unique_ptr<PrefetchGCMHandler> gcm_handler, + CreateGCMHandlerClosure create_gcm_handler_closure, std::unique_ptr<PrefetchNetworkRequestFactory> network_request_factory, OfflinePageModel* offline_page_model, std::unique_ptr<PrefetchStore> prefetch_store, @@ -41,7 +43,7 @@ image_fetcher::ImageFetcher* thumbnail_image_fetcher) : offline_metrics_collector_(std::move(offline_metrics_collector)), prefetch_dispatcher_(std::move(dispatcher)), - prefetch_gcm_handler_(std::move(gcm_handler)), + create_gcm_handler_closure_(std::move(create_gcm_handler_closure)), network_request_factory_(std::move(network_request_factory)), offline_page_model_(offline_page_model), prefetch_store_(std::move(prefetch_store)), @@ -55,7 +57,6 @@ weak_ptr_factory_(this) { prefetch_dispatcher_->SetService(this); prefetch_downloader_->SetPrefetchService(this); - prefetch_gcm_handler_->SetService(this); if (suggested_articles_observer_) suggested_articles_observer_->SetPrefetchService(this); } @@ -67,10 +68,18 @@ } void PrefetchServiceImpl::SetCachedGCMToken(const std::string& gcm_token) { - gcm_token_ = gcm_token; + // This method is passed a cached token that was stored in the job scheduler, + // to be used until the PrefetchGCMHandler is created. In some cases, the + // PrefetchGCMHandler could have been already created and a fresher token + // requested before this function is called. Make sure to not override a + // fresher token with a stale one. + if (gcm_token_.empty()) + gcm_token_ = gcm_token; } const std::string& PrefetchServiceImpl::GetCachedGCMToken() const { + DCHECK(!gcm_token_.empty()) << "No cached token is set, you should call " + "PrefetchService::GetGCMToken instead"; return gcm_token_; } @@ -85,7 +94,8 @@ GCMTokenCallback callback, const std::string& gcm_token, instance_id::InstanceID::Result result) { - // Keep the token fresh + // TODO(dimich): Add UMA reporting on instance_id::InstanceID::Result. + // Keep the cached token fresh gcm_token_ = gcm_token; std::move(callback).Run(gcm_token); } @@ -133,7 +143,16 @@ return prefetch_dispatcher_.get(); } -PrefetchGCMHandler* PrefetchServiceImpl::GetPrefetchGCMHandler() { +PrefetchGCMHandler* PrefetchServiceImpl::GetOrCreatePrefetchGCMHandler( + content::BrowserContext* context) { + if (!prefetch_gcm_handler_) { + prefetch_gcm_handler_ = std::move(create_gcm_handler_closure_).Run(context); + prefetch_gcm_handler_->SetService(this); + if (IsPrefetchingOfflinePagesEnabled()) { + // Trigger an update of the cached GCM token. + GetGCMToken(base::DoNothing()); + } + } return prefetch_gcm_handler_.get(); }
diff --git a/components/offline_pages/core/prefetch/prefetch_service_impl.h b/components/offline_pages/core/prefetch/prefetch_service_impl.h index 28a5e144..b036de94 100644 --- a/components/offline_pages/core/prefetch/prefetch_service_impl.h +++ b/components/offline_pages/core/prefetch/prefetch_service_impl.h
@@ -20,12 +20,16 @@ class PrefetchServiceImpl : public PrefetchService { public: + using CreateGCMHandlerClosure = + base::OnceCallback<std::unique_ptr<PrefetchGCMHandler>( + content::BrowserContext*)>; + // Zine/Feed: when using Feed, suggested_articles_observer and // thumbnail_fetcher should be null. All other parameters must be non-null. PrefetchServiceImpl( std::unique_ptr<OfflineMetricsCollector> offline_metrics_collector, std::unique_ptr<PrefetchDispatcher> dispatcher, - std::unique_ptr<PrefetchGCMHandler> gcm_handler, + CreateGCMHandlerClosure create_gcm_handler_closure, std::unique_ptr<PrefetchNetworkRequestFactory> network_request_factory, OfflinePageModel* offline_page_model, std::unique_ptr<PrefetchStore> prefetch_store, @@ -46,7 +50,8 @@ SuggestionsProvider* suggestions_provider) override; void NewSuggestionsAvailable() override; void RemoveSuggestion(GURL url) override; - PrefetchGCMHandler* GetPrefetchGCMHandler() override; + PrefetchGCMHandler* GetOrCreatePrefetchGCMHandler( + content::BrowserContext* context) override; void SetCachedGCMToken(const std::string& gcm_token) override; const std::string& GetCachedGCMToken() const override; void GetGCMToken(GCMTokenCallback callback) override; @@ -79,10 +84,11 @@ OfflineEventLogger logger_; std::string gcm_token_; + std::unique_ptr<PrefetchGCMHandler> prefetch_gcm_handler_; std::unique_ptr<OfflineMetricsCollector> offline_metrics_collector_; std::unique_ptr<PrefetchDispatcher> prefetch_dispatcher_; - std::unique_ptr<PrefetchGCMHandler> prefetch_gcm_handler_; + CreateGCMHandlerClosure create_gcm_handler_closure_; std::unique_ptr<PrefetchNetworkRequestFactory> network_request_factory_; OfflinePageModel* offline_page_model_; std::unique_ptr<PrefetchStore> prefetch_store_;
diff --git a/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc b/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc index f19bafe6..46ff427 100644 --- a/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc +++ b/components/offline_pages/core/prefetch/prefetch_service_test_taco.cc
@@ -194,14 +194,22 @@ void PrefetchServiceTestTaco::CreatePrefetchService() { CHECK(!prefetch_service_); + auto create_gcm_lambda = [](std::unique_ptr<PrefetchGCMHandler> gcm_handler, + content::BrowserContext* context) { + return gcm_handler; + }; + auto gcm_handler_closure = + base::BindOnce(create_gcm_lambda, std::move(gcm_handler_)); prefetch_service_ = std::make_unique<PrefetchServiceImpl>( std::move(metrics_collector_), std::move(dispatcher_), - std::move(gcm_handler_), std::move(network_request_factory_), + std::move(gcm_handler_closure), std::move(network_request_factory_), offline_page_model_.get(), std::move(prefetch_store_), std::move(suggested_articles_observer_), std::move(prefetch_downloader_), std::move(prefetch_importer_), std::move(prefetch_background_task_handler_), std::move(thumbnail_fetcher_), thumbnail_image_fetcher_.get()); + // Force create PrefetchGCMHandler + prefetch_service_->GetOrCreatePrefetchGCMHandler(nullptr); } std::unique_ptr<PrefetchService>
diff --git a/components/offline_pages/core/prefetch/prefetch_service_test_taco.h b/components/offline_pages/core/prefetch/prefetch_service_test_taco.h index 6ac2da5..d7ae000a 100644 --- a/components/offline_pages/core/prefetch/prefetch_service_test_taco.h +++ b/components/offline_pages/core/prefetch/prefetch_service_test_taco.h
@@ -16,6 +16,9 @@ namespace image_fetcher { class ImageFetcher; } +namespace content { +class BrowserContext; +} namespace offline_pages { class OfflineMetricsCollector; @@ -109,6 +112,9 @@ PrefService* pref_service() const { return pref_service_.get(); } private: + std::unique_ptr<PrefetchGCMHandler> GetPrefetchGCMHandler( + content::BrowserContext* context); + std::unique_ptr<OfflineMetricsCollector> metrics_collector_; std::unique_ptr<PrefetchDispatcher> dispatcher_; std::unique_ptr<PrefetchGCMHandler> gcm_handler_;
diff --git a/components/offline_pages/core/prefetch/stub_prefetch_service.cc b/components/offline_pages/core/prefetch/stub_prefetch_service.cc index f281bda..c6710bf 100644 --- a/components/offline_pages/core/prefetch/stub_prefetch_service.cc +++ b/components/offline_pages/core/prefetch/stub_prefetch_service.cc
@@ -19,13 +19,15 @@ void StubPrefetchService::RemoveSuggestion(GURL url) {} void StubPrefetchService::SetCachedGCMToken(const std::string& gcm_token) {} + void StubPrefetchService::GetGCMToken(GCMTokenCallback callback) {} const std::string& StubPrefetchService::GetCachedGCMToken() const { return gcm_token_; } -PrefetchGCMHandler* StubPrefetchService::GetPrefetchGCMHandler() { +PrefetchGCMHandler* StubPrefetchService::GetOrCreatePrefetchGCMHandler( + content::BrowserContext* context) { return nullptr; }
diff --git a/components/offline_pages/core/prefetch/stub_prefetch_service.h b/components/offline_pages/core/prefetch/stub_prefetch_service.h index 5a5f29f..b8a5fb2 100644 --- a/components/offline_pages/core/prefetch/stub_prefetch_service.h +++ b/components/offline_pages/core/prefetch/stub_prefetch_service.h
@@ -23,7 +23,8 @@ void SetCachedGCMToken(const std::string& gcm_token) override; const std::string& GetCachedGCMToken() const override; void GetGCMToken(GCMTokenCallback callback) override; - PrefetchGCMHandler* GetPrefetchGCMHandler() override; + PrefetchGCMHandler* GetOrCreatePrefetchGCMHandler( + content::BrowserContext* context) override; OfflineEventLogger* GetLogger() override; OfflineMetricsCollector* GetOfflineMetricsCollector() override; PrefetchDispatcher* GetPrefetchDispatcher() override;
diff --git a/components/offline_pages/core/prefetch/tasks/generate_page_bundle_task.cc b/components/offline_pages/core/prefetch/tasks/generate_page_bundle_task.cc index 134e726..871c2ad 100644 --- a/components/offline_pages/core/prefetch/tasks/generate_page_bundle_task.cc +++ b/components/offline_pages/core/prefetch/tasks/generate_page_bundle_task.cc
@@ -144,13 +144,11 @@ GeneratePageBundleTask::GeneratePageBundleTask( PrefetchDispatcher* prefetch_dispatcher, PrefetchStore* prefetch_store, - PrefetchGCMHandler* gcm_handler, const std::string& gcm_token, PrefetchNetworkRequestFactory* request_factory, PrefetchRequestFinishedCallback callback) : prefetch_dispatcher_(prefetch_dispatcher), prefetch_store_(prefetch_store), - gcm_handler_(gcm_handler), gcm_token_(gcm_token), request_factory_(request_factory), callback_(std::move(callback)), @@ -175,24 +173,7 @@ DCHECK(!url_and_ids->urls.empty()); DCHECK_EQ(url_and_ids->urls.size(), url_and_ids->ids.size()); - if (gcm_handler_) { - gcm_handler_->GetGCMToken(base::AdaptCallbackForRepeating( - base::BindOnce(&GeneratePageBundleTask::GotRegistrationId, - weak_factory_.GetWeakPtr(), std::move(url_and_ids)))); - } else { - DCHECK(!gcm_token_.empty()); - GotRegistrationId(std::move(url_and_ids), gcm_token_, - instance_id::InstanceID::Result::SUCCESS); - } -} - -void GeneratePageBundleTask::GotRegistrationId( - std::unique_ptr<UrlAndIds> url_and_ids, - const std::string& id, - instance_id::InstanceID::Result result) { - DCHECK(url_and_ids); - // TODO(dimich): Add UMA reporting on instance_id::InstanceID::Result. - request_factory_->MakeGeneratePageBundleRequest(url_and_ids->urls, id, + request_factory_->MakeGeneratePageBundleRequest(url_and_ids->urls, gcm_token_, std::move(callback_)); prefetch_dispatcher_->GeneratePageBundleRequested( std::make_unique<PrefetchDispatcher::IdsVector>(
diff --git a/components/offline_pages/core/prefetch/tasks/generate_page_bundle_task.h b/components/offline_pages/core/prefetch/tasks/generate_page_bundle_task.h index 224e487..1d2edff4 100644 --- a/components/offline_pages/core/prefetch/tasks/generate_page_bundle_task.h +++ b/components/offline_pages/core/prefetch/tasks/generate_page_bundle_task.h
@@ -10,13 +10,11 @@ #include <vector> #include "base/memory/weak_ptr.h" -#include "components/gcm_driver/instance_id/instance_id.h" #include "components/offline_pages/core/prefetch/prefetch_dispatcher.h" #include "components/offline_pages/core/prefetch/prefetch_types.h" #include "components/offline_pages/task/task.h" namespace offline_pages { -class PrefetchGCMHandler; class PrefetchNetworkRequestFactory; class PrefetchStore; @@ -28,7 +26,6 @@ GeneratePageBundleTask(PrefetchDispatcher* prefetch_dispatcher, PrefetchStore* prefetch_store, - PrefetchGCMHandler* gcm_handler, const std::string& gcm_token, PrefetchNetworkRequestFactory* request_factory, PrefetchRequestFinishedCallback callback); @@ -39,13 +36,9 @@ private: void StartGeneratePageBundle(std::unique_ptr<UrlAndIds> url_and_ids); - void GotRegistrationId(std::unique_ptr<UrlAndIds> url_and_ids, - const std::string& id, - instance_id::InstanceID::Result result); PrefetchDispatcher* prefetch_dispatcher_; PrefetchStore* prefetch_store_; - PrefetchGCMHandler* gcm_handler_; std::string gcm_token_; PrefetchNetworkRequestFactory* request_factory_; PrefetchRequestFinishedCallback callback_;
diff --git a/components/offline_pages/core/prefetch/tasks/generate_page_bundle_task_unittest.cc b/components/offline_pages/core/prefetch/tasks/generate_page_bundle_task_unittest.cc index 43546aa..5dc4496 100644 --- a/components/offline_pages/core/prefetch/tasks/generate_page_bundle_task_unittest.cc +++ b/components/offline_pages/core/prefetch/tasks/generate_page_bundle_task_unittest.cc
@@ -16,7 +16,6 @@ #include "components/offline_pages/core/prefetch/store/prefetch_store_utils.h" #include "components/offline_pages/core/prefetch/tasks/prefetch_task_test_base.h" #include "components/offline_pages/core/prefetch/test_prefetch_dispatcher.h" -#include "components/offline_pages/core/prefetch/test_prefetch_gcm_handler.h" #include "components/offline_pages/core/test_scoped_offline_clock.h" #include "components/offline_pages/task/task.h" #include "services/network/test/test_utils.h" @@ -37,13 +36,11 @@ GeneratePageBundleTaskTest() = default; ~GeneratePageBundleTaskTest() override = default; - TestPrefetchGCMHandler* gcm_handler() { return &gcm_handler_; } std::string gcm_token() { return "dummy_gcm_token"; } TestPrefetchDispatcher* dispatcher() { return &dispatcher_; } private: - TestPrefetchGCMHandler gcm_handler_; TestPrefetchDispatcher dispatcher_; }; @@ -52,16 +49,16 @@ base::MockCallback<PrefetchRequestFinishedCallback> callback; RunTask(std::make_unique<GeneratePageBundleTask>( - dispatcher(), store(), gcm_handler(), gcm_token(), - prefetch_request_factory(), callback.Get())); + dispatcher(), store(), gcm_token(), prefetch_request_factory(), + callback.Get())); EXPECT_EQ(0, dispatcher()->generate_page_bundle_requested); } TEST_F(GeneratePageBundleTaskTest, EmptyTask) { base::MockCallback<PrefetchRequestFinishedCallback> callback; RunTask(std::make_unique<GeneratePageBundleTask>( - dispatcher(), store(), gcm_handler(), gcm_token(), - prefetch_request_factory(), callback.Get())); + dispatcher(), store(), gcm_token(), prefetch_request_factory(), + callback.Get())); EXPECT_FALSE(prefetch_request_factory()->HasOutstandingRequests()); auto requested_urls = prefetch_request_factory()->GetAllUrlsRequested(); @@ -104,7 +101,7 @@ clock.Advance(base::TimeDelta::FromHours(1)); - GeneratePageBundleTask task(dispatcher(), store(), gcm_handler(), gcm_token(), + GeneratePageBundleTask task(dispatcher(), store(), gcm_token(), prefetch_request_factory(), request_callback.Get()); RunTask(&task);
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn index 1d20ae5..839db80 100644 --- a/components/omnibox/browser/BUILD.gn +++ b/components/omnibox/browser/BUILD.gn
@@ -260,7 +260,7 @@ deps = [ "//base:base_java", - "//third_party/android_deps:android_support_compat_java", + "//third_party/android_deps:com_android_support_support_compat_java", ] srcjar_deps = [ ":browser_java_enums_srcjar" ]
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc index 801c474..4d42018 100644 --- a/components/password_manager/core/browser/password_manager.cc +++ b/components/password_manager/core/browser/password_manager.cc
@@ -1341,7 +1341,13 @@ } if (predictions.empty()) return; - driver->AutofillDataReceived(predictions); + + if (driver) { + // |driver_| is nullptr on iOS. + // TODO(https://crbug.com/831123): Remove propagating predictions to the + // renderer when the old parser is gone. + driver->AutofillDataReceived(predictions); + } } PasswordFormManager* PasswordManager::GetMatchingPendingManager(
diff --git a/components/safe_browsing/android/BUILD.gn b/components/safe_browsing/android/BUILD.gn index d248e19..6d51566 100644 --- a/components/safe_browsing/android/BUILD.gn +++ b/components/safe_browsing/android/BUILD.gn
@@ -8,7 +8,7 @@ android_library("safe_browsing_java") { deps = [ "//base:base_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] java_files = [ "java/src/org/chromium/components/safe_browsing/SafeBrowsingApiBridge.java",
diff --git a/components/signin/core/browser/android/BUILD.gn b/components/signin/core/browser/android/BUILD.gn index 71bc6dee..4454a34 100644 --- a/components/signin/core/browser/android/BUILD.gn +++ b/components/signin/core/browser/android/BUILD.gn
@@ -20,7 +20,7 @@ "$google_play_services_package:google_play_services_basement_java", "//base:base_java", "//net/android:net_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] java_files = [ @@ -55,7 +55,7 @@ "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/junit", ] } @@ -67,7 +67,7 @@ ":signin_java_test_support", "//base:base_java", "//base:base_java_test_support", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/jsr-305:jsr_305_javalib", @@ -83,7 +83,7 @@ ":java", "//base:base_java", "//base:base_java_test_support", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/jsr-305:jsr_305_javalib", "//third_party/junit", ]
diff --git a/components/signin/core/browser/signin_pref_names.cc b/components/signin/core/browser/signin_pref_names.cc index c5923a5..75a77be 100644 --- a/components/signin/core/browser/signin_pref_names.cc +++ b/components/signin/core/browser/signin_pref_names.cc
@@ -8,6 +8,10 @@ #if defined(OS_CHROMEOS) // Boolean identifying if Mirror account consistency is required for profile. +// If Chrome OS Account Manager is not available, this has the effect of +// disabling secondary account sign-ins within the content area. +// TODO(https://crbug.com/938835): Clean this up after releasing Chrome OS +// Account Manager. const char kAccountConsistencyMirrorRequired[] = "account_consistency_mirror.required"; #endif
diff --git a/components/sync/android/BUILD.gn b/components/sync/android/BUILD.gn index 37b8fc2..f5dee92 100644 --- a/components/sync/android/BUILD.gn +++ b/components/sync/android/BUILD.gn
@@ -10,7 +10,7 @@ "//base:base_java", "//components/signin/core/browser/android:java", "//net/android:net_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/android_tools:android_gcm_java", "//third_party/cacheinvalidation:cacheinvalidation_javalib", "//third_party/cacheinvalidation:cacheinvalidation_proto_java",
diff --git a/components/ukm/debug/ukm_internals.js b/components/ukm/debug/ukm_internals.js index 6aacd2da..7cffbd4d 100644 --- a/components/ukm/debug/ukm_internals.js +++ b/components/ukm/debug/ukm_internals.js
@@ -408,13 +408,22 @@ (!$('hide_no_metrics').checked || source.entries.length) )); - // Filter sources based on thread id. + // Filter sources based on thread id (High bits of UKM Recorder ID). const threadsFilteredSource = filteredSources.filter(source => { + // Get current selection for thread id. It is either - + // "All" for no restriction. + // "0" for the default thread. This is the thread that record f.e PageLoad + // <lowercase hex string for first 32 bit of source id> for other threads. + // If a UKM is recorded with a custom source id or in renderer, it will + // have a unique value for this shared by all metrics that use the + // same thread. const selectedOption = $('thread_ids').options[$('thread_ids').selectedIndex]; - return !selectedOption || - (selectedOption.value === 'All') || - ((source.id[0] >>> 0).toString() === selectedOption.value); + // Return true if either of the following is true - + // No option is selected or selected option is "All" or the hexadecimal + // representation of source id is matching. + return !selectedOption || (selectedOption.value === 'All') || + ((source.id[0] >>> 0).toString(16) === selectedOption.value); }); // Filter URLs based on URL selector input.
diff --git a/components/variations/android/BUILD.gn b/components/variations/android/BUILD.gn index a1066de..95e4043 100644 --- a/components/variations/android/BUILD.gn +++ b/components/variations/android/BUILD.gn
@@ -7,7 +7,7 @@ android_library("variations_java") { deps = [ "//base:base_java", - "//third_party/android_deps:android_support_core_utils_java", + "//third_party/android_deps:com_android_support_support_core_utils_java", ] java_files = [ "java/src/org/chromium/components/variations/VariationsAssociatedData.java",
diff --git a/components/viz/client/client_resource_provider.cc b/components/viz/client/client_resource_provider.cc index efca8bb..2c59c0b 100644 --- a/components/viz/client/client_resource_provider.cc +++ b/components/viz/client/client_resource_provider.cc
@@ -364,6 +364,7 @@ ClientResourceProvider::ScopedSkSurface::ScopedSkSurface( GrContext* gr_context, + sk_sp<SkColorSpace> color_space, GLuint texture_id, GLenum texture_target, const gfx::Size& size, @@ -381,7 +382,7 @@ bool gpu_compositing = true; surface_ = SkSurface::MakeFromBackendTextureAsRenderTarget( gr_context, backend_texture, kTopLeft_GrSurfaceOrigin, msaa_sample_count, - ResourceFormatToClosestSkColorType(gpu_compositing, format), nullptr, + ResourceFormatToClosestSkColorType(gpu_compositing, format), color_space, &surface_props); }
diff --git a/components/viz/client/client_resource_provider.h b/components/viz/client/client_resource_provider.h index f3965af..b5d8c1d 100644 --- a/components/viz/client/client_resource_provider.h +++ b/components/viz/client/client_resource_provider.h
@@ -113,6 +113,7 @@ class VIZ_CLIENT_EXPORT ScopedSkSurface { public: ScopedSkSurface(GrContext* gr_context, + sk_sp<SkColorSpace> color_space, GLuint texture_id, GLenum texture_target, const gfx::Size& size,
diff --git a/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc b/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc index ae7a1c5..222748e 100644 --- a/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc +++ b/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc
@@ -45,8 +45,8 @@ pass->SetNew(render_pass_id, rect, rect, render_pass_transform); auto* shared_state = pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(shared_state_transform, rect, rect, rect, false, false, - 1, SkBlendMode::kSrcOver, 0); + shared_state->SetAll(shared_state_transform, rect, rect, gfx::RRectF(), rect, + false, false, 1, SkBlendMode::kSrcOver, 0); auto* surface_quad = pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); surface_quad->SetNew( @@ -173,7 +173,8 @@ gfx::Rect rect4_root(kFrameRect); shared_quad_state4_root->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect4_root, - /*visible_quad_layer_rect=*/rect4_root, /*clip_rect=*/rect4_root, + /*visible_quad_layer_rect=*/rect4_root, + /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect4_root, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad4_root_1 = @@ -336,7 +337,8 @@ pass1->filters = filters; auto* shared_state_1 = pass1->CreateAndAppendSharedQuadState(); shared_state_1->SetAll(invertible_transform, kFrameRect, kFrameRect, - kFrameRect, false, false, 1, SkBlendMode::kSrcOver, 0); + gfx::RRectF(), kFrameRect, false, false, 1, + SkBlendMode::kSrcOver, 0); auto* surface_quad_1 = pass1->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); surface_quad_1->SetNew( @@ -384,7 +386,8 @@ pass2->filters = filters2; auto* shared_state_2 = pass2->CreateAndAppendSharedQuadState(); shared_state_2->SetAll(invertible_transform, kFrameRect, kFrameRect, - kFrameRect, false, false, 1, SkBlendMode::kSrcOver, 0); + gfx::RRectF(), kFrameRect, false, false, 1, + SkBlendMode::kSrcOver, 0); auto* surface_quad_3 = pass2->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); surface_quad_3->SetNew(
diff --git a/components/viz/common/quads/draw_quad_perftest.cc b/components/viz/common/quads/draw_quad_perftest.cc index 6759fde2..99c0031 100644 --- a/components/viz/common/quads/draw_quad_perftest.cc +++ b/components/viz/common/quads/draw_quad_perftest.cc
@@ -33,8 +33,8 @@ SkBlendMode blend_mode = SkBlendMode::kSrcOver; SharedQuadState* state = render_pass->CreateAndAppendSharedQuadState(); - state->SetAll(quad_transform, content_rect, visible_layer_rect, clip_rect, - is_clipped, are_contents_opaque, opacity, blend_mode, + state->SetAll(quad_transform, content_rect, visible_layer_rect, gfx::RRectF(), + clip_rect, is_clipped, are_contents_opaque, opacity, blend_mode, sorting_context_id); return state; }
diff --git a/components/viz/common/quads/draw_quad_unittest.cc b/components/viz/common/quads/draw_quad_unittest.cc index 9992732..2eba2ba 100644 --- a/components/viz/common/quads/draw_quad_unittest.cc +++ b/components/viz/common/quads/draw_quad_unittest.cc
@@ -48,8 +48,8 @@ int sorting_context_id = 65536; auto state = std::make_unique<SharedQuadState>(); - state->SetAll(quad_transform, layer_rect, visible_layer_rect, clip_rect, - is_clipped, are_contents_opaque, opacity, blend_mode, + state->SetAll(quad_transform, layer_rect, visible_layer_rect, gfx::RRectF(), + clip_rect, is_clipped, are_contents_opaque, opacity, blend_mode, sorting_context_id); auto copy = std::make_unique<SharedQuadState>(*state); @@ -74,8 +74,8 @@ SkBlendMode blend_mode = SkBlendMode::kSrcOver; SharedQuadState* state = render_pass->CreateAndAppendSharedQuadState(); - state->SetAll(quad_transform, layer_rect, visible_layer_rect, clip_rect, - is_clipped, are_contents_opaque, opacity, blend_mode, + state->SetAll(quad_transform, layer_rect, visible_layer_rect, gfx::RRectF(), + clip_rect, is_clipped, are_contents_opaque, opacity, blend_mode, sorting_context_id); return state; }
diff --git a/components/viz/common/quads/render_pass_unittest.cc b/components/viz/common/quads/render_pass_unittest.cc index 9d106c7..d8b4729 100644 --- a/components/viz/common/quads/render_pass_unittest.cc +++ b/components/viz/common/quads/render_pass_unittest.cc
@@ -98,8 +98,9 @@ // Stick a quad in the pass, this should not get copied. SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), gfx::Rect(), gfx::Rect(), gfx::Rect(), - false, false, 1, SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), gfx::Rect(), gfx::Rect(), + gfx::RRectF(), gfx::Rect(), false, false, 1, + SkBlendMode::kSrcOver, 0); auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad->SetNew(pass->shared_quad_state_list.back(), gfx::Rect(), @@ -155,7 +156,8 @@ // Two quads using one shared state. SharedQuadState* shared_state1 = pass->CreateAndAppendSharedQuadState(); shared_state1->SetAll(gfx::Transform(), gfx::Rect(0, 0, 1, 1), gfx::Rect(), - gfx::Rect(), false, false, 1, SkBlendMode::kSrcOver, 0); + gfx::RRectF(), gfx::Rect(), false, false, 1, + SkBlendMode::kSrcOver, 0); auto* color_quad1 = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad1->SetNew(pass->shared_quad_state_list.back(), @@ -170,7 +172,8 @@ // And two quads using another shared state. SharedQuadState* shared_state2 = pass->CreateAndAppendSharedQuadState(); shared_state2->SetAll(gfx::Transform(), gfx::Rect(0, 0, 2, 2), gfx::Rect(), - gfx::Rect(), false, false, 1, SkBlendMode::kSrcOver, 0); + gfx::RRectF(), gfx::Rect(), false, false, 1, + SkBlendMode::kSrcOver, 0); auto* color_quad3 = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad3->SetNew(pass->shared_quad_state_list.back(), @@ -211,8 +214,8 @@ SharedQuadState* contrib_shared_state = contrib->CreateAndAppendSharedQuadState(); contrib_shared_state->SetAll(gfx::Transform(), gfx::Rect(0, 0, 2, 2), - gfx::Rect(), gfx::Rect(), false, false, 1, - SkBlendMode::kSrcOver, 0); + gfx::Rect(), gfx::RRectF(), gfx::Rect(), false, + false, 1, SkBlendMode::kSrcOver, 0); auto* contrib_quad = contrib->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); contrib_quad->SetNew(contrib->shared_quad_state_list.back(), @@ -264,7 +267,8 @@ // A shared state with a quad. SharedQuadState* shared_state1 = pass->CreateAndAppendSharedQuadState(); shared_state1->SetAll(gfx::Transform(), gfx::Rect(0, 0, 1, 1), gfx::Rect(), - gfx::Rect(), false, false, 1, SkBlendMode::kSrcOver, 0); + gfx::RRectF(), gfx::Rect(), false, false, 1, + SkBlendMode::kSrcOver, 0); auto* color_quad1 = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad1->SetNew(pass->shared_quad_state_list.back(), @@ -274,17 +278,20 @@ // A shared state with no quads, they were culled. SharedQuadState* shared_state2 = pass->CreateAndAppendSharedQuadState(); shared_state2->SetAll(gfx::Transform(), gfx::Rect(0, 0, 2, 2), gfx::Rect(), - gfx::Rect(), false, false, 1, SkBlendMode::kSrcOver, 0); + gfx::RRectF(), gfx::Rect(), false, false, 1, + SkBlendMode::kSrcOver, 0); // A second shared state with no quads. SharedQuadState* shared_state3 = pass->CreateAndAppendSharedQuadState(); shared_state3->SetAll(gfx::Transform(), gfx::Rect(0, 0, 2, 2), gfx::Rect(), - gfx::Rect(), false, false, 1, SkBlendMode::kSrcOver, 0); + gfx::RRectF(), gfx::Rect(), false, false, 1, + SkBlendMode::kSrcOver, 0); // A last shared state with a quad again. SharedQuadState* shared_state4 = pass->CreateAndAppendSharedQuadState(); shared_state4->SetAll(gfx::Transform(), gfx::Rect(0, 0, 2, 2), gfx::Rect(), - gfx::Rect(), false, false, 1, SkBlendMode::kSrcOver, 0); + gfx::RRectF(), gfx::Rect(), false, false, 1, + SkBlendMode::kSrcOver, 0); auto* color_quad2 = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad2->SetNew(pass->shared_quad_state_list.back(),
diff --git a/components/viz/common/quads/shared_quad_state.cc b/components/viz/common/quads/shared_quad_state.cc index 67e84ef..0c2c3bb 100644 --- a/components/viz/common/quads/shared_quad_state.cc +++ b/components/viz/common/quads/shared_quad_state.cc
@@ -29,6 +29,7 @@ void SharedQuadState::SetAll(const gfx::Transform& quad_to_target_transform, const gfx::Rect& quad_layer_rect, const gfx::Rect& visible_quad_layer_rect, + const gfx::RRectF& rounded_corner_bounds, const gfx::Rect& clip_rect, bool is_clipped, bool are_contents_opaque, @@ -38,6 +39,7 @@ this->quad_to_target_transform = quad_to_target_transform; this->quad_layer_rect = quad_layer_rect; this->visible_quad_layer_rect = visible_quad_layer_rect; + this->rounded_corner_bounds = rounded_corner_bounds; this->clip_rect = clip_rect; this->is_clipped = is_clipped; this->are_contents_opaque = are_contents_opaque; @@ -51,6 +53,8 @@ cc::MathUtil::AddToTracedValue("layer_content_rect", quad_layer_rect, value); cc::MathUtil::AddToTracedValue("layer_visible_content_rect", visible_quad_layer_rect, value); + cc::MathUtil::AddToTracedValue("rounded_corner_bounds", rounded_corner_bounds, + value); value->SetBoolean("is_clipped", is_clipped); cc::MathUtil::AddToTracedValue("clip_rect", clip_rect, value);
diff --git a/components/viz/common/quads/shared_quad_state.h b/components/viz/common/quads/shared_quad_state.h index 1de514c1..d8dcf3c 100644 --- a/components/viz/common/quads/shared_quad_state.h +++ b/components/viz/common/quads/shared_quad_state.h
@@ -10,6 +10,7 @@ #include "components/viz/common/viz_common_export.h" #include "third_party/skia/include/core/SkBlendMode.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/rrect_f.h" #include "ui/gfx/transform.h" namespace base { @@ -34,6 +35,7 @@ void SetAll(const gfx::Transform& quad_to_target_transform, const gfx::Rect& layer_rect, const gfx::Rect& visible_layer_rect, + const gfx::RRectF& rounded_corner_bounds, const gfx::Rect& clip_rect, bool is_clipped, bool are_contents_opaque, @@ -52,6 +54,9 @@ // The size of the visible area in the quads' originating layer, in the space // of the quad rects. gfx::Rect visible_quad_layer_rect; + // This rect lives in the target content space. It defines the corner radius + // to clip the quads with. + gfx::RRectF rounded_corner_bounds; // This rect lives in the target content space. gfx::Rect clip_rect; bool is_clipped;
diff --git a/components/viz/demo/client/demo_client.cc b/components/viz/demo/client/demo_client.cc index 7e45330b..a03e1f1c 100644 --- a/components/viz/demo/client/demo_client.cc +++ b/components/viz/demo/client/demo_client.cc
@@ -105,6 +105,7 @@ transform, /*quad_layer_rect=*/child_bounds, /*visible_quad_layer_rect=*/child_bounds, + /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/gfx::Rect(), /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1.f, /*blend_mode=*/SkBlendMode::kSrcOver, /*sorting_context_id=*/0); @@ -130,6 +131,7 @@ gfx::Transform(), /*quad_layer_rect=*/output_rect, /*visible_quad_layer_rect=*/output_rect, + /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/gfx::Rect(), /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1.f, /*blend_mode=*/SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index af050b6..1fd04b6 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -289,6 +289,8 @@ "display_embedder/gl_output_surface_android.h", "display_embedder/gl_output_surface_buffer_queue_android.cc", "display_embedder/gl_output_surface_buffer_queue_android.h", + "display_embedder/overlay_candidate_validator_android.cc", + "display_embedder/overlay_candidate_validator_android.h", ] } @@ -445,7 +447,10 @@ } if (is_android) { - sources += [ "frame_sinks/external_begin_frame_source_android_unittest.cc" ] + sources += [ + "display_embedder/overlay_candidate_validator_android_unittest.cc", + "frame_sinks/external_begin_frame_source_android_unittest.cc", + ] } if (enable_vulkan) {
diff --git a/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer.proto b/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer.proto index 7c29097..3134523 100644 --- a/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer.proto +++ b/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer.proto
@@ -23,6 +23,9 @@ required Transform transform = 1; required Rect layer_rect = 2; required Rect visible_rect = 3; + + // TODO(malaykeshav): add fuzzable rounded corner bounds. + required Rect clip_rect = 4; required bool is_clipped = 5; required bool are_contents_opaque = 6;
diff --git a/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc b/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc index 988c4d4..aa695fb 100644 --- a/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc +++ b/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc
@@ -124,7 +124,7 @@ shared_quad_state->SetAll( GetTransformFromProtobuf(quad_spec.sqs().transform()), GetRectFromProtobuf(quad_spec.sqs().layer_rect()), - GetRectFromProtobuf(quad_spec.sqs().visible_rect()), + GetRectFromProtobuf(quad_spec.sqs().visible_rect()), gfx::RRectF(), GetRectFromProtobuf(quad_spec.sqs().clip_rect()), quad_spec.sqs().is_clipped(), quad_spec.sqs().are_contents_opaque(), Normalize(quad_spec.sqs().opacity()), SkBlendMode::kSrcOver,
diff --git a/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc b/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc index a3ed55ce..d6f9f15c 100644 --- a/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc +++ b/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc
@@ -113,6 +113,7 @@ renderer_sqs->SetAll(gfx::Transform(1.0, 0.0, 0.0, 1.0, 0, 80), gfx::Rect(kRendererFrameSize), gfx::Rect(kRendererFrameSize), + /*rounded_corner_bounds=*/gfx::RRectF(), gfx::Rect(kRendererFrameSize), /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); @@ -125,11 +126,12 @@ /*ignores_input_event=*/false); auto* toolbar_sqs = pass->CreateAndAppendSharedQuadState(); - toolbar_sqs->SetAll(gfx::Transform(), gfx::Rect(kTopBarSize), - gfx::Rect(kTopBarSize), gfx::Rect(kTopBarSize), - /*is_clipped=*/false, /*are_contents_opaque=*/false, - /*opacity=*/1, SkBlendMode::kSrcOver, - /*sorting_context_id=*/0); + toolbar_sqs->SetAll( + gfx::Transform(), gfx::Rect(kTopBarSize), gfx::Rect(kTopBarSize), + /*rounded_corner_bounds=*/gfx::RRectF(), gfx::Rect(kTopBarSize), + /*is_clipped=*/false, /*are_contents_opaque=*/false, + /*opacity=*/1, SkBlendMode::kSrcOver, + /*sorting_context_id=*/0); auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad->SetNew(toolbar_sqs, gfx::Rect(kTopBarSize), gfx::Rect(kTopBarSize), SK_ColorLTGRAY,
diff --git a/components/viz/service/display/display_perftest.cc b/components/viz/service/display/display_perftest.cc index d6f91b7..e0b4e2e0 100644 --- a/components/viz/service/display/display_perftest.cc +++ b/components/viz/service/display/display_perftest.cc
@@ -66,7 +66,8 @@ SkBlendMode blend_mode = SkBlendMode::kSrcOver; SharedQuadState* state = render_pass->CreateAndAppendSharedQuadState(); - state->SetAll(quad_transform, rect, rect, rect, is_clipped, + state->SetAll(quad_transform, rect, rect, + /*rounded_corner_bounds=*/gfx::RRectF(), rect, is_clipped, are_contents_opaque, opacity, blend_mode, sorting_context_id); return state; }
diff --git a/components/viz/service/display/display_unittest.cc b/components/viz/service/display/display_unittest.cc index 926fe2c..0ec87b65 100644 --- a/components/viz/service/display/display_unittest.cc +++ b/components/viz/service/display/display_unittest.cc
@@ -791,8 +791,8 @@ // | | // +----+ { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -816,12 +816,12 @@ // +----+ | // +----+ { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -851,12 +851,12 @@ // | | | | // +--+ +--+ { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, rect3, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), + rect3, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -885,12 +885,12 @@ // +----+ +----+ // +--+ +--+ { - shared_quad_state->SetAll(gfx::Transform(), rect7, rect7, rect7, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect7, rect7, gfx::RRectF(), + rect7, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect6, rect6, rect6, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect6, rect6, gfx::RRectF(), + rect6, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect7, rect7, SK_ColorBLACK, false); @@ -918,12 +918,12 @@ // | | +--+ // +----+ { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect4, rect4, rect4, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect4, rect4, gfx::RRectF(), + rect4, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -950,12 +950,12 @@ // +-----+| // +------+ { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect5, rect5, rect5, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect5, rect5, gfx::RRectF(), + rect5, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1013,11 +1013,11 @@ // | | // +-----+ { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, rect1, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1038,11 +1038,11 @@ { quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1064,11 +1064,11 @@ { quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, rect3, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), + rect3, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1090,12 +1090,12 @@ { quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect4, rect4, rect4, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect4, rect4, gfx::RRectF(), + rect4, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1156,13 +1156,13 @@ // | | | | // +--------+ +--------+ { - shared_quad_state->SetAll(gfx::Transform(), rect, rect, rect, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), more_then_minimum_size, - more_then_minimum_size, more_then_minimum_size, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), more_then_minimum_size, more_then_minimum_size, + gfx::RRectF(), more_then_minimum_size, is_clipped, are_contents_opaque, + opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, more_then_minimum_size, more_then_minimum_size, SK_ColorBLACK, false); @@ -1180,12 +1180,13 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect, rect, rect, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); shared_quad_state2->SetAll(gfx::Transform(), minimum_size, minimum_size, - minimum_size, is_clipped, are_contents_opaque, - opacity, SkBlendMode::kSrcOver, 0); + gfx::RRectF(), minimum_size, is_clipped, + are_contents_opaque, opacity, + SkBlendMode::kSrcOver, 0); quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); @@ -1208,13 +1209,13 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect, rect, rect, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), less_than_minimum_size, - less_than_minimum_size, less_than_minimum_size, - is_clipped, are_contents_opaque, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), less_than_minimum_size, less_than_minimum_size, + gfx::RRectF(), less_than_minimum_size, is_clipped, are_contents_opaque, + opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, less_than_minimum_size, less_than_minimum_size, SK_ColorBLACK, false); @@ -1267,14 +1268,14 @@ auto* quad3 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, SkBlendMode::kSrcOver, - 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, + SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, rect3, is_clipped, - are_contents_opaque, opacity, + shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), + rect3, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -1343,11 +1344,11 @@ ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(half_scale, rect2, rect2, rect2, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(half_scale, rect2, rect2, gfx::RRectF(), rect2, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1366,11 +1367,11 @@ { quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(half_scale, rect3, rect3, rect3, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(half_scale, rect3, rect3, gfx::RRectF(), rect3, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1389,12 +1390,12 @@ { quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(half_scale, rect4, rect4, rect4, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(half_scale, rect4, rect4, gfx::RRectF(), rect4, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1412,8 +1413,8 @@ } { - shared_quad_state->SetAll(double_scale, rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(double_scale, rect1, rect1, gfx::RRectF(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1430,12 +1431,12 @@ { quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(double_scale, rect5, rect5, rect5, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(double_scale, rect5, rect5, gfx::RRectF(), rect5, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1458,12 +1459,12 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(double_scale, rect6, rect6, rect6, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(double_scale, rect6, rect6, gfx::RRectF(), rect6, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1487,12 +1488,12 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(double_scale, rect7, rect7, rect7, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(double_scale, rect7, rect7, gfx::RRectF(), rect7, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1515,12 +1516,12 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(double_scale, rect8, rect8, rect8, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(double_scale, rect8, rect8, gfx::RRectF(), rect8, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -1543,12 +1544,12 @@ } { - shared_quad_state->SetAll(double_scale, rect10, rect10, rect10, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(double_scale, rect10, rect10, gfx::RRectF(), + rect10, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(double_scale, rect9, rect9, rect9, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(double_scale, rect9, rect9, gfx::RRectF(), rect9, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect10, rect10, SK_ColorBLACK, false); @@ -1604,11 +1605,11 @@ gfx::Transform inverted; { - shared_quad_state->SetAll(gfx::Transform(), rect, rect, rect, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(zero_scale, rect, rect, rect, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(zero_scale, rect, rect, gfx::RRectF(), rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); @@ -1628,11 +1629,11 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect, rect, rect, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(epsilon_scale, rect, rect, rect, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(epsilon_scale, rect, rect, gfx::RRectF(), rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 1); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); @@ -1658,11 +1659,11 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect, rect, rect, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(larger_epsilon_scale, rect, rect, rect, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(larger_epsilon_scale, rect, rect, gfx::RRectF(), + rect, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); @@ -1709,11 +1710,11 @@ { negative_scale.Scale3d(-1, 1, 1); - shared_quad_state->SetAll(gfx::Transform(), rect, rect, rect, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(negative_scale, rect, rect, rect, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(negative_scale, rect, rect, gfx::RRectF(), rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); @@ -1741,11 +1742,11 @@ { negative_scale.MakeIdentity(); negative_scale.Scale3d(1, -1, 1); - shared_quad_state->SetAll(gfx::Transform(), rect, rect, rect, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(negative_scale, rect, rect, rect, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(negative_scale, rect, rect, gfx::RRectF(), rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); @@ -1773,11 +1774,11 @@ { negative_scale.MakeIdentity(); negative_scale.Scale3d(1, 1, -1); - shared_quad_state->SetAll(gfx::Transform(), rect, rect, rect, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(negative_scale, rect, rect, rect, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(negative_scale, rect, rect, gfx::RRectF(), rect, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false); @@ -1838,11 +1839,11 @@ ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); { // Apply rotation transform on |rect1| only. - shared_quad_state->SetAll(rotate, rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(rotate, rect1, rect1, gfx::RRectF(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -1862,11 +1863,11 @@ { // Apply rotation transform on |rect1| and |rect2|. - shared_quad_state->SetAll(rotate, rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(rotate, rect1, rect1, gfx::RRectF(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(rotate, rect2, rect2, rect2, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(rotate, rect2, rect2, gfx::RRectF(), rect2, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -1884,11 +1885,11 @@ { quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(rotate, rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(rotate, rect1, rect1, gfx::RRectF(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, rect3, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), + rect3, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect3, rect3, SK_ColorBLACK, false); @@ -1910,11 +1911,11 @@ // Since we only support updating |visible_rect| of DrawQuad with scale // or translation transform and rotation transform applies to quads, // |visible_rect| of |quad2| should not be changed. - shared_quad_state->SetAll(rotate, rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(rotate, rect1, rect1, gfx::RRectF(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(rotate, rect3, rect3, rect3, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(rotate, rect3, rect3, gfx::RRectF(), rect3, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect3, rect3, SK_ColorBLACK, false); @@ -1965,11 +1966,11 @@ auto* quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); { - shared_quad_state->SetAll(perspective, rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(perspective, rect1, rect1, gfx::RRectF(), rect1, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, rect1, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect1, rect1, SK_ColorBLACK, false); @@ -1989,11 +1990,11 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(perspective, rect2, rect2, rect2, is_clipped, - are_contents_opaque, opacity, + shared_quad_state2->SetAll(perspective, rect2, rect2, gfx::RRectF(), rect2, + is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -2037,11 +2038,11 @@ auto* quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacityLess1, - SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, - is_clipped, are_contents_opaque, opacity1, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, + opacityLess1, SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, is_clipped, are_contents_opaque, opacity1, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -2059,11 +2060,11 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity1, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity1, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, - is_clipped, are_contents_opaque, opacity1, + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, is_clipped, are_contents_opaque, opacity1, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -2104,11 +2105,11 @@ auto* quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - transparent_content, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, transparent_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, - is_clipped, opaque_content, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -2126,11 +2127,11 @@ } { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, - is_clipped, opaque_content, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, opaque_content, opacity, + SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -2178,11 +2179,11 @@ // | | // +-----+ { - shared_quad_state->SetAll(translate_back, rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(translate_back, rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 1); - shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, rect1, - is_clipped, are_contents_opaque, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 1); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -2238,11 +2239,11 @@ // +----+ // +-+ // +-+ - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - transparent_content, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, transparent_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, - is_clipped, opaque_content, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -2267,11 +2268,11 @@ // +----+ => | +-+ | // +-+ | +-+ | // +-+ +-----+ - shared_quad_state->SetAll(translate_up, rect1, rect1, rect1, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, - is_clipped, opaque_content, opacity, + shared_quad_state->SetAll(translate_up, rect1, rect1, gfx::RRectF(), rect1, + is_clipped, opaque_content, opacity, + SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -2297,11 +2298,11 @@ // +---+ +----+ quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(translate_up, rect1, rect1, rect1, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); - shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, rect3, - is_clipped, opaque_content, opacity, + shared_quad_state->SetAll(translate_up, rect1, rect1, gfx::RRectF(), rect1, + is_clipped, opaque_content, opacity, + SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), + rect3, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect3, rect3, SK_ColorBLACK, false); @@ -2363,14 +2364,14 @@ // | |----+ => | |----+ // +----+ +----+ // - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, - is_clipped, opaque_content, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, opaque_content, opacity, + SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, rect3, - is_clipped, opaque_content, opacity, + shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), + rect3, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -2398,8 +2399,8 @@ // quad3 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state3->SetAll(gfx::Transform(), rect4, rect4, rect4, - is_clipped, opaque_content, opacity, + shared_quad_state3->SetAll(gfx::Transform(), rect4, rect4, gfx::RRectF(), + rect4, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad3->SetNew(shared_quad_state3, rect4, rect4, SK_ColorBLACK, false); EXPECT_EQ(3u, frame.render_pass_list.front()->quad_list.size()); @@ -2427,8 +2428,8 @@ // | |----+ => | | |--|-+ // +----+ +-|--+ | // +-----+ - shared_quad_state3->SetAll(gfx::Transform(), rect5, rect5, rect5, - is_clipped, opaque_content, opacity, + shared_quad_state3->SetAll(gfx::Transform(), rect5, rect5, gfx::RRectF(), + rect5, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad3->SetNew(shared_quad_state3, rect5, rect5, SK_ColorBLACK, false); EXPECT_EQ(3u, frame.render_pass_list.front()->quad_list.size()); @@ -2494,14 +2495,14 @@ // | |----+ => | |----+ // +----+ +----+ // - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, - is_clipped, opaque_content, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, opaque_content, opacity, + SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, rect3, - is_clipped, opaque_content, opacity, + shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), + rect3, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -2566,11 +2567,11 @@ // +----+ // - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); - shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, rect1, - is_clipped, opaque_content, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, opaque_content, opacity, + SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad1->SetNew(shared_quad_state2, rect1, rect1, render_pass_id, @@ -2630,11 +2631,11 @@ // | | || // +------+ // - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, - non_clipped, opaque_content, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, non_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, - non_clipped, opaque_content, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, non_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -2657,11 +2658,11 @@ // quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, clip_rect, - clipped, opaque_content, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + clip_rect, clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, - non_clipped, opaque_content, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, non_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -2686,11 +2687,11 @@ // | +-+| => +--+++ // +------+ // - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, clip_rect, - clipped, opaque_content, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + clip_rect, clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, rect3, - non_clipped, opaque_content, opacity, + shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), + rect3, non_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect3, rect3, SK_ColorBLACK, false); @@ -2737,11 +2738,11 @@ auto* quad2 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, - is_clipped, opaque_content, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, opaque_content, opacity, + SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); @@ -2807,17 +2808,17 @@ // | | | | // | R1 | | R2 | // +-------+---+--------+ - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); - shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, rect2, - is_clipped, opaque_content, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, opaque_content, opacity, + SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, rect3, - is_clipped, opaque_content, opacity, + shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), + rect3, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state4->SetAll(gfx::Transform(), rect4, rect4, rect4, - is_clipped, opaque_content, opacity, + shared_quad_state4->SetAll(gfx::Transform(), rect4, rect4, gfx::RRectF(), + rect4, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); R1->SetNew(shared_quad_state, rect1, rect1, render_pass_id, mask_resource_id, gfx::RectF(), gfx::Size(), @@ -2855,17 +2856,17 @@ // | | | // | R2 | R1 | // +-------+-----------+ - shared_quad_state->SetAll(gfx::Transform(), rect5, rect5, rect5, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); - shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, rect1, - is_clipped, opaque_content, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect5, rect5, gfx::RRectF(), + rect5, is_clipped, opaque_content, opacity, + SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, rect3, - is_clipped, opaque_content, opacity, + shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), + rect3, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state4->SetAll(gfx::Transform(), rect6, rect6, rect6, - is_clipped, opaque_content, opacity, + shared_quad_state4->SetAll(gfx::Transform(), rect6, rect6, gfx::RRectF(), + rect6, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); R1->SetNew(shared_quad_state, rect5, rect5, render_pass_id, mask_resource_id, gfx::RectF(), gfx::Size(), @@ -2902,17 +2903,17 @@ // |-----+ | | // | R2 | R1 | // +-----------+-------+ - shared_quad_state->SetAll(gfx::Transform(), rect5, rect5, rect5, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); - shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, rect1, - is_clipped, opaque_content, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect5, rect5, gfx::RRectF(), + rect5, is_clipped, opaque_content, opacity, + SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, rect3, - is_clipped, opaque_content, opacity, + shared_quad_state3->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), + rect3, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); - shared_quad_state4->SetAll(gfx::Transform(), rect7, rect7, rect7, - is_clipped, opaque_content, opacity, + shared_quad_state4->SetAll(gfx::Transform(), rect7, rect7, gfx::RRectF(), + rect7, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); R1->SetNew(shared_quad_state, rect5, rect5, render_pass_id, mask_resource_id, gfx::RectF(), gfx::Size(), @@ -2993,12 +2994,13 @@ // +--+--+ // | | | // +--+--+ - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, opaque_content, opacity, + SkBlendMode::kSrcOver, 0); shared_quad_state2->SetAll(gfx::Transform(), rect_in_rect1, rect_in_rect1, - rect_in_rect1, is_clipped, opaque_content, - opacity, SkBlendMode::kSrcOver, 0); + gfx::RRectF(), rect_in_rect1, is_clipped, + opaque_content, opacity, SkBlendMode::kSrcOver, + 0); quad1->SetNew(shared_quad_state, rect1_1, rect1_1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state, rect1_2, rect1_2, SK_ColorBLACK, false); quad3->SetNew(shared_quad_state, rect1_3, rect1_3, SK_ColorBLACK, false); @@ -3034,10 +3036,10 @@ // +--+--+ quad5 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state2->SetAll(gfx::Transform(), rect_intersects_rect1, - rect_intersects_rect1, rect_intersects_rect1, - is_clipped, opaque_content, opacity, - SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll( + gfx::Transform(), rect_intersects_rect1, rect_intersects_rect1, + gfx::RRectF(), rect_intersects_rect1, is_clipped, opaque_content, + opacity, SkBlendMode::kSrcOver, 0); quad5->SetNew(shared_quad_state2, rect_intersects_rect1, rect_intersects_rect1, SK_ColorBLACK, false); EXPECT_EQ(5u, frame.render_pass_list.front()->quad_list.size()); @@ -3075,11 +3077,11 @@ auto* quad6 = frame.render_pass_list.front() ->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); - shared_quad_state->SetAll(gfx::Transform(), rect2, rect2, rect2, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); - shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, rect3, - is_clipped, opaque_content, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect2, rect2, gfx::RRectF(), + rect2, is_clipped, opaque_content, opacity, + SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(gfx::Transform(), rect3, rect3, gfx::RRectF(), + rect3, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); quad1->SetNew(shared_quad_state, rect2_1, rect2_1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state, rect2_2, rect2_2, SK_ColorBLACK, false); @@ -3167,15 +3169,15 @@ // |quad1| forms an occlusion rect; |quad2| follows a invertible transform // and is hiding behind quad1; |quad3| follows a non-invertible transform // and it is not covered by the occlusion rect. - shared_quad_state1->SetAll(invertible, rect1, rect1, rect1, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); - shared_quad_state2->SetAll(invertible, rect2, rect2, rect2, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); - shared_quad_state3->SetAll(non_invertible, rect3, rect3, rect3, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); + shared_quad_state1->SetAll(invertible, rect1, rect1, gfx::RRectF(), rect1, + is_clipped, opaque_content, opacity, + SkBlendMode::kSrcOver, 0); + shared_quad_state2->SetAll(invertible, rect2, rect2, gfx::RRectF(), rect2, + is_clipped, opaque_content, opacity, + SkBlendMode::kSrcOver, 0); + shared_quad_state3->SetAll(non_invertible, rect3, rect3, gfx::RRectF(), + rect3, is_clipped, opaque_content, opacity, + SkBlendMode::kSrcOver, 0); quad1->SetNew(shared_quad_state1, rect1, rect1, SK_ColorBLACK, false); quad2->SetNew(shared_quad_state2, rect2, rect2, SK_ColorBLACK, false); quad3->SetNew(shared_quad_state3, rect3, rect3, SK_ColorBLACK, false); @@ -3201,12 +3203,12 @@ // +--------+ +--------+ // Verify if draw occlusion can occlude quad with non-invertible // transfrom. - shared_quad_state1->SetAll(invertible, rect1, rect1, rect1, is_clipped, - opaque_content, opacity, SkBlendMode::kSrcOver, - 0); - shared_quad_state3->SetAll(non_invertible_miss_z, rect3, rect3, rect3, + shared_quad_state1->SetAll(invertible, rect1, rect1, gfx::RRectF(), rect1, is_clipped, opaque_content, opacity, SkBlendMode::kSrcOver, 0); + shared_quad_state3->SetAll(non_invertible_miss_z, rect3, rect3, + gfx::RRectF(), rect3, is_clipped, opaque_content, + opacity, SkBlendMode::kSrcOver, 0); quad1->SetNew(shared_quad_state1, rect1, rect1, SK_ColorBLACK, false); quad3->SetNew(shared_quad_state3, rect3, rect3, SK_ColorBLACK, false); @@ -3246,8 +3248,8 @@ // | | // +----+ { - shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, rect1, is_clipped, - are_contents_opaque, opacity, + shared_quad_state->SetAll(gfx::Transform(), rect1, rect1, gfx::RRectF(), + rect1, is_clipped, are_contents_opaque, opacity, SkBlendMode::kSrcOver, 0); quad->SetNew(shared_quad_state, rect1, rect1, SK_ColorBLACK, false); @@ -3314,7 +3316,8 @@ gfx::Rect rect1(display_size); shared_quad_state1->SetAll( gfx::Transform(), rect1 /* quad_layer_rect */, - rect1 /* visible_quad_layer_rect */, rect1 /*clip_rect */, + rect1 /* visible_quad_layer_rect */, + gfx::RRectF() /* rounded_corner_bounds*/, rect1 /*clip_rect */, false /* is_clipped */, false /* are_contents_opaque */, 0.5f /* opacity */, SkBlendMode::kSrcOver, 0 /* sorting_context_id */); auto* quad1 = pass->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); @@ -3326,7 +3329,8 @@ gfx::Rect rect2(gfx::Point(20, 20), sub_surface_size); shared_quad_state2->SetAll( gfx::Transform(), rect2 /* quad_layer_rect */, - rect2 /* visible_quad_layer_rect */, rect2 /*clip_rect */, + rect2 /* visible_quad_layer_rect */, + gfx::RRectF() /* rounded_corner_bounds */, rect2 /*clip_rect */, false /* is_clipped */, true /* are_contents_opaque */, 1.0f /* opacity */, SkBlendMode::kSrcOver, 0 /* sorting_context_id */); auto* quad2 = pass->quad_list.AllocateAndConstruct<SurfaceDrawQuad>();
diff --git a/components/viz/service/display/gl_renderer_unittest.cc b/components/viz/service/display/gl_renderer_unittest.cc index 0a6b9d8..584ac05 100644 --- a/components/viz/service/display/gl_renderer_unittest.cc +++ b/components/viz/service/display/gl_renderer_unittest.cc
@@ -693,8 +693,9 @@ root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(gfx::Transform(), gfx::Rect(viewport_size), - gfx::Rect(1023, 1023), gfx::Rect(1023, 1023), false, - false, 1, SkBlendMode::kSrcOver, 0); + gfx::Rect(1023, 1023), gfx::RRectF(), + gfx::Rect(1023, 1023), false, false, 1, + SkBlendMode::kSrcOver, 0); overlay_quad->SetNew(shared_state, gfx::Rect(1023, 1023), gfx::Rect(1023, 1023), needs_blending, resource_id, premultiplied_alpha, uv_top_left, uv_bottom_right, @@ -755,8 +756,9 @@ root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(gfx::Transform(), gfx::Rect(viewport_size), - gfx::Rect(1025, 1025), gfx::Rect(1025, 1025), false, - false, 1, SkBlendMode::kSrcOver, 0); + gfx::Rect(1025, 1025), gfx::RRectF(), + gfx::Rect(1025, 1025), false, false, 1, + SkBlendMode::kSrcOver, 0); overlay_quad->SetNew(shared_state, gfx::Rect(1025, 1025), gfx::Rect(1025, 1025), needs_blending, resource_id, premultiplied_alpha, uv_top_left, uv_bottom_right, @@ -2473,8 +2475,9 @@ root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(gfx::Transform(), gfx::Rect(viewport_size), - gfx::Rect(viewport_size), gfx::Rect(viewport_size), - false, false, 1, SkBlendMode::kSrcOver, 0); + gfx::Rect(viewport_size), gfx::RRectF(), + gfx::Rect(viewport_size), false, false, 1, + SkBlendMode::kSrcOver, 0); overlay_quad->SetNew(shared_state, gfx::Rect(viewport_size), gfx::Rect(viewport_size), needs_blending, parent_resource_id, premultiplied_alpha, uv_top_left, @@ -2856,8 +2859,8 @@ gfx::RectF tex_coord_rect(0, 0, 1, 1); SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), rect, rect, rect, false, false, 1, - SkBlendMode::kSrcOver, 0); + shared_state->SetAll(gfx::Transform(), rect, rect, gfx::RRectF(), rect, + false, false, 1, SkBlendMode::kSrcOver, 0); YUVVideoDrawQuad* quad = root_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>(); quad->SetNew(shared_state, rect, rect, needs_blending, tex_coord_rect, @@ -4140,8 +4143,9 @@ root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(gfx::Transform(), gfx::Rect(viewport_size), - gfx::Rect(50, 50), gfx::Rect(viewport_size), false, - false, 1, SkBlendMode::kSrcOver, 0); + gfx::Rect(50, 50), gfx::RRectF(), + gfx::Rect(viewport_size), false, false, 1, + SkBlendMode::kSrcOver, 0); overlay_quad->SetNew( shared_state, gfx::Rect(viewport_size), gfx::Rect(viewport_size), needs_blending, create_overlay_resource(), premultiplied_alpha,
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc index 22feb9f..2cd3ef1 100644 --- a/components/viz/service/display/renderer_pixeltest.cc +++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -144,8 +144,9 @@ int sorting_context_id = 0; SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(quad_to_target_transform, layer_rect, visible_layer_rect, - clip_rect, is_clipped, are_contents_opaque, opacity, - blend_mode, sorting_context_id); + /*rounded_corner_bounds=*/gfx::RRectF(), clip_rect, + is_clipped, are_contents_opaque, opacity, blend_mode, + sorting_context_id); return shared_state; } @@ -163,8 +164,9 @@ int sorting_context_id = 0; SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(quad_to_target_transform, layer_rect, visible_layer_rect, - clip_rect, is_clipped, are_contents_opaque, opacity, - blend_mode, sorting_context_id); + /*rounded_corner_bounds=*/gfx::RRectF(), clip_rect, + is_clipped, are_contents_opaque, opacity, blend_mode, + sorting_context_id); return shared_state; }
diff --git a/components/viz/service/display/software_renderer_unittest.cc b/components/viz/service/display/software_renderer_unittest.cc index 4aff55f..853ef75 100644 --- a/components/viz/service/display/software_renderer_unittest.cc +++ b/components/viz/service/display/software_renderer_unittest.cc
@@ -147,8 +147,8 @@ SharedQuadState* shared_quad_state = root_render_pass->CreateAndAppendSharedQuadState(); shared_quad_state->SetAll(gfx::Transform(), outer_rect, outer_rect, - outer_rect, false, true, 1.0, SkBlendMode::kSrcOver, - 0); + gfx::RRectF(), outer_rect, false, true, 1.0, + SkBlendMode::kSrcOver, 0); auto* inner_quad = root_render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); inner_quad->SetNew(shared_quad_state, inner_rect, inner_rect, SK_ColorCYAN, @@ -215,8 +215,8 @@ SharedQuadState* shared_quad_state = root_render_pass->CreateAndAppendSharedQuadState(); shared_quad_state->SetAll(gfx::Transform(), outer_rect, outer_rect, - outer_rect, false, true, 1.0, SkBlendMode::kSrcOver, - 0); + gfx::RRectF(), outer_rect, false, true, 1.0, + SkBlendMode::kSrcOver, 0); auto* inner_quad = root_render_pass->CreateAndAppendDrawQuad<TileDrawQuad>(); inner_quad->SetNew(shared_quad_state, inner_rect, inner_rect, needs_blending, mapped_resource_cyan, gfx::RectF(gfx::SizeF(inner_size)), @@ -275,8 +275,9 @@ gfx::Transform()); SharedQuadState* shared_quad_state = root_render_pass->CreateAndAppendSharedQuadState(); - shared_quad_state->SetAll(gfx::Transform(), tile_rect, tile_rect, tile_rect, - false, true, 1.0, SkBlendMode::kSrcOver, 0); + shared_quad_state->SetAll(gfx::Transform(), tile_rect, tile_rect, + gfx::RRectF(), tile_rect, false, true, 1.0, + SkBlendMode::kSrcOver, 0); auto* quad = root_render_pass->CreateAndAppendDrawQuad<TileDrawQuad>(); quad->SetNew(shared_quad_state, tile_rect, tile_rect, needs_blending, mapped_resource_cyan, gfx::RectF(gfx::SizeF(tile_size)),
diff --git a/components/viz/service/display/surface_aggregator.cc b/components/viz/service/display/surface_aggregator.cc index c08fab0..9aa6b7d 100644 --- a/components/viz/service/display/surface_aggregator.cc +++ b/components/viz/service/display/surface_aggregator.cc
@@ -542,6 +542,7 @@ /*quad_to_target_transform=*/gfx::Transform(), /*quad_layer_rect=*/output_rect, /*visible_quad_layer_rect=*/output_rect, + /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/gfx::Rect(), /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/1.f, /*blend_mode=*/SkBlendMode::kSrcOver, /*sorting_context_id=*/0); @@ -593,9 +594,10 @@ shared_quad_state->SetAll( new_transform, quad_layer_rect, visible_quad_layer_rect, - new_clip_rect.rect, new_clip_rect.is_clipped, - source_sqs->are_contents_opaque, source_sqs->opacity, - source_sqs->blend_mode, source_sqs->sorting_context_id); + source_sqs->rounded_corner_bounds, new_clip_rect.rect, + new_clip_rect.is_clipped, source_sqs->are_contents_opaque, + source_sqs->opacity, source_sqs->blend_mode, + source_sqs->sorting_context_id); shared_quad_state->has_surface_damage = has_surface_damage; return shared_quad_state;
diff --git a/components/viz/service/display/surface_aggregator_pixeltest.cc b/components/viz/service/display/surface_aggregator_pixeltest.cc index 3422dd0..1021e7a1 100644 --- a/components/viz/service/display/surface_aggregator_pixeltest.cc +++ b/components/viz/service/display/surface_aggregator_pixeltest.cc
@@ -67,14 +67,16 @@ const gfx::Size& size) { const gfx::Rect layer_rect = gfx::Rect(size); const gfx::Rect visible_layer_rect = gfx::Rect(size); + const gfx::RRectF rounded_corner_bounds = gfx::RRectF(); const gfx::Rect clip_rect = gfx::Rect(size); bool is_clipped = false; bool are_contents_opaque = false; float opacity = 1.f; const SkBlendMode blend_mode = SkBlendMode::kSrcOver; auto* shared_state = render_pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(transform, layer_rect, visible_layer_rect, clip_rect, - is_clipped, are_contents_opaque, opacity, blend_mode, 0); + shared_state->SetAll(transform, layer_rect, visible_layer_rect, + rounded_corner_bounds, clip_rect, is_clipped, + are_contents_opaque, opacity, blend_mode, 0); return shared_state; }
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc index 0aa827e..83bd96e2 100644 --- a/components/viz/service/display/surface_aggregator_unittest.cc +++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -316,6 +316,7 @@ gfx::Transform layer_to_target_transform = transform; gfx::Rect layer_bounds(primary_surface_rect); gfx::Rect visible_layer_rect(primary_surface_rect); + gfx::RRectF rounded_corner_bounds = gfx::RRectF(); gfx::Rect clip_rect(primary_surface_rect); bool is_clipped = false; bool are_contents_opaque = false; @@ -323,8 +324,9 @@ auto* shared_quad_state = pass->CreateAndAppendSharedQuadState(); shared_quad_state->SetAll(layer_to_target_transform, layer_bounds, - visible_layer_rect, clip_rect, is_clipped, - are_contents_opaque, opacity, blend_mode, 0); + visible_layer_rect, rounded_corner_bounds, + clip_rect, is_clipped, are_contents_opaque, + opacity, blend_mode, 0); SurfaceDrawQuad* surface_quad = pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); @@ -338,8 +340,8 @@ gfx::Rect output_rect = gfx::Rect(0, 0, 5, 5); auto* shared_state = pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(gfx::Transform(), output_rect, output_rect, - output_rect, false, false, 1, SkBlendMode::kSrcOver, - 0); + gfx::RRectF(), output_rect, false, false, 1, + SkBlendMode::kSrcOver, 0); auto* quad = pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); quad->SetNew(shared_state, output_rect, output_rect, render_pass_id, 0, gfx::RectF(), gfx::Size(), gfx::Vector2dF(), gfx::PointF(), @@ -2144,6 +2146,7 @@ const gfx::Transform layer_to_target_transform; const gfx::Rect layer_rect(size); const gfx::Rect visible_layer_rect(size); + const gfx::RRectF rounded_corner_bounds = gfx::RRectF(); const gfx::Rect clip_rect(size); bool is_clipped = false; @@ -2154,8 +2157,8 @@ bool force_anti_aliasing_off = false; auto* sqs = pass->CreateAndAppendSharedQuadState(); sqs->SetAll(layer_to_target_transform, layer_rect, visible_layer_rect, - clip_rect, is_clipped, are_contents_opaque, opacity, blend_mode, - 0); + rounded_corner_bounds, clip_rect, is_clipped, are_contents_opaque, + opacity, blend_mode, 0); auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); color_quad->SetNew(pass->shared_quad_state_list.back(), visible_layer_rect,
diff --git a/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.cc b/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.cc index 8797564..391f9265 100644 --- a/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.cc +++ b/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.cc
@@ -4,56 +4,9 @@ #include "components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.h" -#include "components/viz/service/display/overlay_strategy_fullscreen.h" -#include "components/viz/service/display/overlay_strategy_single_on_top.h" -#include "components/viz/service/display/overlay_strategy_underlay.h" -#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator_android.h" #include "third_party/khronos/GLES2/gl2.h" -#include "ui/gfx/geometry/rect_conversions.h" -#include "ui/gl/android/android_surface_control_compat.h" namespace viz { -namespace { -class OverlayCandidateValidatorImpl : public OverlayCandidateValidator { - public: - OverlayCandidateValidatorImpl() = default; - ~OverlayCandidateValidatorImpl() override = default; - - void GetStrategies(OverlayProcessor::StrategyList* strategies) override { - // Added in priority order, most to least desirable. - strategies->push_back(std::make_unique<OverlayStrategyFullscreen>(this)); - strategies->push_back(std::make_unique<OverlayStrategySingleOnTop>(this)); - strategies->push_back(std::make_unique<OverlayStrategyUnderlay>( - this, OverlayStrategyUnderlay::OpaqueMode::AllowTransparentCandidates)); - } - bool AllowCALayerOverlays() override { return false; } - bool AllowDCLayerOverlays() override { return false; } - void CheckOverlaySupport(OverlayCandidateList* surfaces) override { - DCHECK(!surfaces->empty()); - - // Only update the last candidate that was added to the list. All previous - // overlays should have already been handled. - auto& candidate = surfaces->back(); - if (!gl::SurfaceControl::SupportsColorSpace(candidate.color_space)) { - DCHECK(!candidate.use_output_surface_for_resource) - << "The main overlay must only use color space supported by the " - "device"; - candidate.overlay_handled = false; - return; - } - - candidate.display_rect = - gfx::RectF(gfx::ToEnclosingRect(candidate.display_rect)); - candidate.overlay_handled = true; - -#if DCHECK_IS_ON() - for (auto& candidate : *surfaces) - DCHECK(candidate.overlay_handled); -#endif - } -}; - -} // namespace GLOutputSurfaceBufferQueueAndroid::GLOutputSurfaceBufferQueueAndroid( scoped_refptr<VizProcessContextProvider> context_provider, @@ -66,16 +19,16 @@ synthetic_begin_frame_source, gpu_memory_buffer_manager, GL_TEXTURE_2D, - buffer_format), - overlay_candidate_validator_( - std::make_unique<OverlayCandidateValidatorImpl>()) {} + buffer_format) {} GLOutputSurfaceBufferQueueAndroid::~GLOutputSurfaceBufferQueueAndroid() = default; OverlayCandidateValidator* GLOutputSurfaceBufferQueueAndroid::GetOverlayCandidateValidator() const { - return overlay_candidate_validator_.get(); + // TODO(khushalsagar): The API shouldn't be const. + return &const_cast<GLOutputSurfaceBufferQueueAndroid*>(this) + ->overlay_candidate_validator_; } } // namespace viz
diff --git a/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.h b/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.h index 134006f..bf8f72c 100644 --- a/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.h +++ b/components/viz/service/display_embedder/gl_output_surface_buffer_queue_android.h
@@ -6,6 +6,8 @@ #define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_GL_OUTPUT_SURFACE_BUFFER_QUEUE_ANDROID_H_ #include "components/viz/service/display_embedder/gl_output_surface_buffer_queue.h" + +#include "components/viz/service/display_embedder/overlay_candidate_validator_android.h" #include "ui/gfx/buffer_types.h" namespace viz { @@ -24,7 +26,7 @@ OverlayCandidateValidator* GetOverlayCandidateValidator() const override; private: - std::unique_ptr<OverlayCandidateValidator> overlay_candidate_validator_; + OverlayCandidateValidatorAndroid overlay_candidate_validator_; DISALLOW_COPY_AND_ASSIGN(GLOutputSurfaceBufferQueueAndroid); };
diff --git a/components/viz/service/display_embedder/overlay_candidate_validator_android.cc b/components/viz/service/display_embedder/overlay_candidate_validator_android.cc new file mode 100644 index 0000000..78b1392 --- /dev/null +++ b/components/viz/service/display_embedder/overlay_candidate_validator_android.cc
@@ -0,0 +1,93 @@ +// 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/viz/service/display_embedder/overlay_candidate_validator_android.h" + +#include "cc/base/math_util.h" +#include "components/viz/service/display/overlay_strategy_fullscreen.h" +#include "components/viz/service/display/overlay_strategy_single_on_top.h" +#include "components/viz/service/display/overlay_strategy_underlay.h" +#include "ui/gfx/geometry/rect_conversions.h" +#include "ui/gl/android/android_surface_control_compat.h" + +namespace viz { +namespace { + +gfx::RectF ClipFromOrigin(gfx::RectF input) { + if (input.x() < 0.f) { + input.set_width(input.width() + input.x()); + input.set_x(0.f); + } + + if (input.y() < 0) { + input.set_height(input.height() + input.y()); + input.set_y(0.f); + } + + return input; +} + +} // namespace + +OverlayCandidateValidatorAndroid::OverlayCandidateValidatorAndroid() = default; +OverlayCandidateValidatorAndroid::~OverlayCandidateValidatorAndroid() = default; + +void OverlayCandidateValidatorAndroid::GetStrategies( + OverlayProcessor::StrategyList* strategies) { + // Added in priority order, most to least desirable. + strategies->push_back(std::make_unique<OverlayStrategyFullscreen>(this)); + strategies->push_back(std::make_unique<OverlayStrategySingleOnTop>(this)); + strategies->push_back(std::make_unique<OverlayStrategyUnderlay>( + this, OverlayStrategyUnderlay::OpaqueMode::AllowTransparentCandidates)); +} + +bool OverlayCandidateValidatorAndroid::AllowCALayerOverlays() { + return false; +} + +bool OverlayCandidateValidatorAndroid::AllowDCLayerOverlays() { + return false; +} + +void OverlayCandidateValidatorAndroid::CheckOverlaySupport( + OverlayCandidateList* surfaces) { + DCHECK(!surfaces->empty()); + + // Only update the last candidate that was added to the list. All previous + // overlays should have already been handled. + auto& candidate = surfaces->back(); + if (!gl::SurfaceControl::SupportsColorSpace(candidate.color_space)) { + DCHECK(!candidate.use_output_surface_for_resource) + << "The main overlay must only use color space supported by the " + "device"; + candidate.overlay_handled = false; + return; + } + + const gfx::RectF orig_display_rect = + gfx::RectF(gfx::ToEnclosingRect(candidate.display_rect)); + + candidate.display_rect = orig_display_rect; + if (candidate.is_clipped) + candidate.display_rect.Intersect(gfx::RectF(candidate.clip_rect)); + + // The framework doesn't support display rects positioned at a negative + // offset. + candidate.display_rect = ClipFromOrigin(candidate.display_rect); + if (candidate.display_rect.IsEmpty()) { + candidate.overlay_handled = false; + return; + } + + candidate.uv_rect = cc::MathUtil::ScaleRectProportional( + candidate.uv_rect, orig_display_rect, candidate.display_rect); + candidate.overlay_handled = true; + +#if DCHECK_IS_ON() + for (auto& candidate : *surfaces) + DCHECK(candidate.overlay_handled); +#endif +} + +} // namespace viz
diff --git a/components/viz/service/display_embedder/overlay_candidate_validator_android.h b/components/viz/service/display_embedder/overlay_candidate_validator_android.h new file mode 100644 index 0000000..ee498faba --- /dev/null +++ b/components/viz/service/display_embedder/overlay_candidate_validator_android.h
@@ -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. + +#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_OVERLAY_CANDIDATE_VALIDATOR_ANDROID_H_ +#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_OVERLAY_CANDIDATE_VALIDATOR_ANDROID_H_ + +#include "components/viz/service/display/overlay_candidate_validator.h" +#include "components/viz/service/viz_service_export.h" + +namespace viz { + +class VIZ_SERVICE_EXPORT OverlayCandidateValidatorAndroid + : public OverlayCandidateValidator { + public: + OverlayCandidateValidatorAndroid(); + ~OverlayCandidateValidatorAndroid() override; + + void GetStrategies(OverlayProcessor::StrategyList* strategies) override; + bool AllowCALayerOverlays() override; + bool AllowDCLayerOverlays() override; + void CheckOverlaySupport(OverlayCandidateList* surfaces) override; + + private: + DISALLOW_COPY_AND_ASSIGN(OverlayCandidateValidatorAndroid); +}; + +} // namespace viz + +#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_OVERLAY_CANDIDATE_VALIDATOR_ANDROID_H_
diff --git a/components/viz/service/display_embedder/overlay_candidate_validator_android_unittest.cc b/components/viz/service/display_embedder/overlay_candidate_validator_android_unittest.cc new file mode 100644 index 0000000..6ba5a5ec --- /dev/null +++ b/components/viz/service/display_embedder/overlay_candidate_validator_android_unittest.cc
@@ -0,0 +1,87 @@ +// 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/viz/service/display_embedder/overlay_candidate_validator_android.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/test/gfx_util.h" + +namespace viz { + +TEST(OverlayCandidateValidatorAndroidTest, NoClipOrNegativeOffset) { + OverlayCandidate candidate; + candidate.display_rect = gfx::RectF(10.f, 10.f); + candidate.uv_rect = gfx::RectF(1.f, 1.f); + candidate.is_clipped = false; + candidate.clip_rect = gfx::Rect(5, 5); + candidate.overlay_handled = false; + + OverlayCandidateList candidates; + candidates.push_back(candidate); + + OverlayCandidateValidatorAndroid validator; + validator.CheckOverlaySupport(&candidates); + EXPECT_TRUE(candidates.at(0).overlay_handled); + EXPECT_RECTF_EQ(candidates.at(0).display_rect, gfx::RectF(10.f, 10.f)); +} + +TEST(OverlayCandidateValidatorAndroidTest, Clipped) { + OverlayCandidate candidate; + candidate.display_rect = gfx::RectF(10.f, 10.f); + candidate.uv_rect = gfx::RectF(1.f, 1.f); + candidate.is_clipped = true; + candidate.clip_rect = gfx::Rect(2, 2, 5, 5); + candidate.overlay_handled = false; + + OverlayCandidateList candidates; + candidates.push_back(candidate); + + OverlayCandidateValidatorAndroid validator; + validator.CheckOverlaySupport(&candidates); + EXPECT_TRUE(candidates.at(0).overlay_handled); + EXPECT_RECTF_EQ(candidates.at(0).display_rect, + gfx::RectF(2.f, 2.f, 5.f, 5.f)); + EXPECT_RECTF_EQ(candidates.at(0).uv_rect, gfx::RectF(0.2f, 0.2f, 0.5f, 0.5f)); +} + +TEST(OverlayCandidateValidatorAndroidTest, NegativeOffset) { + OverlayCandidate candidate; + candidate.display_rect = gfx::RectF(-2.f, -4.f, 10.f, 10.f); + candidate.uv_rect = gfx::RectF(0.5f, 0.5f); + candidate.is_clipped = false; + candidate.clip_rect = gfx::Rect(5, 5); + candidate.overlay_handled = false; + + OverlayCandidateList candidates; + candidates.push_back(candidate); + + OverlayCandidateValidatorAndroid validator; + validator.CheckOverlaySupport(&candidates); + EXPECT_TRUE(candidates.at(0).overlay_handled); + EXPECT_RECTF_EQ(candidates.at(0).display_rect, + gfx::RectF(0.f, 0.f, 8.f, 6.f)); + EXPECT_RECTF_EQ(candidates.at(0).uv_rect, gfx::RectF(0.1f, 0.2f, 0.4f, 0.3f)); +} + +TEST(OverlayCandidateValidatorAndroidTest, ClipAndNegativeOffset) { + OverlayCandidate candidate; + candidate.display_rect = gfx::RectF(-5.0f, -5.0f, 10.0f, 10.0f); + candidate.uv_rect = gfx::RectF(0.5f, 0.5f, 0.5f, 0.5f); + candidate.is_clipped = true; + candidate.clip_rect = gfx::Rect(5, 5); + candidate.overlay_handled = false; + + OverlayCandidateList candidates; + candidates.push_back(candidate); + + OverlayCandidateValidatorAndroid validator; + validator.CheckOverlaySupport(&candidates); + EXPECT_TRUE(candidates.at(0).overlay_handled); + EXPECT_RECTF_EQ(candidates.at(0).display_rect, + gfx::RectF(0.f, 0.f, 5.f, 5.f)); + EXPECT_RECTF_EQ(candidates.at(0).uv_rect, + gfx::RectF(0.75f, 0.75f, 0.25f, 0.25f)); +} + +} // namespace viz
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 5e1af789..0fb8ca1c 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
@@ -579,7 +579,10 @@ // |context_provider_| and clients want either the context to be lost or made // current on destruction. - MakeCurrent(false /* need_fbo0 */); + if (MakeCurrent(false /* need_fbo0 */)) { + // This ensures any outstanding callbacks for promise images are performed. + gr_context()->flush(); + } copier_ = nullptr; texture_deleter_ = nullptr; context_provider_ = nullptr;
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc index 1ef6ae0..1b70c10 100644 --- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc +++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc
@@ -174,7 +174,8 @@ gfx::Rect rect1(display_rect_); shared_quad_state1->SetAll( gfx::Transform(), rect1 /* quad_layer_rect */, - rect1 /* visible_quad_layer_rect */, rect1 /*clip_rect */, + rect1 /* visible_quad_layer_rect */, + gfx::RRectF() /* rounded_corner_bounds */, rect1 /*clip_rect */, false /* is_clipped */, false /* are_contents_opaque */, 0.5f /* opacity */, SkBlendMode::kSrcOver, 0 /* sorting_context_id */); auto* quad1 = pass1->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); @@ -210,7 +211,8 @@ transform2.Translate(-200, -100); shared_quad_state2->SetAll( transform2, rect2 /* quad_layer_rect */, - rect2 /* visible_quad_layer_rect */, rect2 /*clip_rect */, + rect2 /* visible_quad_layer_rect */, + gfx::RRectF() /* rounded_corner_bounds */, rect2 /*clip_rect */, false /* is_clipped */, false /* are_contents_opaque */, 0.5f /* opacity */, SkBlendMode::kSrcOver, 0 /* sorting_context_id */); auto* quad2 = pass2->quad_list.AllocateAndConstruct<SurfaceDrawQuad>(); @@ -227,7 +229,8 @@ gfx::Rect rect3(display_rect_); shared_quad_state3->SetAll( gfx::Transform(), rect3 /* quad_layer_rect */, - rect3 /* visible_quad_layer_rect */, rect3 /*clip_rect */, + rect3 /* visible_quad_layer_rect */, + gfx::RRectF() /* rounded_corner_bounds */, rect3 /*clip_rect */, false /* is_clipped */, false /* are_contents_opaque */, 0.5f /* opacity */, SkBlendMode::kSrcOver, 0 /* sorting_context_id */); auto* quad3 = pass3->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); @@ -250,7 +253,8 @@ transform4.matrix().set(3, 3, 0.f); shared_quad_state4->SetAll( transform4, rect4 /* quad_layer_rect */, - rect4 /* visible_quad_layer_rect */, rect4 /*clip_rect */, + rect4 /* visible_quad_layer_rect */, + gfx::RRectF() /* rounded_corner_bounds */, rect4 /*clip_rect */, false /* is_clipped */, false /* are_contents_opaque */, 0.5f /* opacity */, SkBlendMode::kSrcOver, 0 /* sorting_context_id */); auto* quad4 = pass4->quad_list.AllocateAndConstruct<SurfaceDrawQuad>(); @@ -267,7 +271,8 @@ gfx::Rect rect5_root(display_rect_); shared_quad_state5_root->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect5_root, - /*visible_quad_layer_rect=*/rect5_root, /*clip_rect=*/rect5_root, + /*visible_quad_layer_rect=*/rect5_root, + gfx::RRectF() /* rounded_corner_bounds */, /*clip_rect=*/rect5_root, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad5_root_1 = @@ -332,7 +337,8 @@ gfx::Rect rect1(display_rect_); shared_quad_state1->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect1, - /*visible_quad_layer_rect=*/rect1, /*clip_rect=*/rect1, + /*visible_quad_layer_rect=*/rect1, + gfx::RRectF() /* rounded_corner_bounds */, /*clip_rect=*/rect1, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad1 = pass1->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); @@ -352,7 +358,8 @@ gfx::Rect rect2(display_rect_); shared_quad_state2->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect2, - /*visible_quad_layer_rect=*/rect2, /*clip_rect=*/rect2, + /*visible_quad_layer_rect=*/rect2, + gfx::RRectF() /* rounded_corner_bounds */, /*clip_rect=*/rect2, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad2 = pass2->quad_list.AllocateAndConstruct<SolidColorDrawQuad>(); @@ -384,7 +391,8 @@ transform3_0.Translate(-200, -100); shared_quad_state3_0->SetAll( transform3_0, /*quad_layer_rect=*/rect3_0, - /*visible_quad_layer_rect=*/rect3_0, /*clip_rect=*/rect3_0, + /*visible_quad_layer_rect=*/rect3_0, + gfx::RRectF() /* rounded_corner_bounds */, /*clip_rect=*/rect3_0, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad3_0 = pass3_0->quad_list.AllocateAndConstruct<SurfaceDrawQuad>(); @@ -403,7 +411,8 @@ gfx::Rect rect3_1(display_rect_); shared_quad_state3_1->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect3_1, - /*visible_quad_layer_rect=*/rect3_1, /*clip_rect=*/rect3_1, + /*visible_quad_layer_rect=*/rect3_1, + gfx::RRectF() /* rounded_corner_bounds */, /*clip_rect=*/rect3_1, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad3_1 = @@ -421,7 +430,8 @@ gfx::Rect rect3_root(display_rect_); shared_quad_state3_root->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect3_root, - /*visible_quad_layer_rect=*/rect3_root, /*clip_rect=*/rect3_root, + /*visible_quad_layer_rect=*/rect3_root, + gfx::RRectF() /* rounded_corner_bounds */, /*clip_rect=*/rect3_root, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad3_root_1 = @@ -456,7 +466,8 @@ transform4_0.Translate(-199, -100); shared_quad_state4_0->SetAll( transform4_0, /*quad_layer_rect=*/rect4_0, - /*visible_quad_layer_rect=*/rect4_0, /*clip_rect=*/rect4_0, + /*visible_quad_layer_rect=*/rect4_0, + gfx::RRectF() /* rounded_corner_bounds */, /*clip_rect=*/rect4_0, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad4_0 = pass4_0->quad_list.AllocateAndConstruct<SurfaceDrawQuad>(); @@ -475,7 +486,8 @@ gfx::Rect rect4_1(display_rect_); shared_quad_state4_1->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect4_1, - /*visible_quad_layer_rect=*/rect4_1, /*clip_rect=*/rect4_1, + /*visible_quad_layer_rect=*/rect4_1, + gfx::RRectF() /* rounded_corner_bounds */, /*clip_rect=*/rect4_1, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad4_1 = @@ -493,7 +505,8 @@ gfx::Rect rect4_root(display_rect_); shared_quad_state4_root->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect4_root, - /*visible_quad_layer_rect=*/rect4_root, /*clip_rect=*/rect4_root, + /*visible_quad_layer_rect=*/rect4_root, + gfx::RRectF() /* rounded_corner_bounds */, /*clip_rect=*/rect4_root, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad4_root_1 = @@ -530,7 +543,8 @@ transform5_0.Translate(-199, -100); shared_quad_state5_0->SetAll( transform5_0, /*quad_layer_rect=*/rect5_0, - /*visible_quad_layer_rect=*/rect5_0, /*clip_rect=*/rect5_0, + /*visible_quad_layer_rect=*/rect5_0, + gfx::RRectF() /* rounded_corner_bounds */, /*clip_rect=*/rect5_0, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad5_0 = pass5_0->quad_list.AllocateAndConstruct<SurfaceDrawQuad>(); @@ -549,7 +563,8 @@ gfx::Rect rect5_1(display_rect_); shared_quad_state5_1->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect5_1, - /*visible_quad_layer_rect=*/rect5_1, /*clip_rect=*/rect5_1, + /*visible_quad_layer_rect=*/rect5_1, + gfx::RRectF() /* rounded_corner_bounds */, /*clip_rect=*/rect5_1, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad5_1 = @@ -567,7 +582,8 @@ gfx::Rect rect5_root(display_rect_); shared_quad_state5_root->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect5_root, - /*visible_quad_layer_rect=*/rect5_root, /*clip_rect=*/rect5_root, + /*visible_quad_layer_rect=*/rect5_root, + gfx::RRectF() /* rounded_corner_bounds */, /*clip_rect=*/rect5_root, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad5_root_1 = @@ -605,7 +621,8 @@ transform6_0.Translate(-199, -100); shared_quad_state6_0->SetAll( transform6_0, /*quad_layer_rect=*/rect6_0, - /*visible_quad_layer_rect=*/rect6_0, /*clip_rect=*/rect6_0, + /*visible_quad_layer_rect=*/rect6_0, + gfx::RRectF() /* rounded_corner_bounds */, /*clip_rect=*/rect6_0, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad6_0 = pass6_0->quad_list.AllocateAndConstruct<SurfaceDrawQuad>(); @@ -624,7 +641,8 @@ gfx::Rect rect6_1(display_rect_); shared_quad_state6_1->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect6_1, - /*visible_quad_layer_rect=*/rect6_1, /*clip_rect=*/rect6_1, + /*visible_quad_layer_rect=*/rect6_1, + gfx::RRectF() /* rounded_corner_bounds */, /*clip_rect=*/rect6_1, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad6_1 = @@ -642,7 +660,8 @@ gfx::Rect rect6_root(display_rect_); shared_quad_state6_root->SetAll( gfx::Transform(), /*quad_layer_rect=*/rect6_root, - /*visible_quad_layer_rect=*/rect6_root, /*clip_rect=*/rect6_root, + /*visible_quad_layer_rect=*/rect6_root, + gfx::RRectF() /* rounded_corner_bounds */, /*clip_rect=*/rect6_root, /*is_clipped=*/false, /*are_contents_opaque=*/false, /*opacity=*/0.6f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0); auto* quad6_root_1 =
diff --git a/components/viz/test/surface_hittest_test_helpers.cc b/components/viz/test/surface_hittest_test_helpers.cc index 0d19edf..4e3ec60 100644 --- a/components/viz/test/surface_hittest_test_helpers.cc +++ b/components/viz/test/surface_hittest_test_helpers.cc
@@ -18,8 +18,9 @@ const gfx::Transform& transform, const gfx::Rect& root_rect) { SharedQuadState* child_shared_state = pass->CreateAndAppendSharedQuadState(); - child_shared_state->SetAll(transform, root_rect, root_rect, root_rect, false, - false, 1.0f, SkBlendMode::kSrcOver, 0); + child_shared_state->SetAll(transform, root_rect, root_rect, gfx::RRectF(), + root_rect, false, false, 1.0f, + SkBlendMode::kSrcOver, 0); } void CreateSolidColorDrawQuad(RenderPass* pass,
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index e7f5b90a..3d6d1cd 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -186,6 +186,7 @@ "//third_party/boringssl", "//third_party/brotli:dec", "//third_party/icu", + "//third_party/inspector_protocol:encoding", "//third_party/libyuv", "//third_party/re2", "//third_party/sqlite", @@ -477,6 +478,8 @@ "background_fetch/storage/start_next_pending_request_task.h", "background_sync/background_sync_context_impl.cc", "background_sync/background_sync_context_impl.h", + "background_sync/background_sync_launcher.cc", + "background_sync/background_sync_launcher.h", "background_sync/background_sync_manager.cc", "background_sync/background_sync_manager.h", "background_sync/background_sync_metrics.cc", @@ -660,6 +663,8 @@ "devtools/devtools_renderer_channel.h", "devtools/devtools_session.cc", "devtools/devtools_session.h", + "devtools/devtools_session_encoding.cc", + "devtools/devtools_session_encoding.h", "devtools/devtools_stream_blob.cc", "devtools/devtools_stream_blob.h", "devtools/devtools_stream_file.cc", @@ -1651,8 +1656,6 @@ "service_worker/service_worker_context_core.cc", "service_worker/service_worker_context_core.h", "service_worker/service_worker_context_core_observer.h", - "service_worker/service_worker_context_request_handler.cc", - "service_worker/service_worker_context_request_handler.h", "service_worker/service_worker_context_watcher.cc", "service_worker/service_worker_context_watcher.h", "service_worker/service_worker_context_wrapper.cc",
diff --git a/content/browser/background_sync/background_sync.proto b/content/browser/background_sync/background_sync.proto index c65aed9..b1ba296 100644 --- a/content/browser/background_sync/background_sync.proto +++ b/content/browser/background_sync/background_sync.proto
@@ -14,6 +14,10 @@ NETWORK_STATE_ONLINE = 2; } +message PeriodicSyncOptions { + optional int64 min_interval = 1; +} + message BackgroundSyncRegistrationProto { // required int64 id = 1; required string tag = 2; @@ -23,6 +27,7 @@ // required SyncPowerState power_state = 6; required int32 num_attempts = 7; required int64 delay_until = 8; + optional PeriodicSyncOptions periodic_sync_options = 9; } message BackgroundSyncRegistrationsProto {
diff --git a/content/browser/background_sync/background_sync_context_impl.cc b/content/browser/background_sync/background_sync_context_impl.cc index e2e9b9ce..231111d 100644 --- a/content/browser/background_sync/background_sync_context_impl.cc +++ b/content/browser/background_sync/background_sync_context_impl.cc
@@ -9,6 +9,8 @@ #include "base/bind.h" #include "base/stl_util.h" #include "base/task/post_task.h" +#include "build/build_config.h" +#include "content/browser/background_sync/background_sync_launcher.h" #include "content/browser/background_sync/background_sync_manager.h" #include "content/browser/background_sync/background_sync_service_impl.h" #include "content/browser/devtools/devtools_background_services_context.h" @@ -80,10 +82,32 @@ background_sync_manager_ = std::move(manager); } -void BackgroundSyncContextImpl::FireBackgroundSyncEventsForStoragePartition( - content::StoragePartition* storage_partition, +void BackgroundSyncContextImpl::set_wakeup_delta_for_testing( + base::TimeDelta wakeup_delta) { + test_wakeup_delta_ = wakeup_delta; +} + +base::TimeDelta BackgroundSyncContextImpl::GetSoonestWakeupDelta() { + if (!test_wakeup_delta_.is_max()) + return test_wakeup_delta_; + + if (!background_sync_manager_) + return base::TimeDelta::Max(); + + return background_sync_manager_->GetSoonestWakeupDelta(); +} + +void BackgroundSyncContextImpl::GetSoonestWakeupDeltaAcrossPartitions( + BrowserContext* browser_context, + base::OnceCallback<void(base::TimeDelta)> callback) { + DCHECK(browser_context); + + BackgroundSyncLauncher::GetSoonestWakeupDelta(browser_context, + std::move(callback)); +} + +void BackgroundSyncContextImpl::FireBackgroundSyncEvents( base::OnceClosure done_closure) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); if (!background_sync_manager_) { std::move(done_closure).Run(); return; @@ -92,6 +116,15 @@ std::move(done_closure)); } +#if defined(OS_ANDROID) +void BackgroundSyncContextImpl::FireBackgroundSyncEventsAcrossPartitions( + BrowserContext* browser_context, + const base::android::JavaParamRef<jobject>& j_runnable) { + DCHECK(browser_context); + BackgroundSyncLauncher::FireBackgroundSyncEvents(browser_context, j_runnable); +} +#endif + void BackgroundSyncContextImpl::CreateBackgroundSyncManager( scoped_refptr<ServiceWorkerContextWrapper> service_worker_context, scoped_refptr<DevToolsBackgroundServicesContext> devtools_context) {
diff --git a/content/browser/background_sync/background_sync_context_impl.h b/content/browser/background_sync/background_sync_context_impl.h index 9365f80b..68c33276 100644 --- a/content/browser/background_sync/background_sync_context_impl.h +++ b/content/browser/background_sync/background_sync_context_impl.h
@@ -11,6 +11,8 @@ #include "base/macros.h" #include "base/memory/ref_counted_delete_on_sequence.h" #include "base/memory/scoped_refptr.h" +#include "base/time/time.h" +#include "build/build_config.h" #include "content/common/content_export.h" #include "content/public/browser/background_sync_context.h" #include "third_party/blink/public/mojom/background_sync/background_sync.mojom.h" @@ -54,9 +56,16 @@ BackgroundSyncManager* background_sync_manager() const; // BackgroundSyncContext implementation. - void FireBackgroundSyncEventsForStoragePartition( - content::StoragePartition* storage_partition, - base::OnceClosure done_closure) override; + void FireBackgroundSyncEvents(base::OnceClosure done_closure) override; +#if defined(OS_ANDROID) + void FireBackgroundSyncEventsAcrossPartitions( + BrowserContext* browser_context, + const base::android::JavaParamRef<jobject>& j_runnable) override; +#endif + base::TimeDelta GetSoonestWakeupDelta() override; + void GetSoonestWakeupDeltaAcrossPartitions( + BrowserContext* browser_context, + base::OnceCallback<void(base::TimeDelta)> callback) override; protected: friend class base::RefCountedDeleteOnSequence<BackgroundSyncContextImpl>; @@ -65,9 +74,11 @@ void set_background_sync_manager_for_testing( std::unique_ptr<BackgroundSyncManager> manager); + void set_wakeup_delta_for_testing(base::TimeDelta wakeup_delta); private: friend class BackgroundSyncServiceImplTest; + friend class BackgroundSyncLauncherTest; virtual void CreateBackgroundSyncManager( scoped_refptr<ServiceWorkerContextWrapper> service_worker_context, @@ -87,6 +98,7 @@ std::map<BackgroundSyncServiceImpl*, std::unique_ptr<BackgroundSyncServiceImpl>> services_; + base::TimeDelta test_wakeup_delta_ = base::TimeDelta::Max(); DISALLOW_COPY_AND_ASSIGN(BackgroundSyncContextImpl); };
diff --git a/content/browser/background_sync/background_sync_launcher.cc b/content/browser/background_sync/background_sync_launcher.cc new file mode 100644 index 0000000..efab1e5 --- /dev/null +++ b/content/browser/background_sync/background_sync_launcher.cc
@@ -0,0 +1,120 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/background_sync/background_sync_launcher.h" + +#include <utility> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/time/time.h" +#include "build/build_config.h" +#include "content/public/browser/background_sync_context.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/storage_partition.h" +#if defined(OS_ANDROID) +#include "base/android/callback_android.h" +#include "base/barrier_closure.h" +#endif + +namespace content { + +namespace { + +base::LazyInstance<BackgroundSyncLauncher>::DestructorAtExit + g_background_sync_launcher = LAZY_INSTANCE_INITIALIZER; + +#if defined(OS_ANDROID) +unsigned int GetStoragePartitionCount(BrowserContext* browser_context) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(browser_context); + + int num_partitions = 0; + BrowserContext::ForEachStoragePartition( + browser_context, + base::BindRepeating( + [](int* num_partitions, StoragePartition* storage_partition) { + (*num_partitions)++; + }, + &num_partitions)); + + // It's valid for a profile to not have any storage partitions. This DCHECK + // is to ensure that we're not waking up Chrome for no reason, because that's + // expensive and unnecessary. + DCHECK(num_partitions); + + return num_partitions; +} +#endif + +} // namespace + +// static +BackgroundSyncLauncher* BackgroundSyncLauncher::Get() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + return g_background_sync_launcher.Pointer(); +} + +// static +void BackgroundSyncLauncher::GetSoonestWakeupDelta( + BrowserContext* browser_context, + base::OnceCallback<void(base::TimeDelta)> callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + base::TimeDelta soonest_wakeup_delta = base::TimeDelta::Max(); + BrowserContext::ForEachStoragePartition( + browser_context, base::BindRepeating( + [](base::TimeDelta* soonest_wakeup_delta, + StoragePartition* storage_partition) { + BackgroundSyncContext* sync_context = + storage_partition->GetBackgroundSyncContext(); + DCHECK(sync_context); + + base::TimeDelta wakeup_delta = + sync_context->GetSoonestWakeupDelta(); + if (wakeup_delta < *soonest_wakeup_delta) + *soonest_wakeup_delta = wakeup_delta; + }, + &soonest_wakeup_delta)); + std::move(callback).Run(soonest_wakeup_delta); +} + +// static +#if defined(OS_ANDROID) +void BackgroundSyncLauncher::FireBackgroundSyncEvents( + BrowserContext* browser_context, + const base::android::JavaParamRef<jobject>& j_runnable) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(browser_context); + + base::RepeatingClosure done_closure = base::BarrierClosure( + GetStoragePartitionCount(browser_context), + base::BindOnce(base::android::RunRunnableAndroid, + base::android::ScopedJavaGlobalRef<jobject>(j_runnable))); + + BrowserContext::ForEachStoragePartition( + browser_context, + base::BindRepeating( + [](base::RepeatingClosure done_closure, + StoragePartition* storage_partition) { + BackgroundSyncContext* sync_context = + storage_partition->GetBackgroundSyncContext(); + DCHECK(sync_context); + sync_context->FireBackgroundSyncEvents(std::move(done_closure)); + }, + std::move(done_closure))); +} +#endif + +BackgroundSyncLauncher::BackgroundSyncLauncher() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); +} + +BackgroundSyncLauncher::~BackgroundSyncLauncher() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); +} + +} // namespace content \ No newline at end of file
diff --git a/content/browser/background_sync/background_sync_launcher.h b/content/browser/background_sync/background_sync_launcher.h new file mode 100644 index 0000000..28d6acba --- /dev/null +++ b/content/browser/background_sync/background_sync_launcher.h
@@ -0,0 +1,49 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_LAUNCHER_H_ +#define CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_LAUNCHER_H_ + +#include "base/callback_forward.h" +#include "base/lazy_instance.h" +#include "base/time/time.h" +#include "build/build_config.h" +#include "content/common/content_export.h" + +#if defined(OS_ANDROID) +#include "base/android/jni_android.h" +#include "base/android/scoped_java_ref.h" +#endif + +namespace content { + +class BrowserContext; + +class CONTENT_EXPORT BackgroundSyncLauncher { + public: + static BackgroundSyncLauncher* Get(); + static void GetSoonestWakeupDelta( + BrowserContext* browser_context, + base::OnceCallback<void(base::TimeDelta)> callback); +#if defined(OS_ANDROID) + static void FireBackgroundSyncEvents( + BrowserContext* browser_context, + const base::android::JavaParamRef<jobject>& j_runnable); +#endif + + private: + friend struct base::LazyInstanceTraitsBase<BackgroundSyncLauncher>; + friend class BackgroundSyncLauncherTest; + + // Constructor and destructor marked private to enforce singleton. + BackgroundSyncLauncher(); + ~BackgroundSyncLauncher(); + + base::TimeDelta soonest_wakeup_delta_ = base::TimeDelta::Max(); + DISALLOW_COPY_AND_ASSIGN(BackgroundSyncLauncher); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_LAUNCHER_H_ \ No newline at end of file
diff --git a/content/browser/background_sync/background_sync_launcher_unittest.cc b/content/browser/background_sync/background_sync_launcher_unittest.cc new file mode 100644 index 0000000..6a81ee3 --- /dev/null +++ b/content/browser/background_sync/background_sync_launcher_unittest.cc
@@ -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. + +#include "content/browser/background_sync/background_sync_launcher.h" + +#include <map> +#include <vector> + +#include "base/callback_forward.h" +#include "base/test/scoped_task_environment.h" +#include "base/time/time.h" +#include "content/browser/storage_partition_impl.h" +#include "content/common/content_export.h" +#include "content/public/browser/background_sync_context.h" +#include "content/public/browser/content_browser_client.h" +#include "content/public/common/content_client.h" +#include "content/public/test/test_browser_context.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace content { + +namespace { + +const char kUrl_1[] = "https://example.com"; +const char kUrl_2[] = "https://whereswaldo.com"; + +class TestBrowserClient : public ContentBrowserClient { + public: + TestBrowserClient() = default; + ~TestBrowserClient() override = default; + + void GetStoragePartitionConfigForSite(BrowserContext* browser_context, + const GURL& site, + bool can_be_default, + std::string* partition_domain, + std::string* partition_name, + bool* in_memory) override { + DCHECK(browser_context); + DCHECK(partition_domain); + DCHECK(partition_name); + + auto partition_num = std::to_string(++partition_count_); + *partition_domain = std::string("PartitionDomain") + partition_num; + *partition_name = std::string("Partition") + partition_num; + *in_memory = false; + } + + private: + int partition_count_ = 0; +}; + +} // namespace + +class BackgroundSyncLauncherTest : public testing::Test { + public: + BackgroundSyncLauncherTest() + : browser_thread_bundle_(TestBrowserThreadBundle::MainThreadType::UI) {} + + void SetUpBrowserContext(const std::vector<GURL>& urls, + const std::map<GURL, int>& wakeup_deltas = {}) { + DCHECK(!urls.empty()); + + for (const auto& url : urls) { + auto* storage_partition = BrowserContext::GetStoragePartitionForSite( + &test_browser_context_, url); + + auto iter = wakeup_deltas.find(url); + if (iter == wakeup_deltas.end()) + continue; + + static_cast<StoragePartitionImpl*>(storage_partition) + ->GetBackgroundSyncContext() + ->set_wakeup_delta_for_testing( + base::TimeDelta::FromMilliseconds(iter->second)); + } + } + + void SetUp() override { + original_client_ = SetBrowserClientForTesting(&browser_client_); + } + + void TearDown() override { SetBrowserClientForTesting(original_client_); } + + base::TimeDelta GetSoonestWakeupDelta() { + base::TimeDelta to_return; + BackgroundSyncLauncher::GetSoonestWakeupDelta( + &test_browser_context_, base::BindOnce( + [](base::TimeDelta* to_return, + base::TimeDelta soonest_wakeup_delta) { + DCHECK(to_return); + *to_return = soonest_wakeup_delta; + }, + &to_return)); + browser_thread_bundle_.RunUntilIdle(); + return to_return; + } + + protected: + TestBrowserClient browser_client_; + ContentBrowserClient* original_client_; + TestBrowserThreadBundle browser_thread_bundle_; + TestBrowserContext test_browser_context_; +}; + +// Tests that we pick the correct wake up delta for the one-shot Background +// Sync wake up task, across all storage partitions. +TEST_F(BackgroundSyncLauncherTest, CorrectSoonestWakeupDeltaIsPicked) { + std::vector<GURL> urls = {GURL(kUrl_1), GURL(kUrl_2)}; + + // Add two storage partitions. Verify that we set the soonest wake up delta + // to base::TimeDelta::Max(). This will cause cancellation of the wakeup + // task. + SetUpBrowserContext(urls); + EXPECT_TRUE(GetSoonestWakeupDelta().is_max()); + + // Add two more storage partitions, this time with wakeup_deltas. + // Verify that we pick the smaller of the two. + int delta_ms = 0; + std::map<GURL, int> wakeup_deltas; + for (const auto& url : urls) + wakeup_deltas[url] = delta_ms += 1000; + SetUpBrowserContext(urls, wakeup_deltas); + + EXPECT_EQ(GetSoonestWakeupDelta().InMilliseconds(), 1000); +} + +} // namespace content \ No newline at end of file
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc index b7f7d0a..de713b19 100644 --- a/content/browser/background_sync/background_sync_manager.cc +++ b/content/browser/background_sync/background_sync_manager.cc
@@ -33,6 +33,7 @@ #include "third_party/blink/public/common/service_worker/service_worker_type_converters.h" #include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h" #if defined(OS_ANDROID) #include "content/browser/android/background_sync_network_observer_android.h" @@ -42,6 +43,10 @@ namespace { +// The only allowed value of min_interval for one shot Background Sync +// registrations. +constexpr int kMinIntervalForOneShotSync = -1; + // The key used to index the background sync data in ServiceWorkerStorage. const char kBackgroundSyncUserDataKey[] = "BackgroundSyncUserData"; @@ -117,15 +122,13 @@ } void RunInBackgroundOnUIThread( - scoped_refptr<ServiceWorkerContextWrapper> sw_context_wrapper, - bool enabled, - int64_t min_ms) { + scoped_refptr<ServiceWorkerContextWrapper> sw_context_wrapper) { DCHECK_CURRENTLY_ON(BrowserThread::UI); BackgroundSyncController* background_sync_controller = GetBackgroundSyncControllerOnUIThread(sw_context_wrapper); if (background_sync_controller) { - background_sync_controller->RunInBackground(enabled, min_ms); + background_sync_controller->RunInBackground(); } } @@ -172,6 +175,12 @@ std::move(task).Run(std::move(callback)); } +blink::mojom::BackgroundSyncType GetBackgroundSyncType( + const blink::mojom::SyncRegistrationOptions& options) { + return options.min_interval >= 0 ? blink::mojom::BackgroundSyncType::PERIODIC + : blink::mojom::BackgroundSyncType::ONE_SHOT; +} + } // namespace BackgroundSyncManager::BackgroundSyncRegistrations:: @@ -213,6 +222,13 @@ return; } + if (options.min_interval < 0 && + options.min_interval != kMinIntervalForOneShotSync) { + RecordFailureAndPostError(BACKGROUND_SYNC_STATUS_NOT_ALLOWED, + std::move(callback)); + return; + } + op_scheduler_.ScheduleOperation( CacheStorageSchedulerOp::kBackgroundSync, base::BindOnce(&BackgroundSyncManager::RegisterCheckIfHasMainFrame, @@ -221,8 +237,10 @@ op_scheduler_.WrapCallbackToRunNext(std::move(callback)))); } -void BackgroundSyncManager::DidResolveRegistration(int64_t sw_registration_id, - const std::string& tag) { +void BackgroundSyncManager::DidResolveRegistration( + int64_t sw_registration_id, + const std::string& tag, + blink::mojom::BackgroundSyncType sync_type) { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (disabled_) @@ -230,7 +248,8 @@ op_scheduler_.ScheduleOperation( CacheStorageSchedulerOp::kBackgroundSync, base::BindOnce(&BackgroundSyncManager::DidResolveRegistrationImpl, - weak_ptr_factory_.GetWeakPtr(), sw_registration_id, tag)); + weak_ptr_factory_.GetWeakPtr(), sw_registration_id, tag, + sync_type)); } void BackgroundSyncManager::GetRegistrations( @@ -402,7 +421,6 @@ if (status != blink::ServiceWorkerStatusCode::kOk && status != blink::ServiceWorkerStatusCode::kErrorNotFound) { - LOG(ERROR) << "BackgroundSync failed to init due to backend failure."; DisableAndClearManager(std::move(callback)); return; } @@ -415,17 +433,29 @@ registrations->origin = url::Origin::Create(GURL(registrations_proto.origin())); - for (int i = 0, max = registrations_proto.registration_size(); i < max; - ++i) { - const BackgroundSyncRegistrationProto& registration_proto = - registrations_proto.registration(i); - + for (const auto& registration_proto : + registrations_proto.registration()) { + blink::mojom::BackgroundSyncType sync_type = + registration_proto.has_periodic_sync_options() + ? blink::mojom::BackgroundSyncType::PERIODIC + : blink::mojom::BackgroundSyncType::ONE_SHOT; BackgroundSyncRegistration* registration = - ®istrations->registration_map[registration_proto.tag()]; + ®istrations + ->registration_map[{registration_proto.tag(), sync_type}]; blink::mojom::SyncRegistrationOptions* options = registration->options(); options->tag = registration_proto.tag(); + if (sync_type == blink::mojom::BackgroundSyncType::PERIODIC) { + options->min_interval = + registration_proto.periodic_sync_options().min_interval(); + if (options->min_interval < 0) { + DisableAndClearManager(std::move(callback)); + return; + } + } else { + options->min_interval = kMinIntervalForOneShotSync; + } registration->set_num_attempts(registration_proto.num_attempts()); registration->set_delay_until( @@ -534,14 +564,15 @@ return; } + // TODO(crbug.com/925297): Record Periodic Sync metrics. base::PostTaskWithTraits( FROM_HERE, {BrowserThread::UI}, base::BindOnce( &NotifyBackgroundSyncRegisteredOnUIThread, service_worker_context_, url::Origin::Create(sw_registration->scope().GetOrigin()))); - BackgroundSyncRegistration* existing_registration = - LookupActiveRegistration(sw_registration_id, options.tag); + BackgroundSyncRegistration* existing_registration = LookupActiveRegistration( + sw_registration_id, options.tag, GetBackgroundSyncType(options)); if (existing_registration) { DCHECK(existing_registration->options()->Equals(options)); @@ -639,7 +670,8 @@ BackgroundSyncRegistration* BackgroundSyncManager::LookupActiveRegistration( int64_t sw_registration_id, - const std::string& tag) { + const std::string& tag, + blink::mojom::BackgroundSyncType sync_type) { DCHECK_CURRENTLY_ON(BrowserThread::IO); auto it = active_registrations_.find(sw_registration_id); @@ -649,7 +681,8 @@ BackgroundSyncRegistrations& registrations = it->second; DCHECK(!registrations.origin.opaque()); - auto key_and_registration_iter = registrations.registration_map.find(tag); + auto key_and_registration_iter = + registrations.registration_map.find({tag, sync_type}); if (key_and_registration_iter == registrations.registration_map.end()) return nullptr; @@ -673,6 +706,10 @@ BackgroundSyncRegistrationProto* registration_proto = registrations_proto.add_registration(); registration_proto->set_tag(registration.options()->tag); + if (registration.options()->min_interval >= 0) { + registration_proto->mutable_periodic_sync_options()->set_min_interval( + registration.options()->min_interval); + } registration_proto->set_num_attempts(registration.num_attempts()); registration_proto->set_delay_until( registration.delay_until().ToInternalValue()); @@ -729,10 +766,12 @@ void BackgroundSyncManager::DidResolveRegistrationImpl( int64_t sw_registration_id, - const std::string& tag) { + const std::string& tag, + blink::mojom::BackgroundSyncType sync_type) { DCHECK_CURRENTLY_ON(BrowserThread::IO); + BackgroundSyncRegistration* registration = - LookupActiveRegistration(sw_registration_id, tag); + LookupActiveRegistration(sw_registration_id, tag, sync_type); if (!registration) { // There might not be a registration if the client ack's a registration that // was a duplicate in the first place and was already firing and finished by @@ -746,15 +785,17 @@ op_scheduler_.CompleteOperationAndRunNext(); } -void BackgroundSyncManager::RemoveActiveRegistration(int64_t sw_registration_id, - const std::string& tag) { +void BackgroundSyncManager::RemoveActiveRegistration( + int64_t sw_registration_id, + const std::string& tag, + blink::mojom::BackgroundSyncType sync_type) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - DCHECK(LookupActiveRegistration(sw_registration_id, tag)); + DCHECK(LookupActiveRegistration(sw_registration_id, tag, sync_type)); BackgroundSyncRegistrations* registrations = &active_registrations_[sw_registration_id]; - registrations->registration_map.erase(tag); + registrations->registration_map.erase({tag, sync_type}); } void BackgroundSyncManager::AddActiveRegistration( @@ -767,10 +808,14 @@ &active_registrations_[sw_registration_id]; registrations->origin = origin; - registrations->registration_map[sync_registration.options()->tag] = + blink::mojom::BackgroundSyncType sync_type = + GetBackgroundSyncType(*sync_registration.options()); + registrations + ->registration_map[{sync_registration.options()->tag, sync_type}] = sync_registration; - if (devtools_context_->IsRecording(devtools::proto::BACKGROUND_SYNC)) { + if (devtools_context_->IsRecording(devtools::proto::BACKGROUND_SYNC) && + sync_type == blink::mojom::BackgroundSyncType::ONE_SHOT) { devtools_context_->LogBackgroundServiceEvent( sw_registration_id, origin, devtools::proto::BACKGROUND_SYNC, /* event_name= */ "Registered Sync", @@ -875,9 +920,9 @@ if (it != active_registrations_.end()) { const BackgroundSyncRegistrations& registrations = it->second; - for (const auto& tag_and_registration : registrations.registration_map) { + for (const auto& key_and_registration : registrations.registration_map) { const BackgroundSyncRegistration& registration = - tag_and_registration.second; + key_and_registration.second; out_registrations.push_back( std::make_unique<BackgroundSyncRegistration>(registration)); } @@ -915,10 +960,10 @@ return AreOptionConditionsMet(); } -void BackgroundSyncManager::RunInBackgroundIfNecessary() { +base::TimeDelta BackgroundSyncManager::GetSoonestWakeupDelta() { DCHECK_CURRENTLY_ON(BrowserThread::IO); - base::TimeDelta soonest_wakeup_delta = base::TimeDelta::Max(); + base::TimeDelta soonest_wakeup_delta = base::TimeDelta::Max(); for (const auto& sw_id_and_registrations : active_registrations_) { for (const auto& key_and_registration : sw_id_and_registrations.second.registration_map) { @@ -945,6 +990,14 @@ soonest_wakeup_delta = parameters_->min_sync_recovery_time; } + return soonest_wakeup_delta; +} + +void BackgroundSyncManager::RunInBackgroundIfNecessary() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + base::TimeDelta soonest_wakeup_delta = GetSoonestWakeupDelta(); + // Try firing again after the wakeup delta. if (!soonest_wakeup_delta.is_max() && !soonest_wakeup_delta.is_zero()) { delayed_sync_task_.Reset(base::Bind(&BackgroundSyncManager::FireReadyEvents, @@ -953,14 +1006,11 @@ } // In case the browser closes (or to prevent it from closing), call - // RunInBackground to either wake up the browser at the wakeup delta or to - // keep the browser running. + // RunInBackground to wake up the browser at the soonest wakeup delta across + // all the storage partitions. base::PostTaskWithTraits( FROM_HERE, {BrowserThread::UI}, - base::BindOnce( - RunInBackgroundOnUIThread, service_worker_context_, - !soonest_wakeup_delta.is_max() /* should run in background */, - soonest_wakeup_delta.InMilliseconds())); + base::BindOnce(RunInBackgroundOnUIThread, service_worker_context_)); } void BackgroundSyncManager::FireReadyEvents() { @@ -992,17 +1042,33 @@ } // Find the registrations that are ready to run. - std::vector<std::pair<int64_t, std::string>> sw_id_and_tags_to_fire; + struct RegistrationsToFire { + RegistrationsToFire(int64_t service_worker_registration_id_, + std::string tag_, + blink::mojom::BackgroundSyncType sync_type_) + : service_worker_registration_id(service_worker_registration_id_), + tag(tag_), + sync_type(sync_type_) {} + int64_t service_worker_registration_id; + std::string tag; + blink::mojom::BackgroundSyncType sync_type; + }; + std::vector<RegistrationsToFire> to_fire; for (auto& sw_id_and_registrations : active_registrations_) { - const int64_t service_worker_id = sw_id_and_registrations.first; + const int64_t service_worker_registration_id = + sw_id_and_registrations.first; for (auto& key_and_registration : sw_id_and_registrations.second.registration_map) { BackgroundSyncRegistration* registration = &key_and_registration.second; - if (IsRegistrationReadyToFire(*registration, service_worker_id)) { - sw_id_and_tags_to_fire.push_back( - std::make_pair(service_worker_id, key_and_registration.first)); + if (IsRegistrationReadyToFire(*registration, + service_worker_registration_id)) { + to_fire.emplace_back( + service_worker_registration_id, + /* tag= */ key_and_registration.first.first, + /* sync_type= */ key_and_registration.first.second); + // The state change is not saved to persistent storage because // if the sync event is killed mid-sync then it should return to // SYNC_STATE_PENDING. @@ -1011,7 +1077,7 @@ } } - if (sw_id_and_tags_to_fire.empty()) { + if (to_fire.empty()) { RunInBackgroundIfNecessary(); base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(callback)); @@ -1023,36 +1089,39 @@ // Fire the sync event of the ready registrations and run |callback| once // they're all done. base::RepeatingClosure events_fired_barrier_closure = base::BarrierClosure( - sw_id_and_tags_to_fire.size(), + to_fire.size(), base::BindOnce(&BackgroundSyncManager::FireReadyEventsAllEventsFiring, weak_ptr_factory_.GetWeakPtr(), std::move(callback))); // Record the total time taken after all events have run to completion. base::RepeatingClosure events_completed_barrier_closure = - base::BarrierClosure(sw_id_and_tags_to_fire.size(), + base::BarrierClosure(to_fire.size(), base::BindOnce(&OnAllSyncEventsCompleted, start_time, - sw_id_and_tags_to_fire.size())); + to_fire.size())); - for (const auto& sw_id_and_tag : sw_id_and_tags_to_fire) { - int64_t service_worker_id = sw_id_and_tag.first; - const BackgroundSyncRegistration* registration = - LookupActiveRegistration(service_worker_id, sw_id_and_tag.second); + for (auto& registration_info : to_fire) { + const BackgroundSyncRegistration* registration = LookupActiveRegistration( + registration_info.service_worker_registration_id, registration_info.tag, + registration_info.sync_type); DCHECK(registration); service_worker_context_->FindReadyRegistrationForId( - service_worker_id, - active_registrations_[service_worker_id].origin.GetURL(), + registration_info.service_worker_registration_id, + active_registrations_[registration_info.service_worker_registration_id] + .origin.GetURL(), base::BindOnce( &BackgroundSyncManager::FireReadyEventsDidFindRegistration, - weak_ptr_factory_.GetWeakPtr(), service_worker_id, - sw_id_and_tag.second, events_fired_barrier_closure, - events_completed_barrier_closure)); + weak_ptr_factory_.GetWeakPtr(), + registration_info.service_worker_registration_id, + std::move(registration_info.tag), registration_info.sync_type, + events_fired_barrier_closure, events_completed_barrier_closure)); } } void BackgroundSyncManager::FireReadyEventsDidFindRegistration( int64_t service_worker_id, const std::string& tag, + blink::mojom::BackgroundSyncType sync_type, base::OnceClosure event_fired_callback, base::OnceClosure event_completed_callback, blink::ServiceWorkerStatusCode service_worker_status, @@ -1060,7 +1129,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); BackgroundSyncRegistration* registration = - LookupActiveRegistration(service_worker_id, tag); + LookupActiveRegistration(service_worker_id, tag, sync_type); if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) { if (registration) @@ -1075,6 +1144,19 @@ DCHECK_EQ(service_worker_id, service_worker_registration->id()); DCHECK(registration); + // Don't dispatch a sync event if the sync is periodic. + // TODO(crbug.com/925297): Remove this code when we've added the logic to + // dispatch periodic sync events. + if (registration && sync_type == blink::mojom::BackgroundSyncType::PERIODIC) { + RemoveActiveRegistration(service_worker_id, tag, sync_type); + StoreRegistrations(service_worker_id, base::DoNothing()); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, std::move(event_fired_callback)); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, std::move(event_completed_callback)); + return; + } + const bool option_conditions_met = AreOptionConditionsMet(); UMA_HISTOGRAM_BOOLEAN("BackgroundSync.OptionConditionsChanged", !option_conditions_met); @@ -1099,13 +1181,13 @@ url::Origin::Create(service_worker_registration->scope().GetOrigin()), base::BindOnce(&BackgroundSyncMetrics::RecordEventStarted)); - DispatchSyncEvent(registration->options()->tag, - service_worker_registration->active_version(), last_chance, - base::BindOnce(&BackgroundSyncManager::EventComplete, - weak_ptr_factory_.GetWeakPtr(), - service_worker_registration, - service_worker_registration->id(), tag, - std::move(event_completed_callback))); + DispatchSyncEvent( + registration->options()->tag, + service_worker_registration->active_version(), last_chance, + base::BindOnce( + &BackgroundSyncManager::EventComplete, weak_ptr_factory_.GetWeakPtr(), + service_worker_registration, service_worker_registration->id(), tag, + sync_type, std::move(event_completed_callback))); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, std::move(event_fired_callback)); @@ -1125,6 +1207,7 @@ scoped_refptr<ServiceWorkerRegistration> service_worker_registration, int64_t service_worker_id, const std::string& tag, + blink::mojom::BackgroundSyncType sync_type, base::OnceClosure callback, blink::ServiceWorkerStatusCode status_code) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -1139,13 +1222,14 @@ CacheStorageSchedulerOp::kBackgroundSync, base::BindOnce(&BackgroundSyncManager::EventCompleteImpl, weak_ptr_factory_.GetWeakPtr(), service_worker_id, tag, - status_code, + sync_type, status_code, op_scheduler_.WrapCallbackToRunNext(std::move(callback)))); } void BackgroundSyncManager::EventCompleteImpl( int64_t service_worker_id, const std::string& tag, + blink::mojom::BackgroundSyncType sync_type, blink::ServiceWorkerStatusCode status_code, base::OnceClosure callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -1159,7 +1243,7 @@ num_firing_registrations_ -= 1; BackgroundSyncRegistration* registration = - LookupActiveRegistration(service_worker_id, tag); + LookupActiveRegistration(service_worker_id, tag, sync_type); if (!registration) { base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(callback)); @@ -1202,7 +1286,8 @@ registration->set_delay_until(clock_->Now() + delay); registration_completed = false; - if (devtools_context_->IsRecording(devtools::proto::BACKGROUND_SYNC)) { + if (devtools_context_->IsRecording(devtools::proto::BACKGROUND_SYNC) && + sync_type == blink::mojom::BackgroundSyncType::ONE_SHOT) { devtools_context_->LogBackgroundServiceEvent( sw_registration->id(), origin, devtools::proto::BACKGROUND_SYNC, /* event_name= */ "Sync Event Failed", @@ -1214,9 +1299,10 @@ } if (registration_completed) { - RemoveActiveRegistration(service_worker_id, tag); + RemoveActiveRegistration(service_worker_id, tag, sync_type); - if (devtools_context_->IsRecording(devtools::proto::BACKGROUND_SYNC)) { + if (devtools_context_->IsRecording(devtools::proto::BACKGROUND_SYNC) && + sync_type == blink::mojom::BackgroundSyncType::ONE_SHOT) { bool succeded = status_code == blink::ServiceWorkerStatusCode::kOk; devtools_context_->LogBackgroundServiceEvent( sw_registration->id(), origin, devtools::proto::BACKGROUND_SYNC,
diff --git a/content/browser/background_sync/background_sync_manager.h b/content/browser/background_sync/background_sync_manager.h index 14e4923..19f9917 100644 --- a/content/browser/background_sync/background_sync_manager.h +++ b/content/browser/background_sync/background_sync_manager.h
@@ -82,7 +82,8 @@ // Called after the client has resolved its registration promise. At this // point it's safe to fire any pending registrations. void DidResolveRegistration(int64_t sw_registration_id, - const std::string& tag); + const std::string& tag, + blink::mojom::BackgroundSyncType sync_type); // Finds the background sync registrations associated with // |sw_registration_id|. Calls |callback| with BACKGROUND_SYNC_STATUS_OK on @@ -123,6 +124,10 @@ // Once all of this is done, invokes |callback|. void FireReadyEventsThenRunCallback(base::OnceClosure callback); + // Gets the soonest delta after which the browser should be woken up to send + // a Background Sync event. If set to max, the browser won't be woken up. + virtual base::TimeDelta GetSoonestWakeupDelta(); + protected: BackgroundSyncManager( scoped_refptr<ServiceWorkerContextWrapper> context, @@ -156,7 +161,9 @@ friend class BackgroundSyncManagerTest; struct BackgroundSyncRegistrations { - using RegistrationMap = std::map<std::string, BackgroundSyncRegistration>; + using RegistrationMap = + std::map<std::pair<std::string, blink::mojom::BackgroundSyncType>, + BackgroundSyncRegistration>; BackgroundSyncRegistrations(); BackgroundSyncRegistrations(const BackgroundSyncRegistrations& other); @@ -186,7 +193,8 @@ // Returns the existing registration or nullptr if it cannot be found. BackgroundSyncRegistration* LookupActiveRegistration( int64_t sw_registration_id, - const std::string& tag); + const std::string& tag, + blink::mojom::BackgroundSyncType sync_type); // Write all registrations for a given |sw_registration_id| to persistent // storage. @@ -195,7 +203,8 @@ // Removes the active registration if it is in the map. void RemoveActiveRegistration(int64_t sw_registration_id, - const std::string& tag); + const std::string& tag, + blink::mojom::BackgroundSyncType sync_type); void AddActiveRegistration( int64_t sw_registration_id, @@ -236,7 +245,8 @@ // DidResolveRegistration callbacks void DidResolveRegistrationImpl(int64_t sw_registration_id, - const std::string& tag); + const std::string& tag, + blink::mojom::BackgroundSyncType sync_type); // GetRegistrations callbacks void GetRegistrationsImpl(int64_t sw_registration_id, @@ -263,6 +273,7 @@ void FireReadyEventsDidFindRegistration( int64_t service_worker_id, const std::string& tag, + blink::mojom::BackgroundSyncType sync_type, base::OnceClosure event_fired_callback, base::OnceClosure event_completed_callback, blink::ServiceWorkerStatusCode service_worker_status, @@ -274,10 +285,12 @@ scoped_refptr<ServiceWorkerRegistration> service_worker_registration, int64_t service_worker_id, const std::string& tag, + blink::mojom::BackgroundSyncType sync_type, base::OnceClosure callback, blink::ServiceWorkerStatusCode status_code); void EventCompleteImpl(int64_t service_worker_id, const std::string& tag, + blink::mojom::BackgroundSyncType sync_type, blink::ServiceWorkerStatusCode status_code, base::OnceClosure callback); void EventCompleteDidStore(int64_t service_worker_id,
diff --git a/content/browser/background_sync/background_sync_manager_unittest.cc b/content/browser/background_sync/background_sync_manager_unittest.cc index 70fb93b..b6c3d96 100644 --- a/content/browser/background_sync/background_sync_manager_unittest.cc +++ b/content/browser/background_sync/background_sync_manager_unittest.cc
@@ -50,8 +50,8 @@ namespace { -using ::testing::Return; using ::testing::_; +using ::testing::Return; const char kScope1[] = "https://example.com/a"; const char kScope2[] = "https://example.com/b"; @@ -84,6 +84,12 @@ *called = true; } +blink::mojom::BackgroundSyncType GetBackgroundSyncType( + const blink::mojom::SyncRegistrationOptions& options) { + return options.min_interval >= 0 ? blink::mojom::BackgroundSyncType::PERIODIC + : blink::mojom::BackgroundSyncType::ONE_SHOT; +} + } // namespace class BackgroundSyncManagerTest @@ -270,6 +276,7 @@ blink::mojom::SyncRegistrationOptions options) { bool was_called = false; const std::string tag = options.tag; + blink::mojom::BackgroundSyncType sync_type = GetBackgroundSyncType(options); background_sync_manager_->Register( sw_registration_id, std::move(options), base::BindOnce( @@ -281,7 +288,8 @@ // Mock the client receiving the response and calling // DidResolveRegistration. if (callback_status_ == BACKGROUND_SYNC_STATUS_OK) { - background_sync_manager_->DidResolveRegistration(sw_registration_id, tag); + background_sync_manager_->DidResolveRegistration(sw_registration_id, tag, + sync_type); base::RunLoop().RunUntilIdle(); } @@ -314,7 +322,7 @@ if (callback_status_ == BACKGROUND_SYNC_STATUS_OK) { for (auto iter = callback_registrations_.begin(); iter < callback_registrations_.end(); ++iter) { - if ((*iter)->options()->tag == registration_options.tag) { + if ((*iter)->options()->Equals(registration_options)) { // Transfer the matching registration out of the vector into // callback_registration_ for testing. callback_registration_ = std::move(*iter); @@ -464,6 +472,11 @@ EXPECT_TRUE(Register(sync_options_1_)); } +TEST_F(BackgroundSyncManagerTest, FailToRegisterWithInvalidOptions) { + sync_options_1_.min_interval = -2000; + EXPECT_FALSE(Register(sync_options_1_)); +} + TEST_F(BackgroundSyncManagerTest, RegisterAndWaitToFireUntilResolved) { InitSyncEventTest(); bool was_called = false; @@ -478,8 +491,9 @@ // client to acknowledge with DidResolveRegistration. EXPECT_EQ(0, sync_events_called_); - background_sync_manager_->DidResolveRegistration(sw_registration_id_1_, - sync_options_1_.tag); + background_sync_manager_->DidResolveRegistration( + sw_registration_id_1_, sync_options_1_.tag, + GetBackgroundSyncType(sync_options_1_)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1, sync_events_called_); } @@ -499,8 +513,9 @@ EXPECT_EQ(0, sync_events_called_); // Resolve a non-existing registration. - background_sync_manager_->DidResolveRegistration(sw_registration_id_1_, - "unknown_tag"); + background_sync_manager_->DidResolveRegistration( + sw_registration_id_1_, "unknown_tag", + GetBackgroundSyncType(sync_options_1_)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(0, sync_events_called_); } @@ -835,6 +850,30 @@ EXPECT_TRUE(sync_options_1_.Equals(*callback_registration_->options())); } +TEST_F(BackgroundSyncManagerTest, PeriodicSyncOptions) { + sync_options_1_.min_interval = 2; + EXPECT_TRUE(Register(sync_options_1_)); + EXPECT_TRUE(GetRegistration(sync_options_1_)); + EXPECT_TRUE(sync_options_1_.Equals(*callback_registration_->options())); +} + +TEST_F(BackgroundSyncManagerTest, BothTypesOfSyncShareATag) { + sync_options_1_.tag = "foo"; + sync_options_2_.tag = "foo"; + // Make the registration periodic. + sync_options_2_.min_interval = 36000; + + EXPECT_TRUE(Register(sync_options_1_)); + EXPECT_TRUE(GetRegistration(sync_options_1_)); + EXPECT_EQ(callback_registration_->options()->tag, "foo"); + EXPECT_TRUE(sync_options_1_.Equals(*callback_registration_->options())); + + EXPECT_TRUE(Register(sync_options_2_)); + EXPECT_TRUE(GetRegistration(sync_options_2_)); + EXPECT_TRUE(sync_options_2_.Equals(*callback_registration_->options())); + EXPECT_EQ(callback_registration_->options()->tag, "foo"); +} + TEST_F(BackgroundSyncManagerTest, FiresOnRegistration) { InitSyncEventTest(); @@ -843,6 +882,21 @@ EXPECT_FALSE(GetRegistration(sync_options_1_)); } +// TODO(crbug.com/925297): Update once we support dispatching periodic sync +// events. +TEST_F(BackgroundSyncManagerTest, PeriodicSyncDoesNotFireOnRegistration) { + InitSyncEventTest(); + sync_options_2_.min_interval = 36000; + + EXPECT_TRUE(Register(sync_options_1_)); + EXPECT_EQ(1, sync_events_called_); + EXPECT_FALSE(GetRegistration(sync_options_1_)); + + EXPECT_TRUE(Register(sync_options_2_)); + EXPECT_EQ(1, sync_events_called_); // no increase. + EXPECT_FALSE(GetRegistration(sync_options_2_)); +} + TEST_F(BackgroundSyncManagerTest, ReregisterMidSyncFirstAttemptFails) { InitDelayedSyncEventTest(); RegisterAndVerifySyncEventDelayed(sync_options_1_); @@ -1200,30 +1254,29 @@ // The BackgroundSyncManager should declare in initialization // that it doesn't need to be woken up since it has no registrations. EXPECT_LT(0, GetController()->run_in_background_count()); - EXPECT_FALSE(GetController()->run_in_background_enabled()); + EXPECT_FALSE(test_background_sync_manager_->IsBrowserWakeupScheduled()); SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE); - EXPECT_FALSE(GetController()->run_in_background_enabled()); + EXPECT_FALSE(test_background_sync_manager_->IsBrowserWakeupScheduled()); // Register a one-shot but it can't fire due to lack of network, wake up is // required. Register(sync_options_1_); - EXPECT_TRUE(GetController()->run_in_background_enabled()); + EXPECT_TRUE(test_background_sync_manager_->IsBrowserWakeupScheduled()); // Start the event but it will pause mid-sync due to // InitDelayedSyncEventTest() above. SetNetwork(network::mojom::ConnectionType::CONNECTION_WIFI); - EXPECT_TRUE(GetController()->run_in_background_enabled()); - EXPECT_EQ(test_background_sync_manager_->background_sync_parameters() - ->min_sync_recovery_time, - base::TimeDelta::FromMilliseconds( - GetController()->run_in_background_min_ms())); + EXPECT_TRUE(test_background_sync_manager_->IsBrowserWakeupScheduled()); + EXPECT_TRUE(test_background_sync_manager_->EqualsSoonestWakeupDelta( + test_background_sync_manager_->background_sync_parameters() + ->min_sync_recovery_time)); // Finish the sync. ASSERT_TRUE(sync_fired_callback_); std::move(sync_fired_callback_).Run(blink::ServiceWorkerStatusCode::kOk); base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(GetController()->run_in_background_enabled()); + EXPECT_FALSE(test_background_sync_manager_->IsBrowserWakeupScheduled()); } TEST_F(BackgroundSyncManagerTest, OneAttempt) {
diff --git a/content/browser/background_sync/background_sync_service_impl.cc b/content/browser/background_sync/background_sync_service_impl.cc index 678a828..e64b103 100644 --- a/content/browser/background_sync/background_sync_service_impl.cc +++ b/content/browser/background_sync/background_sync_service_impl.cc
@@ -76,13 +76,15 @@ void BackgroundSyncServiceImpl::DidResolveRegistration( int64_t sw_registration_id, - const std::string& tag) { + const std::string& tag, + blink::mojom::BackgroundSyncType sync_type) { DCHECK_CURRENTLY_ON(BrowserThread::IO); BackgroundSyncManager* background_sync_manager = background_sync_context_->background_sync_manager(); DCHECK(background_sync_manager); - background_sync_manager->DidResolveRegistration(sw_registration_id, tag); + background_sync_manager->DidResolveRegistration(sw_registration_id, tag, + sync_type); } void BackgroundSyncServiceImpl::GetRegistrations( @@ -113,7 +115,7 @@ DCHECK(result); blink::mojom::SyncRegistrationOptionsPtr mojo_options = - blink::mojom::SyncRegistrationOptions::New(result->options()->tag); + blink::mojom::SyncRegistrationOptions::New(*result->options()); std::move(callback).Run( static_cast<blink::mojom::BackgroundSyncError>(status), std::move(mojo_options)); @@ -127,9 +129,10 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); std::vector<blink::mojom::SyncRegistrationOptionsPtr> mojo_registrations; - for (const auto& registration : result_registrations) - mojo_registrations.push_back(blink::mojom::SyncRegistrationOptions::New( - registration->options()->tag)); + for (const auto& registration : result_registrations) { + mojo_registrations.push_back( + blink::mojom::SyncRegistrationOptions::New(*registration->options())); + } std::move(callback).Run( static_cast<blink::mojom::BackgroundSyncError>(status),
diff --git a/content/browser/background_sync/background_sync_service_impl.h b/content/browser/background_sync/background_sync_service_impl.h index d044a62158..e064e96f 100644 --- a/content/browser/background_sync/background_sync_service_impl.h +++ b/content/browser/background_sync/background_sync_service_impl.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include <memory> +#include <string> #include <vector> #include "base/containers/id_map.h" @@ -37,8 +38,10 @@ void Register(blink::mojom::SyncRegistrationOptionsPtr options, int64_t sw_registration_id, RegisterCallback callback) override; - void DidResolveRegistration(int64_t sw_registration_id, - const std::string& tag) override; + void DidResolveRegistration( + int64_t sw_registration_id, + const std::string& tag, + blink::mojom::BackgroundSyncType sync_type) override; void GetRegistrations(int64_t sw_registration_id, GetRegistrationsCallback callback) override;
diff --git a/content/browser/devtools/BUILD.gn b/content/browser/devtools/BUILD.gn index f14e719..2250166 100644 --- a/content/browser/devtools/BUILD.gn +++ b/content/browser/devtools/BUILD.gn
@@ -129,3 +129,16 @@ "devtools_background_services.proto", ] } + +source_set("inspector_protocol_encoding_test") { + testonly = true + sources = [ + "../../../third_party/inspector_protocol/encoding/encoding_test.cc", + ] + deps = [ + "//base", + "//testing/gmock", + "//testing/gtest", + "//third_party/inspector_protocol:encoding", + ] +}
diff --git a/content/browser/devtools/DEPS b/content/browser/devtools/DEPS index 93bf7150..962e548 100644 --- a/content/browser/devtools/DEPS +++ b/content/browser/devtools/DEPS
@@ -3,4 +3,7 @@ "+content/shell/browser/shell.h", # for access to web contents from devtools_protocol_test_support.cc # V8 version info "+v8/include/v8-version-string.h", + + # For converting between JSON and CBOR in devtools_session_encoding.cc. + "+third_party/inspector_protocol/encoding", ]
diff --git a/content/browser/devtools/browser_devtools_agent_host.cc b/content/browser/devtools/browser_devtools_agent_host.cc index 2862801..e491560 100644 --- a/content/browser/devtools/browser_devtools_agent_host.cc +++ b/content/browser/devtools/browser_devtools_agent_host.cc
@@ -88,7 +88,7 @@ socket_callback_, tethering_task_runner_)); } session->AddHandler(std::make_unique<protocol::TracingHandler>( - nullptr, GetIOContext(), session->client()->UsesBinaryProtocol())); + nullptr, GetIOContext(), session->UsesBinaryProtocol())); return true; }
diff --git a/content/browser/devtools/devtools_session.cc b/content/browser/devtools/devtools_session.cc index 75d2d42..c88086c 100644 --- a/content/browser/devtools/devtools_session.cc +++ b/content/browser/devtools/devtools_session.cc
@@ -4,10 +4,11 @@ #include "content/browser/devtools/devtools_session.h" +#include <vector> + #include "base/bind.h" -#include "base/json/json_reader.h" -#include "base/strings/stringprintf.h" #include "content/browser/devtools/devtools_manager.h" +#include "content/browser/devtools/devtools_session_encoding.h" #include "content/browser/devtools/protocol/devtools_domain_handler.h" #include "content/browser/devtools/protocol/protocol.h" #include "content/browser/devtools/render_frame_devtools_agent_host.h" @@ -34,7 +35,6 @@ static const char kMethod[] = "method"; static const char kResumeMethod[] = "Runtime.runIfWaitingForDebugger"; static const char kSessionId[] = "sessionId"; - } // namespace DevToolsSession::DevToolsSession(DevToolsAgentHostClient* client) @@ -73,6 +73,11 @@ return root_session_ ? root_session_ : this; } +bool DevToolsSession::UsesBinaryProtocol() const { + return client_->UsesBinaryProtocol() || + EnableInternalDevToolsBinaryProtocol(); +} + void DevToolsSession::AddHandler( std::unique_ptr<protocol::DevToolsDomainHandler> handler) { DCHECK(agent_host_); @@ -133,10 +138,27 @@ io_session_ptr_.reset(); } +// The client of the devtools session will call this method to send a message +// to handlers / agents that the session is connected with. bool DevToolsSession::DispatchProtocolMessage(const std::string& message) { + std::string converted_cbor_message; + const std::string* message_to_send = &message; + if (EnableInternalDevToolsBinaryProtocol()) { + if (client_->UsesBinaryProtocol()) { + // If the client uses the binary protocol, then |message| is already + // CBOR (it comes from the client). + DCHECK(IsCBOR(message)); + } else { + converted_cbor_message = ConvertJSONToCBOR(message); + message_to_send = &converted_cbor_message; + } + } if (proxy_delegate_) { - // Note: we assume that child sessions are not forwarding. - proxy_delegate_->SendMessageToBackend(this, message); + // TODO(dgozman): revisit the proxy delegate. + // TODO(johannes): Should we send CBOR to an external backend? Maybe not! + // Revisit this when EnableInternalDevToolsBinaryProtocol() is on + // unconditionally. Note: we assume that child sessions are not forwarding. + proxy_delegate_->SendMessageToBackend(this, *message_to_send); return true; } @@ -146,14 +168,15 @@ std::string session_id; if (!value || !value->getString(kSessionId, &session_id)) - return DispatchProtocolMessageInternal(message, std::move(value)); + return DispatchProtocolMessageInternal(*message_to_send, std::move(value)); auto it = child_sessions_.find(session_id); if (it == child_sessions_.end()) return false; DevToolsSession* session = it->second; DCHECK(!session->proxy_delegate_); - return session->DispatchProtocolMessageInternal(message, std::move(value)); + return session->DispatchProtocolMessageInternal(*message_to_send, + std::move(value)); } bool DevToolsSession::DispatchProtocolMessageInternal( @@ -242,34 +265,73 @@ suspended_messages_.clear(); } +// The following methods handle responses or notifications coming from +// the browser to the client. +static void SendProtocolResponseOrNotification( + DevToolsAgentHostClient* client, + DevToolsAgentHostImpl* agent_host, + std::unique_ptr<protocol::Serializable> message) { + if (!EnableInternalDevToolsBinaryProtocol()) { + bool binary = client->UsesBinaryProtocol(); + client->DispatchProtocolMessage(agent_host, message->serialize(binary)); + return; + } + std::string cbor = message->serialize(/*binary=*/true); + DCHECK(IsCBOR(cbor)); + client->DispatchProtocolMessage(agent_host, client->UsesBinaryProtocol() + ? cbor + : ConvertCBORToJSON(cbor)); +} + void DevToolsSession::sendProtocolResponse( int call_id, std::unique_ptr<protocol::Serializable> message) { - bool binary = client_->UsesBinaryProtocol(); - client_->DispatchProtocolMessage(agent_host_, message->serialize(binary)); + SendProtocolResponseOrNotification(client_, agent_host_, std::move(message)); // |this| may be deleted at this point. } void DevToolsSession::sendProtocolNotification( std::unique_ptr<protocol::Serializable> message) { - bool binary = client_->UsesBinaryProtocol(); - client_->DispatchProtocolMessage(agent_host_, message->serialize(binary)); + SendProtocolResponseOrNotification(client_, agent_host_, std::move(message)); // |this| may be deleted at this point. } void DevToolsSession::flushProtocolNotifications() { } +// The following methods handle responses or notifications coming from +// the renderer (blink) to the client. +static void DispatchProtocolResponseOrNotification( + DevToolsAgentHostClient* client, + DevToolsAgentHostImpl* agent_host, + blink::mojom::DevToolsMessagePtr message) { + // TODO(johannes): When eliminating the + // --enable-internal-devtools-binary-protocol flag, reconsider the similarity + // with SendProtocolResponseOrNotification above and either merge the methods + // or inline them again. + if (!EnableInternalDevToolsBinaryProtocol()) { + client->DispatchProtocolMessage( + agent_host, + std::string(reinterpret_cast<const char*>(message->data.data()), + message->data.size())); + return; + } + std::string cbor(reinterpret_cast<const char*>(message->data.data()), + message->data.size()); + DCHECK(IsCBOR(cbor)); + client->DispatchProtocolMessage(agent_host, client->UsesBinaryProtocol() + ? cbor + : ConvertCBORToJSON(cbor)); +} + void DevToolsSession::DispatchProtocolResponse( blink::mojom::DevToolsMessagePtr message, int call_id, blink::mojom::DevToolsSessionStatePtr updates) { ApplySessionStateUpdates(std::move(updates)); waiting_for_response_messages_.erase(call_id); - client_->DispatchProtocolMessage( - agent_host_, - std::string(reinterpret_cast<const char*>(message->data.data()), - message->data.size())); + DispatchProtocolResponseOrNotification(client_, agent_host_, + std::move(message)); // |this| may be deleted at this point. } @@ -277,10 +339,8 @@ blink::mojom::DevToolsMessagePtr message, blink::mojom::DevToolsSessionStatePtr updates) { ApplySessionStateUpdates(std::move(updates)); - client_->DispatchProtocolMessage( - agent_host_, - std::string(reinterpret_cast<const char*>(message->data.data()), - message->data.size())); + DispatchProtocolResponseOrNotification(client_, agent_host_, + std::move(message)); // |this| may be deleted at this point. }
diff --git a/content/browser/devtools/devtools_session.h b/content/browser/devtools/devtools_session.h index 413d757..619c96e 100644 --- a/content/browser/devtools/devtools_session.h +++ b/content/browser/devtools/devtools_session.h
@@ -42,6 +42,11 @@ DevToolsAgentHostClient* client() { return client_; } DevToolsSession* GetRootSession(); + // Whether this session uses binary protocol. This is true if + // |client()->UsesBinaryProtocol()| or if the + // --enable-devtools-binary-protocol flag is set. + bool UsesBinaryProtocol() const; + // Browser-only sessions do not talk to mojom::DevToolsAgent, but instead // handle all protocol messages locally in the browser process. void SetBrowserOnly(bool browser_only);
diff --git a/content/browser/devtools/devtools_session_encoding.cc b/content/browser/devtools/devtools_session_encoding.cc new file mode 100644 index 0000000..a297b78e0 --- /dev/null +++ b/content/browser/devtools/devtools_session_encoding.cc
@@ -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. + +#include "content/browser/devtools/devtools_session_encoding.h" + +#include <memory> +#include <vector> + +#include "base/command_line.h" +#include "base/strings/string_number_conversions.h" +#include "content/public/common/content_switches.h" +#include "third_party/inspector_protocol/encoding/encoding.h" + +using inspector_protocol_encoding::span; +using inspector_protocol_encoding::Status; +using inspector_protocol_encoding::StreamingParserHandler; +using inspector_protocol_encoding::cbor::NewCBOREncoder; +using inspector_protocol_encoding::cbor::ParseCBOR; +using inspector_protocol_encoding::json::NewJSONEncoder; +using inspector_protocol_encoding::json::ParseJSON; +using inspector_protocol_encoding::json::Platform; + +namespace content { +namespace { +// ContentShellPlatform allows us to inject the string<->double conversion +// routines from base:: into the inspector_protocol JSON parser / serializer. +class ContentShellPlatform : public Platform { + public: + bool StrToD(const char* str, double* result) const override { + return base::StringToDouble(str, result); + } + + // Prints |value| in a format suitable for JSON. + std::unique_ptr<char[]> DToStr(double value) const override { + std::string str = base::NumberToString(value); + std::unique_ptr<char[]> result(new char[str.size() + 1]); + memcpy(result.get(), str.c_str(), str.size() + 1); + return result; + } +}; +} // namespace +bool EnableInternalDevToolsBinaryProtocol() { + static bool enabled = base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableInternalDevToolsBinaryProtocol); + return enabled; +} + +// TODO(johannes): Move this into the cbor library. Don't want to +// do this just yet to first gain more experience about the most +// appropriate API, including how to propagate errors. +std::string ConvertCBORToJSON(const std::string& cbor) { + ContentShellPlatform platform; + std::string json_message; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(&platform, &json_message, &status); + ParseCBOR( + span<uint8_t>(reinterpret_cast<const uint8_t*>(cbor.data()), cbor.size()), + json_writer.get()); + if (!status.ok()) { + LOG(ERROR) << "ConvertCBORToJSON error " + << static_cast<uint32_t>(status.error) << " position " + << static_cast<uint32_t>(status.pos); + return ""; + } + return json_message; +} + +std::string ConvertJSONToCBOR(const std::string& json) { + ContentShellPlatform platform; + std::vector<uint8_t> cbor; + Status status; + std::unique_ptr<StreamingParserHandler> encoder = + NewCBOREncoder(&cbor, &status); + ParseJSON( + &platform, + span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), + encoder.get()); + if (!status.ok()) { + LOG(ERROR) << "ConvertJSONToCBOR error " + << static_cast<uint32_t>(status.error) << " position " + << static_cast<uint32_t>(status.pos); + return ""; + } + return std::string(cbor.begin(), cbor.end()); +} + +bool IsCBOR(const std::string& serialized) { + return serialized.size() >= 6 && + reinterpret_cast<const uint8_t&>(serialized[0]) == 0xd8 && + reinterpret_cast<const uint8_t&>(serialized[1]) == 0x5a; +} +} // namespace content
diff --git a/content/browser/devtools/devtools_session_encoding.h b/content/browser/devtools/devtools_session_encoding.h new file mode 100644 index 0000000..f4bb1ef --- /dev/null +++ b/content/browser/devtools/devtools_session_encoding.h
@@ -0,0 +1,29 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_SESSION_ENCODING_H_ +#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_SESSION_ENCODING_H_ + +#include <string> + +namespace content { + +// Whether --enable-internal-devtools-binary-parotocol was passed on the command +// line. If so, the DevtoolsSession will convert all outgoing traffic to agents +// / handlers / etc. to the CBOR-based binary protocol. +bool EnableInternalDevToolsBinaryProtocol(); + +// Conversion routines between the inspector protocol binary wire format +// (based on CBOR RFC 7049) and JSON. +std::string ConvertCBORToJSON(const std::string& cbor); +std::string ConvertJSONToCBOR(const std::string& json); + +// Whether |serialized| is CBOR produced by the inspector protocol. +// We always enclose messages with an envelope, that is, the 0xd8 tag +// followed by the indicator for the byte string, followed by a 32 bit +// length value (4 bytes). +bool IsCBOR(const std::string& serialized); +} // namespace content + +#endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_SESSION_ENCODING_H_
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc index 4fa2f08..cfef102 100644 --- a/content/browser/devtools/protocol/network_handler.cc +++ b/content/browser/devtools/protocol/network_handler.cc
@@ -665,12 +665,14 @@ protocol = "h2"; } else if (url.SchemeIsHTTPOrHTTPS()) { protocol = "http"; - if (info.headers->GetHttpVersion() == net::HttpVersion(0, 9)) - protocol = "http/0.9"; - else if (info.headers->GetHttpVersion() == net::HttpVersion(1, 0)) - protocol = "http/1.0"; - else if (info.headers->GetHttpVersion() == net::HttpVersion(1, 1)) - protocol = "http/1.1"; + if (info.headers) { + if (info.headers->GetHttpVersion() == net::HttpVersion(0, 9)) + protocol = "http/0.9"; + else if (info.headers->GetHttpVersion() == net::HttpVersion(1, 0)) + protocol = "http/1.0"; + else if (info.headers->GetHttpVersion() == net::HttpVersion(1, 1)) + protocol = "http/1.1"; + } } else { protocol = url.scheme(); }
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc index d88e0a5..b4d72bc 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host.cc +++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -306,8 +306,7 @@ session->AddHandler(std::make_unique<protocol::SecurityHandler>()); if (!frame_tree_node_ || !frame_tree_node_->parent()) { session->AddHandler(std::make_unique<protocol::TracingHandler>( - frame_tree_node_, GetIOContext(), - session->client()->UsesBinaryProtocol())); + frame_tree_node_, GetIOContext(), session->UsesBinaryProtocol())); } if (sessions().empty()) {
diff --git a/content/browser/indexed_db/cursor_impl.cc b/content/browser/indexed_db/cursor_impl.cc index 23a274e5..687e5cb9 100644 --- a/content/browser/indexed_db/cursor_impl.cc +++ b/content/browser/indexed_db/cursor_impl.cc
@@ -28,7 +28,9 @@ const IndexedDBKey& key, const IndexedDBKey& primary_key, blink::mojom::IDBCursor::CursorContinueCallback callback); - void Prefetch(int32_t count, scoped_refptr<IndexedDBCallbacks> callbacks); + void Prefetch(base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, + int32_t count, + blink::mojom::IDBCursor::PrefetchCallback callback); void PrefetchReset(int32_t used_prefetches, int32_t unused_prefetches); void OnRemoveBinding(base::OnceClosure remove_binding_cb); @@ -73,14 +75,10 @@ std::move(callback)); } -void CursorImpl::Prefetch( - int32_t count, - blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks_info) { +void CursorImpl::Prefetch(int32_t count, + blink::mojom::IDBCursor::PrefetchCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - scoped_refptr<IndexedDBCallbacks> callbacks( - new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_, - std::move(callbacks_info), idb_runner_)); - helper_->Prefetch(count, std::move(callbacks)); + helper_->Prefetch(dispatcher_host_->AsWeakPtr(), count, std::move(callback)); } void CursorImpl::PrefetchReset(int32_t used_prefetches, @@ -129,10 +127,12 @@ } void CursorImpl::IDBSequenceHelper::Prefetch( + base::WeakPtr<content::IndexedDBDispatcherHost> dispatcher_host, int32_t count, - scoped_refptr<IndexedDBCallbacks> callbacks) { + blink::mojom::IDBCursor::PrefetchCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - cursor_->PrefetchContinue(count, std::move(callbacks)); + cursor_->PrefetchContinue(std::move(dispatcher_host), count, + std::move(callback)); } void CursorImpl::IDBSequenceHelper::PrefetchReset(int32_t used_prefetches,
diff --git a/content/browser/indexed_db/cursor_impl.h b/content/browser/indexed_db/cursor_impl.h index 76a5b64..feb7f89 100644 --- a/content/browser/indexed_db/cursor_impl.h +++ b/content/browser/indexed_db/cursor_impl.h
@@ -38,7 +38,7 @@ const blink::IndexedDBKey& primary_key, blink::mojom::IDBCursor::CursorContinueCallback callback) override; void Prefetch(int32_t count, - blink::mojom::IDBCallbacksAssociatedPtrInfo callbacks) override; + blink::mojom::IDBCursor::PrefetchCallback callback) override; void PrefetchReset(int32_t used_prefetches, int32_t unused_prefetches) override;
diff --git a/content/browser/indexed_db/indexed_db_cursor.cc b/content/browser/indexed_db/indexed_db_cursor.cc index 7facb7b..c5fe78fc 100644 --- a/content/browser/indexed_db/indexed_db_cursor.cc +++ b/content/browser/indexed_db/indexed_db_cursor.cc
@@ -161,9 +161,13 @@ mojo_value = blink::mojom::IDBValue::New(); } + std::vector<IndexedDBKey> keys = {key()}; + std::vector<IndexedDBKey> primary_keys = {primary_key()}; + std::vector<blink::mojom::IDBValuePtr> values; + values.push_back(std::move(mojo_value)); blink::mojom::IDBCursorValuePtr cursor_value = - blink::mojom::IDBCursorValue::New(key(), primary_key(), - std::move(mojo_value)); + blink::mojom::IDBCursorValue::New( + std::move(keys), std::move(primary_keys), std::move(values)); std::move(callback).Run(blink::mojom::IDBErrorPtr(), std::move(cursor_value)); return s; } @@ -243,35 +247,50 @@ mojo_value = blink::mojom::IDBValue::New(); } + std::vector<IndexedDBKey> keys = {this->key()}; + std::vector<IndexedDBKey> primary_keys = {this->primary_key()}; + std::vector<blink::mojom::IDBValuePtr> values; + values.push_back(std::move(mojo_value)); blink::mojom::IDBCursorValuePtr cursor_value = - blink::mojom::IDBCursorValue::New(this->key(), this->primary_key(), - std::move(mojo_value)); + blink::mojom::IDBCursorValue::New( + std::move(keys), std::move(primary_keys), std::move(values)); std::move(callback).Run(blink::mojom::IDBErrorPtr(), std::move(cursor_value)); return s; } void IndexedDBCursor::PrefetchContinue( + base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, int number_to_fetch, - scoped_refptr<IndexedDBCallbacks> callbacks) { + blink::mojom::IDBCursor::PrefetchCallback callback) { IDB_TRACE("IndexedDBCursor::PrefetchContinue"); if (closed_) { - callbacks->OnError(CreateCursorClosedError()); + const IndexedDBDatabaseError error(CreateCursorClosedError()); + std::move(callback).Run( + blink::mojom::IDBError::New(error.code(), error.message()), + blink::mojom::IDBCursorValuePtr()); return; } transaction_->ScheduleTask( task_type_, - BindWeakOperation(&IndexedDBCursor::CursorPrefetchIterationOperation, - ptr_factory_.GetWeakPtr(), number_to_fetch, callbacks)); + BindWeakOperation( + &IndexedDBCursor::CursorPrefetchIterationOperation, + ptr_factory_.GetWeakPtr(), std::move(dispatcher_host), + base::WrapRefCounted(dispatcher_host->context()->TaskRunner()), + number_to_fetch, std::move(callback))); } leveldb::Status IndexedDBCursor::CursorPrefetchIterationOperation( + base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, + scoped_refptr<base::SequencedTaskRunner> idb_runner, int number_to_fetch, - scoped_refptr<IndexedDBCallbacks> callbacks, + blink::mojom::IDBCursor::PrefetchCallback callback, IndexedDBTransaction* /*transaction*/) { IDB_TRACE("IndexedDBCursor::CursorPrefetchIterationOperation"); leveldb::Status s = leveldb::Status::OK(); + if (!dispatcher_host) + return s; std::vector<IndexedDBKey> found_keys; std::vector<IndexedDBKey> found_primary_keys; @@ -292,11 +311,15 @@ // We've reached the end, so just return what we have. break; } + // |transaction_| must be valid for CreateError(), so we can't call + // Close() until after calling CreateError(). IndexedDBDatabaseError error = CreateError(blink::kWebIDBDatabaseExceptionUnknownError, "Error continuing cursor.", transaction_); Close(); - callbacks->OnError(std::move(error)); + std::move(callback).Run( + blink::mojom::IDBError::New(error.code(), error.message()), + blink::mojom::IDBCursorValuePtr()); return s; } @@ -331,12 +354,38 @@ } if (found_keys.empty()) { - callbacks->OnSuccess(nullptr); + std::move(callback).Run(blink::mojom::IDBErrorPtr(), + blink::mojom::IDBCursorValuePtr()); return s; } - callbacks->OnSuccessWithPrefetch( - found_keys, found_primary_keys, &found_values); + DCHECK_EQ(found_keys.size(), found_primary_keys.size()); + DCHECK_EQ(found_keys.size(), found_values.size()); + + std::vector<blink::mojom::IDBValuePtr> mojo_values; + mojo_values.reserve(found_values.size()); + for (size_t i = 0; i < found_values.size(); ++i) + mojo_values.push_back( + IndexedDBValue::ConvertAndEraseValue(&found_values[i])); + + std::vector<IndexedDBCallbacks::IndexedDBValueBlob> value_blobs; + for (size_t i = 0; i < mojo_values.size(); ++i) { + IndexedDBCallbacks::IndexedDBValueBlob::GetIndexedDBValueBlobs( + &value_blobs, found_values[i].blob_info, + &mojo_values[i]->blob_or_file_info); + } + + if (!IndexedDBCallbacks::CreateAllBlobs( + dispatcher_host->blob_storage_context(), idb_runner, + std::move(value_blobs))) { + return s; + } + + blink::mojom::IDBCursorValuePtr cursor_value = + blink::mojom::IDBCursorValue::New(std::move(found_keys), + std::move(found_primary_keys), + std::move(mojo_values)); + std::move(callback).Run(blink::mojom::IDBErrorPtr(), std::move(cursor_value)); return s; }
diff --git a/content/browser/indexed_db/indexed_db_cursor.h b/content/browser/indexed_db/indexed_db_cursor.h index 5021ae8..e3d935a2 100644 --- a/content/browser/indexed_db/indexed_db_cursor.h +++ b/content/browser/indexed_db/indexed_db_cursor.h
@@ -36,8 +36,9 @@ std::unique_ptr<blink::IndexedDBKey> key, std::unique_ptr<blink::IndexedDBKey> primary_key, blink::mojom::IDBCursor::CursorContinueCallback callback); - void PrefetchContinue(int number_to_fetch, - scoped_refptr<IndexedDBCallbacks> callbacks); + void PrefetchContinue(base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, + int number_to_fetch, + blink::mojom::IDBCursor::PrefetchCallback callback); leveldb::Status PrefetchReset(int used_prefetches, int unused_prefetches); void OnRemoveBinding(base::OnceClosure remove_binding_cb); @@ -70,8 +71,10 @@ blink::mojom::IDBCursor::AdvanceCallback callback, IndexedDBTransaction* transaction); leveldb::Status CursorPrefetchIterationOperation( + base::WeakPtr<IndexedDBDispatcherHost> dispatcher_host, + scoped_refptr<base::SequencedTaskRunner> idb_runner, int number_to_fetch, - scoped_refptr<IndexedDBCallbacks> callbacks, + blink::mojom::IDBCursor::PrefetchCallback callback, IndexedDBTransaction* transaction); private:
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index 068a7c8..1411491 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -1027,14 +1027,6 @@ url_loader_removed_headers_ = removed_headers; url_loader_modified_headers_ = modified_headers; - // Don't send Accept: application/signed-exchange for fallback redirects. - if (redirect_info_.is_signed_exchange_fallback_redirect) { - url_loader_modified_headers_.SetHeader(network::kAcceptHeader, - network::kFrameAcceptHeader); - resource_request_->headers.SetHeader(network::kAcceptHeader, - network::kFrameAcceptHeader); - } - Restart(); }
diff --git a/content/browser/renderer_host/input/fling_controller.cc b/content/browser/renderer_host/input/fling_controller.cc index 92445d3..0ec5116 100644 --- a/content/browser/renderer_host/input/fling_controller.cc +++ b/content/browser/renderer_host/input/fling_controller.cc
@@ -148,9 +148,40 @@ bool FlingController::FilterGestureEvent( const GestureEventWithLatencyInfo& gesture_event) { - return !ShouldForwardForGFCFiltering(gesture_event) || - !ShouldForwardForTapSuppression(gesture_event) || - FilterGestureEventForFlingBoosting(gesture_event); + if (!ShouldForwardForGFCFiltering(gesture_event) || + !ShouldForwardForTapSuppression(gesture_event) || + FilterGestureEventForFlingBoosting(gesture_event)) + return true; + + if (gesture_event.event.GetType() == WebInputEvent::kGestureScrollUpdate) { + last_seen_scroll_update_ = gesture_event.event.TimeStamp(); + } else if (gesture_event.event.GetType() == + WebInputEvent::kGestureScrollEnd || + gesture_event.event.GetType() == + WebInputEvent::kGestureScrollBegin) { + // TODO(bokan): We reset this on Begin as well as End since there appear to + // be cases where we see an invalid event sequence: + // https://crbug.com/928569. + last_seen_scroll_update_ = base::TimeTicks(); + } + + // fling_controller_ is in charge of handling GFS events and the events are + // not sent to the renderer, the controller processes the fling and generates + // fling progress events (wheel events for touchpad and GSU events for + // touchscreen and autoscroll) which are handled normally. + if (gesture_event.event.GetType() == WebInputEvent::kGestureFlingStart) { + ProcessGestureFlingStart(gesture_event); + return true; + } + + // If the GestureFlingStart event is processed by the fling_controller_, the + // GestureFlingCancel event should be the same. + if (gesture_event.event.GetType() == WebInputEvent::kGestureFlingCancel) { + ProcessGestureFlingCancel(gesture_event); + return true; + } + + return false; } void FlingController::ProcessGestureFlingStart( @@ -216,7 +247,7 @@ // later than the fling start time, delay the fling start time to one frame // prior to the current time. This makes sure that at least one progress // event is sent while the fling is active even when the fling duration is - // short (samll velocity) and the time delta between its timestamp and its + // short (small velocity) and the time delta between its timestamp and its // processing time is big (e.g. When a GFS gets bubbled from an oopif). if (current_time >= current_fling_parameters_.start_time + kMaxMicrosecondsFromFlingTimestampToFirstProgress) { @@ -419,8 +450,16 @@ current_fling_parameters_.global_point = fling_start_event.PositionInScreen(); current_fling_parameters_.modifiers = fling_start_event.GetModifiers(); current_fling_parameters_.source_device = fling_start_event.SourceDevice(); - // NOTE: This time may be more than a frame in the past. - current_fling_parameters_.start_time = fling_start_event.TimeStamp(); + + if (fling_start_event.SourceDevice() == + blink::kWebGestureDeviceSyntheticAutoscroll || + last_seen_scroll_update_.is_null()) { + current_fling_parameters_.start_time = fling_start_event.TimeStamp(); + } else { + // To maintain a smooth, continuous transition from a drag scroll to a fling + // scroll, the animation should begin at the time of the last update. + current_fling_parameters_.start_time = last_seen_scroll_update_; + } if (velocity.IsZero() && fling_start_event.SourceDevice() != blink::kWebGestureDeviceSyntheticAutoscroll) {
diff --git a/content/browser/renderer_host/input/fling_controller.h b/content/browser/renderer_host/input/fling_controller.h index 4bd1d1b..4254134b 100644 --- a/content/browser/renderer_host/input/fling_controller.h +++ b/content/browser/renderer_host/input/fling_controller.h
@@ -178,6 +178,10 @@ // The clock used; overridable for tests. const base::TickClock* clock_; + // Time of the last seen scroll update that wasn't filtered. Used to know the + // starting time for a possible fling gesture curve. + base::TimeTicks last_seen_scroll_update_; + base::WeakPtrFactory<FlingController> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(FlingController);
diff --git a/content/browser/renderer_host/input/fling_controller_unittest.cc b/content/browser/renderer_host/input/fling_controller_unittest.cc index f52f544..502026f 100644 --- a/content/browser/renderer_host/input/fling_controller_unittest.cc +++ b/content/browser/renderer_host/input/fling_controller_unittest.cc
@@ -97,8 +97,26 @@ // Wait for up to one frame before processing the event. AdvanceTime(base::RandInt(0, static_cast<int>(kFrameDelta))); } - if (!fling_controller_->FilterGestureEvent(fling_start_with_latency)) - fling_controller_->ProcessGestureFlingStart(fling_start_with_latency); + fling_controller_->FilterGestureEvent(fling_start_with_latency); + } + + void SimulateScrollUpdate(blink::WebGestureDevice source_device, + const gfx::Vector2dF& delta) { + WebGestureEvent scroll_update(WebInputEvent::kGestureScrollUpdate, 0, + NowTicks(), source_device); + scroll_update.data.scroll_update.delta_x = delta.x(); + scroll_update.data.scroll_update.delta_y = delta.y(); + scroll_update.data.scroll_update.velocity_x = delta.x(); + scroll_update.data.scroll_update.velocity_y = delta.y(); + scroll_update.data.scroll_update.inertial_phase = + WebGestureEvent::kNonMomentumPhase; + scroll_update.data.scroll_update.previous_update_in_sequence_prevented = + false; + scroll_update.data.scroll_update.delta_units = + WebGestureEvent::kPrecisePixels; + GestureEventWithLatencyInfo scroll_update_with_latency(scroll_update); + + fling_controller_->FilterGestureEvent(scroll_update_with_latency); } void SimulateFlingCancel(blink::WebGestureDevice source_device) { @@ -109,10 +127,7 @@ if (source_device == blink::kWebGestureDeviceSyntheticAutoscroll) fling_cancel.data.fling_cancel.prevent_boosting = true; GestureEventWithLatencyInfo fling_cancel_with_latency(fling_cancel); - last_fling_cancel_filtered_ = - fling_controller_->FilterGestureEvent(fling_cancel_with_latency); - if (!last_fling_cancel_filtered_) - fling_controller_->ProcessGestureFlingCancel(fling_cancel_with_latency); + fling_controller_->FilterGestureEvent(fling_cancel_with_latency); } void ProgressFling(base::TimeTicks current_time) { @@ -135,7 +150,6 @@ int wheel_event_count_ = 0; WebMouseWheelEvent last_sent_wheel_; WebGestureEvent last_sent_gesture_; - bool last_fling_cancel_filtered_ = false; bool scheduled_next_fling_progress_ = false; bool notified_client_after_fling_stop_ = false; bool first_wheel_event_sent_ = false; @@ -173,7 +187,7 @@ TEST_P(FlingControllerTest, ControllerHandlesTouchpadGestureFling) { SimulateFlingStart(blink::kWebGestureDeviceTouchpad, gfx::Vector2dF(1000, 0)); EXPECT_TRUE(FlingInProgress()); - // Processing GFS will send the first fling prgoress event if the time delta + // Processing GFS will send the first fling progress event if the time delta // between the timestamp of the GFS and the time that ProcessGestureFlingStart // is called is large enough. bool process_GFS_sent_first_event = first_wheel_event_sent_; @@ -197,7 +211,6 @@ // Now cancel the fling. The GFC will get suppressed by fling booster. SimulateFlingCancel(blink::kWebGestureDeviceTouchpad); - EXPECT_TRUE(last_fling_cancel_filtered_); EXPECT_TRUE(FlingInProgress()); // Wait for the boosting timer to expire. The delayed cancelation must work. @@ -209,6 +222,30 @@ EXPECT_EQ(0.f, last_sent_wheel_.delta_y); } +// Ensure that the start time of a fling is measured from the last received +// GSU. This ensures that the first progress fling during FlingStart should +// send significant delta. If we're using the FlingStart as the start time, we +// would send none or very little delta. +TEST_P(FlingControllerTest, FlingStartsAtLastScrollUpdate) { + SimulateScrollUpdate(blink::kWebGestureDeviceTouchscreen, + gfx::Vector2dF(1000, 0)); + double time_to_advance_ms = 30.0; + AdvanceTime(time_to_advance_ms); + SimulateFlingStart(blink::kWebGestureDeviceTouchscreen, + gfx::Vector2dF(1000, 0), /*wait_before_processing=*/false); + EXPECT_TRUE(FlingInProgress()); + + if (NeedsBeginFrameForFlingProgress()) + ProgressFling(NowTicks()); + + // We haven't advanced time since the FlingStart. Ensure we still send a + // significant amount of delta (~0.030sec * 1000pixels/sec) since we should + // be measuring the time since the last GSU. + EXPECT_EQ(1, sent_scroll_gesture_count_); + ASSERT_EQ(WebInputEvent::kGestureScrollUpdate, last_sent_gesture_.GetType()); + EXPECT_NEAR(last_sent_gesture_.data.scroll_update.delta_x, 30.0, 5); +} + TEST_P(FlingControllerTest, ControllerHandlesTouchscreenGestureFling) { SimulateFlingStart(blink::kWebGestureDeviceTouchscreen, gfx::Vector2dF(1000, 0)); @@ -224,7 +261,6 @@ // Now cancel the fling. The GFC will get suppressed by fling booster. SimulateFlingCancel(blink::kWebGestureDeviceTouchscreen); - EXPECT_TRUE(last_fling_cancel_filtered_); EXPECT_TRUE(FlingInProgress()); // Wait for the boosting timer to expire. The delayed cancelation must work. @@ -237,7 +273,7 @@ TEST_P(FlingControllerTest, ControllerSendsWheelEndWhenTouchpadFlingIsOver) { SimulateFlingStart(blink::kWebGestureDeviceTouchpad, gfx::Vector2dF(100, 0)); EXPECT_TRUE(FlingInProgress()); - // Processing GFS will send the first fling prgoress event if the time delta + // Processing GFS will send the first fling progress event if the time delta // between the timestamp of the GFS and the time that ProcessGestureFlingStart // is called is large enough. bool process_GFS_sent_first_event = first_wheel_event_sent_; @@ -290,7 +326,7 @@ TEST_P(FlingControllerTest, EarlyTouchpadFlingCancelationOnFlingStop) { SimulateFlingStart(blink::kWebGestureDeviceTouchpad, gfx::Vector2dF(1000, 0)); EXPECT_TRUE(FlingInProgress()); - // Processing GFS will send the first fling prgoress event if the time delta + // Processing GFS will send the first fling progress event if the time delta // between the timestamp of the GFS and the time that ProcessGestureFlingStart // is called is large enough. bool process_GFS_sent_first_event = first_wheel_event_sent_; @@ -333,19 +369,18 @@ TEST_P(FlingControllerTest, GestureFlingCancelsFiltered) { // GFC without previous GFS is dropped. SimulateFlingCancel(blink::kWebGestureDeviceTouchscreen); - EXPECT_TRUE(last_fling_cancel_filtered_); + EXPECT_FALSE(FlingInProgress()); // GFC after previous GFS is filtered by fling booster. SimulateFlingStart(blink::kWebGestureDeviceTouchscreen, gfx::Vector2dF(1000, 0)); EXPECT_TRUE(FlingInProgress()); SimulateFlingCancel(blink::kWebGestureDeviceTouchscreen); - EXPECT_TRUE(last_fling_cancel_filtered_); EXPECT_TRUE(FlingInProgress()); // Any other GFC while the fling cancelation is deferred gets filtered. SimulateFlingCancel(blink::kWebGestureDeviceTouchscreen); - EXPECT_TRUE(last_fling_cancel_filtered_); + EXPECT_TRUE(FlingInProgress()); } TEST_P(FlingControllerTest, GestureFlingNotCancelledBySmallTimeDelta) { @@ -416,7 +451,6 @@ // Start the fling animation later, as if there was a delay in event dispatch. AdvanceTime(1.f); - ASSERT_FALSE(fling_controller_->FilterGestureEvent(fling_start_with_latency)); fling_controller_->ProcessGestureFlingStart(fling_start_with_latency); EXPECT_TRUE(FlingInProgress()); @@ -450,7 +484,7 @@ TEST_P(FlingControllerTest, MAYBE_ControllerBoostsTouchpadFling) { SimulateFlingStart(blink::kWebGestureDeviceTouchpad, gfx::Vector2dF(1000, 0)); EXPECT_TRUE(FlingInProgress()); - // Processing GFS will send the first fling prgoress event if the time delta + // Processing GFS will send the first fling progress event if the time delta // between the timestamp of the GFS and the time that ProcessGestureFlingStart // is called is large enough. bool process_GFS_sent_first_event = first_wheel_event_sent_; @@ -473,7 +507,6 @@ // Now cancel the fling. The GFC will get suppressed by fling booster. SimulateFlingCancel(blink::kWebGestureDeviceTouchpad); - EXPECT_TRUE(last_fling_cancel_filtered_); EXPECT_TRUE(FlingInProgress()); // The second GFS will boost the current active fling. @@ -496,7 +529,6 @@ // Now cancel the fling. The GFC will get suppressed by fling booster. SimulateFlingCancel(blink::kWebGestureDeviceTouchscreen); - EXPECT_TRUE(last_fling_cancel_filtered_); EXPECT_TRUE(FlingInProgress()); // The second GFS will boost the current active fling. @@ -513,7 +545,6 @@ // Now cancel the fling. The GFC will get suppressed by fling booster. SimulateFlingCancel(blink::kWebGestureDeviceTouchscreen); - EXPECT_TRUE(last_fling_cancel_filtered_); EXPECT_TRUE(FlingInProgress()); // Wait for the boosting timer to expire. The delayed cancelation must work @@ -548,7 +579,6 @@ // Now cancel the fling. The GFC won't get suppressed by fling booster since // autoscroll fling doesn't have boosting. SimulateFlingCancel(blink::kWebGestureDeviceSyntheticAutoscroll); - EXPECT_FALSE(last_fling_cancel_filtered_); EXPECT_FALSE(FlingInProgress()); }
diff --git a/content/browser/renderer_host/input/fling_scheduler_unittest.cc b/content/browser/renderer_host/input/fling_scheduler_unittest.cc index 392cc8d..1a13b4f 100644 --- a/content/browser/renderer_host/input/fling_scheduler_unittest.cc +++ b/content/browser/renderer_host/input/fling_scheduler_unittest.cc
@@ -86,8 +86,7 @@ fling_start.data.fling_start.velocity_x = velocity.x(); fling_start.data.fling_start.velocity_y = velocity.y(); GestureEventWithLatencyInfo fling_start_with_latency(fling_start); - if (!fling_controller_->FilterGestureEvent(fling_start_with_latency)) - fling_controller_->ProcessGestureFlingStart(fling_start_with_latency); + fling_controller_->FilterGestureEvent(fling_start_with_latency); } void SimulateFlingCancel() { @@ -96,8 +95,7 @@ blink::kWebGestureDeviceTouchscreen); fling_cancel.data.fling_cancel.prevent_boosting = true; GestureEventWithLatencyInfo fling_cancel_with_latency(fling_cancel); - if (!fling_controller_->FilterGestureEvent(fling_cancel_with_latency)) - fling_controller_->ProcessGestureFlingCancel(fling_cancel_with_latency); + fling_controller_->FilterGestureEvent(fling_cancel_with_latency); } // FlingControllerEventSenderClient
diff --git a/content/browser/renderer_host/input/gesture_event_queue.cc b/content/browser/renderer_host/input/gesture_event_queue.cc index 6724bfb..e9d5dc6 100644 --- a/content/browser/renderer_host/input/gesture_event_queue.cc +++ b/content/browser/renderer_host/input/gesture_event_queue.cc
@@ -57,26 +57,7 @@ bool GestureEventQueue::FlingControllerFilterEvent( const GestureEventWithLatencyInfo& gesture_event) { TRACE_EVENT0("input", "GestureEventQueue::QueueEvent"); - if (fling_controller_.FilterGestureEvent(gesture_event)) - return true; - - // fling_controller_ is in charge of handling GFS events and the events are - // not sent to the renderer, the controller processes the fling and generates - // fling progress events (wheel events for touchpad and GSU events for - // touchscreen and autoscroll) which are handled normally. - if (gesture_event.event.GetType() == WebInputEvent::kGestureFlingStart) { - fling_controller_.ProcessGestureFlingStart(gesture_event); - return true; - } - - // If the GestureFlingStart event is processed by the fling_controller_, the - // GestureFlingCancel event should be the same. - if (gesture_event.event.GetType() == WebInputEvent::kGestureFlingCancel) { - fling_controller_.ProcessGestureFlingCancel(gesture_event); - return true; - } - - return false; + return fling_controller_.FilterGestureEvent(gesture_event); } void GestureEventQueue::QueueDeferredEvents(
diff --git a/content/browser/service_worker/service_worker_context_request_handler.cc b/content/browser/service_worker/service_worker_context_request_handler.cc deleted file mode 100644 index 32af334..0000000 --- a/content/browser/service_worker/service_worker_context_request_handler.cc +++ /dev/null
@@ -1,209 +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. - -#include "content/browser/service_worker/service_worker_context_request_handler.h" - -#include "base/command_line.h" -#include "base/time/time.h" -#include "content/browser/service_worker/service_worker_context_core.h" -#include "content/browser/service_worker/service_worker_provider_host.h" -#include "content/browser/service_worker/service_worker_read_from_cache_job.h" -#include "content/browser/service_worker/service_worker_storage.h" -#include "content/browser/service_worker/service_worker_version.h" -#include "content/browser/service_worker/service_worker_write_to_cache_job.h" -#include "content/common/service_worker/service_worker_utils.h" -#include "content/public/common/content_switches.h" -#include "net/base/load_flags.h" -#include "net/log/net_log.h" -#include "net/log/net_log_event_type.h" -#include "net/log/net_log_with_source.h" -#include "net/url_request/url_request.h" -#include "net/url_request/url_request_error_job.h" -#include "services/network/public/cpp/resource_response_info.h" - -namespace content { - -ServiceWorkerContextRequestHandler::ServiceWorkerContextRequestHandler( - base::WeakPtr<ServiceWorkerContextCore> context, - base::WeakPtr<ServiceWorkerProviderHost> provider_host, - base::WeakPtr<storage::BlobStorageContext> blob_storage_context, - ResourceType resource_type) - : ServiceWorkerRequestHandler(context, - provider_host, - blob_storage_context, - resource_type), - version_(provider_host_->running_hosted_version()) { - DCHECK(provider_host_->IsProviderForServiceWorker()); - DCHECK(version_); -} - -ServiceWorkerContextRequestHandler::~ServiceWorkerContextRequestHandler() { -} - -// static -std::string ServiceWorkerContextRequestHandler::CreateJobStatusToString( - CreateJobStatus status) { - switch (status) { - case CreateJobStatus::UNINITIALIZED: - return "UNINITIALIZED"; - case CreateJobStatus::WRITE_JOB: - return "WRITE_JOB"; - case CreateJobStatus::WRITE_JOB_WITH_INCUMBENT: - return "WRITE_JOB_WITH_INCUMBENT"; - case CreateJobStatus::READ_JOB: - return "READ_JOB"; - case CreateJobStatus::READ_JOB_FOR_DUPLICATE_SCRIPT_IMPORT: - return "READ_JOB_FOR_DUPLICATE_SCRIPT_IMPORT"; - case CreateJobStatus::ERROR_NO_PROVIDER: - return "ERROR_NO_PROVIDER"; - case CreateJobStatus::ERROR_REDUNDANT_VERSION: - return "ERROR_REDUNDANT_VERSION"; - case CreateJobStatus::ERROR_NO_CONTEXT: - return "ERROR_NO_CONTEXT"; - case CreateJobStatus::ERROR_REDIRECT: - return "ERROR_REDIRECT"; - case CreateJobStatus::ERROR_UNINSTALLED_SCRIPT_IMPORT: - return "ERROR_UNINSTALLED_SCRIPT_IMPORT"; - case CreateJobStatus::ERROR_OUT_OF_RESOURCE_IDS: - return "ERROR_OUT_OF_RESOURCE_IDS"; - } - NOTREACHED() << static_cast<int>(status); - return "UNKNOWN"; -} - -net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJob( - net::URLRequest* request, - net::NetworkDelegate* network_delegate, - ResourceContext* resource_context) { - // We only use the script cache for main script loading and - // importScripts(), even if a cached script is xhr'd, we don't - // retrieve it from the script cache. - // TODO(falken): Get the desired behavior clarified in the spec, - // and make tweak the behavior here to match. - if (resource_type_ != RESOURCE_TYPE_SERVICE_WORKER && - resource_type_ != RESOURCE_TYPE_SCRIPT) { - // Fall back to network. - return nullptr; - } - - CreateJobStatus status = CreateJobStatus::UNINITIALIZED; - net::URLRequestJob* job = - MaybeCreateJobImpl(request, network_delegate, &status); - const bool is_main_script = resource_type_ == RESOURCE_TYPE_SERVICE_WORKER; - ServiceWorkerMetrics::RecordContextRequestHandlerStatus( - status, ServiceWorkerVersion::IsInstalled(version_->status()), - is_main_script); - if (job) - return job; - - // If we got here, a job couldn't be created. Return an error job rather than - // falling back to network. Otherwise the renderer may receive the response - // from network and start a service worker whose browser-side - // ServiceWorkerVersion is not properly initialized. - std::string error_str(CreateJobStatusToString(status)); - request->net_log().AddEvent( - net::NetLogEventType::SERVICE_WORKER_SCRIPT_LOAD_UNHANDLED_REQUEST_ERROR, - net::NetLog::StringCallback("error", &error_str)); - - return new net::URLRequestErrorJob(request, network_delegate, - net::Error::ERR_FAILED); -} - -net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJobImpl( - net::URLRequest* request, - net::NetworkDelegate* network_delegate, - CreateJobStatus* out_status) { - if (!context_) { - *out_status = CreateJobStatus::ERROR_NO_CONTEXT; - return nullptr; - } - if (!provider_host_) { - *out_status = CreateJobStatus::ERROR_NO_PROVIDER; - return nullptr; - } - - // This could happen if browser-side has set the status to redundant but the - // worker has not yet stopped. The worker is already doomed so just reject the - // request. Handle it specially here because otherwise it'd be unclear whether - // "REDUNDANT" should count as installed or not installed when making - // decisions about how to handle the request and logging UMA. - if (version_->status() == ServiceWorkerVersion::REDUNDANT) { - *out_status = CreateJobStatus::ERROR_REDUNDANT_VERSION; - return nullptr; - } - - // We currently have no use case for hijacking a redirected request. - if (request->url_chain().size() > 1) { - *out_status = CreateJobStatus::ERROR_REDIRECT; - return nullptr; - } - - const bool is_main_script = resource_type_ == RESOURCE_TYPE_SERVICE_WORKER; - int64_t resource_id = - version_->script_cache_map()->LookupResourceId(request->url()); - if (resource_id != kInvalidServiceWorkerResourceId) { - if (ServiceWorkerVersion::IsInstalled(version_->status())) { - // An installed worker is loading a stored script. - *out_status = CreateJobStatus::READ_JOB; - } else { - // A new worker is loading a stored script. The script was already - // imported (or the main script is being recursively imported). - *out_status = CreateJobStatus::READ_JOB_FOR_DUPLICATE_SCRIPT_IMPORT; - } - return new ServiceWorkerReadFromCacheJob(request, network_delegate, - resource_type_, context_, version_, - resource_id); - } - - // An installed worker is importing a non-stored script. - if (ServiceWorkerVersion::IsInstalled(version_->status())) { - DCHECK(!is_main_script); - *out_status = CreateJobStatus::ERROR_UNINSTALLED_SCRIPT_IMPORT; - return nullptr; - } - - // A new worker is loading a script for the first time. Create a write job to - // store the script. - ServiceWorkerRegistration* registration = - context_->GetLiveRegistration(version_->registration_id()); - DCHECK(registration); // We're registering or updating so must be there. - - resource_id = context_->storage()->NewResourceId(); - if (resource_id == kInvalidServiceWorkerResourceId) { - *out_status = CreateJobStatus::ERROR_OUT_OF_RESOURCE_IDS; - return nullptr; - } - - // Bypass the browser cache for initial installs and update checks after 24 - // hours have passed. - int extra_load_flags = 0; - base::TimeDelta time_since_last_check = - base::Time::Now() - registration->last_update_check(); - - if (ServiceWorkerUtils::ShouldBypassCacheDueToUpdateViaCache( - is_main_script, registration->update_via_cache()) || - time_since_last_check > kServiceWorkerScriptMaxCacheAge || - version_->force_bypass_cache_for_scripts()) { - extra_load_flags = net::LOAD_BYPASS_CACHE; - } - - ServiceWorkerVersion* stored_version = registration->waiting_version() - ? registration->waiting_version() - : registration->active_version(); - int64_t incumbent_resource_id = kInvalidServiceWorkerResourceId; - if (is_main_script) { - if (stored_version && stored_version->script_url() == request->url()) { - incumbent_resource_id = - stored_version->script_cache_map()->LookupResourceId(request->url()); - } - } - *out_status = incumbent_resource_id == kInvalidServiceWorkerResourceId - ? CreateJobStatus::WRITE_JOB - : CreateJobStatus::WRITE_JOB_WITH_INCUMBENT; - return new ServiceWorkerWriteToCacheJob( - request, network_delegate, resource_type_, context_, version_.get(), - extra_load_flags, resource_id, incumbent_resource_id); -} - -} // namespace content
diff --git a/content/browser/service_worker/service_worker_context_request_handler.h b/content/browser/service_worker/service_worker_context_request_handler.h deleted file mode 100644 index 4c9fa5c..0000000 --- a/content/browser/service_worker/service_worker_context_request_handler.h +++ /dev/null
@@ -1,84 +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. - -#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_REQUEST_HANDLER_H_ -#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_REQUEST_HANDLER_H_ - -#include <stdint.h> - -#include "base/macros.h" -#include "content/browser/service_worker/service_worker_request_handler.h" - -namespace content { - -class ServiceWorkerVersion; - -// A request handler derivative used to handle requests from -// service workers. -class CONTENT_EXPORT ServiceWorkerContextRequestHandler - : public ServiceWorkerRequestHandler { - public: - // The result status for MaybeCreateJob. Used in histograms. Append-only. - enum class CreateJobStatus { - // Unitialized status. - UNINITIALIZED, - // A ServiceWorkerWriteToCacheJob was created. - WRITE_JOB, - // A ServiceWorkerWriteToCacheJob was created with an incumbent script to - // compare against. - WRITE_JOB_WITH_INCUMBENT, - // A ServiceWorkerReadFromCacheJob was created. - READ_JOB, - // A ServiceWorkerReadFromCacheJob was created for a new worker that is - // importing a script that was already imported. - READ_JOB_FOR_DUPLICATE_SCRIPT_IMPORT, - // A job could not be created because there is no live - // ServiceWorkerProviderHost. - ERROR_NO_PROVIDER, - // A job could not be created because the ServiceWorkerVersion is in status - // REDUNDANT. - ERROR_REDUNDANT_VERSION, - // A job could not be created because there is no live - // ServiceWorkerContextCore. - ERROR_NO_CONTEXT, - // A job could not be created because a redirect occurred. - ERROR_REDIRECT, - // A job was not created because an installed worker is importing a script - // that was not stored at installation time. - ERROR_UNINSTALLED_SCRIPT_IMPORT, - // A job could not be created because there are no resource ids available. - ERROR_OUT_OF_RESOURCE_IDS, - // Add new types here. - - kMaxValue = ERROR_OUT_OF_RESOURCE_IDS, - }; - - ServiceWorkerContextRequestHandler( - base::WeakPtr<ServiceWorkerContextCore> context, - base::WeakPtr<ServiceWorkerProviderHost> provider_host, - base::WeakPtr<storage::BlobStorageContext> blob_storage_context, - ResourceType resource_type); - ~ServiceWorkerContextRequestHandler() override; - - // Called via custom URLRequestJobFactory. - net::URLRequestJob* MaybeCreateJob( - net::URLRequest* request, - net::NetworkDelegate* network_delegate, - ResourceContext* resource_context) override; - - static std::string CreateJobStatusToString(CreateJobStatus status); - - private: - net::URLRequestJob* MaybeCreateJobImpl(net::URLRequest* request, - net::NetworkDelegate* network_delegate, - CreateJobStatus* out_status); - - scoped_refptr<ServiceWorkerVersion> version_; - - DISALLOW_COPY_AND_ASSIGN(ServiceWorkerContextRequestHandler); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_REQUEST_HANDLER_H_
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.h b/content/browser/service_worker/service_worker_fetch_dispatcher.h index a5745ab0..cbf37a3d 100644 --- a/content/browser/service_worker/service_worker_fetch_dispatcher.h +++ b/content/browser/service_worker/service_worker_fetch_dispatcher.h
@@ -16,6 +16,7 @@ #include "base/time/time.h" #include "content/browser/service_worker/service_worker_metrics.h" #include "content/common/content_export.h" +#include "content/public/browser/web_contents.h" #include "content/public/common/resource_type.h" #include "mojo/public/cpp/system/data_pipe.h" #include "services/network/public/mojom/url_loader.mojom.h" @@ -31,6 +32,7 @@ namespace content { +class ServiceWorkerContextWrapper; class ServiceWorkerVersion; class URLLoaderFactoryGetter;
diff --git a/content/browser/service_worker/service_worker_metrics.cc b/content/browser/service_worker/service_worker_metrics.cc index 255678d..386d74f 100644 --- a/content/browser/service_worker/service_worker_metrics.cc +++ b/content/browser/service_worker/service_worker_metrics.cc
@@ -842,36 +842,6 @@ } } -void ServiceWorkerMetrics::RecordContextRequestHandlerStatus( - ServiceWorkerContextRequestHandler::CreateJobStatus status, - bool is_installed, - bool is_main_script) { - if (is_installed) { - if (is_main_script) { - UMA_HISTOGRAM_ENUMERATION( - "ServiceWorker.ContextRequestHandlerStatus.InstalledWorker." - "MainScript", - status); - } else { - UMA_HISTOGRAM_ENUMERATION( - "ServiceWorker.ContextRequestHandlerStatus.InstalledWorker." - "ImportedScript", - status); - } - } else { - if (is_main_script) { - UMA_HISTOGRAM_ENUMERATION( - "ServiceWorker.ContextRequestHandlerStatus.NewWorker.MainScript", - status); - } else { - UMA_HISTOGRAM_ENUMERATION( - "ServiceWorker.ContextRequestHandlerStatus.NewWorker." - "ImportedScript", - status); - } - } -} - void ServiceWorkerMetrics::RecordRuntime(base::TimeDelta time) { // Start at 1 second since we expect service worker to last at least this // long: the update timer and idle timeout timer run on the order of seconds.
diff --git a/content/browser/service_worker/service_worker_metrics.h b/content/browser/service_worker/service_worker_metrics.h index 4112e80..f76a462 100644 --- a/content/browser/service_worker/service_worker_metrics.h +++ b/content/browser/service_worker/service_worker_metrics.h
@@ -11,11 +11,11 @@ #include "base/macros.h" #include "base/time/time.h" -#include "content/browser/service_worker/service_worker_context_request_handler.h" #include "content/browser/service_worker/service_worker_database.h" #include "content/browser/service_worker/service_worker_installed_script_reader.h" #include "content/common/service_worker/service_worker_types.h" #include "content/public/browser/service_worker_context.h" +#include "content/public/common/resource_type.h" #include "services/network/public/mojom/fetch_api.mojom.h" #include "third_party/blink/public/mojom/service_worker/embedded_worker.mojom.h" #include "ui/base/page_transition_types.h" @@ -418,13 +418,6 @@ StartSituation start_situation, ResourceType resource_type); - // Records the result of trying to handle a request for a service worker - // script. - static void RecordContextRequestHandlerStatus( - ServiceWorkerContextRequestHandler::CreateJobStatus status, - bool is_installed, - bool is_main_script); - static void RecordRuntime(base::TimeDelta time); // Records the result of starting service worker for a navigation hint.
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index a513911..379830f5 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -20,7 +20,6 @@ #include "content/browser/service_worker/embedded_worker_status.h" #include "content/browser/service_worker/service_worker_consts.h" #include "content/browser/service_worker/service_worker_context_core.h" -#include "content/browser/service_worker/service_worker_context_request_handler.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_controllee_request_handler.h" #include "content/browser/service_worker/service_worker_registration_object_host.h" @@ -641,34 +640,27 @@ base::WeakPtr<storage::BlobStorageContext> blob_storage_context, scoped_refptr<network::ResourceRequestBody> body, bool skip_service_worker) { - // |skip_service_worker| is meant to apply to requests that could be handled - // by a service worker, as opposed to requests for the service worker script - // itself. So ignore it here for the service worker script and its imported - // scripts. - // TODO(falken): Really it should be treated as an error to set - // |skip_service_worker| for requests to start the service worker, but it's - // difficult to fix that renderer-side (maybe try after S13nServiceWorker). - if (IsProviderForServiceWorker() && - (resource_type == RESOURCE_TYPE_SERVICE_WORKER || - resource_type == RESOURCE_TYPE_SCRIPT)) { - skip_service_worker = false; - } + // We only get here for main resource requests for service worker clients + // (navigations, dedicated workers, and shared workers). + DCHECK(!IsProviderForServiceWorker()); + + // TODO(falken): Add DCHECK(IsMainResourceType()) and remove the calls to it + // below. + if (skip_service_worker) { if (!ServiceWorkerUtils::IsMainResourceType(resource_type)) return std::unique_ptr<ServiceWorkerRequestHandler>(); return std::make_unique<ServiceWorkerURLTrackingRequestHandler>( context_, AsWeakPtr(), blob_storage_context, resource_type); } - if (IsProviderForServiceWorker()) { - return std::make_unique<ServiceWorkerContextRequestHandler>( - context_, AsWeakPtr(), blob_storage_context, resource_type); - } + if (ServiceWorkerUtils::IsMainResourceType(resource_type) || controller()) { return std::make_unique<ServiceWorkerControlleeRequestHandler>( context_, AsWeakPtr(), blob_storage_context, request_mode, credentials_mode, redirect_mode, integrity, keepalive, resource_type, request_context_type, frame_type, body); } + return std::unique_ptr<ServiceWorkerRequestHandler>(); }
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h index 23b35f86..258fcbc 100644 --- a/content/browser/service_worker/service_worker_provider_host.h +++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -472,7 +472,6 @@ friend class LinkHeaderServiceWorkerTest; friend class ServiceWorkerProviderHostTest; friend class ServiceWorkerWriteToCacheJobTest; - friend class ServiceWorkerContextRequestHandlerTest; friend class service_worker_controllee_request_handler_unittest:: ServiceWorkerControlleeRequestHandlerTest; friend class service_worker_object_host_unittest::ServiceWorkerObjectHostTest;
diff --git a/content/browser/service_worker/service_worker_read_from_cache_job.h b/content/browser/service_worker/service_worker_read_from_cache_job.h index 6509d478..c2aa051 100644 --- a/content/browser/service_worker/service_worker_read_from_cache_job.h +++ b/content/browser/service_worker/service_worker_read_from_cache_job.h
@@ -41,8 +41,6 @@ private: friend class ServiceWorkerReadFromCacheJobTest; - FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextRequestHandlerTestP, - DuplicateScriptImport); bool is_main_script() const { return resource_type_ == RESOURCE_TYPE_SERVICE_WORKER;
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index a9961fa..3892721 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h
@@ -31,7 +31,6 @@ #include "content/browser/service_worker/embedded_worker_status.h" #include "content/browser/service_worker/service_worker_client_info.h" #include "content/browser/service_worker/service_worker_client_utils.h" -#include "content/browser/service_worker/service_worker_context_request_handler.h" #include "content/browser/service_worker/service_worker_metrics.h" #include "content/browser/service_worker/service_worker_ping_controller.h" #include "content/browser/service_worker/service_worker_script_cache_map.h"
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job.h b/content/browser/service_worker/service_worker_write_to_cache_job.h index 5c18785..35b7f83 100644 --- a/content/browser/service_worker/service_worker_write_to_cache_job.h +++ b/content/browser/service_worker/service_worker_write_to_cache_job.h
@@ -26,7 +26,6 @@ class ServiceWorkerCacheWriter; class ServiceWorkerContextCore; -class ServiceWorkerContextRequestHandlerTest; // A URLRequestJob derivative used to cache the main script // and its imports during the initial install of a new version. @@ -61,10 +60,6 @@ const static net::Error kIdenticalScriptError; private: - friend class ServiceWorkerContextRequestHandlerTest; - FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextRequestHandlerTest, - ServiceWorkerDataRequestAnnotation); - ~ServiceWorkerWriteToCacheJob() override; // net::URLRequestJob overrides
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc b/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc index c13bc8a..ef4cacf 100644 --- a/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc +++ b/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
@@ -17,10 +17,10 @@ #include "base/threading/thread_task_runner_handle.h" #include "content/browser/service_worker/embedded_worker_test_helper.h" #include "content/browser/service_worker/service_worker_context_core.h" -#include "content/browser/service_worker/service_worker_context_request_handler.h" #include "content/browser/service_worker/service_worker_disk_cache.h" #include "content/browser/service_worker/service_worker_provider_host.h" #include "content/browser/service_worker/service_worker_registration.h" +#include "content/browser/service_worker/service_worker_request_handler.h" #include "content/browser/service_worker/service_worker_test_utils.h" #include "content/common/service_worker/service_worker_utils.h" #include "content/public/test/test_browser_thread_bundle.h"
diff --git a/content/browser/web_package/signed_exchange_loader.cc b/content/browser/web_package/signed_exchange_loader.cc index b27c2e0a..86d0026e9 100644 --- a/content/browser/web_package/signed_exchange_loader.cc +++ b/content/browser/web_package/signed_exchange_loader.cc
@@ -45,8 +45,7 @@ net::RedirectInfo CreateRedirectInfo( const GURL& new_url, const network::ResourceRequest& outer_request, - const network::ResourceResponseHead& outer_response, - bool is_fallback_redirect) { + const network::ResourceResponseHead& outer_response) { // https://wicg.github.io/webpackage/loading.html#mp-http-fetch // Step 3. Set actualResponse's status to 303. [spec text] return net::RedirectInfo::ComputeRedirectInfo( @@ -59,8 +58,7 @@ outer_request.referrer_policy, outer_request.referrer.spec(), 303, new_url, net::RedirectUtil::GetReferrerPolicyHeader(outer_response.headers.get()), - false /* insecure_scheme_was_upgraded */, true /* copy_fragment */, - is_fallback_redirect); + false /* insecure_scheme_was_upgraded */); } bool HasNoSniffHeader(const network::ResourceResponseHead& response) { @@ -304,8 +302,7 @@ fallback_url_ = request_url; DCHECK(outer_response_timing_info_); forwarding_client_->OnReceiveRedirect( - CreateRedirectInfo(request_url, outer_request_, outer_response_, - true /* is_fallback_redirect */), + CreateRedirectInfo(request_url, outer_request_, outer_response_), std::move(outer_response_timing_info_)->CreateRedirectResponseHead()); forwarding_client_.reset(); return; @@ -315,8 +312,7 @@ DCHECK(outer_response_timing_info_); forwarding_client_->OnReceiveRedirect( - CreateRedirectInfo(request_url, outer_request_, outer_response_, - false /* is_fallback_redirect */), + CreateRedirectInfo(request_url, outer_request_, outer_response_), std::move(outer_response_timing_info_)->CreateRedirectResponseHead()); forwarding_client_.reset();
diff --git a/content/browser/web_package/signed_exchange_request_handler_browsertest.cc b/content/browser/web_package/signed_exchange_request_handler_browsertest.cc index d0eac74..59a9a894 100644 --- a/content/browser/web_package/signed_exchange_request_handler_browsertest.cc +++ b/content/browser/web_package/signed_exchange_request_handler_browsertest.cc
@@ -771,8 +771,6 @@ https_server_.ServeFilesFromSourceDirectory("content/test/data"); https_server_.RegisterRequestHandler( base::BindRepeating(&self::RedirectResponseHandler)); - https_server_.RegisterRequestHandler( - base::BindRepeating(&self::FallbackSxgResponseHandler)); https_server_.RegisterRequestMonitor( base::BindRepeating(&self::MonitorRequest, base::Unretained(this))); ASSERT_TRUE(https_server_.Start()); @@ -787,16 +785,16 @@ EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); } - bool IsSignedExchangeEnabled() const { return GetParam(); } + bool ShouldHaveSXGAcceptHeaderInEnabledOrigin() const { return GetParam(); } - void CheckAcceptHeader(const GURL& url, - bool is_navigation, - bool is_fallback) { + bool ShouldHaveSXGAcceptHeader() const { return GetParam(); } + + void CheckAcceptHeader(const GURL& url, bool is_navigation) { const auto accept_header = GetInterceptedAcceptHeader(url); ASSERT_TRUE(accept_header); EXPECT_EQ( *accept_header, - IsSignedExchangeEnabled() && !is_fallback + ShouldHaveSXGAcceptHeader() ? (is_navigation ? std::string(network::kFrameAcceptHeader) + std::string(kAcceptHeaderSignedExchangeSuffix) @@ -808,22 +806,14 @@ void CheckNavigationAcceptHeader(const std::vector<GURL>& urls) { for (const auto& url : urls) { SCOPED_TRACE(url); - CheckAcceptHeader(url, true /* is_navigation */, false /* is_fallback */); + CheckAcceptHeader(url, true /* is_navigation */); } } void CheckPrefetchAcceptHeader(const std::vector<GURL>& urls) { for (const auto& url : urls) { SCOPED_TRACE(url); - CheckAcceptHeader(url, false /* is_navigation */, - false /* is_fallback */); - } - } - - void CheckFallbackAcceptHeader(const std::vector<GURL>& urls) { - for (const auto& url : urls) { - SCOPED_TRACE(url); - CheckAcceptHeader(url, true /* is_navigation */, true /* is_fallback */); + CheckAcceptHeader(url, false /* is_navigation */); } } @@ -854,33 +844,6 @@ return std::move(http_response); } - // Responds with a prologue-only signed exchange that triggers a fallback - // redirect. - static std::unique_ptr<net::test_server::HttpResponse> - FallbackSxgResponseHandler(const net::test_server::HttpRequest& request) { - const std::string prefix = "/fallback_sxg?"; - if (!base::StartsWith(request.relative_url, prefix, - base::CompareCase::SENSITIVE)) { - return std::unique_ptr<net::test_server::HttpResponse>(); - } - std::string fallback_url(request.relative_url.substr(prefix.length())); - - std::unique_ptr<net::test_server::BasicHttpResponse> http_response( - new net::test_server::BasicHttpResponse); - http_response->set_code(net::HTTP_OK); - http_response->set_content_type("application/signed-exchange;v=b3"); - - std::string sxg("sxg1-b3", 8); - sxg.push_back(fallback_url.length() >> 8); - sxg.push_back(fallback_url.length() & 0xff); - sxg += fallback_url; - // FallbackUrlAndAfter() requires 6 more bytes for sizes of next fields. - sxg.resize(sxg.length() + 6); - - http_response->set_content(sxg); - return std::move(http_response); - } - void MonitorRequest(const net::test_server::HttpRequest& request) { const auto it = request.headers.find(std::string(network::kAcceptHeader)); if (it == request.headers.end()) @@ -897,7 +860,7 @@ IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest, Simple) { const GURL test_url = https_server_.GetURL("/sxg/test.html"); - EXPECT_EQ(IsSignedExchangeEnabled(), + EXPECT_EQ(ShouldHaveSXGAcceptHeaderInEnabledOrigin(), signed_exchange_utils::IsSignedExchangeHandlingEnabled()); NavigateAndWaitForTitle(test_url, test_url.spec()); CheckNavigationAcceptHeader({test_url}); @@ -914,20 +877,6 @@ } IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest, - FallbackRedirect) { - if (!IsSignedExchangeEnabled()) - return; - - const GURL fallback_url = https_server_.GetURL("/sxg/test.html"); - const GURL test_url = - https_server_.GetURL("/fallback_sxg?" + fallback_url.spec()); - NavigateAndWaitForTitle(test_url, fallback_url.spec()); - - CheckNavigationAcceptHeader({test_url}); - CheckFallbackAcceptHeader({fallback_url}); -} - -IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest, PrefetchEnabledPageEnabledTarget) { const GURL target = https_server_.GetURL("/sxg/hello.txt"); const GURL page_url = @@ -973,12 +922,13 @@ const std::string expected_title = is_generated_scope - ? (IsSignedExchangeEnabled() ? frame_accept_with_sxg : frame_accept) + ? (ShouldHaveSXGAcceptHeader() ? frame_accept_with_sxg + : frame_accept) : "Done"; const base::Optional<std::string> expected_target_accept_header = is_generated_scope ? base::nullopt - : base::Optional<std::string>(IsSignedExchangeEnabled() + : base::Optional<std::string>(ShouldHaveSXGAcceptHeader() ? frame_accept_with_sxg : frame_accept);
diff --git a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc index 487194d..e2c91ea0 100644 --- a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc +++ b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
@@ -876,14 +876,6 @@ ExecuteJavascriptAndWaitForOk("verifyAfterAudioServiceCrash()"); } -IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest, - GetUserMediaCloneAndApplyConstraints) { - ASSERT_TRUE(embedded_test_server()->Start()); - GURL url(embedded_test_server()->GetURL("/media/getusermedia.html")); - NavigateToURL(shell(), url); - ExecuteJavascriptAndWaitForOk("getUserMediaCloneAndApplyConstraints()"); -} - // We run these tests with the audio service both in and out of the the browser // process to have waterfall coverage while the feature rolls out. It should be // removed after launch.
diff --git a/content/browser/worker_host/worker_script_loader.cc b/content/browser/worker_host/worker_script_loader.cc index 52a723f..ad71e04 100644 --- a/content/browser/worker_host/worker_script_loader.cc +++ b/content/browser/worker_host/worker_script_loader.cc
@@ -9,6 +9,7 @@ #include "content/browser/loader/navigation_loader_interceptor.h" #include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/service_worker/service_worker_provider_host.h" +#include "content/browser/service_worker/service_worker_request_handler.h" #include "content/public/browser/resource_context.h" #include "net/url_request/redirect_util.h" #include "services/network/public/cpp/shared_url_loader_factory.h"
diff --git a/content/common/origin_util.cc b/content/common/origin_util.cc index 878cb24a..422c62e2 100644 --- a/content/common/origin_util.cc +++ b/content/common/origin_util.cc
@@ -10,6 +10,7 @@ #include "base/strings/pattern.h" #include "content/common/url_schemes.h" #include "net/base/url_util.h" +#include "services/network/public/cpp/is_potentially_trustworthy.h" #include "url/gurl.h" #include "url/url_util.h" @@ -43,18 +44,8 @@ if (base::ContainsValue(url::GetSecureSchemes(), url.scheme())) return true; - return IsWhitelistedAsSecureOrigin(url::Origin::Create(url)); -} - -bool IsWhitelistedAsSecureOrigin(const url::Origin& origin) { - if (base::ContainsValue(content::GetSecureOriginsAndPatterns(), - origin.Serialize())) - return true; - for (const auto& origin_or_pattern : content::GetSecureOriginsAndPatterns()) { - if (base::MatchPattern(origin.host(), origin_or_pattern)) - return true; - } - return false; + return network::IsAllowlistedAsSecureOrigin( + url::Origin::Create(url), network::GetSecureOriginAllowlist()); } bool OriginCanAccessServiceWorkers(const GURL& url) { @@ -83,7 +74,8 @@ return true; } - return IsWhitelistedAsSecureOrigin(origin); + return network::IsAllowlistedAsSecureOrigin( + origin, network::GetSecureOriginAllowlist()); } } // namespace content
diff --git a/content/common/url_schemes.cc b/content/common/url_schemes.cc index e532406..6c6bf27 100644 --- a/content/common/url_schemes.cc +++ b/content/common/url_schemes.cc
@@ -7,6 +7,7 @@ #include <string.h> #include <iterator> +#include <utility> #include "base/no_destructor.h" #include "base/strings/string_util.h" @@ -39,11 +40,6 @@ // This set contains serialized canonicalized origins as well as hostname // patterns. The latter are canonicalized by component. -std::vector<std::string>& GetMutableSecureOriginsAndPatterns() { - static base::NoDestructor<std::vector<std::string>> origins; - return *origins; -} - std::vector<std::string>& GetMutableServiceWorkerSchemes() { static base::NoDestructor<std::vector<std::string>> schemes; return *schemes; @@ -111,18 +107,12 @@ schemes.savable_schemes.end()); GetMutableServiceWorkerSchemes() = std::move(schemes.service_worker_schemes); - - GetMutableSecureOriginsAndPatterns() = std::move(schemes.secure_origins); } const std::vector<std::string>& GetSavableSchemes() { return GetMutableSavableSchemes(); } -const std::vector<std::string>& GetSecureOriginsAndPatterns() { - return GetMutableSecureOriginsAndPatterns(); -} - const std::vector<std::string>& GetServiceWorkerSchemes() { return GetMutableServiceWorkerSchemes(); }
diff --git a/content/common/url_schemes.h b/content/common/url_schemes.h index 802c80b..407d6f5 100644 --- a/content/common/url_schemes.h +++ b/content/common/url_schemes.h
@@ -9,7 +9,6 @@ #include <vector> #include "content/common/content_export.h" -#include "url/origin.h" namespace content { @@ -28,11 +27,6 @@ // See comment in ContentClient::AddAdditionalSchemes for explanations. These // getters can be invoked on any thread. const std::vector<std::string>& GetSavableSchemes(); -// Contains serialized canonicalized origins as well as hostname patterns such -// as "*.foo.com". An origin should be considered secure if it matches an origin -// in this list or if its hostname matches one of the hostname patterns. The -// hostname patterns are canonicalized by component. -const std::vector<std::string>& GetSecureOriginsAndPatterns(); const std::vector<std::string>& GetServiceWorkerSchemes(); } // namespace content
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index b4217dc..ed16a41 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -76,8 +76,8 @@ "//services/shape_detection:shape_detection_java", "//services/shape_detection/public/mojom:mojom_java", "//skia/public/interfaces:interfaces_java", - "//third_party/android_deps:android_support_annotations_java", - "//third_party/android_deps:android_support_compat_java", + "//third_party/android_deps:com_android_support_support_annotations_java", + "//third_party/android_deps:com_android_support_support_compat_java", "//third_party/blink/public:android_mojo_bindings_java", "//third_party/blink/public:blink_headers_java", "//third_party/blink/public/mojom:mojom_core_java", @@ -476,7 +476,7 @@ "//services/device/public/java:geolocation_java_test_support", "//services/service_manager/public/java:service_manager_java", "//services/test/echo/public/mojom:mojom_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/blink/public:android_mojo_bindings_java",
diff --git a/content/public/browser/background_sync_context.h b/content/public/browser/background_sync_context.h index f4ec66a3..fd7c4064 100644 --- a/content/public/browser/background_sync_context.h +++ b/content/public/browser/background_sync_context.h
@@ -7,9 +7,16 @@ #include "base/callback_forward.h" #include "base/macros.h" +#include "base/time/time.h" +#include "build/build_config.h" +#if defined(OS_ANDROID) +#include "base/android/jni_android.h" +#include "base/android/scoped_java_ref.h" +#endif namespace content { +class BrowserContext; class StoragePartition; // One instance of this exists per StoragePartition, and services multiple child @@ -20,13 +27,30 @@ public: BackgroundSyncContext() = default; - // Process any pending Background Sync registrations for |storage_partition|. + // Process any pending Background Sync registrations. // This involves firing any sync events ready to be fired, and optionally // scheduling a job to wake up the browser when the next event needs to be // fired. - virtual void FireBackgroundSyncEventsForStoragePartition( - StoragePartition* storage_partition, - base::OnceClosure done_closure) = 0; + virtual void FireBackgroundSyncEvents(base::OnceClosure done_closure) = 0; + +#if defined(OS_ANDROID) + // Processes pending Background Sync registrations for all storage partitions + // in |browser_context|, and then runs the |j_runnable| when done. + virtual void FireBackgroundSyncEventsAcrossPartitions( + BrowserContext* browser_context, + const base::android::JavaParamRef<jobject>& j_runnable) = 0; +#endif + + // Gets the soonest time delta from now, when the browser should be woken up + // to fire any Background Sync events. + virtual base::TimeDelta GetSoonestWakeupDelta() = 0; + + // Gets the soonest time delta from now, when the browser should be woken up + // to fire any Background Sync events, across all storage partitions in + // |browser_context|, and invokes |callback| with it. + virtual void GetSoonestWakeupDeltaAcrossPartitions( + BrowserContext* browser_context, + base::OnceCallback<void(base::TimeDelta)> callback) = 0; protected: virtual ~BackgroundSyncContext() = default;
diff --git a/content/public/browser/background_sync_controller.h b/content/public/browser/background_sync_controller.h index 33ad82d..50e6c4064 100644 --- a/content/public/browser/background_sync_controller.h +++ b/content/public/browser/background_sync_controller.h
@@ -33,16 +33,9 @@ // registered a background sync event. virtual void NotifyBackgroundSyncRegistered(const url::Origin& origin) {} - // If |enabled|, ensures that the browser is running when the device next goes - // online after |min_ms| has passed. The behavior is platform dependent: - // * Android: Registers a GCM task which verifies that the browser is running - // the next time the device goes online after |min_ms| has passed. If it's - // not, it starts it. - // - // * Other Platforms: (UNIMPLEMENTED) Keeps the browser alive via - // BackgroundModeManager until called with |enabled| = false. |min_ms| is - // ignored. - virtual void RunInBackground(bool enabled, int64_t min_ms) {} + // Calculates the soonest wakeup delta across all storage partitions and + // schedules a background task to wake up the browser. + virtual void RunInBackground() {} }; } // namespace content
diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h index bfe6deb..394936e 100644 --- a/content/public/common/content_client.h +++ b/content/public/common/content_client.h
@@ -135,9 +135,6 @@ std::vector<std::string> csp_bypassing_schemes; // See https://www.w3.org/TR/powerful-features/#is-origin-trustworthy. std::vector<std::string> secure_schemes; - // Registers a serialized origin or a hostname pattern that should be - // considered trustworthy. - std::vector<std::string> secure_origins; // Registers a URL scheme as strictly empty documents, allowing them to // commit synchronously. std::vector<std::string> empty_document_schemes;
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index a6e748b..6f34b5b 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -220,6 +220,12 @@ // the use of persistent gpu memory buffers. const char kDisablePartialRaster[] = "disable-partial-raster"; +// Internally (in devtools_session.cc) switches the protocol to binary format +// (CBOR). This setting is temporary; we plan to remove it after transition to +// binary is sufficiently complete (2019-04-01). +const char kEnableInternalDevToolsBinaryProtocol[] = + "enable-internal-devtools-binary-protocol"; + // Enable partial raster in the renderer. const char kEnablePartialRaster[] = "enable-partial-raster";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index b298c312..69ad632 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -75,6 +75,7 @@ CONTENT_EXPORT extern const char kDisableNotifications[]; CONTENT_EXPORT extern const char kDisableOriginTrialControlledBlinkFeatures[]; CONTENT_EXPORT extern const char kDisablePartialRaster[]; +CONTENT_EXPORT extern const char kEnableInternalDevToolsBinaryProtocol[]; CONTENT_EXPORT extern const char kEnablePartialRaster[]; extern const char kDisablePepper3d[]; CONTENT_EXPORT extern const char kDisablePepper3DImageChromium[];
diff --git a/content/public/common/origin_util.h b/content/public/common/origin_util.h index 4e4bbc3a9..bb4a389a 100644 --- a/content/public/common/origin_util.h +++ b/content/public/common/origin_util.h
@@ -23,10 +23,6 @@ // may be insecure iframes present even if this method returns true. bool CONTENT_EXPORT IsOriginSecure(const GURL& url); -// Returns true if |origin| is whitelisted as secure, e.g. it was specified via -// the --unsafely-treat-insecure-origin-as-secure flag, and false otherwise. -bool CONTENT_EXPORT IsWhitelistedAsSecureOrigin(const url::Origin& origin); - // Returns true if the origin can register a service worker. Scheme must be // http (localhost only), https, or a custom-set secure scheme. bool CONTENT_EXPORT OriginCanAccessServiceWorkers(const GURL& url);
diff --git a/content/renderer/android/synchronous_layer_tree_frame_sink.cc b/content/renderer/android/synchronous_layer_tree_frame_sink.cc index c6e998d..dfc42c5 100644 --- a/content/renderer/android/synchronous_layer_tree_frame_sink.cc +++ b/content/renderer/android/synchronous_layer_tree_frame_sink.cc
@@ -309,9 +309,9 @@ embed_render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>(); shared_quad_state->SetAll( child_transform, gfx::Rect(child_size), gfx::Rect(child_size), - gfx::Rect() /* clip_rect */, false /* is_clipped */, - are_contents_opaque /* are_contents_opaque */, 1.f /* opacity */, - SkBlendMode::kSrcOver, 0 /* sorting_context_id */); + gfx::RRectF() /* rounded_corner_bounds */, gfx::Rect() /* clip_rect */, + false /* is_clipped */, are_contents_opaque /* are_contents_opaque */, + 1.f /* opacity */, SkBlendMode::kSrcOver, 0 /* sorting_context_id */); surface_quad->SetNew( shared_quad_state, gfx::Rect(child_size), gfx::Rect(child_size), viz::SurfaceRange(
diff --git a/content/renderer/media/webrtc/rtc_video_decoder.cc b/content/renderer/media/webrtc/rtc_video_decoder.cc index 7a71afae..7705e72 100644 --- a/content/renderer/media/webrtc/rtc_video_decoder.cc +++ b/content/renderer/media/webrtc/rtc_video_decoder.cc
@@ -13,6 +13,7 @@ #include "base/numerics/safe_conversions.h" #include "base/synchronization/waitable_event.h" #include "base/task_runner_util.h" +#include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "content/renderer/media/webrtc/webrtc_video_frame_adapter.h" #include "gpu/command_buffer/common/mailbox_holder.h" @@ -136,6 +137,9 @@ return decoder; } + // This wait is necessary because this task is completed in GPU process + // asynchronously but WebRTC API is synchronous. + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait; base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED); decoder.reset(new RTCVideoDecoder(type, factories));
diff --git a/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc b/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc index 9c4d2799..ad53e97 100644 --- a/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc +++ b/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc
@@ -19,6 +19,7 @@ #include "base/single_thread_task_runner.h" #include "base/stl_util.h" #include "base/synchronization/waitable_event.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "content/renderer/media/render_media_log.h" @@ -196,6 +197,7 @@ // Can be called on |worker_thread_| or |decoding_thread_|. DCHECK(!media_task_runner_->BelongsToCurrentThread()); + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait; bool result = false; base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED); @@ -444,6 +446,7 @@ const media::VideoDecoderConfig& config) { DCHECK_CALLED_ON_VALID_THREAD(decoding_thread_checker_); + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait; bool result = false; base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED);
diff --git a/content/renderer/media/webrtc/rtc_video_encoder.cc b/content/renderer/media/webrtc/rtc_video_encoder.cc index d24ff0c..5d5ce77 100644 --- a/content/renderer/media/webrtc/rtc_video_encoder.cc +++ b/content/renderer/media/webrtc/rtc_video_encoder.cc
@@ -21,6 +21,7 @@ #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread_checker.h" +#include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "content/public/common/content_features.h" @@ -888,6 +889,9 @@ ? webrtc::VideoContentType::SCREENSHARE : webrtc::VideoContentType::UNSPECIFIED); + // This wait is necessary because this task is completed in GPU process + // asynchronously but WebRTC API is synchronous. + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait; base::WaitableEvent initialization_waiter( base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED); @@ -917,6 +921,7 @@ const bool want_key_frame = frame_types && frame_types->size() && frame_types->front() == webrtc::kVideoFrameKey; + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait; base::WaitableEvent encode_waiter( base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED); @@ -940,6 +945,7 @@ return WEBRTC_VIDEO_CODEC_UNINITIALIZED; } + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait; base::WaitableEvent register_waiter( base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED); @@ -957,6 +963,7 @@ if (!impl_.get()) return WEBRTC_VIDEO_CODEC_OK; + base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait; base::WaitableEvent release_waiter( base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED);
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 28a2ffa..894bf91 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1385,6 +1385,7 @@ "../browser/background_fetch/background_fetch_service_unittest.cc", "../browser/background_fetch/storage/database_helpers_unittest.cc", "../browser/background_fetch/storage/image_helpers_unittest.cc", + "../browser/background_sync/background_sync_launcher_unittest.cc", "../browser/background_sync/background_sync_manager_unittest.cc", "../browser/background_sync/background_sync_network_observer_unittest.cc", "../browser/background_sync/background_sync_service_impl_unittest.cc", @@ -1922,6 +1923,7 @@ "//content/browser/background_fetch:background_fetch_proto", "//content/browser/cache_storage:cache_storage_proto", "//content/browser/devtools:devtools_background_services_proto", + "//content/browser/devtools:inspector_protocol_encoding_test", "//content/browser/dom_storage:local_storage_proto", "//content/browser/notifications:notification_proto", "//content/browser/service_worker:service_worker_proto",
diff --git a/content/test/data/media/getusermedia.html b/content/test/data/media/getusermedia.html index 05085f5b..23e2568 100644 --- a/content/test/data/media/getusermedia.html +++ b/content/test/data/media/getusermedia.html
@@ -916,38 +916,6 @@ } } - function playStreamAndGetElement(stream) { - v = document.createElement("video"); - document.body.append(v); - v.srcObject = stream; - v.play(); - return v; - } - - async function getUserMediaCloneAndApplyConstraints() { - const stream = await navigator.mediaDevices.getUserMedia({video: { width: 640, height: 480 }}); - const video = playStreamAndGetElement(stream); - - const clone1 = stream.clone(); - await clone1.getVideoTracks()[0].applyConstraints({width: 500, height: 500}); - const video1 = playStreamAndGetElement(clone1); - - const clone2 = stream.clone(); - await clone2.getVideoTracks()[0].applyConstraints({width: 100, height: 100}); - const video2 = playStreamAndGetElement(clone2); - - var numFrames = 0; - var numOnProgress = 0; - video2.onprogress = () => { - numFrames += video2.webkitDecodedFrameCount; - ++numOnProgress; - if (numFrames >= 1) - reportTestSuccess(); - if (numOnProgress > 1) - failTest("track from cloned stream is not producing any frames"); - } - } - </script> </head> <body>
diff --git a/content/test/mock_background_sync_controller.cc b/content/test/mock_background_sync_controller.cc index 13b94930..b671965 100644 --- a/content/test/mock_background_sync_controller.cc +++ b/content/test/mock_background_sync_controller.cc
@@ -12,11 +12,8 @@ registration_origin_ = origin; } -void MockBackgroundSyncController::RunInBackground(bool enabled, - int64_t min_ms) { +void MockBackgroundSyncController::RunInBackground() { run_in_background_count_ += 1; - run_in_background_enabled_ = enabled; - run_in_background_min_ms_ = min_ms; } void MockBackgroundSyncController::GetParameterOverrides(
diff --git a/content/test/mock_background_sync_controller.h b/content/test/mock_background_sync_controller.h index 0a854ea..3f97681 100644 --- a/content/test/mock_background_sync_controller.h +++ b/content/test/mock_background_sync_controller.h
@@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/time/time.h" #include "content/public/browser/background_sync_controller.h" #include "content/public/browser/background_sync_parameters.h" #include "url/gurl.h" @@ -24,7 +25,7 @@ // BackgroundSyncController: void NotifyBackgroundSyncRegistered(const url::Origin& origin) override; - void RunInBackground(bool enabled, int64_t min_ms) override; + void RunInBackground() override; void GetParameterOverrides( BackgroundSyncParameters* parameters) const override; @@ -33,8 +34,6 @@ return registration_origin_; } int run_in_background_count() const { return run_in_background_count_; } - bool run_in_background_enabled() const { return run_in_background_enabled_; } - int64_t run_in_background_min_ms() const { return run_in_background_min_ms_; } BackgroundSyncParameters* background_sync_parameters() { return &background_sync_parameters_; } @@ -44,8 +43,6 @@ url::Origin registration_origin_; int run_in_background_count_ = 0; - bool run_in_background_enabled_ = true; - int64_t run_in_background_min_ms_ = 0; BackgroundSyncParameters background_sync_parameters_; DISALLOW_COPY_AND_ASSIGN(MockBackgroundSyncController);
diff --git a/content/test/test_background_sync_manager.cc b/content/test/test_background_sync_manager.cc index 3e95d08..0635711 100644 --- a/content/test/test_background_sync_manager.cc +++ b/content/test/test_background_sync_manager.cc
@@ -118,4 +118,9 @@ BackgroundSyncManager::GetDataFromBackend(key, std::move(callback)); } +base::TimeDelta TestBackgroundSyncManager::GetSoonestWakeupDelta() { + soonest_wakeup_delta_ = BackgroundSyncManager::GetSoonestWakeupDelta(); + return soonest_wakeup_delta_; +} + } // namespace content
diff --git a/content/test/test_background_sync_manager.h b/content/test/test_background_sync_manager.h index a4566e0c..4fd6508c 100644 --- a/content/test/test_background_sync_manager.h +++ b/content/test/test_background_sync_manager.h
@@ -86,6 +86,13 @@ return parameters_.get(); } + bool IsBrowserWakeupScheduled() const { + return !soonest_wakeup_delta_.is_max(); + } + bool EqualsSoonestWakeupDelta(base::TimeDelta compare_to) const { + return soonest_wakeup_delta_ == compare_to; + } + protected: // Override to allow delays to be injected by tests. void StoreDataInBackend( @@ -119,6 +126,8 @@ void HasMainFrameProviderHost(const url::Origin& origin, BoolCallback callback) override; + base::TimeDelta GetSoonestWakeupDelta() override; + private: // Callback to resume the StoreDataInBackend operation, after explicit // delays injected by tests. @@ -143,6 +152,7 @@ DispatchSyncCallback dispatch_sync_callback_; base::OnceClosure delayed_task_; base::TimeDelta delayed_task_delta_; + base::TimeDelta soonest_wakeup_delta_; DISALLOW_COPY_AND_ASSIGN(TestBackgroundSyncManager); };
diff --git a/courgette/disassembler.h b/courgette/disassembler.h index 5b1bb8de..78a4005f 100644 --- a/courgette/disassembler.h +++ b/courgette/disassembler.h
@@ -115,7 +115,12 @@ bool Good(); bool Bad(const char *reason); - // Returns true if the array lies within our memory region. + // Returns true if the given range lies within our memory region. + bool IsRangeInBounds(size_t offset, size_t size) { + return offset <= length() && size <= length() - offset; + } + + // Returns true if the given array lies within our memory region. bool IsArrayInBounds(size_t offset, size_t elements, size_t element_size) { return offset <= length() && elements <= (length() - offset) / element_size; }
diff --git a/courgette/disassembler_elf_32.cc b/courgette/disassembler_elf_32.cc index fac661c7..e5852080 100644 --- a/courgette/disassembler_elf_32.cc +++ b/courgette/disassembler_elf_32.cc
@@ -101,28 +101,36 @@ header_ = reinterpret_cast<const Elf32_Ehdr*>(start()); - // Have magic for ELF header? - if (header_->e_ident[0] != 0x7f || - header_->e_ident[1] != 'E' || - header_->e_ident[2] != 'L' || - header_->e_ident[3] != 'F') - return Bad("No Magic Number"); + // Perform DisassemblerElf32::QuickDetect() checks (with error messages). - if (header_->e_type != ET_EXEC && - header_->e_type != ET_DYN) + // Have magic for ELF header? + if (header_->e_ident[EI_MAG0] != 0x7F || header_->e_ident[EI_MAG1] != 'E' || + header_->e_ident[EI_MAG2] != 'L' || header_->e_ident[EI_MAG3] != 'F') { + return Bad("No Magic Number"); + } + + if (header_->e_ident[EI_CLASS] != ELFCLASS32 || + header_->e_ident[EI_DATA] != ELFDATA2LSB || + header_->e_machine != ElfEM()) { + return Bad("Not a supported architecture"); + } + + if (header_->e_type != ET_EXEC && header_->e_type != ET_DYN) return Bad("Not an executable file or shared library"); - if (header_->e_machine != ElfEM()) - return Bad("Not a supported architecture"); - - if (header_->e_version != 1) + if (header_->e_version != 1 || header_->e_ident[EI_VERSION] != 1) return Bad("Unknown file version"); if (header_->e_shentsize != sizeof(Elf32_Shdr)) return Bad("Unexpected section header size"); - if (!IsArrayInBounds(header_->e_shoff, header_->e_shnum, sizeof(Elf32_Shdr))) + // Perform more complex checks, while extracting data. + + if (header_->e_shoff < sizeof(Elf32_Ehdr) || + !IsArrayInBounds(header_->e_shoff, header_->e_shnum, + sizeof(Elf32_Shdr))) { return Bad("Out of bounds section header table"); + } // Extract |section_header_table_|, ordered by section id. const Elf32_Shdr* section_header_table_raw = @@ -131,34 +139,41 @@ section_header_table_size_ = header_->e_shnum; section_header_table_.assign(section_header_table_raw, section_header_table_raw + section_header_table_size_); - - // TODO(huangs): Validate offsets of all section headers. - + if (!CheckSectionRanges()) + return Bad("Out of bound section"); section_header_file_offset_order_ = GetSectionHeaderFileOffsetOrder(section_header_table_); - - if (!IsArrayInBounds(header_->e_phoff, header_->e_phnum, sizeof(Elf32_Phdr))) + if (header_->e_phoff < sizeof(Elf32_Ehdr) || + !IsArrayInBounds(header_->e_phoff, header_->e_phnum, + sizeof(Elf32_Phdr))) { return Bad("Out of bounds program header table"); + } + // Extract |program_header_table_|. + program_header_table_size_ = header_->e_phnum; program_header_table_ = reinterpret_cast<const Elf32_Phdr*>( FileOffsetToPointer(header_->e_phoff)); - program_header_table_size_ = header_->e_phnum; + if (!CheckProgramSegmentRanges()) + return Bad("Out of bound segment"); + // Extract |default_string_section_|. Elf32_Half string_section_id = header_->e_shstrndx; + if (string_section_id == SHN_UNDEF) + return Bad("Missing string section"); if (string_section_id >= header_->e_shnum) return Bad("Out of bounds string section index"); - + if (SectionHeader(string_section_id)->sh_type != SHT_STRTAB) + return Bad("Invalid string section"); + default_string_section_size_ = SectionHeader(string_section_id)->sh_size; default_string_section_ = reinterpret_cast<const char*>(SectionBody(string_section_id)); - default_string_section_size_ = SectionHeader(string_section_id)->sh_size; // String section may be empty. If nonempty, then last byte must be null. if (default_string_section_size_ > 0) { if (default_string_section_[default_string_section_size_ - 1] != '\0') return Bad("String section does not terminate"); } - if (!UpdateLength()) - return Bad("Out of bounds section or segment"); + UpdateLength(); return Good(); } @@ -195,15 +210,17 @@ const Elf32_Ehdr* header = reinterpret_cast<const Elf32_Ehdr*>(start); // Have magic for ELF header? - if (header->e_ident[0] != 0x7f || header->e_ident[1] != 'E' || - header->e_ident[2] != 'L' || header->e_ident[3] != 'F') + if (header->e_ident[EI_MAG0] != 0x7F || header->e_ident[EI_MAG1] != 'E' || + header->e_ident[EI_MAG2] != 'L' || header->e_ident[EI_MAG3] != 'F') { return false; - + } + if (header->e_ident[EI_CLASS] != ELFCLASS32 || + header->e_ident[EI_DATA] != ELFDATA2LSB || header->e_machine != elf_em) { + return false; + } if (header->e_type != ET_EXEC && header->e_type != ET_DYN) return false; - if (header->e_machine != elf_em) - return false; - if (header->e_version != 1) + if (header->e_version != 1 || header->e_ident[EI_VERSION] != 1) return false; if (header->e_shentsize != sizeof(Elf32_Shdr)) return false; @@ -211,32 +228,47 @@ return true; } -bool DisassemblerElf32::UpdateLength() { - Elf32_Off result = 0; - - // Find the end of the last section +bool DisassemblerElf32::CheckSectionRanges() { for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); ++section_id) { const Elf32_Shdr* section_header = SectionHeader(section_id); + if (section_header->sh_type == SHT_NOBITS) // E.g., .bss. + continue; + if (!IsRangeInBounds(section_header->sh_offset, section_header->sh_size)) + return false; + } + return true; +} +bool DisassemblerElf32::CheckProgramSegmentRanges() { + for (Elf32_Half segment_id = 0; segment_id < ProgramSegmentHeaderCount(); + ++segment_id) { + const Elf32_Phdr* segment_header = ProgramSegmentHeader(segment_id); + if (!IsRangeInBounds(segment_header->p_offset, segment_header->p_filesz)) + return false; + } + return true; +} + +void DisassemblerElf32::UpdateLength() { + Elf32_Off result = 0; + + // Find the end of the last section. + for (Elf32_Half section_id = 0; section_id < SectionHeaderCount(); + ++section_id) { + const Elf32_Shdr* section_header = SectionHeader(section_id); if (section_header->sh_type == SHT_NOBITS) continue; - - if (!IsArrayInBounds(section_header->sh_offset, section_header->sh_size, 1)) - return false; - + DCHECK(IsRangeInBounds(section_header->sh_offset, section_header->sh_size)); Elf32_Off section_end = section_header->sh_offset + section_header->sh_size; result = std::max(result, section_end); } - // Find the end of the last segment + // Find the end of the last segment. for (Elf32_Half segment_id = 0; segment_id < ProgramSegmentHeaderCount(); ++segment_id) { const Elf32_Phdr* segment_header = ProgramSegmentHeader(segment_id); - - if (!IsArrayInBounds(segment_header->p_offset, segment_header->p_filesz, 1)) - return false; - + DCHECK(IsRangeInBounds(segment_header->p_offset, segment_header->p_filesz)); Elf32_Off segment_end = segment_header->p_offset + segment_header->p_filesz; result = std::max(result, segment_end); } @@ -250,7 +282,6 @@ result = std::max(result, segment_table_end); ReduceLength(result); - return true; } CheckBool DisassemblerElf32::SectionName(const Elf32_Shdr& shdr,
diff --git a/courgette/disassembler_elf_32.h b/courgette/disassembler_elf_32.h index a75773d..fba67f1 100644 --- a/courgette/disassembler_elf_32.h +++ b/courgette/disassembler_elf_32.h
@@ -129,7 +129,13 @@ size_t length, e_machine_values elf_em); - bool UpdateLength(); + // Returns whether all non-SHT_NOBITS sections lie within image. + bool CheckSectionRanges(); + + // Returns whether all program segments lie within image. + bool CheckProgramSegmentRanges(); + + void UpdateLength(); // Misc Section Helpers @@ -143,8 +149,9 @@ } const uint8_t* SectionBody(Elf32_Half id) const { - // TODO(huangs): Assert that section does not have SHT_NOBITS. - return FileOffsetToPointer(SectionHeader(id)->sh_offset); + const Elf32_Shdr* section_header = SectionHeader(id); + DCHECK(section_header->sh_type != SHT_NOBITS); + return FileOffsetToPointer(section_header->sh_offset); } // Gets the |name| of section |shdr|. Returns true on success.
diff --git a/courgette/types_elf.h b/courgette/types_elf.h index a98fd8b..d45a10e 100644 --- a/courgette/types_elf.h +++ b/courgette/types_elf.h
@@ -36,6 +36,35 @@ Elf32_Half e_shstrndx; }; +// Indexes for header->e_ident[]. +enum e_ident_indexes { + EI_MAG0 = 0, // File identification. + EI_MAG1 = 1, // File identification. + EI_MAG2 = 2, // File identification. + EI_MAG3 = 3, // File identification. + EI_CLASS = 4, // File class. + EI_DATA = 5, // Data encoding. + EI_VERSION = 6, // File version. + EI_OSABI = 7, // Operating system/ABI identification. + EI_ABIVERSION = 8, // ABI version. + EI_PAD = 9, // Start of padding bytes. + EI_NIDENT = 16 // Size of e_ident[]. +}; + +// Values for header->e_ident[EI_CLASS]. +enum e_ident_class_values { + ELFCLASSNONE = 0, // Invalid class. + ELFCLASS32 = 1, // 32-bit objects. + ELFCLASS64 = 2 // 64-bit objects. +}; + +// Values for header->e_ident[EI_DATA]. +enum e_ident_data_values { + ELFDATANONE = 0, // Unknown data format. + ELFDATA2LSB = 1, // Two's complement, little-endian. + ELFDATA2MSB = 2, // Two's complement, big-endian. +}; + // values for header->e_type enum e_type_values { ET_NONE = 0, // No file type @@ -56,6 +85,8 @@ // Other values skipped }; +enum { SHN_UNDEF = 0 }; + // A section header in the section header table struct Elf32_Shdr { Elf32_Word sh_name;
diff --git a/device/BUILD.gn b/device/BUILD.gn index 68e466e..42c9f05 100644 --- a/device/BUILD.gn +++ b/device/BUILD.gn
@@ -403,7 +403,7 @@ "//base:base_java", "//components/location/android:location_java", "//device/bluetooth:java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/android_tools:android_test_mock_java", ] @@ -421,7 +421,7 @@ "//base:base_junit_test_support", "//device/gamepad:java", "//mojo/public/java:bindings_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] srcjar_deps = [ "//device/gamepad:java_enums_srcjar" ] }
diff --git a/device/gamepad/BUILD.gn b/device/gamepad/BUILD.gn index db70eff..759c76e 100644 --- a/device/gamepad/BUILD.gn +++ b/device/gamepad/BUILD.gn
@@ -185,7 +185,7 @@ ] deps = [ "//base:base_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] srcjar_deps = [ ":java_enums_srcjar" ] }
diff --git a/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc b/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc index e6ede47..a5326123 100644 --- a/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc +++ b/device/vr/windows_mixed_reality/mixed_reality_renderloop.cc
@@ -5,10 +5,12 @@ #include "device/vr/windows_mixed_reality/mixed_reality_renderloop.h" #include <HolographicSpaceInterop.h> +#include <SpatialInteractionManagerInterop.h> #include <Windows.Graphics.DirectX.Direct3D11.interop.h> #include <windows.graphics.holographic.h> #include <windows.perception.h> #include <windows.perception.spatial.h> +#include <windows.ui.input.spatial.h> #include <algorithm> #include <utility> @@ -28,6 +30,7 @@ namespace device { +// TODO(crbug.com/941546): Remove namespaces to comply with coding standard. using namespace ABI::Windows::Foundation; using namespace ABI::Windows::Graphics::Holographic; using namespace ABI::Windows::Perception; @@ -35,6 +38,10 @@ using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers; +namespace WFC = ABI::Windows::Foundation::Collections; +namespace WFN = ABI::Windows::Foundation::Numerics; +namespace WInput = ABI::Windows::UI::Input::Spatial; + class MixedRealityWindow : public gfx::WindowImpl { BOOL ProcessWindowMessage(HWND window, UINT message, @@ -100,6 +107,94 @@ return field_of_view; } +gfx::Transform CreateTransform(WFN::Vector3 position, + WFN::Quaternion rotation) { + gfx::DecomposedTransform decomposed_transform; + decomposed_transform.translate[0] = position.X; + decomposed_transform.translate[1] = position.Y; + decomposed_transform.translate[2] = position.Z; + + decomposed_transform.quaternion = + gfx::Quaternion(rotation.X, rotation.Y, rotation.Z, rotation.W); + return gfx::ComposeTransform(decomposed_transform); +} + +bool TryGetGripFromLocation( + ComPtr<WInput::ISpatialInteractionSourceLocation> location_in_origin, + gfx::Transform* origin_from_grip) { + DCHECK(origin_from_grip); + *origin_from_grip = gfx::Transform(); + + if (!location_in_origin) + return false; + + ComPtr<IReference<WFN::Vector3>> pos_ref; + + if (FAILED(location_in_origin->get_Position(&pos_ref)) || !pos_ref) + return false; + + WFN::Vector3 pos; + if (FAILED(pos_ref->get_Value(&pos))) + return false; + + ComPtr<WInput::ISpatialInteractionSourceLocation2> location_in_origin2; + if (FAILED(location_in_origin.As(&location_in_origin2))) + return false; + + ComPtr<IReference<WFN::Quaternion>> quat_ref; + if (FAILED(location_in_origin2->get_Orientation(&quat_ref)) || !quat_ref) + return false; + + WFN::Quaternion quat; + if (FAILED(quat_ref->get_Value(&quat))) + return false; + + *origin_from_grip = CreateTransform(pos, quat); + return true; +} + +bool TryGetPointerOffsetFromLocation( + ComPtr<WInput::ISpatialInteractionSourceLocation> location_in_origin, + gfx::Transform origin_from_grip, + gfx::Transform* grip_from_pointer) { + DCHECK(grip_from_pointer); + *grip_from_pointer = gfx::Transform(); + + if (!location_in_origin) + return false; + + // We can get the pointer position, but we'll need to transform it to an + // offset from the grip position. If we can't get an inverse of that, + // then go ahead and bail early. + gfx::Transform grip_from_origin; + if (!origin_from_grip.GetInverse(&grip_from_origin)) + return false; + + ComPtr<WInput::ISpatialInteractionSourceLocation3> location_in_origin3; + if (FAILED(location_in_origin.As(&location_in_origin3))) + return false; + + ComPtr<WInput::ISpatialPointerInteractionSourcePose> pointer_pose; + if (FAILED(location_in_origin3->get_SourcePointerPose(&pointer_pose)) || + !pointer_pose) + return false; + + WFN::Vector3 pos; + if (FAILED(pointer_pose->get_Position(&pos))) + return false; + + ComPtr<WInput::ISpatialPointerInteractionSourcePose2> pose2; + if (FAILED(pointer_pose.As(&pose2))) + return false; + + WFN::Quaternion rot; + if (FAILED(pose2->get_Orientation(&rot))) + return false; + + gfx::Transform origin_from_pointer = CreateTransform(pos, rot); + *grip_from_pointer = (grip_from_origin * origin_from_pointer); + return true; +} } // namespace MixedRealityRenderLoop::MixedRealityRenderLoop( @@ -232,7 +327,7 @@ origin_ = nullptr; holographic_frame_ = nullptr; - prediction_ = nullptr; + timestamp_ = nullptr; poses_ = nullptr; pose_ = nullptr; rendering_params_ = nullptr; @@ -436,12 +531,10 @@ } mojom::XRFrameDataPtr CreateDefaultFrameData( - ComPtr<IHolographicFramePrediction> prediction, + ComPtr<IPerceptionTimestamp> timestamp, int16_t frame_id) { mojom::XRFrameDataPtr ret = mojom::XRFrameData::New(); - ComPtr<IPerceptionTimestamp> timestamp; - prediction->get_Timestamp(×tamp); ABI::Windows::Foundation::DateTime date_time; timestamp->get_TargetTime(&date_time); @@ -465,22 +558,27 @@ void MixedRealityRenderLoop::UpdateWMRDataForNextFrame() { holographic_frame_ = nullptr; - prediction_ = nullptr; poses_ = nullptr; pose_ = nullptr; rendering_params_ = nullptr; camera_ = nullptr; + timestamp_ = nullptr; // Start populating this frame's data. HRESULT hr = holographic_space_->CreateNextFrame(&holographic_frame_); if (FAILED(hr)) return; - hr = holographic_frame_->get_CurrentPrediction(&prediction_); + ComPtr<IHolographicFramePrediction> prediction; + hr = holographic_frame_->get_CurrentPrediction(&prediction); if (FAILED(hr)) return; - hr = prediction_->get_CameraPoses(&poses_); + hr = prediction->get_Timestamp(×tamp_); + if (FAILED(hr)) + return; + + hr = prediction->get_CameraPoses(&poses_); if (FAILED(hr)) return; @@ -597,12 +695,12 @@ mojom::XRFrameDataPtr MixedRealityRenderLoop::GetNextFrameData() { UpdateWMRDataForNextFrame(); - if (!prediction_) + if (!timestamp_) return nullptr; // Once we have a prediction, we can generate a frame data. mojom::XRFrameDataPtr ret = - CreateDefaultFrameData(prediction_, next_frame_id_); + CreateDefaultFrameData(timestamp_, next_frame_id_); if (!origin_ || !pose_) { // If we don't have an origin or pose for this frame, we can still give out @@ -666,6 +764,8 @@ current_display_info_.Clone())); } + ret->pose->input_state = GetInputState(); + return ret; } @@ -678,10 +778,146 @@ return; } +bool MixedRealityRenderLoop::EnsureSpatialInteractionManager() { + if (spatial_interaction_manager_) + return true; + + if (!window_) + return false; + + ComPtr<ISpatialInteractionManagerInterop> spatial_interaction_interop; + base::win::ScopedHString spatial_interaction_interop_string = + base::win::ScopedHString::Create( + RuntimeClass_Windows_UI_Input_Spatial_SpatialInteractionManager); + HRESULT hr = base::win::RoGetActivationFactory( + spatial_interaction_interop_string.get(), + IID_PPV_ARGS(&spatial_interaction_interop)); + if (FAILED(hr)) + return false; + + hr = spatial_interaction_interop->GetForWindow( + window_->hwnd(), IID_PPV_ARGS(&spatial_interaction_manager_)); + return SUCCEEDED(hr); +} + std::vector<mojom::XRInputSourceStatePtr> MixedRealityRenderLoop::GetInputState() { - // Not yet implemented. - return {}; + std::vector<mojom::XRInputSourceStatePtr> input_states; + + if (!timestamp_ || !origin_ || !EnsureSpatialInteractionManager()) + return input_states; + + ComPtr<WFC::IVectorView<WInput::SpatialInteractionSourceState*>> + source_states; + if (FAILED(spatial_interaction_manager_->GetDetectedSourcesAtTimestamp( + timestamp_.Get(), &source_states))) + return input_states; + + unsigned int size; + if (FAILED(source_states->get_Size(&size))) + return input_states; + + for (unsigned int i = 0; i < size; i++) { + ComPtr<WInput::ISpatialInteractionSourceState> state; + if (FAILED(source_states->GetAt(i, &state))) + continue; + + // Get the source and query for all of the state that we send first + ComPtr<WInput::ISpatialInteractionSource> source; + if (FAILED(state->get_Source(&source))) + continue; + + WInput::SpatialInteractionSourceKind source_kind; + if (FAILED(source->get_Kind(&source_kind)) || + source_kind != WInput::SpatialInteractionSourceKind_Controller) + continue; + + uint32_t id; + if (FAILED(source->get_Id(&id))) + continue; + + ComPtr<WInput::ISpatialInteractionSourceState2> state2; + if (FAILED(state.As(&state2))) + continue; + + boolean pressed = false; + if (FAILED(state2->get_IsSelectPressed(&pressed))) + continue; + + ComPtr<WInput::ISpatialInteractionSourceProperties> props; + if (FAILED(state->get_Properties(&props))) + continue; + + ComPtr<WInput::ISpatialInteractionSourceLocation> location_in_origin; + if (FAILED(props->TryGetLocation(origin_.Get(), &location_in_origin)) || + !location_in_origin) + continue; + + gfx::Transform origin_from_grip; + if (!TryGetGripFromLocation(location_in_origin, &origin_from_grip)) + continue; + + ComPtr<WInput::ISpatialInteractionSource2> source2; + boolean pointingSupported = false; + if (FAILED(source.As(&source2)) || + FAILED(source2->get_IsPointingSupported(&pointingSupported)) || + !pointingSupported) + continue; + + gfx::Transform grip_from_pointer; + if (!TryGetPointerOffsetFromLocation(location_in_origin, origin_from_grip, + &grip_from_pointer)) + continue; + + // Now that we've queried for all of the state we're going to send, + // build the object to send it. + device::mojom::XRInputSourceStatePtr source_state = + device::mojom::XRInputSourceState::New(); + + // Hands may not have the same id especially if they are lost but since we + // are only tracking controllers, this id should be consistent. + source_state->source_id = id; + + source_state->primary_input_pressed = pressed; + source_state->primary_input_clicked = + !pressed && controller_pressed_state_[id]; + controller_pressed_state_[id] = pressed; + + source_state->grip = origin_from_grip; + + device::mojom::XRInputSourceDescriptionPtr description = + device::mojom::XRInputSourceDescription::New(); + + // It's a fully 6DoF handheld pointing device + description->emulated_position = false; + description->target_ray_mode = device::mojom::XRTargetRayMode::POINTING; + + description->pointer_offset = grip_from_pointer; + + WInput::SpatialInteractionSourceHandedness handedness; + ComPtr<WInput::ISpatialInteractionSource3> source3; + if (SUCCEEDED(source.As(&source3) && + SUCCEEDED(source3->get_Handedness(&handedness)))) { + switch (handedness) { + case WInput::SpatialInteractionSourceHandedness_Left: + description->handedness = device::mojom::XRHandedness::LEFT; + break; + case WInput::SpatialInteractionSourceHandedness_Right: + description->handedness = device::mojom::XRHandedness::RIGHT; + break; + default: + description->handedness = device::mojom::XRHandedness::NONE; + break; + } + } else { + description->handedness = device::mojom::XRHandedness::NONE; + } + + source_state->description = std::move(description); + input_states.push_back(std::move(source_state)); + } + + return input_states; } } // namespace device
diff --git a/device/vr/windows_mixed_reality/mixed_reality_renderloop.h b/device/vr/windows_mixed_reality/mixed_reality_renderloop.h index 92f7ee6..1701003 100644 --- a/device/vr/windows_mixed_reality/mixed_reality_renderloop.h +++ b/device/vr/windows_mixed_reality/mixed_reality_renderloop.h
@@ -7,9 +7,12 @@ #include <windows.graphics.holographic.h> #include <windows.perception.spatial.h> +#include <windows.ui.input.spatial.h> + #include <wrl.h> #include <memory> +#include <unordered_map> #include <vector> #include "base/callback.h" @@ -55,6 +58,7 @@ // Helpers to implement XRDeviceAbstraction. std::vector<mojom::XRInputSourceStatePtr> GetInputState(); + bool EnsureSpatialInteractionManager(); void InitializeOrigin(); void InitializeSpace(); void StartPresenting(); @@ -76,9 +80,8 @@ // Per frame data: Microsoft::WRL::ComPtr<ABI::Windows::Graphics::Holographic::IHolographicFrame> holographic_frame_; - Microsoft::WRL::ComPtr< - ABI::Windows::Graphics::Holographic::IHolographicFramePrediction> - prediction_; + Microsoft::WRL::ComPtr<ABI::Windows::Perception::IPerceptionTimestamp> + timestamp_; // The set of all poses for this frame (there could be multiple headsets or // external cameras). @@ -97,6 +100,12 @@ ABI::Windows::Graphics::Holographic::IHolographicCamera> camera_; + // Input Data + Microsoft::WRL::ComPtr< + ABI::Windows::UI::Input::Spatial::ISpatialInteractionManager> + spatial_interaction_manager_; + std::unordered_map<uint32_t, bool> controller_pressed_state_; + DISALLOW_COPY_AND_ASSIGN(MixedRealityRenderLoop); };
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index 492e6f3..17cf3299 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn
@@ -540,11 +540,14 @@ "//base", "//content/public/browser", "//extensions/browser", - "//extensions/browser/api/declarative_net_request:test_support", "//extensions/common", "//extensions/common:test_support", "//testing/gtest", ] + + public_deps = [ + "//extensions/browser/api/declarative_net_request:test_support", + ] } source_set("unit_tests") { @@ -559,6 +562,7 @@ "api/declarative/declarative_rule_unittest.cc", "api/declarative/deduping_factory_unittest.cc", "api/declarative/rules_registry_unittest.cc", + "api/declarative_net_request/composite_matcher_unittest.cc", "api/declarative_net_request/flat_ruleset_indexer_unittest.cc", "api/declarative_net_request/indexed_rule_unittest.cc", "api/declarative_net_request/indexed_ruleset_format_version_unittest.cc",
diff --git a/extensions/browser/api/declarative_net_request/BUILD.gn b/extensions/browser/api/declarative_net_request/BUILD.gn index a415211..ca30728b 100644 --- a/extensions/browser/api/declarative_net_request/BUILD.gn +++ b/extensions/browser/api/declarative_net_request/BUILD.gn
@@ -4,6 +4,8 @@ source_set("declarative_net_request") { sources = [ + "composite_matcher.cc", + "composite_matcher.h", "constants.cc", "constants.h", "declarative_net_request_api.cc",
diff --git a/extensions/browser/api/declarative_net_request/composite_matcher.cc b/extensions/browser/api/declarative_net_request/composite_matcher.cc new file mode 100644 index 0000000..cc236c0 --- /dev/null +++ b/extensions/browser/api/declarative_net_request/composite_matcher.cc
@@ -0,0 +1,88 @@ +// 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 "extensions/browser/api/declarative_net_request/composite_matcher.h" + +#include <algorithm> +#include <set> +#include <utility> + +#include "base/metrics/histogram_macros.h" + +namespace extensions { +namespace declarative_net_request { + +namespace { + +bool AreIDsUnique(const CompositeMatcher::MatcherList& matchers) { + std::set<size_t> ids; + for (const auto& matcher : matchers) { + bool did_insert = ids.insert(matcher->id()).second; + if (!did_insert) + return false; + } + + return true; +} + +bool AreSortedPrioritiesUnique(const CompositeMatcher::MatcherList& matchers) { + base::Optional<size_t> previous_priority; + for (const auto& matcher : matchers) { + if (matcher->priority() == previous_priority) + return false; + previous_priority = matcher->priority(); + } + + return true; +} + +} // namespace + +CompositeMatcher::CompositeMatcher(MatcherList matchers) + : matchers_(std::move(matchers)) { + // Sort in descending order of priority. + std::sort(matchers_.begin(), matchers_.end(), + [](const std::unique_ptr<RulesetMatcher>& a, + const std::unique_ptr<RulesetMatcher>& b) { + return a->priority() > b->priority(); + }); + + DCHECK(AreIDsUnique(matchers_)); + DCHECK(AreSortedPrioritiesUnique(matchers_)); +} + +CompositeMatcher::~CompositeMatcher() = default; + +bool CompositeMatcher::ShouldBlockRequest(const RequestParams& params) const { + // TODO(karandeepb): change this to report time in micro-seconds. + SCOPED_UMA_HISTOGRAM_TIMER( + "Extensions.DeclarativeNetRequest.ShouldBlockRequestTime." + "SingleExtension"); + + for (const auto& matcher : matchers_) { + if (matcher->HasMatchingAllowRule(params)) + return false; + if (matcher->HasMatchingBlockRule(params)) + return true; + } + return false; +} + +bool CompositeMatcher::ShouldRedirectRequest(const RequestParams& params, + GURL* redirect_url) const { + // TODO(karandeepb): change this to report time in micro-seconds. + SCOPED_UMA_HISTOGRAM_TIMER( + "Extensions.DeclarativeNetRequest.ShouldRedirectRequestTime." + "SingleExtension"); + + for (const auto& matcher : matchers_) { + if (matcher->HasMatchingRedirectRule(params, redirect_url)) + return true; + } + + return false; +} + +} // namespace declarative_net_request +} // namespace extensions
diff --git a/extensions/browser/api/declarative_net_request/composite_matcher.h b/extensions/browser/api/declarative_net_request/composite_matcher.h new file mode 100644 index 0000000..81362a1e --- /dev/null +++ b/extensions/browser/api/declarative_net_request/composite_matcher.h
@@ -0,0 +1,46 @@ +// 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 EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_COMPOSITE_MATCHER_H_ +#define EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_COMPOSITE_MATCHER_H_ + +#include <memory> +#include <vector> + +#include "base/macros.h" +#include "extensions/browser/api/declarative_net_request/ruleset_matcher.h" + +namespace extensions { +namespace declarative_net_request { + +// Per extension instance which manages the different rulesets for an extension +// while respecting their priorities. +class CompositeMatcher { + public: + using MatcherList = std::vector<std::unique_ptr<RulesetMatcher>>; + + // Each RulesetMatcher should have a distinct ID and priority. + explicit CompositeMatcher(MatcherList matchers); + ~CompositeMatcher(); + + // Returns whether the network request as specified by |params| should be + // blocked. + bool ShouldBlockRequest(const RequestParams& params) const; + + // Returns whether the network request as specified by |params| should be + // redirected along with the |redirect_url|. |redirect_url| must not be null. + bool ShouldRedirectRequest(const RequestParams& params, + GURL* redirect_url) const; + + private: + // Sorted by priority in descending order. + MatcherList matchers_; + + DISALLOW_COPY_AND_ASSIGN(CompositeMatcher); +}; + +} // namespace declarative_net_request +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_COMPOSITE_MATCHER_H_
diff --git a/extensions/browser/api/declarative_net_request/composite_matcher_unittest.cc b/extensions/browser/api/declarative_net_request/composite_matcher_unittest.cc new file mode 100644 index 0000000..beb7e42 --- /dev/null +++ b/extensions/browser/api/declarative_net_request/composite_matcher_unittest.cc
@@ -0,0 +1,119 @@ +// 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 "extensions/browser/api/declarative_net_request/composite_matcher.h" + +#include <string> +#include <utility> +#include <vector> + +#include "components/version_info/version_info.h" +#include "extensions/browser/api/declarative_net_request/ruleset_matcher.h" +#include "extensions/browser/api/declarative_net_request/ruleset_source.h" +#include "extensions/browser/api/declarative_net_request/test_utils.h" +#include "extensions/common/api/declarative_net_request/constants.h" +#include "extensions/common/api/declarative_net_request/test_utils.h" +#include "extensions/common/features/feature_channel.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace extensions { +namespace declarative_net_request { + +class CompositeMatcherTest : public ::testing::Test { + public: + CompositeMatcherTest() : channel_(::version_info::Channel::UNKNOWN) {} + + private: + // Run this on the trunk channel to ensure the API is available. + ScopedCurrentChannel channel_; + + DISALLOW_COPY_AND_ASSIGN(CompositeMatcherTest); +}; + +// Ensure CompositeMatcher respects priority of individual rulesets. +TEST_F(CompositeMatcherTest, RulesetPriority) { + TestRule block_rule = CreateGenericRule(); + block_rule.condition->url_filter = std::string("google.com"); + block_rule.id = kMinValidID; + + TestRule redirect_rule_1 = CreateGenericRule(); + redirect_rule_1.condition->url_filter = std::string("example.com"); + redirect_rule_1.priority = kMinValidPriority; + redirect_rule_1.action->type = std::string("redirect"); + redirect_rule_1.action->redirect_url = std::string("http://ruleset1.com"); + redirect_rule_1.id = kMinValidID + 1; + + // Create the first ruleset matcher. + const size_t kSource1ID = 1; + const size_t kSource1Priority = 1; + std::unique_ptr<RulesetMatcher> matcher_1; + ASSERT_TRUE(CreateVerifiedMatcher({block_rule, redirect_rule_1}, + CreateTemporarySource(), &matcher_1)); + matcher_1->set_id_for_testing(kSource1ID); + matcher_1->set_priority_for_testing(kSource1Priority); + + // Now create a second ruleset matcher. + const size_t kSource2ID = 2; + const size_t kSource2Priority = 2; + TestRule allow_rule = block_rule; + allow_rule.action->type = std::string("allow"); + TestRule redirect_rule_2 = redirect_rule_1; + redirect_rule_2.action->redirect_url = std::string("http://ruleset2.com"); + std::unique_ptr<RulesetMatcher> matcher_2; + ASSERT_TRUE(CreateVerifiedMatcher({allow_rule, redirect_rule_2}, + CreateTemporarySource(), &matcher_2)); + matcher_2->set_id_for_testing(kSource2ID); + matcher_2->set_priority_for_testing(kSource2Priority); + + // Create a composite matcher with the two rulesets. + std::vector<std::unique_ptr<RulesetMatcher>> matchers; + matchers.push_back(std::move(matcher_1)); + matchers.push_back(std::move(matcher_2)); + auto composite_matcher = + std::make_unique<CompositeMatcher>(std::move(matchers)); + + GURL google_url = GURL("http://google.com"); + RequestParams google_params; + google_params.url = &google_url; + google_params.element_type = url_pattern_index::flat::ElementType_SUBDOCUMENT; + google_params.is_third_party = false; + + // The second ruleset should get more priority. + EXPECT_FALSE(composite_matcher->ShouldBlockRequest(google_params)); + + GURL example_url = GURL("http://example.com"); + RequestParams example_params = google_params; + example_params.url = &example_url; + GURL redirect_url; + EXPECT_TRUE( + composite_matcher->ShouldRedirectRequest(example_params, &redirect_url)); + EXPECT_EQ(GURL("http://ruleset2.com"), redirect_url); + + // Now switch the priority of the two rulesets. This requires re-constructing + // the two ruleset matchers. + matcher_1.reset(); + matcher_2.reset(); + matchers.clear(); + ASSERT_TRUE(CreateVerifiedMatcher({block_rule, redirect_rule_1}, + CreateTemporarySource(), &matcher_1)); + matcher_1->set_id_for_testing(kSource1ID); + matcher_1->set_priority_for_testing(kSource2Priority); + ASSERT_TRUE(CreateVerifiedMatcher({allow_rule, redirect_rule_2}, + CreateTemporarySource(), &matcher_2)); + matcher_2->set_id_for_testing(kSource2ID); + matcher_2->set_priority_for_testing(kSource1Priority); + matchers.push_back(std::move(matcher_1)); + matchers.push_back(std::move(matcher_2)); + composite_matcher = std::make_unique<CompositeMatcher>(std::move(matchers)); + + // The first ruleset should get more priority. + EXPECT_TRUE(composite_matcher->ShouldBlockRequest(google_params)); + EXPECT_TRUE( + composite_matcher->ShouldRedirectRequest(example_params, &redirect_url)); + EXPECT_EQ(GURL("http://ruleset1.com"), redirect_url); +} + +} // namespace declarative_net_request +} // namespace extensions
diff --git a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc index 21485f8..72bfb7f 100644 --- a/extensions/browser/api/declarative_net_request/rules_monitor_service.cc +++ b/extensions/browser/api/declarative_net_request/rules_monitor_service.cc
@@ -17,6 +17,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/service_manager_connection.h" +#include "extensions/browser/api/declarative_net_request/composite_matcher.h" #include "extensions/browser/api/declarative_net_request/ruleset_manager.h" #include "extensions/browser/api/declarative_net_request/ruleset_matcher.h" #include "extensions/browser/api/declarative_net_request/ruleset_source.h" @@ -51,8 +52,14 @@ InfoMap* info_map) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(info_map); + + // Only a single ruleset per extension is supported currently. + CompositeMatcher::MatcherList matchers; + matchers.push_back(std::move(ruleset_matcher)); + info_map->GetRulesetManager()->AddRuleset( - extension_id, std::move(ruleset_matcher), std::move(allowed_pages)); + extension_id, std::make_unique<CompositeMatcher>(std::move(matchers)), + std::move(allowed_pages)); } void UnloadRulesetOnIOThread(ExtensionId extension_id, InfoMap* info_map) { @@ -110,7 +117,7 @@ DCHECK(GetExtensionFileTaskRunner()->RunsTasksInCurrentSequence()); load_ruleset_result_ = RulesetMatcher::CreateVerifiedMatcher( - source_.indexed_path(), *expected_checksum_, &matcher_); + source_, *expected_checksum_, &matcher_); UMA_HISTOGRAM_ENUMERATION( "Extensions.DeclarativeNetRequest.LoadRulesetResult",
diff --git a/extensions/browser/api/declarative_net_request/ruleset_manager.cc b/extensions/browser/api/declarative_net_request/ruleset_manager.cc index f54f621..46cacc4 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_manager.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_manager.cc
@@ -18,14 +18,13 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/resource_request_info.h" -#include "extensions/browser/api/declarative_net_request/ruleset_matcher.h" +#include "extensions/browser/api/declarative_net_request/composite_matcher.h" #include "extensions/browser/api/extensions_api_client.h" #include "extensions/browser/api/web_request/web_request_info.h" #include "extensions/browser/api/web_request/web_request_permissions.h" #include "extensions/browser/info_map.h" #include "extensions/common/api/declarative_net_request/utils.h" #include "extensions/common/constants.h" -#include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "url/origin.h" namespace extensions { @@ -48,66 +47,6 @@ kMaxValue = kBothCandidatesMatchInitiator, }; -// Maps content::ResourceType to flat_rule::ElementType. -flat_rule::ElementType GetElementType(content::ResourceType type) { - switch (type) { - case content::RESOURCE_TYPE_LAST_TYPE: - case content::RESOURCE_TYPE_PREFETCH: - case content::RESOURCE_TYPE_SUB_RESOURCE: - case content::RESOURCE_TYPE_NAVIGATION_PRELOAD: - return flat_rule::ElementType_OTHER; - case content::RESOURCE_TYPE_MAIN_FRAME: - return flat_rule::ElementType_MAIN_FRAME; - case content::RESOURCE_TYPE_CSP_REPORT: - return flat_rule::ElementType_CSP_REPORT; - case content::RESOURCE_TYPE_SCRIPT: - case content::RESOURCE_TYPE_WORKER: - case content::RESOURCE_TYPE_SHARED_WORKER: - case content::RESOURCE_TYPE_SERVICE_WORKER: - return flat_rule::ElementType_SCRIPT; - case content::RESOURCE_TYPE_IMAGE: - case content::RESOURCE_TYPE_FAVICON: - return flat_rule::ElementType_IMAGE; - case content::RESOURCE_TYPE_STYLESHEET: - return flat_rule::ElementType_STYLESHEET; - case content::RESOURCE_TYPE_OBJECT: - case content::RESOURCE_TYPE_PLUGIN_RESOURCE: - return flat_rule::ElementType_OBJECT; - case content::RESOURCE_TYPE_XHR: - return flat_rule::ElementType_XMLHTTPREQUEST; - case content::RESOURCE_TYPE_SUB_FRAME: - return flat_rule::ElementType_SUBDOCUMENT; - case content::RESOURCE_TYPE_PING: - return flat_rule::ElementType_PING; - case content::RESOURCE_TYPE_MEDIA: - return flat_rule::ElementType_MEDIA; - case content::RESOURCE_TYPE_FONT_RESOURCE: - return flat_rule::ElementType_FONT; - } - NOTREACHED(); - return flat_rule::ElementType_OTHER; -} - -// Returns the flat_rule::ElementType for the given |request|. -flat_rule::ElementType GetElementType(const WebRequestInfo& request) { - if (request.url.SchemeIsWSOrWSS()) - return flat_rule::ElementType_WEBSOCKET; - - return request.type.has_value() ? GetElementType(request.type.value()) - : flat_rule::ElementType_OTHER; -} - -// Returns whether the request to |url| is third party to its |document_origin|. -// TODO(crbug.com/696822): Look into caching this. -bool IsThirdPartyRequest(const GURL& url, const url::Origin& document_origin) { - if (document_origin.opaque()) - return true; - - return !net::registry_controlled_domains::SameDomainOrHost( - url, document_origin, - net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); -} - void ClearRendererCacheOnUI() { web_cache::WebCacheManager::GetInstance()->ClearCacheOnNavigation(); } @@ -264,7 +203,7 @@ } void RulesetManager::AddRuleset(const ExtensionId& extension_id, - std::unique_ptr<RulesetMatcher> ruleset_matcher, + std::unique_ptr<CompositeMatcher> matcher, URLPatternSet allowed_pages) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(IsAPIAvailable()); @@ -272,7 +211,7 @@ bool inserted; std::tie(std::ignore, inserted) = rulesets_.emplace(extension_id, info_map_->GetInstallTime(extension_id), - std::move(ruleset_matcher), std::move(allowed_pages)); + std::move(matcher), std::move(allowed_pages)); DCHECK(inserted) << "AddRuleset called twice in succession for " << extension_id; @@ -350,11 +289,7 @@ SCOPED_UMA_HISTOGRAM_TIMER( "Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions2"); - const GURL& url = request.url; - const url::Origin first_party_origin = - request.initiator.value_or(url::Origin()); - const flat_rule::ElementType element_type = GetElementType(request); - const bool is_third_party = IsThirdPartyRequest(url, first_party_origin); + RequestParams params(request); const int tab_id = request.frame_data ? request.frame_data->tab_id : extension_misc::kUnknownTabId; @@ -388,10 +323,10 @@ if (page_access != PageAccess::kAllowed) continue; - if (ruleset_data->matcher->ShouldBlockRequest( - url, first_party_origin, element_type, is_third_party)) { - return ShouldCollapseResourceType(element_type) ? Action::COLLAPSE - : Action::BLOCK; + if (ruleset_data->matcher->ShouldBlockRequest(params)) { + return ShouldCollapseResourceType(params.element_type) + ? Action::COLLAPSE + : Action::BLOCK; } } } @@ -400,7 +335,7 @@ // redirect the request. // Redirecting WebSocket handshake request is prohibited. - if (element_type == flat_rule::ElementType_WEBSOCKET) + if (params.element_type == flat_rule::ElementType_WEBSOCKET) return Action::NONE; // This iterates in decreasing order of extension installation time. Hence @@ -427,9 +362,7 @@ continue; } - if (ruleset_data->matcher->ShouldRedirectRequest( - url, first_party_origin, element_type, is_third_party, - redirect_url)) { + if (ruleset_data->matcher->ShouldRedirectRequest(params, redirect_url)) { return Action::REDIRECT; } } @@ -446,7 +379,7 @@ RulesetManager::ExtensionRulesetData::ExtensionRulesetData( const ExtensionId& extension_id, const base::Time& extension_install_time, - std::unique_ptr<RulesetMatcher> matcher, + std::unique_ptr<CompositeMatcher> matcher, URLPatternSet allowed_pages) : extension_id(extension_id), extension_install_time(extension_install_time),
diff --git a/extensions/browser/api/declarative_net_request/ruleset_manager.h b/extensions/browser/api/declarative_net_request/ruleset_manager.h index 7deb96d..19c06a9 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_manager.h +++ b/extensions/browser/api/declarative_net_request/ruleset_manager.h
@@ -23,7 +23,7 @@ struct WebRequestInfo; namespace declarative_net_request { -class RulesetMatcher; +class CompositeMatcher; // Manages the set of active rulesets for the Declarative Net Request API. Can // be constructed on any sequence but must be accessed and destroyed from the @@ -59,7 +59,7 @@ // Adds the ruleset for the given |extension_id|. Should not be called twice // in succession for an extension. void AddRuleset(const ExtensionId& extension_id, - std::unique_ptr<RulesetMatcher> ruleset_matcher, + std::unique_ptr<CompositeMatcher> matcher, URLPatternSet allowed_pages); // Removes the ruleset for |extension_id|. Should be called only after a @@ -78,7 +78,7 @@ bool is_incognito_context, GURL* redirect_url) const; - // Returns the number of RulesetMatcher currently being managed. + // Returns the number of CompositeMatchers currently being managed. size_t GetMatcherCountForTest() const { return rulesets_.size(); } // Sets the TestObserver. Client maintains ownership of |observer|. @@ -88,7 +88,7 @@ struct ExtensionRulesetData { ExtensionRulesetData(const ExtensionId& extension_id, const base::Time& extension_install_time, - std::unique_ptr<RulesetMatcher> matcher, + std::unique_ptr<CompositeMatcher> matcher, URLPatternSet allowed_pages); ~ExtensionRulesetData(); ExtensionRulesetData(ExtensionRulesetData&& other); @@ -96,7 +96,7 @@ ExtensionId extension_id; base::Time extension_install_time; - std::unique_ptr<RulesetMatcher> matcher; + std::unique_ptr<CompositeMatcher> matcher; URLPatternSet allowed_pages; bool operator<(const ExtensionRulesetData& other) const;
diff --git a/extensions/browser/api/declarative_net_request/ruleset_matcher.cc b/extensions/browser/api/declarative_net_request/ruleset_matcher.cc index 82ed7060..16ac956 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_matcher.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_matcher.cc
@@ -12,10 +12,13 @@ #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/timer/elapsed_timer.h" +#include "content/public/common/resource_type.h" #include "extensions/browser/api/declarative_net_request/flat/extension_ruleset_generated.h" +#include "extensions/browser/api/declarative_net_request/ruleset_source.h" #include "extensions/browser/api/declarative_net_request/utils.h" +#include "extensions/browser/api/web_request/web_request_info.h" #include "extensions/common/api/declarative_net_request/utils.h" -#include "url/gurl.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" namespace extensions { namespace declarative_net_request { @@ -26,11 +29,84 @@ using FindRuleStrategy = url_pattern_index::UrlPatternIndexMatcher::FindRuleStrategy; +// Don't exclude generic rules from being matched. A generic rule is one with +// an empty included domains list. +const bool kDisableGenericRules = false; + +// Maps content::ResourceType to flat_rule::ElementType. +flat_rule::ElementType GetElementType(content::ResourceType type) { + switch (type) { + case content::RESOURCE_TYPE_LAST_TYPE: + case content::RESOURCE_TYPE_PREFETCH: + case content::RESOURCE_TYPE_SUB_RESOURCE: + case content::RESOURCE_TYPE_NAVIGATION_PRELOAD: + return flat_rule::ElementType_OTHER; + case content::RESOURCE_TYPE_MAIN_FRAME: + return flat_rule::ElementType_MAIN_FRAME; + case content::RESOURCE_TYPE_CSP_REPORT: + return flat_rule::ElementType_CSP_REPORT; + case content::RESOURCE_TYPE_SCRIPT: + case content::RESOURCE_TYPE_WORKER: + case content::RESOURCE_TYPE_SHARED_WORKER: + case content::RESOURCE_TYPE_SERVICE_WORKER: + return flat_rule::ElementType_SCRIPT; + case content::RESOURCE_TYPE_IMAGE: + case content::RESOURCE_TYPE_FAVICON: + return flat_rule::ElementType_IMAGE; + case content::RESOURCE_TYPE_STYLESHEET: + return flat_rule::ElementType_STYLESHEET; + case content::RESOURCE_TYPE_OBJECT: + case content::RESOURCE_TYPE_PLUGIN_RESOURCE: + return flat_rule::ElementType_OBJECT; + case content::RESOURCE_TYPE_XHR: + return flat_rule::ElementType_XMLHTTPREQUEST; + case content::RESOURCE_TYPE_SUB_FRAME: + return flat_rule::ElementType_SUBDOCUMENT; + case content::RESOURCE_TYPE_PING: + return flat_rule::ElementType_PING; + case content::RESOURCE_TYPE_MEDIA: + return flat_rule::ElementType_MEDIA; + case content::RESOURCE_TYPE_FONT_RESOURCE: + return flat_rule::ElementType_FONT; + } + NOTREACHED(); + return flat_rule::ElementType_OTHER; +} + +// Returns the flat_rule::ElementType for the given |request|. +flat_rule::ElementType GetElementType(const WebRequestInfo& request) { + if (request.url.SchemeIsWSOrWSS()) + return flat_rule::ElementType_WEBSOCKET; + + return request.type.has_value() ? GetElementType(request.type.value()) + : flat_rule::ElementType_OTHER; +} + +// Returns whether the request to |url| is third party to its |document_origin|. +// TODO(crbug.com/696822): Look into caching this. +bool IsThirdPartyRequest(const GURL& url, const url::Origin& document_origin) { + if (document_origin.opaque()) + return true; + + return !net::registry_controlled_domains::SameDomainOrHost( + url, document_origin, + net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); +} + } // namespace +RequestParams::RequestParams(const WebRequestInfo& info) + : url(&info.url), + first_party_origin(info.initiator.value_or(url::Origin())), + element_type(GetElementType(info)) { + is_third_party = IsThirdPartyRequest(*url, first_party_origin); +} + +RequestParams::RequestParams() = default; + // static RulesetMatcher::LoadRulesetResult RulesetMatcher::CreateVerifiedMatcher( - const base::FilePath& indexed_ruleset_path, + const RulesetSource& source, int expected_ruleset_checksum, std::unique_ptr<RulesetMatcher>* matcher) { DCHECK(matcher); @@ -38,11 +114,11 @@ base::ElapsedTimer timer; - if (!base::PathExists(indexed_ruleset_path)) + if (!base::PathExists(source.indexed_path())) return kLoadErrorInvalidPath; std::string ruleset_data; - if (!base::ReadFileToString(indexed_ruleset_path, &ruleset_data)) + if (!base::ReadFileToString(source.indexed_path(), &ruleset_data)) return kLoadErrorFileRead; if (!StripVersionHeaderAndParseVersion(&ruleset_data)) @@ -62,57 +138,41 @@ // Using WrapUnique instead of make_unique since this class has a private // constructor. - *matcher = base::WrapUnique(new RulesetMatcher(std::move(ruleset_data))); + *matcher = base::WrapUnique(new RulesetMatcher( + std::move(ruleset_data), source.id(), source.priority())); return kLoadSuccess; } RulesetMatcher::~RulesetMatcher() = default; -bool RulesetMatcher::ShouldBlockRequest(const GURL& url, - const url::Origin& first_party_origin, - flat_rule::ElementType element_type, - bool is_third_party) const { - SCOPED_UMA_HISTOGRAM_TIMER( - "Extensions.DeclarativeNetRequest.ShouldBlockRequestTime." - "SingleExtension"); - - // Don't exclude generic rules from being matched. A generic rule is one with - // an empty included domains list. - const bool disable_generic_rules = false; - - bool success = - !!blocking_matcher_.FindMatch( - url, first_party_origin, element_type, flat_rule::ActivationType_NONE, - is_third_party, disable_generic_rules, FindRuleStrategy::kAny) && - !allowing_matcher_.FindMatch( - url, first_party_origin, element_type, flat_rule::ActivationType_NONE, - is_third_party, disable_generic_rules, FindRuleStrategy::kAny); - return success; +bool RulesetMatcher::HasMatchingBlockRule(const RequestParams& params) const { + DCHECK(params.url); + return blocking_matcher_.FindMatch( + *params.url, params.first_party_origin, params.element_type, + flat_rule::ActivationType_NONE, params.is_third_party, + kDisableGenericRules, FindRuleStrategy::kAny); } -bool RulesetMatcher::ShouldRedirectRequest( - const GURL& url, - const url::Origin& first_party_origin, - flat_rule::ElementType element_type, - bool is_third_party, - GURL* redirect_url) const { +bool RulesetMatcher::HasMatchingAllowRule(const RequestParams& params) const { + DCHECK(params.url); + return allowing_matcher_.FindMatch( + *params.url, params.first_party_origin, params.element_type, + flat_rule::ActivationType_NONE, params.is_third_party, + kDisableGenericRules, FindRuleStrategy::kAny); +} + +bool RulesetMatcher::HasMatchingRedirectRule(const RequestParams& params, + GURL* redirect_url) const { DCHECK(redirect_url); - DCHECK_NE(flat_rule::ElementType_WEBSOCKET, element_type); - - SCOPED_UMA_HISTOGRAM_TIMER( - "Extensions.DeclarativeNetRequest.ShouldRedirectRequestTime." - "SingleExtension"); - - // Don't exclude generic rules from being matched. A generic rule is one with - // an empty included domains list. - const bool disable_generic_rules = false; + DCHECK(params.url); + DCHECK_NE(flat_rule::ElementType_WEBSOCKET, params.element_type); // Retrieve the highest priority matching rule corresponding to the given // request parameters. const flat_rule::UrlRule* rule = redirect_matcher_.FindMatch( - url, first_party_origin, element_type, flat_rule::ActivationType_NONE, - is_third_party, disable_generic_rules, - FindRuleStrategy::kHighestPriority); + *params.url, params.first_party_origin, params.element_type, + flat_rule::ActivationType_NONE, params.is_third_party, + kDisableGenericRules, FindRuleStrategy::kHighestPriority); if (!rule) return false; @@ -131,13 +191,17 @@ return true; } -RulesetMatcher::RulesetMatcher(std::string ruleset_data) +RulesetMatcher::RulesetMatcher(std::string ruleset_data, + size_t id, + size_t priority) : ruleset_data_(std::move(ruleset_data)), root_(flat::GetExtensionIndexedRuleset(ruleset_data_.data())), blocking_matcher_(root_->blocking_index()), allowing_matcher_(root_->allowing_index()), redirect_matcher_(root_->redirect_index()), - metadata_list_(root_->extension_metadata()) {} + metadata_list_(root_->extension_metadata()), + id_(id), + priority_(priority) {} } // namespace declarative_net_request } // namespace extensions
diff --git a/extensions/browser/api/declarative_net_request/ruleset_matcher.h b/extensions/browser/api/declarative_net_request/ruleset_matcher.h index 76876a2..cc959f0 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_matcher.h +++ b/extensions/browser/api/declarative_net_request/ruleset_matcher.h
@@ -9,27 +9,35 @@ #include <string> #include "components/url_pattern_index/url_pattern_index.h" - -namespace base { -class FilePath; -} // namespace base - -class GURL; - -namespace url { -class Origin; -} // namespace url +#include "url/gurl.h" +#include "url/origin.h" namespace extensions { +struct WebRequestInfo; + namespace declarative_net_request { +class RulesetSource; namespace flat { struct ExtensionIndexedRuleset; struct UrlRuleMetadata; } // namespace flat +// Struct to hold parameters for a network request. +struct RequestParams { + // |info| must outlive this instance. + explicit RequestParams(const WebRequestInfo& info); + RequestParams(); + + // This is a pointer to a GURL. Hence the GURL must outlive this struct. + const GURL* url = nullptr; + url::Origin first_party_origin; + url_pattern_index::flat::ElementType element_type; + bool is_third_party; +}; + // RulesetMatcher encapsulates the Declarative Net Request API ruleset -// corresponding to a single extension. This uses the url_pattern_index +// corresponding to a single RulesetSource. This uses the url_pattern_index // component to achieve fast matching of network requests against declarative // rules. Since this class is immutable, it is thread-safe. In practice it is // accessed on the IO thread but created on a sequence where file IO is allowed. @@ -57,39 +65,44 @@ kLoadResultMax }; - // Factory function to create a verified RulesetMatcher. - // |indexed_ruleset_path| is the path of the extension ruleset in flatbuffer - // format. Must be called on a sequence where file IO is allowed. Returns - // kLoadSuccess on success along with the ruleset |matcher|. + // Factory function to create a verified RulesetMatcher for |source|. Must be + // called on a sequence where file IO is allowed. Returns kLoadSuccess on + // success along with the ruleset |matcher|. static LoadRulesetResult CreateVerifiedMatcher( - const base::FilePath& indexed_ruleset_path, + const RulesetSource& source, int expected_ruleset_checksum, std::unique_ptr<RulesetMatcher>* matcher); ~RulesetMatcher(); - // Returns whether the network request as specified by the passed parameters - // should be blocked. - bool ShouldBlockRequest(const GURL& url, - const url::Origin& first_party_origin, - url_pattern_index::flat::ElementType element_type, - bool is_third_party) const; + // Returns whether the ruleset has a matching blocking rule. + bool HasMatchingBlockRule(const RequestParams& params) const; - // Returns whether the network request as specified by the passed parameters - // should be redirected along with the |redirect_url|. |redirect_url| must - // not be null. - bool ShouldRedirectRequest(const GURL& url, - const url::Origin& first_party_origin, - url_pattern_index::flat::ElementType element_type, - bool is_third_party, - GURL* redirect_url) const; + // Returns whether the ruleset has a matching allow rule. + bool HasMatchingAllowRule(const RequestParams& params) const; + + // Returns whether the ruleset has a matching redirect rule. Populates + // |redirect_url| on returning true. |redirect_url| must not be null. + bool HasMatchingRedirectRule(const RequestParams& params, + GURL* redirect_url) const; + + // ID of the ruleset. Each extension can have multiple rulesets with + // their own unique ids. + size_t id() const { return id_; } + + // Priority of the ruleset. Each extension can have multiple rulesets with + // their own different priorities. + size_t priority() const { return priority_; } + + void set_id_for_testing(size_t id) { id_ = id; } + void set_priority_for_testing(size_t priority) { priority_ = priority; } private: using UrlPatternIndexMatcher = url_pattern_index::UrlPatternIndexMatcher; using ExtensionMetadataList = flatbuffers::Vector<flatbuffers::Offset<flat::UrlRuleMetadata>>; - explicit RulesetMatcher(std::string ruleset_data); + explicit RulesetMatcher(std::string ruleset_data, size_t id, size_t priority); const std::string ruleset_data_; @@ -99,6 +112,9 @@ const UrlPatternIndexMatcher redirect_matcher_; const ExtensionMetadataList* const metadata_list_; + size_t id_; + size_t priority_; + DISALLOW_COPY_AND_ASSIGN(RulesetMatcher); };
diff --git a/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc b/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc index 0a0c958a..0a92a9a 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_matcher_unittest.cc
@@ -7,18 +7,16 @@ #include <utility> #include <vector> -#include "base/files/file_path.h" #include "base/files/file_util.h" -#include "base/json/json_file_value_serializer.h" #include "base/logging.h" #include "components/url_pattern_index/flat/url_pattern_index_generated.h" #include "components/version_info/version_info.h" #include "extensions/browser/api/declarative_net_request/ruleset_source.h" +#include "extensions/browser/api/declarative_net_request/test_utils.h" #include "extensions/browser/api/declarative_net_request/utils.h" #include "extensions/common/api/declarative_net_request/constants.h" #include "extensions/common/api/declarative_net_request/test_utils.h" #include "extensions/common/features/feature_channel.h" -#include "extensions/common/value_builder.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" #include "url/origin.h" @@ -31,42 +29,6 @@ public: RulesetMatcherTest() : channel_(::version_info::Channel::UNKNOWN) {} - protected: - // Helper to create a verified ruleset matcher. Populates |matcher| and - // |expected_checksum|. - void CreateVerifiedMatcher(const std::vector<TestRule>& rules, - const RulesetSource& source, - std::unique_ptr<RulesetMatcher>* matcher, - int* expected_checksum = nullptr) { - // Serialize |rules|. - ListBuilder builder; - for (const auto& rule : rules) - builder.Append(rule.ToValue()); - JSONFileValueSerializer(source.json_path()).Serialize(*builder.Build()); - - // Index ruleset. - IndexAndPersistRulesResult result = source.IndexAndPersistRulesUnsafe(); - ASSERT_TRUE(result.success); - ASSERT_TRUE(result.error.empty()); - - if (expected_checksum) - *expected_checksum = result.ruleset_checksum; - - // Create verified matcher. - RulesetMatcher::LoadRulesetResult load_result = - RulesetMatcher::CreateVerifiedMatcher(source.indexed_path(), - result.ruleset_checksum, matcher); - ASSERT_EQ(RulesetMatcher::kLoadSuccess, load_result); - } - - RulesetSource CreateTemporarySource() { - base::FilePath json_path; - base::FilePath indexed_path; - CHECK(base::CreateTemporaryFile(&json_path)); - CHECK(base::CreateTemporaryFile(&indexed_path)); - return RulesetSource(std::move(json_path), std::move(indexed_path)); - } - private: // Run this on the trunk channel to ensure the API is available. ScopedCurrentChannel channel_; @@ -75,24 +37,33 @@ }; // Tests a simple blocking rule. -TEST_F(RulesetMatcherTest, ShouldBlockRequest) { +TEST_F(RulesetMatcherTest, BlockingRule) { TestRule rule = CreateGenericRule(); rule.condition->url_filter = std::string("google.com"); std::unique_ptr<RulesetMatcher> matcher; - ASSERT_NO_FATAL_FAILURE( - CreateVerifiedMatcher({rule}, CreateTemporarySource(), &matcher)); + ASSERT_TRUE(CreateVerifiedMatcher({rule}, CreateTemporarySource(), &matcher)); - EXPECT_TRUE(matcher->ShouldBlockRequest( - GURL("http://google.com"), url::Origin(), - url_pattern_index::flat::ElementType_SUBDOCUMENT, true)); - EXPECT_FALSE(matcher->ShouldBlockRequest( - GURL("http://yahoo.com"), url::Origin(), - url_pattern_index::flat::ElementType_SUBDOCUMENT, true)); + auto should_block_request = [&matcher](const RequestParams& params) { + return !matcher->HasMatchingAllowRule(params) && + matcher->HasMatchingBlockRule(params); + }; + + GURL google_url("http://google.com"); + RequestParams params; + params.url = &google_url; + params.element_type = url_pattern_index::flat::ElementType_SUBDOCUMENT; + params.is_third_party = true; + + EXPECT_TRUE(should_block_request(params)); + + GURL yahoo_url("http://yahoo.com"); + params.url = &yahoo_url; + EXPECT_FALSE(should_block_request(params)); } // Tests a simple redirect rule. -TEST_F(RulesetMatcherTest, ShouldRedirectRequest) { +TEST_F(RulesetMatcherTest, RedirectRule) { TestRule rule = CreateGenericRule(); rule.condition->url_filter = std::string("google.com"); rule.priority = kMinValidPriority; @@ -100,18 +71,27 @@ rule.action->redirect_url = std::string("http://yahoo.com"); std::unique_ptr<RulesetMatcher> matcher; - ASSERT_NO_FATAL_FAILURE( - CreateVerifiedMatcher({rule}, CreateTemporarySource(), &matcher)); + ASSERT_TRUE(CreateVerifiedMatcher({rule}, CreateTemporarySource(), &matcher)); + + auto should_redirect_request = [&matcher](const RequestParams& params, + GURL* redirect_url) { + return matcher->HasMatchingRedirectRule(params, redirect_url); + }; + + GURL google_url("http://google.com"); + GURL yahoo_url("http://yahoo.com"); + + RequestParams params; + params.url = &google_url; + params.element_type = url_pattern_index::flat::ElementType_SUBDOCUMENT; + params.is_third_party = true; GURL redirect_url; - EXPECT_TRUE(matcher->ShouldRedirectRequest( - GURL("http://google.com"), url::Origin(), - url_pattern_index::flat::ElementType_SUBDOCUMENT, true, &redirect_url)); - EXPECT_EQ(GURL("http://yahoo.com"), redirect_url); + EXPECT_TRUE(should_redirect_request(params, &redirect_url)); + EXPECT_EQ(yahoo_url, redirect_url); - EXPECT_FALSE(matcher->ShouldRedirectRequest( - GURL("http://yahoo.com"), url::Origin(), - url_pattern_index::flat::ElementType_SUBDOCUMENT, true, &redirect_url)); + params.url = &yahoo_url; + EXPECT_FALSE(should_redirect_request(params, &redirect_url)); } // Tests that a modified ruleset file fails verification. @@ -119,8 +99,7 @@ RulesetSource source = CreateTemporarySource(); std::unique_ptr<RulesetMatcher> matcher; int expected_checksum; - ASSERT_NO_FATAL_FAILURE( - CreateVerifiedMatcher({}, source, &matcher, &expected_checksum)); + ASSERT_TRUE(CreateVerifiedMatcher({}, source, &matcher, &expected_checksum)); // Persist invalid data to the ruleset file and ensure that a version mismatch // occurs. @@ -128,8 +107,8 @@ ASSERT_EQ(static_cast<int>(data.size()), base::WriteFile(source.indexed_path(), data.c_str(), data.size())); EXPECT_EQ(RulesetMatcher::kLoadErrorVersionMismatch, - RulesetMatcher::CreateVerifiedMatcher(source.indexed_path(), - expected_checksum, &matcher)); + RulesetMatcher::CreateVerifiedMatcher(source, expected_checksum, + &matcher)); // Now, persist invalid data to the ruleset file, while maintaining the // correct version header. Ensure that it fails verification due to checksum @@ -138,8 +117,8 @@ ASSERT_EQ(static_cast<int>(data.size()), base::WriteFile(source.indexed_path(), data.c_str(), data.size())); EXPECT_EQ(RulesetMatcher::kLoadErrorChecksumMismatch, - RulesetMatcher::CreateVerifiedMatcher(source.indexed_path(), - expected_checksum, &matcher)); + RulesetMatcher::CreateVerifiedMatcher(source, expected_checksum, + &matcher)); } } // namespace
diff --git a/extensions/browser/api/declarative_net_request/ruleset_source.cc b/extensions/browser/api/declarative_net_request/ruleset_source.cc index 04cb0f8..a955b034 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_source.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_source.cc
@@ -43,6 +43,11 @@ namespace dnr_api = extensions::api::declarative_net_request; +// TODO(crbug.com/930961): Change once multiple rulesets within an extension are +// supported. +const size_t kDefaultRulesetID = 0; +const size_t kDefaultRulesetPriority = 0; + // Helper to retrieve the filename for the given |file_path|. std::string GetFilename(const base::FilePath& file_path) { return file_path.BaseName().AsUTF8Unsafe(); @@ -225,7 +230,9 @@ RulesetSource::RulesetSource(base::FilePath json_path, base::FilePath indexed_path) : json_path_(std::move(json_path)), - indexed_path_(std::move(indexed_path)) {} + indexed_path_(std::move(indexed_path)), + id_(kDefaultRulesetID), + priority_(kDefaultRulesetPriority) {} RulesetSource::~RulesetSource() = default; RulesetSource::RulesetSource(RulesetSource&&) = default;
diff --git a/extensions/browser/api/declarative_net_request/ruleset_source.h b/extensions/browser/api/declarative_net_request/ruleset_source.h index aad63c11..2a3814e 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_source.h +++ b/extensions/browser/api/declarative_net_request/ruleset_source.h
@@ -73,6 +73,10 @@ // Path to the indexed flatbuffer rules. const base::FilePath& indexed_path() const { return indexed_path_; } + // Each ruleset source within an extension has a distinct ID and priority. + size_t id() const { return id_; } + size_t priority() const { return priority_; } + // Indexes and persists the JSON ruleset. This is potentially unsafe since the // JSON rules file is parsed in-process. Note: This must be called on a // sequence where file IO is allowed. @@ -94,6 +98,8 @@ private: base::FilePath json_path_; base::FilePath indexed_path_; + size_t id_; + size_t priority_; DISALLOW_COPY_AND_ASSIGN(RulesetSource); };
diff --git a/extensions/browser/api/declarative_net_request/test_utils.cc b/extensions/browser/api/declarative_net_request/test_utils.cc index 6347c79..185337b0 100644 --- a/extensions/browser/api/declarative_net_request/test_utils.cc +++ b/extensions/browser/api/declarative_net_request/test_utils.cc
@@ -5,11 +5,18 @@ #include "extensions/browser/api/declarative_net_request/test_utils.h" #include <string> +#include <utility> +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/json/json_file_value_serializer.h" +#include "base/logging.h" #include "extensions/browser/api/declarative_net_request/ruleset_matcher.h" +#include "extensions/browser/api/declarative_net_request/ruleset_source.h" #include "extensions/browser/extension_prefs.h" +#include "extensions/common/api/declarative_net_request/test_utils.h" #include "extensions/common/extension.h" -#include "extensions/common/file_util.h" +#include "extensions/common/value_builder.h" namespace extensions { namespace declarative_net_request { @@ -23,9 +30,44 @@ } std::unique_ptr<RulesetMatcher> matcher; - return RulesetMatcher::CreateVerifiedMatcher( - file_util::GetIndexedRulesetPath(extension.path()), - expected_checksum, &matcher) == RulesetMatcher::kLoadSuccess; + return RulesetMatcher::CreateVerifiedMatcher(RulesetSource::Create(extension), + expected_checksum, &matcher) == + RulesetMatcher::kLoadSuccess; +} + +bool CreateVerifiedMatcher(const std::vector<TestRule>& rules, + const RulesetSource& source, + std::unique_ptr<RulesetMatcher>* matcher, + int* expected_checksum) { + // Serialize |rules|. + ListBuilder builder; + for (const auto& rule : rules) + builder.Append(rule.ToValue()); + JSONFileValueSerializer(source.json_path()).Serialize(*builder.Build()); + + // Index ruleset. + IndexAndPersistRulesResult result = source.IndexAndPersistRulesUnsafe(); + if (!result.success) { + DCHECK(result.error.empty()); + return false; + } + + if (expected_checksum) + *expected_checksum = result.ruleset_checksum; + + // Create verified matcher. + RulesetMatcher::LoadRulesetResult load_result = + RulesetMatcher::CreateVerifiedMatcher(source, result.ruleset_checksum, + matcher); + return load_result == RulesetMatcher::kLoadSuccess; +} + +RulesetSource CreateTemporarySource() { + base::FilePath json_path; + base::FilePath indexed_path; + CHECK(base::CreateTemporaryFile(&json_path)); + CHECK(base::CreateTemporaryFile(&indexed_path)); + return RulesetSource(std::move(json_path), std::move(indexed_path)); } } // namespace declarative_net_request
diff --git a/extensions/browser/api/declarative_net_request/test_utils.h b/extensions/browser/api/declarative_net_request/test_utils.h index eeb9c87..1268ce36b 100644 --- a/extensions/browser/api/declarative_net_request/test_utils.h +++ b/extensions/browser/api/declarative_net_request/test_utils.h
@@ -5,6 +5,9 @@ #ifndef EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_TEST_UTILS_H_ #define EXTENSIONS_BROWSER_API_DECLARATIVE_NET_REQUEST_TEST_UTILS_H_ +#include <memory> +#include <vector> + namespace content { class BrowserContext; } // namespace content @@ -14,6 +17,9 @@ class Extension; namespace declarative_net_request { +class RulesetSource; +class RulesetMatcher; +struct TestRule; // Enum specifying the extension load type. Used for parameterized tests. enum class ExtensionLoadType { @@ -26,6 +32,16 @@ bool HasValidIndexedRuleset(const Extension& extension, content::BrowserContext* browser_context); +// Helper to create a verified ruleset matcher. Populates |matcher| and +// |expected_checksum|. Returns true on success. +bool CreateVerifiedMatcher(const std::vector<TestRule>& rules, + const RulesetSource& source, + std::unique_ptr<RulesetMatcher>* matcher, + int* expected_checksum = nullptr); + +// Helper to return a RulesetSource bound to temporary files. +RulesetSource CreateTemporarySource(); + } // namespace declarative_net_request } // namespace extensions
diff --git a/extensions/browser/api/media_perception_private/media_perception_api_manager.cc b/extensions/browser/api/media_perception_private/media_perception_api_manager.cc index 597da59..04ec5ca4 100644 --- a/extensions/browser/api/media_perception_private/media_perception_api_manager.cc +++ b/extensions/browser/api/media_perception_private/media_perception_api_manager.cc
@@ -13,7 +13,7 @@ #include "base/lazy_instance.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/media_analytics_client.h" -#include "chromeos/dbus/upstart_client.h" +#include "chromeos/dbus/upstart/upstart_client.h" #include "extensions/browser/api/extensions_api_client.h" #include "extensions/browser/api/media_perception_private/conversion_utils.h" #include "extensions/browser/api/media_perception_private/media_perception_api_delegate.h" @@ -146,9 +146,7 @@ MediaPerceptionAPIManager::~MediaPerceptionAPIManager() { // Stop the separate media analytics process. - chromeos::UpstartClient* upstart_client = - chromeos::DBusThreadManager::Get()->GetUpstartClient(); - upstart_client->StopMediaAnalytics(); + chromeos::UpstartClient::Get()->StopMediaAnalytics(); } void MediaPerceptionAPIManager::ActivateMediaPerception( @@ -243,12 +241,11 @@ analytics_process_state_ = AnalyticsProcessState::CHANGING_PROCESS_STATE; if (process_state.status == extensions::api::media_perception_private::PROCESS_STATUS_STOPPED) { - chromeos::UpstartClient* dbus_client = - chromeos::DBusThreadManager::Get()->GetUpstartClient(); base::OnceCallback<void(bool)> stop_callback = base::BindOnce(&MediaPerceptionAPIManager::UpstartStopProcessCallback, weak_ptr_factory_.GetWeakPtr(), std::move(callback)); - dbus_client->StopMediaAnalytics(std::move(stop_callback)); + chromeos::UpstartClient::Get()->StopMediaAnalytics( + std::move(stop_callback)); return; } @@ -264,12 +261,10 @@ return; } - chromeos::UpstartClient* dbus_client = - chromeos::DBusThreadManager::Get()->GetUpstartClient(); std::vector<std::string> upstart_env; upstart_env.push_back(std::string("mount_point=") + mount_point_); - dbus_client->StartMediaAnalytics( + chromeos::UpstartClient::Get()->StartMediaAnalytics( upstart_env, base::BindOnce(&MediaPerceptionAPIManager::UpstartStartProcessCallback, weak_ptr_factory_.GetWeakPtr(), std::move(callback))); @@ -305,9 +300,7 @@ // upstart stop command if requested. if (state_proto.status() == mri::State::STOPPED) { analytics_process_state_ = AnalyticsProcessState::CHANGING_PROCESS_STATE; - chromeos::UpstartClient* dbus_client = - chromeos::DBusThreadManager::Get()->GetUpstartClient(); - dbus_client->StopMediaAnalytics( + chromeos::UpstartClient::Get()->StopMediaAnalytics( base::BindOnce(&MediaPerceptionAPIManager::UpstartStopCallback, weak_ptr_factory_.GetWeakPtr(), std::move(callback))); return; @@ -317,9 +310,7 @@ // then send restart upstart command. if (state_proto.status() == mri::State::RESTARTING) { analytics_process_state_ = AnalyticsProcessState::CHANGING_PROCESS_STATE; - chromeos::UpstartClient* dbus_client = - chromeos::DBusThreadManager::Get()->GetUpstartClient(); - dbus_client->RestartMediaAnalytics( + chromeos::UpstartClient::Get()->RestartMediaAnalytics( base::BindOnce(&MediaPerceptionAPIManager::UpstartRestartCallback, weak_ptr_factory_.GetWeakPtr(), std::move(callback))); return; @@ -333,8 +324,6 @@ // Analytics process is in state IDLE. if (state_proto.status() == mri::State::RUNNING) { analytics_process_state_ = AnalyticsProcessState::CHANGING_PROCESS_STATE; - chromeos::UpstartClient* dbus_client = - chromeos::DBusThreadManager::Get()->GetUpstartClient(); std::vector<std::string> upstart_env; // Check if a component is loaded and add the necessary mount_point // information to the Upstart start command. If no component is loaded, @@ -347,7 +336,7 @@ if (!mount_point_.empty()) upstart_env.push_back(std::string("mount_point=") + mount_point_); - dbus_client->StartMediaAnalytics( + chromeos::UpstartClient::Get()->StartMediaAnalytics( upstart_env, base::BindOnce(&MediaPerceptionAPIManager::UpstartStartCallback, weak_ptr_factory_.GetWeakPtr(), std::move(callback),
diff --git a/extensions/browser/api/media_perception_private/media_perception_api_manager_unittest.cc b/extensions/browser/api/media_perception_private/media_perception_api_manager_unittest.cc index 30dc97d..636b44b 100644 --- a/extensions/browser/api/media_perception_private/media_perception_api_manager_unittest.cc +++ b/extensions/browser/api/media_perception_private/media_perception_api_manager_unittest.cc
@@ -4,14 +4,15 @@ #include "extensions/browser/api/media_perception_private/media_perception_api_manager.h" +#include <memory> + #include "base/bind.h" #include "base/containers/queue.h" #include "base/run_loop.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/fake_media_analytics_client.h" -#include "chromeos/dbus/fake_upstart_client.h" #include "chromeos/dbus/media_analytics_client.h" -#include "chromeos/dbus/upstart_client.h" +#include "chromeos/dbus/upstart/fake_upstart_client.h" #include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" @@ -156,7 +157,8 @@ class MediaPerceptionAPIManagerTest : public testing::Test { public: - MediaPerceptionAPIManagerTest() {} + MediaPerceptionAPIManagerTest() = default; + ~MediaPerceptionAPIManagerTest() override = default; void SetUp() override { std::unique_ptr<chromeos::DBusThreadManagerSetter> dbus_setter = @@ -166,9 +168,7 @@ media_analytics_client_ = media_analytics_client.get(); dbus_setter->SetMediaAnalyticsClient(std::move(media_analytics_client)); - auto upstart_client = std::make_unique<TestUpstartClient>(); - upstart_client_ = upstart_client.get(); - dbus_setter->SetUpstartClient(std::move(upstart_client)); + upstart_client_ = std::make_unique<TestUpstartClient>(); manager_ = std::make_unique<MediaPerceptionAPIManager>(&browser_context_); manager_->SetMountPointNonEmptyForTesting(); @@ -178,6 +178,7 @@ // Need to make sure that the MediaPerceptionAPIManager is destructed before // the DbusThreadManager. manager_.reset(); + upstart_client_.reset(); chromeos::DBusThreadManager::Shutdown(); } @@ -185,17 +186,18 @@ // Ownership of both is passed on to chromeos::DbusThreadManager. chromeos::FakeMediaAnalyticsClient* media_analytics_client_; - TestUpstartClient* upstart_client_; + TestUpstartClient* upstart_client() { return upstart_client_.get(); } private: content::TestBrowserThreadBundle thread_bundle_; content::TestBrowserContext browser_context_; + std::unique_ptr<TestUpstartClient> upstart_client_; DISALLOW_COPY_AND_ASSIGN(MediaPerceptionAPIManagerTest); }; TEST_F(MediaPerceptionAPIManagerTest, UpstartFailure) { - upstart_client_->set_enqueue_requests(true); + upstart_client()->set_enqueue_requests(true); media_perception::State state; state.status = media_perception::STATUS_RUNNING; @@ -204,18 +206,18 @@ manager_->SetState(state, base::Bind(&RecordServiceErrorFromStateAndRunClosure, run_loop.QuitClosure(), &service_error)); - EXPECT_TRUE(upstart_client_->HandleNextUpstartRequest(false)); + EXPECT_TRUE(upstart_client()->HandleNextUpstartRequest(false)); run_loop.Run(); EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_NOT_RUNNING, service_error); // Check that after a failed request, setState RUNNING will go through. - upstart_client_->set_enqueue_requests(false); + upstart_client()->set_enqueue_requests(false); EXPECT_EQ(media_perception::SERVICE_ERROR_NONE, SetStateAndWaitForResponse(manager_.get(), state)); } TEST_F(MediaPerceptionAPIManagerTest, ProcessStateUpstartFailure) { - upstart_client_->set_enqueue_requests(true); + upstart_client()->set_enqueue_requests(true); media_perception::ProcessState process_state; process_state.status = media_perception::PROCESS_STATUS_STARTED; @@ -225,19 +227,19 @@ process_state, base::BindOnce(&RecordServiceErrorFromProcessStateAndRunClosure, run_loop.QuitClosure(), &service_error)); - EXPECT_TRUE(upstart_client_->HandleNextUpstartRequest(false)); + EXPECT_TRUE(upstart_client()->HandleNextUpstartRequest(false)); run_loop.Run(); EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_NOT_RUNNING, service_error); // Check that after a failed request, setState RUNNING will go through. - upstart_client_->set_enqueue_requests(false); + upstart_client()->set_enqueue_requests(false); EXPECT_EQ(media_perception::SERVICE_ERROR_NONE, SetComponentProcessStateAndWaitForResponse(manager_.get(), process_state)); } TEST_F(MediaPerceptionAPIManagerTest, UpstartStopFailure) { - upstart_client_->set_enqueue_requests(true); + upstart_client()->set_enqueue_requests(true); media_perception::State state; state.status = media_perception::STATUS_STOPPED; @@ -246,18 +248,18 @@ manager_->SetState(state, base::Bind(&RecordServiceErrorFromStateAndRunClosure, run_loop.QuitClosure(), &service_error)); - EXPECT_TRUE(upstart_client_->HandleNextUpstartRequest(false)); + EXPECT_TRUE(upstart_client()->HandleNextUpstartRequest(false)); run_loop.Run(); EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_UNREACHABLE, service_error); // Check that after a failed request, STOPPED will go through. - upstart_client_->set_enqueue_requests(false); + upstart_client()->set_enqueue_requests(false); EXPECT_EQ(media_perception::SERVICE_ERROR_NONE, SetStateAndWaitForResponse(manager_.get(), state)); } TEST_F(MediaPerceptionAPIManagerTest, ProcessStateUpstartStopFailure) { - upstart_client_->set_enqueue_requests(true); + upstart_client()->set_enqueue_requests(true); media_perception::ProcessState process_state; process_state.status = media_perception::PROCESS_STATUS_STOPPED; @@ -267,19 +269,19 @@ process_state, base::BindOnce(&RecordServiceErrorFromProcessStateAndRunClosure, run_loop.QuitClosure(), &service_error)); - EXPECT_TRUE(upstart_client_->HandleNextUpstartRequest(false)); + EXPECT_TRUE(upstart_client()->HandleNextUpstartRequest(false)); run_loop.Run(); EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_UNREACHABLE, service_error); // Check that after a failed request, STOPPED will go through. - upstart_client_->set_enqueue_requests(false); + upstart_client()->set_enqueue_requests(false); EXPECT_EQ(media_perception::SERVICE_ERROR_NONE, SetComponentProcessStateAndWaitForResponse(manager_.get(), process_state)); } TEST_F(MediaPerceptionAPIManagerTest, UpstartRestartFailure) { - upstart_client_->set_enqueue_requests(true); + upstart_client()->set_enqueue_requests(true); media_perception::State state; state.status = media_perception::STATUS_RESTARTING; @@ -288,19 +290,19 @@ manager_->SetState(state, base::Bind(&RecordServiceErrorFromStateAndRunClosure, run_loop.QuitClosure(), &service_error)); - EXPECT_TRUE(upstart_client_->HandleNextUpstartRequest(false)); + EXPECT_TRUE(upstart_client()->HandleNextUpstartRequest(false)); run_loop.Run(); EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_NOT_RUNNING, service_error); // Check that after a failed request, setState restarted will still go // through. - upstart_client_->set_enqueue_requests(false); + upstart_client()->set_enqueue_requests(false); EXPECT_EQ(media_perception::SERVICE_ERROR_NONE, SetStateAndWaitForResponse(manager_.get(), state)); } TEST_F(MediaPerceptionAPIManagerTest, UpstartStall) { - upstart_client_->set_enqueue_requests(true); + upstart_client()->set_enqueue_requests(true); media_perception::State state; state.status = media_perception::STATUS_RUNNING; @@ -314,12 +316,12 @@ GetStateAndWaitForResponse(manager_.get())); EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_BUSY_LAUNCHING, SetStateAndWaitForResponse(manager_.get(), state)); - EXPECT_TRUE(upstart_client_->HandleNextUpstartRequest(true)); + EXPECT_TRUE(upstart_client()->HandleNextUpstartRequest(true)); run_loop.Run(); EXPECT_EQ(media_perception::SERVICE_ERROR_NONE, service_error); // Verify that after the slow start, things works as normal. - upstart_client_->set_enqueue_requests(false); + upstart_client()->set_enqueue_requests(false); EXPECT_EQ(media_perception::SERVICE_ERROR_NONE, GetStateAndWaitForResponse(manager_.get())); state.status = media_perception::STATUS_SUSPENDED; @@ -328,7 +330,7 @@ } TEST_F(MediaPerceptionAPIManagerTest, SetComponentProcessStateUpstartStall) { - upstart_client_->set_enqueue_requests(true); + upstart_client()->set_enqueue_requests(true); media_perception::ProcessState process_state; process_state.status = media_perception::PROCESS_STATUS_STARTED; @@ -342,19 +344,19 @@ EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_BUSY_LAUNCHING, SetComponentProcessStateAndWaitForResponse(manager_.get(), process_state)); - EXPECT_TRUE(upstart_client_->HandleNextUpstartRequest(true)); + EXPECT_TRUE(upstart_client()->HandleNextUpstartRequest(true)); run_loop.Run(); EXPECT_EQ(media_perception::SERVICE_ERROR_NONE, service_error); // Verify that after the slow start, things works as normal. - upstart_client_->set_enqueue_requests(false); + upstart_client()->set_enqueue_requests(false); process_state.status = media_perception::PROCESS_STATUS_STARTED; EXPECT_EQ(media_perception::SERVICE_ERROR_NONE, SetComponentProcessStateAndWaitForResponse(manager_.get(), process_state)); } TEST_F(MediaPerceptionAPIManagerTest, UpstartRestartStall) { - upstart_client_->set_enqueue_requests(true); + upstart_client()->set_enqueue_requests(true); media_perception::State state; state.status = media_perception::STATUS_RESTARTING; @@ -368,12 +370,12 @@ GetStateAndWaitForResponse(manager_.get())); EXPECT_EQ(media_perception::SERVICE_ERROR_SERVICE_BUSY_LAUNCHING, SetStateAndWaitForResponse(manager_.get(), state)); - EXPECT_TRUE(upstart_client_->HandleNextUpstartRequest(true)); + EXPECT_TRUE(upstart_client()->HandleNextUpstartRequest(true)); run_loop.Run(); EXPECT_EQ(media_perception::SERVICE_ERROR_NONE, service_error); // Verify that after the slow start, things works as normal. - upstart_client_->set_enqueue_requests(false); + upstart_client()->set_enqueue_requests(false); EXPECT_EQ(media_perception::SERVICE_ERROR_NONE, GetStateAndWaitForResponse(manager_.get())); state.status = media_perception::STATUS_RUNNING;
diff --git a/extensions/browser/api/media_perception_private/media_perception_private_apitest.cc b/extensions/browser/api/media_perception_private/media_perception_private_apitest.cc index bf1779f..cc008bd 100644 --- a/extensions/browser/api/media_perception_private/media_perception_private_apitest.cc +++ b/extensions/browser/api/media_perception_private/media_perception_private_apitest.cc
@@ -10,6 +10,7 @@ #include "chromeos/dbus/fake_media_analytics_client.h" #include "chromeos/dbus/media_analytics_client.h" #include "chromeos/dbus/media_perception/media_perception.pb.h" +#include "chromeos/dbus/upstart/upstart_client.h" #include "extensions/browser/api/media_perception_private/media_perception_api_delegate.h" #include "extensions/browser/api/media_perception_private/media_perception_private_api.h" #include "extensions/common/api/media_perception_private.h" @@ -100,6 +101,9 @@ void SetUpInProcessBrowserTestFixture() override { std::unique_ptr<chromeos::DBusThreadManagerSetter> dbus_setter = chromeos::DBusThreadManager::GetSetterForTesting(); + // Initialize UpstartClient here so that it is available for + // FakeMediaAnalyticsClient. It will be shutdown in ChromeBrowserMain. + chromeos::UpstartClient::InitializeFake(); auto media_analytics_client = std::make_unique<chromeos::FakeMediaAnalyticsClient>(); media_analytics_client_ = media_analytics_client.get();
diff --git a/extensions/browser/url_loader_factory_manager.cc b/extensions/browser/url_loader_factory_manager.cc index 0367a71..fb4b1c3 100644 --- a/extensions/browser/url_loader_factory_manager.cc +++ b/extensions/browser/url_loader_factory_manager.cc
@@ -64,6 +64,7 @@ "039F93DD1DF836F1D4E2084C1BEFDB46A854A9D1", "072D729E856B1F2C9894AEEC3A5DF65E519D6BEE", "07333481B7B8D7F57A9BA64FB98CF86EA87455FC", + "086E69ED9071DCB20C93A081A68360963AB09385", "0EAEA2FDEE025D95B3ABB37014EFF5A98AC4BEAE", "109A37B889E7C8AEA7B0103559C3EB6AF73B7832", "16A81AEA09A67B03F7AEA5B957D24A4095E764BE", @@ -73,41 +74,61 @@ "260871EABEDE6F2D07D0D9450096093EDAFCBF34", "29427534E31BB1820714C7CAEDF9C54B47BE154F", "2AA94E2D3F4DA33F0D3BCF5DD48F69B8BDB26F52", + "2E2D8A405430172AB15ADCC09740F3EEE990D605", + "31E6100DC7B4EAB4ABF6CA2A4E191D3945D3C731", + "3230014EA01150A27C1887B700E019B27A6DBA08", "3334952C8387B357A41DD8349D39AD9E7C423943", + "34FB670464B5F16EF5ABD6CD53E26030E97C26B3", "360D8A88545D0C21CBDE2B55EA9E4E4285282B4C", + "3EB17C39F8B6B28FAF34E2406E57A76013A2E066", "3FDD3DB17F3B686F5A05204700ABA13DF20AE957", + "41536C3554CD9458EB2F05F1B58CF84BB7BF83BC", "43865F8D555C201FE452A5A40702EA96240E749C", + "44943FADD66932EF56EE3D856A9FAAD4A8AF0FD9", "4913450195D177430217CAB64B356DC6F6B0F483", + "5053323D1F7B6EEC97A77A350DB6D0D8E51CD0AC", "505F2C1E723731B2C8C9182FEAA73D00525B2048", + "50DDD8734521B61564FCE273F8E60547F88BBCBE", + "52865B2087D0ABCD195A83DFD4BD041A3B4EBC34", + "58BCF05A42C8ECED4E6D76F51E2E1A64AC4F7E7C", + "5F0C47BC039BEDC1B29B68918F75370C292076A6", "61E581B10D83C0AEF8366BB64C18C6615884B3D2", + "6357533CAFFB94A9EA5268ED110079E15561E469", "67528F9B47BE454EC46809C33D24F2C199BE408D", "6AE81EF3B13B15080A2DDB23A205A24C65CCC10B", "6BA5F75FFF75B69507BC4B09B7094926EF93DBD2", "6E49449D56D031B87835CC767734AF5A064E1A13", "71EE66C0F71CD89BEE340F8568A44101D4C3A9A7", + "77D83E0A4157A0E77B51AD60BAB69A346CD4FEA3", "7BFE588B209A15260DE12777B4BBB738DE98FE6C", "808FA9BB3CD501D7801D1CD6D5A3DBA088FDD46F", "82FDBBF79F3517C3946BD89EAAF90C46DFDA4681", "88C372CE52E21560C17BFD52556E60D694E12CAC", "88F5F459139892C0F5DF3022676726BB3F01FB5C", + "89F40D84C0C72C6B02B320716E877FB1671218E9", "8CDD303D6C341D9CAB16713C3CD7587B90A7A84A", + "8CE6227B4E53DF42FF93B24F49D15EDE31E97E79", "934B8F5753A3E5A276FC7D0EE5E575B335A0CC76", "973E35633030AD27DABEC99609424A61386C7309", "99E06C364BBB2D1F82A9D20BC1645BF21E478259", "A30E526CF62131BFBFD7CD9B56253A8F3F171777", "A3660FA31A0DBF07C9F80D5342FF215DBC962719", + "A6057397EDC4E6CF25BC3A142F866ACC653B1CF1", "A8FB3967ADE404B77AC3FB5815A399C0660C3C63", "A9A4B26C2387BA2A5861C790B0FF39F230427AC8", "A9F78610B717B3992F92F490E82FC63FFF46C5FA", "AEEDAC793F184240CFB800DA73EE6321E5145102", + "B3CF6C01796E8D03378FAA77AF507E27BB847E9D", "B4782AE831D849EFCC2AF4BE2012816EDDF8D908", "BF5224FB246A6B67EA986EFF77A43F6C1BCA9672", + "C5539F4EBECABA792CC40D03A56144AAD3BF9D19", "C5BCB9E2E47C3F6FD3F7F83ED982872F77852BA7", "CA89BD35059845F2DB4B4398FD339B9F210E9337", "CC74B2408753932B5D49C81EC073E3E4CA766EE6", "CD8AF9C47DDE6327F8D9A3EFA81F34C6B6C26EBB", "CF40F6289951CBFA3B83B792EFA774E2EA06E4C0", "D0537B1BADCE856227CE76E31B3772F6B68F653C", + "E178D4F4D6617C0B880C36F192DA3B18422C5064", "E6B12430B6166B31BE20E13941C22569EA75B0F2", "E7036E906DBFB77C46EDDEB003A72C0B5CC9BE7F", "E873675B8E754F1B1F1222CB921EA14B4335179D", @@ -115,10 +136,12 @@ "EC24668224116D19FF1A5FFAA61238B88773982C", "EC4A841BD03C8E5202043165188A9E060BF703A3", "EE4BE5F23D2E59E4713958465941EFB4A18166B7", + "F273C23C616F5C56E8EDBAE24B21F5D408936A0D", "F566B33D62CE21415AF5B3F3FD8762B7454B8874", "F59AB261280AB3AE9826D9359507838B90B07431", "F73F9EF0207603992CA3C00A7A0CB223D5571B3F", "F9287A33E15038F2591F23E6E9C486717C7202DD", + "FF0DA4BD87A88469B10709B99E79D4B0E11C0CA6", }; constexpr size_t kHashedExtensionIdLength = base::kSHA1Length * 2;
diff --git a/extensions/renderer/BUILD.gn b/extensions/renderer/BUILD.gn index 157e73a..d29dd5b 100644 --- a/extensions/renderer/BUILD.gn +++ b/extensions/renderer/BUILD.gn
@@ -158,8 +158,6 @@ "injection_host.h", "ipc_message_sender.cc", "ipc_message_sender.h", - "js_extension_bindings_system.cc", - "js_extension_bindings_system.h", "js_renderer_messaging_service.cc", "js_renderer_messaging_service.h", "lazy_background_page_native_handler.cc",
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index 08c7983..fe5b10e1 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -69,7 +69,6 @@ #include "extensions/renderer/guest_view/guest_view_internal_custom_bindings.h" #include "extensions/renderer/id_generator_custom_bindings.h" #include "extensions/renderer/ipc_message_sender.h" -#include "extensions/renderer/js_extension_bindings_system.h" #include "extensions/renderer/logging_native_handler.h" #include "extensions/renderer/messaging_bindings.h" #include "extensions/renderer/messaging_util.h"
diff --git a/extensions/renderer/extension_bindings_system.h b/extensions/renderer/extension_bindings_system.h index c1cc26b0..413e9f9 100644 --- a/extensions/renderer/extension_bindings_system.h +++ b/extensions/renderer/extension_bindings_system.h
@@ -28,6 +28,8 @@ // This is designed to be used on a single thread, but should be safe to use on // threads other than the main thread (so that worker threads can have extension // bindings). +// TODO(devlin): There is now only one ExtensionBindingsSystem (the +// NativeExtensionBindingsSystem); consolidate the classes. class ExtensionBindingsSystem { public: virtual ~ExtensionBindingsSystem() {}
diff --git a/extensions/renderer/js_extension_bindings_system.cc b/extensions/renderer/js_extension_bindings_system.cc deleted file mode 100644 index 78d870b..0000000 --- a/extensions/renderer/js_extension_bindings_system.cc +++ /dev/null
@@ -1,329 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "extensions/renderer/js_extension_bindings_system.h" - -#include "base/command_line.h" -#include "base/strings/string_split.h" -#include "base/timer/elapsed_timer.h" -#include "content/public/common/content_switches.h" -#include "content/public/renderer/v8_value_converter.h" -#include "extensions/common/extension.h" -#include "extensions/common/extension_api.h" -#include "extensions/common/extension_urls.h" -#include "extensions/common/extensions_client.h" -#include "extensions/common/features/feature.h" -#include "extensions/common/features/feature_provider.h" -#include "extensions/common/manifest_constants.h" -#include "extensions/common/manifest_handlers/externally_connectable.h" -#include "extensions/renderer/binding_generating_native_handler.h" -#include "extensions/renderer/event_bindings.h" -#include "extensions/renderer/event_bookkeeper.h" -#include "extensions/renderer/ipc_message_sender.h" -#include "extensions/renderer/renderer_extension_registry.h" -#include "extensions/renderer/request_sender.h" -#include "extensions/renderer/resource_bundle_source_map.h" -#include "extensions/renderer/script_context.h" -#include "gin/converter.h" -#include "v8/include/v8.h" - -namespace extensions { - -namespace { - -// Gets |field| from |object| or creates it as an empty object if it doesn't -// exist. -v8::Local<v8::Object> GetOrCreateObject(const v8::Local<v8::Object>& object, - const std::string& field, - ScriptContext* context) { - v8::Local<v8::String> key = - v8::String::NewFromUtf8(context->isolate(), field.c_str(), - v8::NewStringType::kInternalized) - .ToLocalChecked(); - // If the object has a callback property, it is assumed it is an unavailable - // API, so it is safe to delete. This is checked before GetOrCreateObject is - // called. - if (object->HasRealNamedCallbackProperty(context->v8_context(), key) - .FromMaybe(false)) { - object->Delete(context->v8_context(), key).ToChecked(); - } else if (object->HasRealNamedProperty(context->v8_context(), key) - .FromMaybe(false)) { - v8::Local<v8::Value> value = - object->Get(context->v8_context(), key).ToLocalChecked(); - CHECK(value->IsObject()); - return v8::Local<v8::Object>::Cast(value); - } - - v8::Local<v8::Object> new_object = v8::Object::New(context->isolate()); - object->Set(context->v8_context(), key, new_object).ToChecked(); - return new_object; -} - -// Returns the global value for "chrome" from |context|. If one doesn't exist -// creates a new object for it. If a chrome property exists on the window -// already (as in the case when a script did `window.chrome = true`), returns -// an empty object. -v8::Local<v8::Object> GetOrCreateChrome(ScriptContext* context) { - v8::Local<v8::String> chrome_string( - v8::String::NewFromUtf8(context->isolate(), "chrome", - v8::NewStringType::kInternalized) - .ToLocalChecked()); - v8::Local<v8::Object> global(context->v8_context()->Global()); - v8::Local<v8::Value> chrome( - global->Get(context->v8_context(), chrome_string).ToLocalChecked()); - if (chrome->IsUndefined()) { - chrome = v8::Object::New(context->isolate()); - global->Set(context->v8_context(), chrome_string, chrome).ToChecked(); - } - return chrome->IsObject() ? chrome.As<v8::Object>() : v8::Local<v8::Object>(); -} - -v8::Local<v8::Object> GetOrCreateBindObjectIfAvailable( - const std::string& api_name, - std::string* bind_name, - ScriptContext* context) { - std::vector<std::string> split = base::SplitString( - api_name, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - - v8::Local<v8::Object> bind_object; - - // Check if this API has an ancestor. If the API's ancestor is available and - // the API is not available, don't install the bindings for this API. If - // the API is available and its ancestor is not, delete the ancestor and - // install the bindings for the API. This is to prevent loading the ancestor - // API schema if it will not be needed. - // - // For example: - // If app is available and app.window is not, just install app. - // If app.window is available and app is not, delete app and install - // app.window on a new object so app does not have to be loaded. - const FeatureProvider* api_feature_provider = - FeatureProvider::GetAPIFeatures(); - std::string ancestor_name; - bool only_ancestor_available = false; - - for (size_t i = 0; i < split.size() - 1; ++i) { - ancestor_name += (i ? "." : "") + split[i]; - if (api_feature_provider->GetFeature(ancestor_name) && - context->GetAvailability(ancestor_name).is_available() && - !context->GetAvailability(api_name).is_available()) { - only_ancestor_available = true; - break; - } - - if (bind_object.IsEmpty()) { - bind_object = GetOrCreateChrome(context); - if (bind_object.IsEmpty()) - return v8::Local<v8::Object>(); - } - bind_object = GetOrCreateObject(bind_object, split[i], context); - } - - if (only_ancestor_available) - return v8::Local<v8::Object>(); - - DCHECK(bind_name); - *bind_name = split.back(); - - return bind_object.IsEmpty() ? GetOrCreateChrome(context) : bind_object; -} - -// Creates the event bindings if necessary for the given |context|. -void MaybeCreateEventBindings(ScriptContext* context) { - // chrome.Event is part of the public API (although undocumented). Make it - // lazily evalulate to Event from event_bindings.js. For extensions only - // though, not all webpages! - if (!context->extension()) - return; - v8::Local<v8::Object> chrome = GetOrCreateChrome(context); - if (chrome.IsEmpty()) - return; - context->module_system()->SetLazyField(chrome, "Event", kEventBindings, - "Event"); -} - -} // namespace - -JsExtensionBindingsSystem::JsExtensionBindingsSystem( - ResourceBundleSourceMap* source_map, - std::unique_ptr<IPCMessageSender> ipc_message_sender) - : source_map_(source_map), - ipc_message_sender_(std::move(ipc_message_sender)), - request_sender_( - std::make_unique<RequestSender>(ipc_message_sender_.get())), - messaging_service_(this) {} - -JsExtensionBindingsSystem::~JsExtensionBindingsSystem() {} - -void JsExtensionBindingsSystem::DidCreateScriptContext(ScriptContext* context) { - MaybeCreateEventBindings(context); -} - -void JsExtensionBindingsSystem::WillReleaseScriptContext( - ScriptContext* context) { - // TODO(kalman): Make |request_sender| use |context->AddInvalidationObserver|. - // In fact |request_sender_| should really be owned by ScriptContext. - request_sender_->InvalidateSource(context); -} - -void JsExtensionBindingsSystem::UpdateBindingsForContext( - ScriptContext* context) { - base::ElapsedTimer timer; - - v8::HandleScope handle_scope(context->isolate()); - v8::Context::Scope context_scope(context->v8_context()); - - // TODO(kalman): Make the bindings registration have zero overhead then run - // the same code regardless of context type. - switch (context->context_type()) { - case Feature::UNSPECIFIED_CONTEXT: - case Feature::WEB_PAGE_CONTEXT: - case Feature::BLESSED_WEB_PAGE_CONTEXT: - // Hard-code registration of any APIs that are exposed to webpage-like - // contexts, because it's too expensive to run the full bindings code. - // All of the same permission checks will still apply. - for (const char* feature_name : kWebAvailableFeatures) { - if (context->GetAvailability(feature_name).is_available()) - RegisterBinding(feature_name, feature_name, context); - } - if (IsRuntimeAvailableToContext(context)) - RegisterBinding("runtime", "runtime", context); - break; - - case Feature::SERVICE_WORKER_CONTEXT: - DCHECK(ExtensionsClient::Get() - ->ExtensionAPIEnabledInExtensionServiceWorkers()); - FALLTHROUGH; - case Feature::BLESSED_EXTENSION_CONTEXT: - case Feature::UNBLESSED_EXTENSION_CONTEXT: - case Feature::CONTENT_SCRIPT_CONTEXT: - case Feature::LOCK_SCREEN_EXTENSION_CONTEXT: - case Feature::WEBUI_CONTEXT: { - // Extension context; iterate through all the APIs and bind the available - // ones. - const FeatureProvider* api_feature_provider = - FeatureProvider::GetAPIFeatures(); - for (const auto& map_entry : api_feature_provider->GetAllFeatures()) { - // Internal APIs are included via require(api_name) from internal code - // rather than chrome[api_name]. - if (map_entry.second->IsInternal()) - continue; - - // If this API has a parent feature (and isn't marked 'noparent'), - // then this must be a function or event, so we should not register. - if (api_feature_provider->GetParent(*map_entry.second) != nullptr) - continue; - - // Skip chrome.test if this isn't a test. - if (map_entry.first == "test" && - !base::CommandLine::ForCurrentProcess()->HasSwitch( - ::switches::kTestType)) { - continue; - } - - if (context->IsAnyFeatureAvailableToContext( - *map_entry.second, CheckAliasStatus::NOT_ALLOWED)) { - // Check if the API feature is indeed an alias. If it is, the API - // should use source API bindings as its own. - const std::string& source = map_entry.second->source(); - // TODO(lazyboy): RegisterBinding() uses |source_map_|, any thread - // safety issue? - RegisterBinding(source.empty() ? map_entry.first : source, - map_entry.first, context); - } - } - break; - } - } - - LogUpdateBindingsForContextTime(context->context_type(), timer.Elapsed()); -} - -void JsExtensionBindingsSystem::HandleResponse(int request_id, - bool success, - const base::ListValue& response, - const std::string& error) { - request_sender_->HandleResponse(request_id, success, response, error); - ipc_message_sender_->SendOnRequestResponseReceivedIPC(request_id); -} - -RequestSender* JsExtensionBindingsSystem::GetRequestSender() { - return request_sender_.get(); -} - -IPCMessageSender* JsExtensionBindingsSystem::GetIPCMessageSender() { - return ipc_message_sender_.get(); -} - -RendererMessagingService* JsExtensionBindingsSystem::GetMessagingService() { - return &messaging_service_; -} - -void JsExtensionBindingsSystem::DispatchEventInContext( - const std::string& event_name, - const base::ListValue* event_args, - const EventFilteringInfo* filtering_info, - ScriptContext* context) { - EventBindings::DispatchEventInContext(event_name, event_args, filtering_info, - context); -} - -bool JsExtensionBindingsSystem::HasEventListenerInContext( - const std::string& event_name, - ScriptContext* context) { - return EventBookkeeper::Get()->HasListener(context, event_name); -} - -void JsExtensionBindingsSystem::RegisterBinding( - const std::string& api_name, - const std::string& api_bind_name, - ScriptContext* context) { - std::string bind_name; - v8::Local<v8::Object> bind_object = - GetOrCreateBindObjectIfAvailable(api_bind_name, &bind_name, context); - - // Empty if the bind object failed to be created, probably because the - // extension overrode chrome with a non-object, e.g. window.chrome = true. - if (bind_object.IsEmpty()) - return; - - v8::Local<v8::String> v8_bind_name = - v8::String::NewFromUtf8(context->isolate(), bind_name.c_str(), - v8::NewStringType::kInternalized) - .ToLocalChecked(); - if (bind_object->HasRealNamedProperty(context->v8_context(), v8_bind_name) - .FromMaybe(false)) { - // The bind object may already have the property if the API has been - // registered before (or if the extension has put something there already, - // but, whatevs). - // - // In the former case, we need to re-register the bindings for the APIs - // which the extension now has permissions for (if any), but not touch any - // others so that we don't destroy state such as event listeners. - // - // TODO(kalman): Only register available APIs to make this all moot. - if (bind_object - ->HasRealNamedCallbackProperty(context->v8_context(), v8_bind_name) - .FromMaybe(false)) - return; // lazy binding still there, nothing to do - if (bind_object->Get(context->v8_context(), v8_bind_name) - .ToLocalChecked() - ->IsObject()) - return; // binding has already been fully installed - } - - ModuleSystem* module_system = context->module_system(); - if (!source_map_->Contains(api_name)) { - module_system->RegisterNativeHandler( - api_bind_name, - std::unique_ptr<NativeHandler>( - new BindingGeneratingNativeHandler(context, api_name, "binding"))); - module_system->SetNativeLazyField(bind_object, bind_name, api_bind_name, - "binding"); - } else { - module_system->SetLazyField(bind_object, bind_name, api_name, "binding"); - } -} - -} // namespace extensions
diff --git a/extensions/renderer/js_extension_bindings_system.h b/extensions/renderer/js_extension_bindings_system.h deleted file mode 100644 index 78213ac..0000000 --- a/extensions/renderer/js_extension_bindings_system.h +++ /dev/null
@@ -1,62 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef EXTENSIONS_RENDERER_JS_EXTENSION_BINDINGS_SYSTEM_H_ -#define EXTENSIONS_RENDERER_JS_EXTENSION_BINDINGS_SYSTEM_H_ - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "extensions/renderer/extension_bindings_system.h" -#include "extensions/renderer/js_renderer_messaging_service.h" - -namespace extensions { -class IPCMessageSender; -class ResourceBundleSourceMap; - -// The bindings system using the traditional JS-injection style bindings. -class JsExtensionBindingsSystem : public ExtensionBindingsSystem { - public: - JsExtensionBindingsSystem(ResourceBundleSourceMap* source_map, - std::unique_ptr<IPCMessageSender> request_sender); - ~JsExtensionBindingsSystem() override; - - // ExtensionBindingsSystem: - void DidCreateScriptContext(ScriptContext* context) override; - void WillReleaseScriptContext(ScriptContext* context) override; - void UpdateBindingsForContext(ScriptContext* context) override; - void DispatchEventInContext(const std::string& event_name, - const base::ListValue* event_args, - const EventFilteringInfo* filtering_info, - ScriptContext* context) override; - bool HasEventListenerInContext(const std::string& event_name, - ScriptContext* context) override; - void HandleResponse(int request_id, - bool success, - const base::ListValue& response, - const std::string& error) override; - RequestSender* GetRequestSender() override; - IPCMessageSender* GetIPCMessageSender() override; - RendererMessagingService* GetMessagingService() override; - - private: - void RegisterBinding(const std::string& api_name, - const std::string& api_bind_name, - ScriptContext* context); - - ResourceBundleSourceMap* source_map_ = nullptr; - - std::unique_ptr<IPCMessageSender> ipc_message_sender_; - - std::unique_ptr<RequestSender> request_sender_; - - JSRendererMessagingService messaging_service_; - - DISALLOW_COPY_AND_ASSIGN(JsExtensionBindingsSystem); -}; - -} // namespace extensions - -#endif // EXTENSIONS_RENDERER_JS_EXTENSION_BINDINGS_SYSTEM_H_
diff --git a/extensions/renderer/worker_thread_dispatcher.cc b/extensions/renderer/worker_thread_dispatcher.cc index 5a48537..a6d6ba3a 100644 --- a/extensions/renderer/worker_thread_dispatcher.cc +++ b/extensions/renderer/worker_thread_dispatcher.cc
@@ -20,8 +20,7 @@ #include "extensions/renderer/dispatcher.h" #include "extensions/renderer/extension_bindings_system.h" #include "extensions/renderer/extensions_renderer_client.h" -#include "extensions/renderer/js_extension_bindings_system.h" -#include "extensions/renderer/native_extension_bindings_system.h" +#include "extensions/renderer/renderer_messaging_service.h" #include "extensions/renderer/service_worker_data.h" #include "extensions/renderer/worker_script_context_set.h"
diff --git a/fuchsia/engine/browser/context_impl_browsertest.cc b/fuchsia/engine/browser/context_impl_browsertest.cc index c2b5267..8a51d49 100644 --- a/fuchsia/engine/browser/context_impl_browsertest.cc +++ b/fuchsia/engine/browser/context_impl_browsertest.cc
@@ -95,7 +95,7 @@ EXPECT_CALL(navigation_observer_, MockableOnNavigationStateChanged(_)) .WillOnce(testing::InvokeWithoutArgs([&run_loop] { run_loop.Quit(); })); - nav->LoadUrl(cookie_url.spec(), nullptr); + nav->LoadUrl(cookie_url.spec(), chromium::web::LoadUrlParams()); run_loop.Run(); } @@ -153,7 +153,7 @@ MockableOnNavigationStateChanged( Field(&NavigationDetails::url, url::kAboutBlankURL))) .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); - controller->LoadUrl(url::kAboutBlankURL, nullptr); + controller->LoadUrl(url::kAboutBlankURL, chromium::web::LoadUrlParams()); run_loop.Run(); frame.Unbind(); @@ -171,7 +171,7 @@ EXPECT_CALL(navigation_observer_, MockableOnNavigationStateChanged(_)) .WillOnce(testing::InvokeWithoutArgs([&run_loop] { run_loop.Quit(); })); - nav->LoadUrl(cookie_url.spec(), nullptr); + nav->LoadUrl(cookie_url.spec(), chromium::web::LoadUrlParams()); run_loop.Run(); auto cookies = GetCookies();
diff --git a/fuchsia/engine/browser/frame_impl.cc b/fuchsia/engine/browser/frame_impl.cc index e1e2e6b..648b7b9 100644 --- a/fuchsia/engine/browser/frame_impl.cc +++ b/fuchsia/engine/browser/frame_impl.cc
@@ -447,20 +447,7 @@ }); } -void FrameImpl::LoadUrl(std::string url, - std::unique_ptr<chromium::web::LoadUrlParams> params) { - chromium::web::LoadUrlParams2 converted_params; - if (params) { - converted_params.set_type(params->type); - converted_params.set_referrer_url(std::move(params->referrer)); - converted_params.set_was_user_activated(params->user_activated); - converted_params.set_headers(std::move(params->headers)); - } - LoadUrl2(std::move(url), std::move(converted_params)); -} - -void FrameImpl::LoadUrl2(std::string url, - chromium::web::LoadUrlParams2 params) { +void FrameImpl::LoadUrl(std::string url, chromium::web::LoadUrlParams params) { GURL validated_url(url); if (!validated_url.is_valid()) { // TODO(crbug.com/934539): Add type epitaph. @@ -492,6 +479,24 @@ web_contents_->GetController().LoadURLWithParams(params_converted); } +void FrameImpl::LoadUrl2(std::string url, + chromium::web::LoadUrlParams2 params) { + chromium::web::LoadUrlParams converted_params; + if (params.has_type()) { + converted_params.set_type(*params.type()); + } + if (params.has_referrer_url()) { + converted_params.set_referrer_url(std::move(*params.referrer_url())); + } + if (params.has_was_user_activated()) { + converted_params.set_was_user_activated(*params.was_user_activated()); + } + if (params.has_headers()) { + converted_params.set_headers(std::move(*params.headers())); + } + LoadUrl(std::move(url), std::move(converted_params)); +} + void FrameImpl::GoBack() { if (web_contents_->GetController().CanGoBack()) web_contents_->GetController().GoBack();
diff --git a/fuchsia/engine/browser/frame_impl.h b/fuchsia/engine/browser/frame_impl.h index 2fad2f89..361109e 100644 --- a/fuchsia/engine/browser/frame_impl.h +++ b/fuchsia/engine/browser/frame_impl.h
@@ -105,8 +105,7 @@ void MaybeSendNavigationEvent(); // chromium::web::NavigationController implementation. - void LoadUrl(std::string url, - std::unique_ptr<chromium::web::LoadUrlParams> params) override; + void LoadUrl(std::string url, chromium::web::LoadUrlParams params) override; void LoadUrl2(std::string url, chromium::web::LoadUrlParams2 params) override; void GoBack() override; void GoForward() override;
diff --git a/fuchsia/engine/browser/frame_impl_browsertest.cc b/fuchsia/engine/browser/frame_impl_browsertest.cc index 21bc1f2d..9d5d28d2 100644 --- a/fuchsia/engine/browser/frame_impl_browsertest.cc +++ b/fuchsia/engine/browser/frame_impl_browsertest.cc
@@ -73,7 +73,7 @@ // Navigates a |controller| to |url|, blocking until navigation is complete. void CheckLoadUrl(const std::string& url, const std::string& expected_title, - chromium::web::LoadUrlParams2 load_url_params, + chromium::web::LoadUrlParams load_url_params, chromium::web::NavigationController* controller) { base::RunLoop run_loop; EXPECT_CALL(navigation_observer_, @@ -81,7 +81,7 @@ Field(&NavigationDetails::title, expected_title), Field(&NavigationDetails::url, url)))) .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); - controller->LoadUrl2(url, std::move(load_url_params)); + controller->LoadUrl(url, std::move(load_url_params)); run_loop.Run(); Mock::VerifyAndClearExpectations(this); navigation_observer_.Acknowledge(); @@ -113,7 +113,7 @@ frame->GetNavigationController(controller.NewRequest()); CheckLoadUrl(url::kAboutBlankURL, url::kAboutBlankURL, - chromium::web::LoadUrlParams2(), controller.get()); + chromium::web::LoadUrlParams(), controller.get()); } // TODO(crbug.com/931831): Remove this test once the transition is complete. @@ -129,7 +129,7 @@ Field(&NavigationDetails::title, url::kAboutBlankURL), Field(&NavigationDetails::url, url::kAboutBlankURL)))) .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); - controller->LoadUrl(url::kAboutBlankURL, nullptr); + controller->LoadUrl2(url::kAboutBlankURL, chromium::web::LoadUrlParams2()); run_loop.Run(); Mock::VerifyAndClearExpectations(this); navigation_observer_.Acknowledge(); @@ -141,7 +141,7 @@ chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); - CheckLoadUrl(kDataUrl, kDataUrl, chromium::web::LoadUrlParams2(), + CheckLoadUrl(kDataUrl, kDataUrl, chromium::web::LoadUrlParams(), controller.get()); } @@ -160,7 +160,7 @@ chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); - controller->LoadUrl2(url::kAboutBlankURL, chromium::web::LoadUrlParams2()); + controller->LoadUrl(url::kAboutBlankURL, chromium::web::LoadUrlParams()); frame.Unbind(); run_loop.Run(); @@ -214,9 +214,9 @@ GURL title1(embedded_test_server()->GetURL(kPage1Path)); GURL title2(embedded_test_server()->GetURL(kPage2Path)); - CheckLoadUrl(title1.spec(), kPage1Title, chromium::web::LoadUrlParams2(), + CheckLoadUrl(title1.spec(), kPage1Title, chromium::web::LoadUrlParams(), controller.get()); - CheckLoadUrl(title2.spec(), kPage2Title, chromium::web::LoadUrlParams2(), + CheckLoadUrl(title2.spec(), kPage2Title, chromium::web::LoadUrlParams(), controller.get()); { @@ -268,7 +268,7 @@ GURL url(embedded_test_server()->GetURL(kPage1Path)); EXPECT_CALL(*this, OnServeHttpRequest(_)); - CheckLoadUrl(url.spec(), kPage1Title, chromium::web::LoadUrlParams2(), + CheckLoadUrl(url.spec(), kPage1Title, chromium::web::LoadUrlParams(), navigation_controller.get()); navigation_observer_.Observe( @@ -326,7 +326,7 @@ Field(&NavigationDetails::title, kPage1Title), Field(&NavigationDetails::url, IsSet())))) .WillOnce(testing::InvokeWithoutArgs([&run_loop] { run_loop.Quit(); })); - controller->LoadUrl(title1.spec(), nullptr); + controller->LoadUrl(title1.spec(), chromium::web::LoadUrlParams()); run_loop.Run(); navigation_observer_.Acknowledge(); } @@ -353,7 +353,7 @@ Field(&NavigationDetails::title, kPage2Title), Field(&NavigationDetails::url, IsSet())))) .WillOnce(testing::InvokeWithoutArgs([&run_loop] { run_loop.Quit(); })); - controller->LoadUrl(title2.spec(), nullptr); + controller->LoadUrl(title2.spec(), chromium::web::LoadUrlParams()); run_loop.Run(); navigation_observer_.Acknowledge(); } @@ -419,7 +419,7 @@ base::RunLoop run_loop; EXPECT_CALL(navigation_observer_, DidFinishLoad(_, title1)) .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); - controller->LoadUrl(title1.spec(), nullptr); + controller->LoadUrl(title1.spec(), chromium::web::LoadUrlParams()); run_loop.Run(); } @@ -427,7 +427,7 @@ base::RunLoop run_loop; EXPECT_CALL(navigation_observer_, DidFinishLoad(_, title2)) .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); - controller->LoadUrl(title2.spec(), nullptr); + controller->LoadUrl(title2.spec(), chromium::web::LoadUrlParams()); run_loop.Run(); } } @@ -442,7 +442,7 @@ chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); - CheckLoadUrl(title1.spec(), kPage1Title, chromium::web::LoadUrlParams2(), + CheckLoadUrl(title1.spec(), kPage1Title, chromium::web::LoadUrlParams(), controller.get()); std::vector<std::string> origins = {title1.GetOrigin().spec()}; @@ -477,7 +477,7 @@ chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); - CheckLoadUrl(url.spec(), "hello", chromium::web::LoadUrlParams2(), + CheckLoadUrl(url.spec(), "hello", chromium::web::LoadUrlParams(), controller.get()); } @@ -496,7 +496,7 @@ chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); - CheckLoadUrl(url.spec(), "hello", chromium::web::LoadUrlParams2(), + CheckLoadUrl(url.spec(), "hello", chromium::web::LoadUrlParams(), controller.get()); } @@ -519,7 +519,7 @@ // Expect that the original HTML title is used, because we didn't inject a // script with a replacement title. CheckLoadUrl(url.spec(), "Welcome to Stan the Offline Dino's Homepage", - chromium::web::LoadUrlParams2(), controller.get()); + chromium::web::LoadUrlParams(), controller.get()); } IN_PROC_BROWSER_TEST_F(FrameImplTest, ExecuteJavaScriptOnLoadWildcardOrigin) { @@ -538,16 +538,16 @@ // Test script injection for the origin 127.0.0.1. chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); - CheckLoadUrl(url.spec(), "hello", chromium::web::LoadUrlParams2(), + CheckLoadUrl(url.spec(), "hello", chromium::web::LoadUrlParams(), controller.get()); CheckLoadUrl(url::kAboutBlankURL, url::kAboutBlankURL, - chromium::web::LoadUrlParams2(), controller.get()); + chromium::web::LoadUrlParams(), controller.get()); // Test script injection using a different origin ("localhost"), which should // still be picked up by the wildcard. GURL alt_url = embedded_test_server()->GetURL("localhost", kDynamicTitlePath); - CheckLoadUrl(alt_url.spec(), "hello", chromium::web::LoadUrlParams2(), + CheckLoadUrl(alt_url.spec(), "hello", chromium::web::LoadUrlParams(), controller.get()); } @@ -571,7 +571,7 @@ chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); - CheckLoadUrl(url.spec(), "hello there", chromium::web::LoadUrlParams2(), + CheckLoadUrl(url.spec(), "hello there", chromium::web::LoadUrlParams(), controller.get()); } @@ -590,7 +590,7 @@ chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); - CheckLoadUrl(url.spec(), "hello", chromium::web::LoadUrlParams2(), + CheckLoadUrl(url.spec(), "hello", chromium::web::LoadUrlParams(), controller.get()); frame->ExecuteJavaScript( @@ -601,10 +601,10 @@ // Navigate away to clean the slate. CheckLoadUrl(url::kAboutBlankURL, url::kAboutBlankURL, - chromium::web::LoadUrlParams2(), controller.get()); + chromium::web::LoadUrlParams(), controller.get()); // Navigate back and see if both scripts are working. - CheckLoadUrl(url.spec(), "hello there", chromium::web::LoadUrlParams2(), + CheckLoadUrl(url.spec(), "hello there", chromium::web::LoadUrlParams(), controller.get()); } @@ -616,7 +616,7 @@ chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); - CheckLoadUrl(url.spec(), kPage1Title, chromium::web::LoadUrlParams2(), + CheckLoadUrl(url.spec(), kPage1Title, chromium::web::LoadUrlParams(), controller.get()); base::RunLoop run_loop; @@ -655,7 +655,7 @@ Field(&NavigationDetails::title, kPage1Title), Field(&NavigationDetails::url, IsSet())))) .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); - controller->LoadUrl(title1.spec(), nullptr); + controller->LoadUrl(title1.spec(), chromium::web::LoadUrlParams()); run_loop.Run(); } @@ -668,7 +668,7 @@ base::RunLoop run_loop; EXPECT_CALL(navigation_observer_, DidFinishLoad(_, title2)) .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); - controller->LoadUrl(title2.spec(), nullptr); + controller->LoadUrl(title2.spec(), chromium::web::LoadUrlParams()); run_loop.Run(); } } @@ -692,7 +692,7 @@ Field(&NavigationDetails::title, kPage1Title), Field(&NavigationDetails::url, IsSet())))) .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); - controller->LoadUrl(title1.spec(), nullptr); + controller->LoadUrl(title1.spec(), chromium::web::LoadUrlParams()); run_loop.Run(); Mock::VerifyAndClearExpectations(this); } @@ -707,7 +707,7 @@ base::RunLoop run_loop; EXPECT_CALL(navigation_observer_, DidFinishLoad(_, title2)) .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); - controller->LoadUrl(title2.spec(), nullptr); + controller->LoadUrl(title2.spec(), chromium::web::LoadUrlParams()); run_loop.Run(); Mock::VerifyAndClearExpectations(this); } @@ -717,7 +717,7 @@ base::RunLoop run_loop; EXPECT_CALL(navigation_observer_, DidFinishLoad(_, title1)) .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); - controller->LoadUrl(title1.spec(), nullptr); + controller->LoadUrl(title1.spec(), chromium::web::LoadUrlParams()); run_loop.Run(); Mock::VerifyAndClearExpectations(this); } @@ -763,7 +763,7 @@ base::RunLoop run_loop; EXPECT_CALL(observer, DidStartNavigation(_)) .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); - controller->LoadUrl(hung_url.spec(), nullptr); + controller->LoadUrl(hung_url.spec(), chromium::web::LoadUrlParams()); run_loop.Run(); Mock::VerifyAndClearExpectations(this); } @@ -794,7 +794,7 @@ chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); CheckLoadUrl(post_message_url.spec(), "postmessage", - chromium::web::LoadUrlParams2(), controller.get()); + chromium::web::LoadUrlParams(), controller.get()); chromium::web::WebMessage message; message.data = cr_fuchsia::MemBufferFromString(kPage1Path); @@ -823,7 +823,7 @@ chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); CheckLoadUrl(post_message_url.spec(), "messageport", - chromium::web::LoadUrlParams2(), controller.get()); + chromium::web::LoadUrlParams(), controller.get()); chromium::web::MessagePortPtr message_port; chromium::web::WebMessage msg; @@ -874,7 +874,7 @@ chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); CheckLoadUrl(post_message_url.spec(), "messageport", - chromium::web::LoadUrlParams2(), controller.get()); + chromium::web::LoadUrlParams(), controller.get()); chromium::web::MessagePortPtr message_port; chromium::web::WebMessage msg; @@ -904,7 +904,7 @@ base::RunLoop run_loop; message_port.set_error_handler( [&run_loop](zx_status_t) { run_loop.Quit(); }); - controller->LoadUrl(url::kAboutBlankURL, nullptr); + controller->LoadUrl(url::kAboutBlankURL, chromium::web::LoadUrlParams()); run_loop.Run(); } } @@ -921,7 +921,7 @@ chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); CheckLoadUrl(post_message_url.spec(), "messageport", - chromium::web::LoadUrlParams2(), controller.get()); + chromium::web::LoadUrlParams(), controller.get()); chromium::web::MessagePortPtr incoming_message_port; chromium::web::WebMessage msg; @@ -1007,7 +1007,7 @@ chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); CheckLoadUrl(post_message_url.spec(), "messageport", - chromium::web::LoadUrlParams2(), controller.get()); + chromium::web::LoadUrlParams(), controller.get()); chromium::web::MessagePortPtr bad_origin_incoming_message_port; chromium::web::WebMessage msg; @@ -1073,7 +1073,7 @@ // Verify that the Frame can navigate, prior to the View being created. const GURL page1_url(embedded_test_server()->GetURL(kPage1Path)); - CheckLoadUrl(page1_url.spec(), kPage1Title, chromium::web::LoadUrlParams2(), + CheckLoadUrl(page1_url.spec(), kPage1Title, chromium::web::LoadUrlParams(), controller.get()); // Request a View from the Frame, and pump the loop to process the request. @@ -1085,7 +1085,7 @@ // Verify that the Frame still works, by navigating to Page #2. const GURL page2_url(embedded_test_server()->GetURL(kPage2Path)); - CheckLoadUrl(page2_url.spec(), kPage2Title, chromium::web::LoadUrlParams2(), + CheckLoadUrl(page2_url.spec(), kPage2Title, chromium::web::LoadUrlParams(), controller.get()); // Create new View tokens and request a new view. @@ -1096,7 +1096,7 @@ EXPECT_TRUE(frame_impl->has_view_for_test()); // Verify that the Frame still works, by navigating back to Page #1. - CheckLoadUrl(page1_url.spec(), kPage1Title, chromium::web::LoadUrlParams2(), + CheckLoadUrl(page1_url.spec(), kPage1Title, chromium::web::LoadUrlParams(), controller.get()); } @@ -1148,7 +1148,7 @@ IN_PROC_BROWSER_TEST_F(RequestMonitoringFrameImplBrowserTest, ExtraHeaders) { chromium::web::FramePtr frame = CreateFrame(); - chromium::web::LoadUrlParams2 load_url_params; + chromium::web::LoadUrlParams load_url_params; load_url_params.set_headers({StringToUnsignedVector("X-ExtraHeaders: 1"), StringToUnsignedVector("X-2ExtraHeaders: 2")}); @@ -1175,12 +1175,9 @@ DeprecatedExtraHeaders) { chromium::web::FramePtr frame = CreateFrame(); - chromium::web::LoadUrlParamsPtr load_url_params = - chromium::web::LoadUrlParams::New(); - load_url_params->headers.push_back( - StringToUnsignedVector("X-ExtraHeaders: 1")); - load_url_params->headers.push_back( - StringToUnsignedVector("X-2ExtraHeaders: 2")); + chromium::web::LoadUrlParams2 load_url_params; + load_url_params.set_headers({StringToUnsignedVector("X-ExtraHeaders: 1"), + StringToUnsignedVector("X-2ExtraHeaders: 2")}); chromium::web::NavigationControllerPtr controller; frame->GetNavigationController(controller.NewRequest()); @@ -1193,7 +1190,7 @@ Field(&NavigationDetails::title, kPage1Title), Field(&NavigationDetails::url, page_url.spec())))) .WillOnce(InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); - controller->LoadUrl(page_url.spec(), std::move(load_url_params)); + controller->LoadUrl2(page_url.spec(), std::move(load_url_params)); run_loop.Run(); Mock::VerifyAndClearExpectations(this); navigation_observer_.Acknowledge();
diff --git a/fuchsia/engine/context_provider_impl.cc b/fuchsia/engine/context_provider_impl.cc index fc471f0d..deb06da 100644 --- a/fuchsia/engine/context_provider_impl.cc +++ b/fuchsia/engine/context_provider_impl.cc
@@ -54,23 +54,6 @@ void ContextProviderImpl::Create( chromium::web::CreateContextParams params, - ::fidl::InterfaceRequest<chromium::web::Context> context_request) { - chromium::web::CreateContextParams2 converted_params; - - converted_params.set_service_directory( - fidl::InterfaceHandle<fuchsia::io::Directory>( - std::move(params.service_directory))); - - if (params.data_directory) { - converted_params.set_data_directory( - fidl::InterfaceHandle<fuchsia::io::Directory>( - std::move(params.data_directory))); - } - Create2(std::move(converted_params), std::move(context_request)); -} - -void ContextProviderImpl::Create2( - chromium::web::CreateContextParams2 params, fidl::InterfaceRequest<chromium::web::Context> context_request) { if (!context_request.is_valid()) { // TODO(crbug.com/934539): Add type epitaph. @@ -80,7 +63,7 @@ if (!params.has_service_directory()) { // TODO(crbug.com/934539): Add type epitaph. DLOG(WARNING) - << "Missing argument |service_directory| in CreateContextParams2."; + << "Missing argument |service_directory| in CreateContextParams."; return; } @@ -104,7 +87,7 @@ if (data_directory_channel.get() == ZX_HANDLE_INVALID) { // TODO(crbug.com/934539): Add type epitaph. DLOG(WARNING) - << "Invalid argument |data_directory| in CreateContextParams2."; + << "Invalid argument |data_directory| in CreateContextParams."; return; } @@ -139,6 +122,21 @@ ignore_result(context_handle.release()); } +void ContextProviderImpl::Create2( + chromium::web::CreateContextParams2 params, + ::fidl::InterfaceRequest<chromium::web::Context> context_request) { + chromium::web::CreateContextParams converted_params; + if (params.has_service_directory()) { + converted_params.set_service_directory( + std::move(*params.mutable_service_directory())); + } + if (params.has_data_directory()) { + converted_params.set_data_directory( + std::move(*params.mutable_data_directory())); + } + Create(std::move(converted_params), std::move(context_request)); +} + void ContextProviderImpl::Bind( fidl::InterfaceRequest<chromium::web::ContextProvider> request) { bindings_.AddBinding(this, std::move(request));
diff --git a/fuchsia/engine/context_provider_impl_unittest.cc b/fuchsia/engine/context_provider_impl_unittest.cc index ab1820e..9b3d3a4 100644 --- a/fuchsia/engine/context_provider_impl_unittest.cc +++ b/fuchsia/engine/context_provider_impl_unittest.cc
@@ -145,7 +145,20 @@ EXPECT_EQ(change_observer.captured_event().title, kTitle); } - chromium::web::CreateContextParams2 BuildCreateContextParams() { + chromium::web::CreateContextParams BuildCreateContextParams() { + fidl::InterfaceHandle<fuchsia::io::Directory> directory; + zx_status_t result = + fdio_service_connect(base::fuchsia::kServiceDirectoryPath, + directory.NewRequest().TakeChannel().release()); + ZX_CHECK(result == ZX_OK, result) << "Failed to open /svc"; + + chromium::web::CreateContextParams output; + output.set_service_directory(std::move(directory)); + return output; + } + + // TODO(crbug.com/931831): Remove this method once the transition is complete. + chromium::web::CreateContextParams2 BuildDeprecatedCreateContextParams() { fidl::InterfaceHandle<fuchsia::io::Directory> directory; zx_status_t result = fdio_service_connect(base::fuchsia::kServiceDirectoryPath, @@ -157,22 +170,6 @@ return output; } - // TODO(crbug.com/931831): Remove this method once the transition is complete. - chromium::web::CreateContextParams BuildDeprecatedCreateContextParams() { - zx::channel client_channel; - zx::channel server_channel; - zx_status_t result = - zx::channel::create(0, &client_channel, &server_channel); - ZX_CHECK(result == ZX_OK, result) << "zx_channel_create()"; - result = fdio_service_connect(base::fuchsia::kServiceDirectoryPath, - server_channel.release()); - ZX_CHECK(result == ZX_OK, result) << "Failed to open /svc"; - - chromium::web::CreateContextParams output; - output.service_directory = std::move(client_channel); - return output; - } - // Checks that the Context channel was dropped. void CheckContextUnresponsive( fidl::InterfacePtr<chromium::web::Context>* context) { @@ -222,9 +219,8 @@ TEST_F(ContextProviderImplTest, LaunchContext) { // Connect to a new context process. fidl::InterfacePtr<chromium::web::Context> context; - chromium::web::CreateContextParams2 create_params = - BuildCreateContextParams(); - provider_ptr_->Create2(std::move(create_params), context.NewRequest()); + chromium::web::CreateContextParams create_params = BuildCreateContextParams(); + provider_ptr_->Create(std::move(create_params), context.NewRequest()); CheckContextResponsive(&context); } @@ -232,9 +228,9 @@ TEST_F(ContextProviderImplTest, DeprecatedLaunchContext) { // Connect to a new context process. fidl::InterfacePtr<chromium::web::Context> context; - chromium::web::CreateContextParams create_params = + chromium::web::CreateContextParams2 create_params = BuildDeprecatedCreateContextParams(); - provider_ptr_->Create(std::move(create_params), context.NewRequest()); + provider_ptr_->Create2(std::move(create_params), context.NewRequest()); CheckContextResponsive(&context); } @@ -243,13 +239,13 @@ chromium::web::ContextProviderPtr provider_1_ptr; provider_->Bind(provider_1_ptr.NewRequest()); chromium::web::ContextPtr context_1; - provider_1_ptr->Create2(BuildCreateContextParams(), context_1.NewRequest()); + provider_1_ptr->Create(BuildCreateContextParams(), context_1.NewRequest()); // Do the same on another Provider connection. chromium::web::ContextProviderPtr provider_2_ptr; provider_->Bind(provider_2_ptr.NewRequest()); chromium::web::ContextPtr context_2; - provider_2_ptr->Create2(BuildCreateContextParams(), context_2.NewRequest()); + provider_2_ptr->Create(BuildCreateContextParams(), context_2.NewRequest()); CheckContextResponsive(&context_1); CheckContextResponsive(&context_2); @@ -257,7 +253,7 @@ // Ensure that the initial ContextProvider connection is still usable, by // creating and verifying another Context from it. chromium::web::ContextPtr context_3; - provider_2_ptr->Create2(BuildCreateContextParams(), context_3.NewRequest()); + provider_2_ptr->Create(BuildCreateContextParams(), context_3.NewRequest()); CheckContextResponsive(&context_3); } @@ -266,8 +262,39 @@ // Connect to a new context process. fidl::InterfacePtr<chromium::web::Context> context; + chromium::web::CreateContextParams create_params = BuildCreateContextParams(); + + // Setup data dir. + EXPECT_TRUE(profile_temp_dir.CreateUniqueTempDir()); + ASSERT_EQ( + base::WriteFile(profile_temp_dir.GetPath().AppendASCII(kTestDataFileIn), + nullptr, 0), + 0); + + // Pass a handle data dir to the context. + create_params.set_data_directory( + fidl::InterfaceHandle<fuchsia::io::Directory>( + zx::channel(base::fuchsia::GetHandleFromFile( + base::File(profile_temp_dir.GetPath(), + base::File::FLAG_OPEN | base::File::FLAG_READ))))); + + provider_ptr_->Create(std::move(create_params), context.NewRequest()); + + CheckContextResponsive(&context); + + // Verify that the context process can write to the data dir. + EXPECT_TRUE(base::PathExists( + profile_temp_dir.GetPath().AppendASCII(kTestDataFileOut))); +} + +// TODO(crbug.com/931831): Remove this test once the transition is complete. +TEST_F(ContextProviderImplTest, DeprecatedWithProfileDir) { + base::ScopedTempDir profile_temp_dir; + + // Connect to a new context process. + fidl::InterfacePtr<chromium::web::Context> context; chromium::web::CreateContextParams2 create_params = - BuildCreateContextParams(); + BuildDeprecatedCreateContextParams(); // Setup data dir. EXPECT_TRUE(profile_temp_dir.CreateUniqueTempDir()); @@ -292,45 +319,12 @@ profile_temp_dir.GetPath().AppendASCII(kTestDataFileOut))); } -// TODO(crbug.com/931831): Remove this test once the transition is complete. -TEST_F(ContextProviderImplTest, DeprecatedWithProfileDir) { - base::ScopedTempDir profile_temp_dir; - - // Connect to a new context process. - fidl::InterfacePtr<chromium::web::Context> context; - chromium::web::CreateContextParams create_params = - BuildDeprecatedCreateContextParams(); - - // Setup data dir. - EXPECT_TRUE(profile_temp_dir.CreateUniqueTempDir()); - ASSERT_EQ( - base::WriteFile(profile_temp_dir.GetPath().AppendASCII(kTestDataFileIn), - nullptr, 0), - 0); - - // Pass a handle data dir to the context. - create_params.data_directory.reset( - base::fuchsia::GetHandleFromFile( - base::File(profile_temp_dir.GetPath(), - base::File::FLAG_OPEN | base::File::FLAG_READ)) - .release()); - - provider_ptr_->Create(std::move(create_params), context.NewRequest()); - - CheckContextResponsive(&context); - - // Verify that the context process can write to the data dir. - EXPECT_TRUE(base::PathExists( - profile_temp_dir.GetPath().AppendASCII(kTestDataFileOut))); -} - TEST_F(ContextProviderImplTest, FailsDataDirectoryIsFile) { base::FilePath temp_file_path; // Connect to a new context process. fidl::InterfacePtr<chromium::web::Context> context; - chromium::web::CreateContextParams2 create_params = - BuildCreateContextParams(); + chromium::web::CreateContextParams create_params = BuildCreateContextParams(); // Pass in a handle to a file instead of a directory. CHECK(base::CreateTemporaryFile(&temp_file_path)); @@ -340,7 +334,7 @@ base::File(temp_file_path, base::File::FLAG_OPEN | base::File::FLAG_READ))))); - provider_ptr_->Create2(std::move(create_params), context.NewRequest()); + provider_ptr_->Create(std::move(create_params), context.NewRequest()); CheckContextUnresponsive(&context); } @@ -370,7 +364,7 @@ // Create a Context and verify that it is functional. chromium::web::ContextPtr context; - provider->Create2(BuildCreateContextParams(), context.NewRequest()); + provider->Create(BuildCreateContextParams(), context.NewRequest()); CheckContextResponsive(&context); // Verify that there is at least one job under our default job.
diff --git a/fuchsia/fidl/web/context_provider.fidl b/fuchsia/fidl/web/context_provider.fidl index af22a09..1092d64 100644 --- a/fuchsia/fidl/web/context_provider.fidl +++ b/fuchsia/fidl/web/context_provider.fidl
@@ -15,25 +15,25 @@ /// /// context: An interface request which will receive a bound Context /// service. - // DEPRECATED Use Create2 instead. Create(CreateContextParams params, request<Context> context); + // DEPRECATED Use Create instead. Create2(CreateContextParams2 params, request<Context> context); }; -// DEPRECATED Use CreateContextParams2 instead. -struct CreateContextParams { +table CreateContextParams { /// Service directory to be used by the context. // TODO(https://crbug.com/870057): Document required and optional services // that Context needs. - handle<channel> service_directory; + 1: fuchsia.io.Directory service_directory; /// Handle to the directory that will contain the Context's /// persistent data. If it is left unset, then the created Context will be /// stateless, with all of its data discarded upon Context destruction. - handle<channel>? data_directory; + 2: fuchsia.io.Directory data_directory; }; +// DEPRECATED Use CreateContextParams instead. table CreateContextParams2 { /// Service directory to be used by the context. // TODO(https://crbug.com/870057): Document required and optional services
diff --git a/fuchsia/fidl/web/navigation_controller.fidl b/fuchsia/fidl/web/navigation_controller.fidl index 674afb5..eb3e149 100644 --- a/fuchsia/fidl/web/navigation_controller.fidl +++ b/fuchsia/fidl/web/navigation_controller.fidl
@@ -12,9 +12,9 @@ /// |url|: The address to navigate to. /// |params|: Additional parameters that affect how the resource will be /// loaded (e.g. cookies, HTTP headers, etc.) - // DEPRECATED Use LoadUrl2 instead. - LoadUrl(string url, LoadUrlParams? params); + LoadUrl(string url, LoadUrlParams params); + // DEPRECATED Use LoadUrl instead. LoadUrl2(string url, LoadUrlParams2 params); GoBack(); @@ -28,25 +28,25 @@ }; /// Additional parameters for modifying the behavior of LoadUrl(). -// DEPRECATED Use LoadUrlParams2 instead. -struct LoadUrlParams { +table LoadUrlParams { /// Provides a hint to the browser UI about how LoadUrl was triggered. - LoadUrlReason type; + 1: LoadUrlReason type; /// The URL that linked to the resource being requested. - string referrer; + 2: string referrer_url; /// Should be set to true to propagate user activation to the frame. User /// activation implies that the user is interacting with the web frame. It /// enables some web features that are not available otherwise. For example /// autoplay will work only when this flag is set to true. - bool user_activated = false; + 3: bool was_user_activated; /// Custom HTTP headers. - vector<bytes> headers; + 4: vector<bytes> headers; }; /// Additional parameters for modifying the behavior of LoadUrl(). +// DEPRECATED Use LoadUrlParams instead. table LoadUrlParams2 { /// Provides a hint to the browser UI about how LoadUrl was triggered. 1: LoadUrlReason type;
diff --git a/fuchsia/runners/cast/cast_channel_bindings_browsertest.cc b/fuchsia/runners/cast/cast_channel_bindings_browsertest.cc index 59ebab8..a2869d0 100644 --- a/fuchsia/runners/cast/cast_channel_bindings_browsertest.cc +++ b/fuchsia/runners/cast/cast_channel_bindings_browsertest.cc
@@ -102,7 +102,7 @@ void CheckLoadUrl(const std::string& url, chromium::web::NavigationController* controller) { navigate_run_loop_ = std::make_unique<base::RunLoop>(); - controller->LoadUrl(url, nullptr); + controller->LoadUrl(url, chromium::web::LoadUrlParams()); navigate_run_loop_->Run(); navigate_run_loop_.reset(); }
diff --git a/fuchsia/runners/cast/named_message_port_connector_browsertest.cc b/fuchsia/runners/cast/named_message_port_connector_browsertest.cc index 90c918d6..4263679d 100644 --- a/fuchsia/runners/cast/named_message_port_connector_browsertest.cc +++ b/fuchsia/runners/cast/named_message_port_connector_browsertest.cc
@@ -56,7 +56,7 @@ void CheckLoadUrl(const std::string& url, chromium::web::NavigationController* controller) { navigate_run_loop_ = std::make_unique<base::RunLoop>(); - controller->LoadUrl(url, nullptr); + controller->LoadUrl(url, chromium::web::LoadUrlParams()); navigate_run_loop_->Run(); navigate_run_loop_.reset(); } @@ -118,7 +118,7 @@ (*message_port).set_error_handler([&run_loop](zx_status_t) { run_loop.Quit(); }); - controller->LoadUrl("about:blank", nullptr); + controller->LoadUrl("about:blank", chromium::web::LoadUrlParams()); run_loop.Run(); }
diff --git a/fuchsia/runners/cast/queryable_data_bindings_browsertest.cc b/fuchsia/runners/cast/queryable_data_bindings_browsertest.cc index 821dbad3..1d6ee45b 100644 --- a/fuchsia/runners/cast/queryable_data_bindings_browsertest.cc +++ b/fuchsia/runners/cast/queryable_data_bindings_browsertest.cc
@@ -34,7 +34,7 @@ void CheckLoadUrl(const std::string& url, chromium::web::NavigationController* controller) { navigate_run_loop_ = std::make_unique<base::RunLoop>(); - controller->LoadUrl(url, nullptr); + controller->LoadUrl(url, chromium::web::LoadUrlParams()); navigate_run_loop_->Run(); navigate_run_loop_.reset(); }
diff --git a/fuchsia/runners/common/web_component.cc b/fuchsia/runners/common/web_component.cc index 8981749..2445e96 100644 --- a/fuchsia/runners/common/web_component.cc +++ b/fuchsia/runners/common/web_component.cc
@@ -27,10 +27,10 @@ // Set the page activation flag on the initial load, so that features like // autoplay work as expected when a WebComponent first loads the specified // content. - chromium::web::LoadUrlParams2 params; + chromium::web::LoadUrlParams params; params.set_was_user_activated(true); - navigation_controller->LoadUrl2(url.spec(), std::move(params)); + navigation_controller->LoadUrl(url.spec(), std::move(params)); } WebComponent::WebComponent(
diff --git a/ios/chrome/browser/autofill/autofill_tab_helper.h b/ios/chrome/browser/autofill/autofill_tab_helper.h index 7d0f53e..70499011 100644 --- a/ios/chrome/browser/autofill/autofill_tab_helper.h +++ b/ios/chrome/browser/autofill/autofill_tab_helper.h
@@ -20,7 +20,7 @@ } namespace password_manager { -class PasswordGenerationManager; +class PasswordManager; } namespace ios { @@ -36,7 +36,7 @@ // Create an AutofillTabHelper and attaches it to the given |web_state|. static void CreateForWebState( web::WebState* web_state, - password_manager::PasswordGenerationManager* password_generation_manager); + password_manager::PasswordManager* password_manager); // Sets a weak reference to the view controller used to present UI. void SetBaseViewController(UIViewController* base_view_controller); @@ -47,9 +47,8 @@ private: friend class web::WebStateUserData<AutofillTabHelper>; - AutofillTabHelper( - web::WebState* web_state, - password_manager::PasswordGenerationManager* password_generation_manager); + AutofillTabHelper(web::WebState* web_state, + password_manager::PasswordManager* password_manager); // web::WebStateObserver implementation. void WebStateDestroyed(web::WebState* web_state) override;
diff --git a/ios/chrome/browser/autofill/autofill_tab_helper.mm b/ios/chrome/browser/autofill/autofill_tab_helper.mm index 9c5e96a..9fa3d86 100644 --- a/ios/chrome/browser/autofill/autofill_tab_helper.mm +++ b/ios/chrome/browser/autofill/autofill_tab_helper.mm
@@ -22,12 +22,12 @@ // static void AutofillTabHelper::CreateForWebState( web::WebState* web_state, - password_manager::PasswordGenerationManager* password_generation_manager) { + password_manager::PasswordManager* password_manager) { DCHECK(web_state); if (!FromWebState(web_state)) { - web_state->SetUserData(UserDataKey(), - base::WrapUnique(new AutofillTabHelper( - web_state, password_generation_manager))); + web_state->SetUserData( + UserDataKey(), + base::WrapUnique(new AutofillTabHelper(web_state, password_manager))); } } @@ -42,7 +42,7 @@ AutofillTabHelper::AutofillTabHelper( web::WebState* web_state, - password_manager::PasswordGenerationManager* password_generation_manager) + password_manager::PasswordManager* password_manager) : browser_state_(ios::ChromeBrowserState::FromBrowserState( web_state->GetBrowserState())), autofill_agent_([[AutofillAgent alloc] @@ -55,7 +55,7 @@ DCHECK(infobar_manager); autofill_client_ = std::make_unique<autofill::ChromeAutofillClientIOS>( browser_state_, web_state, infobar_manager, autofill_agent_, - password_generation_manager); + password_manager); autofill::AutofillDriverIOS::PrepareForWebStateWebFrameAndDelegate( web_state, autofill_client_.get(), autofill_agent_,
diff --git a/ios/chrome/browser/ntp/new_tab_page_tab_helper.h b/ios/chrome/browser/ntp/new_tab_page_tab_helper.h index 2dd7d31..64190844 100644 --- a/ios/chrome/browser/ntp/new_tab_page_tab_helper.h +++ b/ios/chrome/browser/ntp/new_tab_page_tab_helper.h
@@ -15,6 +15,10 @@ @protocol NewTabPageTabHelperDelegate; +namespace web { +class NavigationItem; +} + // NewTabPageTabHelper which manages a single NTP per tab. class NewTabPageTabHelper : public web::WebStateObserver, public web::WebStateUserData<NewTabPageTabHelper> { @@ -58,7 +62,7 @@ // Sets the NTP's NavigationItem title and virtualURL to the appropriate // string and chrome://newtab respectively. - void UpdatePendingItem(); + void UpdateItem(web::NavigationItem* item); // Returns true if an |url| is either chrome://newtab or about://newtab. bool IsNTPURL(const GURL& url);
diff --git a/ios/chrome/browser/ntp/new_tab_page_tab_helper.mm b/ios/chrome/browser/ntp/new_tab_page_tab_helper.mm index 7dc646b..1f5bb72d 100644 --- a/ios/chrome/browser/ntp/new_tab_page_tab_helper.mm +++ b/ios/chrome/browser/ntp/new_tab_page_tab_helper.mm
@@ -61,7 +61,7 @@ active_ = IsNTPURL(web_state->GetVisibleURL()); if (active_) { - UpdatePendingItem(); + UpdateItem(web_state_->GetNavigationManager()->GetPendingItem()); [delegate_ newTabPageHelperDidChangeVisibility:this forWebState:web_state_]; // If about://newtab is currently loading but has not yet committed, block @@ -120,7 +120,7 @@ web::WebState* web_state, web::NavigationContext* navigation_context) { if (IsNTPURL(navigation_context->GetUrl())) { - UpdatePendingItem(); + UpdateItem(web_state_->GetNavigationManager()->GetPendingItem()); } else { SetActive(false); } @@ -129,10 +129,12 @@ void NewTabPageTabHelper::DidFinishNavigation( web::WebState* web_state, web::NavigationContext* navigation_context) { - if (navigation_context->IsSameDocument()) { + if (navigation_context->IsSameDocument() || + !navigation_context->HasCommitted()) { return; } + UpdateItem(web_state_->GetNavigationManager()->GetLastCommittedItem()); DisableIgnoreLoadRequests(); SetActive(IsNTPURL(web_state->GetLastCommittedURL())); } @@ -149,10 +151,8 @@ } } -void NewTabPageTabHelper::UpdatePendingItem() { - web::NavigationManager* manager = web_state_->GetNavigationManager(); - web::NavigationItem* item = manager->GetPendingItem(); - if (item) { +void NewTabPageTabHelper::UpdateItem(web::NavigationItem* item) { + if (item && item->GetURL() == GURL(kChromeUIAboutNewTabURL)) { item->SetVirtualURL(GURL(kChromeUINewTabURL)); item->SetTitle(l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE)); }
diff --git a/ios/chrome/browser/ntp/new_tab_page_tab_helper_unittest.mm b/ios/chrome/browser/ntp/new_tab_page_tab_helper_unittest.mm index 039b920..6a59e9a 100644 --- a/ios/chrome/browser/ntp/new_tab_page_tab_helper_unittest.mm +++ b/ios/chrome/browser/ntp/new_tab_page_tab_helper_unittest.mm
@@ -63,6 +63,7 @@ std::make_unique<web::TestNavigationManager>(); test_navigation_manager_ = test_navigation_manager.get(); pending_item_ = web::NavigationItem::Create(); + pending_item_->SetURL(GURL(kChromeUIAboutNewTabURL)); test_navigation_manager->SetPendingItem(pending_item_.get()); test_web_state_.SetNavigationManager(std::move(test_navigation_manager)); test_web_state_.SetBrowserState(chrome_browser_state_.get()); @@ -138,6 +139,7 @@ GURL url(kChromeUINewTabURL); test_web_state_.SetCurrentURL(url); web::FakeNavigationContext context; + context.SetHasCommitted(true); context.SetUrl(url); test_web_state_.OnNavigationFinished(&context); EXPECT_TRUE(tab_helper()->IsActive()); @@ -162,3 +164,28 @@ test_web_state_.OnNavigationFinished(&context); EXPECT_FALSE(tab_helper()->IsActive()); } + +// Tests double navigations from an NTP and non-NTP page at the same time. +TEST_F(NewTabPageTabHelperTest, TestMismatchedPendingItem) { + base::test::ScopedFeatureList scoped_feature_list_; + scoped_feature_list_.InitAndEnableFeature(kBrowserContainerContainsNTP); + + // Test an NTP url with a mismatched pending item. + GURL url(kChromeUINewTabURL); + GURL not_ntp_url(kTestURL); + test_web_state_.SetCurrentURL(url); + pending_item_->SetURL(not_ntp_url); + CreateTabHelper(); + // In this edge case, although the NTP is visible, the pending item is not + // incorrectly updated + EXPECT_EQ(GURL(kTestURL), pending_item_->GetVirtualURL()); + + // On commit, the web state url is correct, and the NTP is inactive. + web::FakeNavigationContext context; + context.SetHasCommitted(true); + context.SetUrl(not_ntp_url); + test_web_state_.SetCurrentURL(not_ntp_url); + test_web_state_.OnNavigationFinished(&context); + EXPECT_FALSE(tab_helper()->IsActive()); + EXPECT_EQ(GURL(kTestURL), pending_item_->GetVirtualURL()); +}
diff --git a/ios/chrome/browser/passwords/password_tab_helper.h b/ios/chrome/browser/passwords/password_tab_helper.h index d4d38ba3..02d5f9d3 100644 --- a/ios/chrome/browser/passwords/password_tab_helper.h +++ b/ios/chrome/browser/passwords/password_tab_helper.h
@@ -19,6 +19,7 @@ namespace password_manager { class PasswordGenerationManager; +class PasswordManager; } // Class binding a PasswordController to a WebState. @@ -55,6 +56,9 @@ // Returns the PasswordGenerationManager owned by the PasswordController. password_manager::PasswordGenerationManager* GetPasswordGenerationManager(); + // Returns the PasswordManager owned by the PasswordController. + password_manager::PasswordManager* GetPasswordManager(); + private: friend class web::WebStateUserData<PasswordTabHelper>;
diff --git a/ios/chrome/browser/passwords/password_tab_helper.mm b/ios/chrome/browser/passwords/password_tab_helper.mm index a9fae3d..11f0355 100644 --- a/ios/chrome/browser/passwords/password_tab_helper.mm +++ b/ios/chrome/browser/passwords/password_tab_helper.mm
@@ -60,6 +60,10 @@ return controller_.passwordGenerationManager; } +password_manager::PasswordManager* PasswordTabHelper::GetPasswordManager() { + return controller_.passwordManager; +} + PasswordTabHelper::PasswordTabHelper(web::WebState* web_state) : controller_([[PasswordController alloc] initWithWebState:web_state]) { web_state->AddObserver(this);
diff --git a/ios/chrome/browser/tabs/tab_helper_util.mm b/ios/chrome/browser/tabs/tab_helper_util.mm index db87f14..e23b5874 100644 --- a/ios/chrome/browser/tabs/tab_helper_util.mm +++ b/ios/chrome/browser/tabs/tab_helper_util.mm
@@ -122,8 +122,8 @@ PasswordTabHelper::CreateForWebState(web_state); AutofillTabHelper::CreateForWebState( - web_state, PasswordTabHelper::FromWebState(web_state) - ->GetPasswordGenerationManager()); + web_state, + PasswordTabHelper::FromWebState(web_state)->GetPasswordManager()); // Depends on favicon::WebFaviconDriver, must be created after it. if (base::FeatureList::IsEnabled(kCustomSearchEngines)) {
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h index 98e1345..b14db696 100644 --- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h +++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h
@@ -21,7 +21,7 @@ #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #import "components/autofill/ios/browser/autofill_client_ios_bridge.h" #include "components/infobars/core/infobar_manager.h" -#include "components/password_manager/core/browser/password_generation_manager.h" +#include "components/password_manager/core/browser/password_manager.h" #include "components/prefs/pref_service.h" #include "components/sync/driver/sync_service.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" @@ -34,12 +34,11 @@ // Chrome iOS implementation of AutofillClient. class ChromeAutofillClientIOS : public AutofillClient { public: - ChromeAutofillClientIOS( - ios::ChromeBrowserState* browser_state, - web::WebState* web_state, - infobars::InfoBarManager* infobar_manager, - id<AutofillClientIOSBridge> bridge, - password_manager::PasswordGenerationManager* password_generation_manager); + ChromeAutofillClientIOS(ios::ChromeBrowserState* browser_state, + web::WebState* web_state, + infobars::InfoBarManager* infobar_manager, + id<AutofillClientIOSBridge> bridge, + password_manager::PasswordManager* password_manager); ~ChromeAutofillClientIOS() override; // Sets a weak reference to the view controller used to present UI. @@ -132,7 +131,7 @@ std::unique_ptr<FormDataImporter> form_data_importer_; scoped_refptr<AutofillWebDataService> autofill_web_data_service_; infobars::InfoBarManager* infobar_manager_; - password_manager::PasswordGenerationManager* password_generation_manager_; + password_manager::PasswordManager* password_manager_; CardUnmaskPromptControllerImpl unmask_controller_; // A weak reference to the view controller used to present UI.
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm index 050b642..b3bedae0 100644 --- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm +++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
@@ -66,7 +66,7 @@ web::WebState* web_state, infobars::InfoBarManager* infobar_manager, id<AutofillClientIOSBridge> bridge, - password_manager::PasswordGenerationManager* password_generation_manager) + password_manager::PasswordManager* password_manager) : pref_service_(browser_state->GetPrefs()), sync_service_( ProfileSyncServiceFactory::GetForBrowserState(browser_state)), @@ -92,7 +92,7 @@ personal_data_manager_, GetApplicationContext()->GetApplicationLocale())), infobar_manager_(infobar_manager), - password_generation_manager_(password_generation_manager), + password_manager_(password_manager), unmask_controller_(browser_state->GetPrefs(), browser_state->IsOffTheRecord()) {} @@ -319,9 +319,7 @@ void ChromeAutofillClientIOS::PropagateAutofillPredictions( content::RenderFrameHost* rfh, const std::vector<FormStructure*>& forms) { - if (password_generation_manager_) { - password_generation_manager_->DetectFormsEligibleForGeneration(forms); - } + password_manager_->ProcessAutofillPredictions(/*driver=*/nullptr, forms); } void ChromeAutofillClientIOS::DidFillOrPreviewField(
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_item.h b/ios/chrome/browser/ui/table_view/cells/table_view_text_item.h index 140deb9..07e62f5 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_item.h +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_item.h
@@ -13,7 +13,7 @@ // TableViewTextItem contains the model data for a TableViewTextCell. @interface TableViewTextItem : TableViewItem -// Text Alignment for the cell's textLabel. Default is NSTextAlignmentLeft. +// Text Alignment for the cell's textLabel. Default is NSTextAlignmentNatural. @property(nonatomic, assign) NSTextAlignment textAlignment; // UIColor for the cell's textLabel. Default is
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm index 558d546a..8d3ab38 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_text_item.mm
@@ -66,7 +66,7 @@ UIColorFromRGB(kTableViewTextLabelColorLightGrey); } cell.textLabel.textAlignment = - self.textAlignment ? self.textAlignment : NSTextAlignmentLeft; + self.textAlignment ? self.textAlignment : NSTextAlignmentNatural; cell.userInteractionEnabled = self.enabled; }
diff --git a/ios/net/cookies/cookie_store_ios_test_util.h b/ios/net/cookies/cookie_store_ios_test_util.h index 4c71e8a..74c51e4 100644 --- a/ios/net/cookies/cookie_store_ios_test_util.h +++ b/ios/net/cookies/cookie_store_ios_test_util.h
@@ -44,7 +44,7 @@ void UpdateCookieAccessTime(const net::CanonicalCookie& cc) override; void DeleteCookie(const net::CanonicalCookie& cc) override; void SetForceKeepSessionState() override; - void SetBeforeFlushCallback(base::RepeatingClosure callback) override; + void SetBeforeCommitCallback(base::RepeatingClosure callback) override; void Flush(base::OnceClosure callback) override; ~TestPersistentCookieStore() override;
diff --git a/ios/net/cookies/cookie_store_ios_test_util.mm b/ios/net/cookies/cookie_store_ios_test_util.mm index 426c0527..a0ef382 100644 --- a/ios/net/cookies/cookie_store_ios_test_util.mm +++ b/ios/net/cookies/cookie_store_ios_test_util.mm
@@ -84,7 +84,7 @@ void TestPersistentCookieStore::SetForceKeepSessionState() {} -void TestPersistentCookieStore::SetBeforeFlushCallback( +void TestPersistentCookieStore::SetBeforeCommitCallback( base::RepeatingClosure callback) {} void TestPersistentCookieStore::Flush(base::OnceClosure callback) {
diff --git a/media/base/android/BUILD.gn b/media/base/android/BUILD.gn index 2e10ae7f..4cb3722 100644 --- a/media/base/android/BUILD.gn +++ b/media/base/android/BUILD.gn
@@ -170,7 +170,7 @@ deps = [ ":media_java_resources", "//base:base_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] srcjar_deps = [ ":java_enums",
diff --git a/media/capture/video/android/BUILD.gn b/media/capture/video/android/BUILD.gn index 046b646..1148a14e 100644 --- a/media/capture/video/android/BUILD.gn +++ b/media/capture/video/android/BUILD.gn
@@ -52,7 +52,7 @@ android_library("capture_java") { deps = [ "//base:base_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] srcjar_deps = [ ":media_java_enums_srcjar" ]
diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc index 3b8d96e..127e7da 100644 --- a/media/renderers/video_resource_updater.cc +++ b/media/renderers/video_resource_updater.cc
@@ -479,6 +479,7 @@ gfx::Transform transform, gfx::Rect quad_rect, gfx::Rect visible_quad_rect, + const gfx::RRectF& rounded_corner_bounds, gfx::Rect clip_rect, bool is_clipped, bool contents_opaque, @@ -488,8 +489,9 @@ viz::SharedQuadState* shared_quad_state = render_pass->CreateAndAppendSharedQuadState(); - shared_quad_state->SetAll(transform, quad_rect, visible_quad_rect, clip_rect, - is_clipped, contents_opaque, draw_opacity, + shared_quad_state->SetAll(transform, quad_rect, visible_quad_rect, + rounded_corner_bounds, clip_rect, is_clipped, + contents_opaque, draw_opacity, SkBlendMode::kSrcOver, sorting_context_id); bool needs_blending = !contents_opaque;
diff --git a/media/renderers/video_resource_updater.h b/media/renderers/video_resource_updater.h index 39c3ed8..634c1ad9 100644 --- a/media/renderers/video_resource_updater.h +++ b/media/renderers/video_resource_updater.h
@@ -27,6 +27,7 @@ namespace gfx { class Rect; +class RRectF; class Transform; } // namespace gfx @@ -109,6 +110,7 @@ gfx::Transform transform, gfx::Rect quad_rect, gfx::Rect visible_quad_rect, + const gfx::RRectF& rounded_corner_bounds, gfx::Rect clip_rect, bool is_clipped, bool context_opaque,
diff --git a/net/android/BUILD.gn b/net/android/BUILD.gn index d0640ac..5ec8814c 100644 --- a/net/android/BUILD.gn +++ b/net/android/BUILD.gn
@@ -28,7 +28,7 @@ deps = [ ":net_thread_stats_uid_java", "//base:base_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/jsr-305:jsr_305_javalib", ] srcjar_deps = [ @@ -52,7 +52,7 @@ android_library("embedded_test_server_aidl_java") { testonly = true deps = [ - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] srcjar_deps = [ ":embedded_test_server_aidl" ] } @@ -72,7 +72,7 @@ ":net_java", "//base:base_java", "//base:base_java_test_support", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/junit",
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc index 83f285e..d96e904a 100644 --- a/net/cookies/cookie_monster.cc +++ b/net/cookies/cookie_monster.cc
@@ -377,7 +377,7 @@ // CookieMonster. To avoid the PersistentCookieStore retaining a pointer to // the ChannelIDStore via this callback after this CookieMonster is // destroyed, CookieMonster's d'tor sets the callback to a null callback. - store_->SetBeforeFlushCallback( + store_->SetBeforeCommitCallback( base::Bind(&ChannelIDStore::Flush, base::Unretained(channel_id_service_->GetChannelIDStore()))); } @@ -585,7 +585,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (channel_id_service_ && store_) { - store_->SetBeforeFlushCallback(base::Closure()); + store_->SetBeforeCommitCallback(base::RepeatingClosure()); } // TODO(mmenke): Does it really make sense to run
diff --git a/net/cookies/cookie_monster.h b/net/cookies/cookie_monster.h index b9aeaaf..d92c94b 100644 --- a/net/cookies/cookie_monster.h +++ b/net/cookies/cookie_monster.h
@@ -683,7 +683,7 @@ // Sets a callback that will be run before the store flushes. If |callback| // performs any async operations, the store will not wait for those to finish // before flushing. - virtual void SetBeforeFlushCallback(base::RepeatingClosure callback) = 0; + virtual void SetBeforeCommitCallback(base::RepeatingClosure callback) = 0; // Flushes the store and posts |callback| when complete. |callback| may be // NULL.
diff --git a/net/cookies/cookie_monster_store_test.cc b/net/cookies/cookie_monster_store_test.cc index d31091b9..c929043 100644 --- a/net/cookies/cookie_monster_store_test.cc +++ b/net/cookies/cookie_monster_store_test.cc
@@ -89,7 +89,7 @@ void MockPersistentCookieStore::SetForceKeepSessionState() {} -void MockPersistentCookieStore::SetBeforeFlushCallback( +void MockPersistentCookieStore::SetBeforeCommitCallback( base::RepeatingClosure callback) {} void MockPersistentCookieStore::Flush(base::OnceClosure callback) { @@ -186,7 +186,7 @@ void MockSimplePersistentCookieStore::SetForceKeepSessionState() {} -void MockSimplePersistentCookieStore::SetBeforeFlushCallback( +void MockSimplePersistentCookieStore::SetBeforeCommitCallback( base::RepeatingClosure callback) {} void MockSimplePersistentCookieStore::Flush(base::OnceClosure callback) {
diff --git a/net/cookies/cookie_monster_store_test.h b/net/cookies/cookie_monster_store_test.h index cc8b25a28..c85c0eb 100644 --- a/net/cookies/cookie_monster_store_test.h +++ b/net/cookies/cookie_monster_store_test.h
@@ -104,7 +104,7 @@ void SetForceKeepSessionState() override; - void SetBeforeFlushCallback(base::RepeatingClosure callback) override; + void SetBeforeCommitCallback(base::RepeatingClosure callback) override; void Flush(base::OnceClosure callback) override; @@ -159,7 +159,7 @@ void SetForceKeepSessionState() override; - void SetBeforeFlushCallback(base::RepeatingClosure callback) override; + void SetBeforeCommitCallback(base::RepeatingClosure callback) override; void Flush(base::OnceClosure callback) override;
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc index b4c354c..02521262 100644 --- a/net/cookies/cookie_monster_unittest.cc +++ b/net/cookies/cookie_monster_unittest.cc
@@ -71,7 +71,7 @@ MOCK_METHOD1(AddCookie, void(const CanonicalCookie& cc)); MOCK_METHOD1(UpdateCookieAccessTime, void(const CanonicalCookie& cc)); MOCK_METHOD1(DeleteCookie, void(const CanonicalCookie& cc)); - MOCK_METHOD1(SetBeforeFlushCallback, void(base::RepeatingClosure)); + MOCK_METHOD1(SetBeforeCommitCallback, void(base::RepeatingClosure)); void Flush(base::OnceClosure callback) override { if (!callback.is_null()) base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, @@ -2561,15 +2561,15 @@ ASSERT_EQ(3, counter->callback_count()); } -TEST_F(CookieMonsterTest, SetBeforeFlushCallbackIsCalled) { +TEST_F(CookieMonsterTest, SetBeforeCommitCallbackIsCalled) { std::unique_ptr<ChannelIDService> channel_id_service( new ChannelIDService(nullptr)); scoped_refptr<NewMockPersistentCookieStore> store( new NewMockPersistentCookieStore()); - // SetBeforeFlushCallback should be called in both the c'tor and d'tor. - EXPECT_CALL(*store, SetBeforeFlushCallback(testing::_)).Times(2); + // SetBeforeCommitCallback should be called in both the c'tor and d'tor. + EXPECT_CALL(*store, SetBeforeCommitCallback(testing::_)).Times(2); std::unique_ptr<CookieMonster> cm( new CookieMonster(store.get(), channel_id_service.get(), &net_log_));
diff --git a/net/cookies/cookie_store_test_helpers.cc b/net/cookies/cookie_store_test_helpers.cc index 047082f..70675bc1 100644 --- a/net/cookies/cookie_store_test_helpers.cc +++ b/net/cookies/cookie_store_test_helpers.cc
@@ -245,7 +245,7 @@ void FlushablePersistentStore::SetForceKeepSessionState() {} -void FlushablePersistentStore::SetBeforeFlushCallback( +void FlushablePersistentStore::SetBeforeCommitCallback( base::RepeatingClosure callback) {} void FlushablePersistentStore::Flush(base::OnceClosure callback) {
diff --git a/net/cookies/cookie_store_test_helpers.h b/net/cookies/cookie_store_test_helpers.h index 85935fa..28fc2c34 100644 --- a/net/cookies/cookie_store_test_helpers.h +++ b/net/cookies/cookie_store_test_helpers.h
@@ -156,7 +156,7 @@ void UpdateCookieAccessTime(const CanonicalCookie&) override; void DeleteCookie(const CanonicalCookie&) override; void SetForceKeepSessionState() override; - void SetBeforeFlushCallback(base::RepeatingClosure callback) override; + void SetBeforeCommitCallback(base::RepeatingClosure callback) override; void Flush(base::OnceClosure callback) override; int flush_count();
diff --git a/net/disk_cache/blockfile/entry_impl.cc b/net/disk_cache/blockfile/entry_impl.cc index dc96b82..dcbb28ac 100644 --- a/net/disk_cache/blockfile/entry_impl.cc +++ b/net/disk_cache/blockfile/entry_impl.cc
@@ -8,6 +8,7 @@ #include "base/hash.h" #include "base/macros.h" +#include "base/numerics/safe_math.h" #include "base/strings/string_util.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" @@ -1034,7 +1035,9 @@ TimeTicks start = TimeTicks::Now(); - if (offset + buf_len > entry_size) + int end_offset; + if (!base::CheckAdd(offset, buf_len).AssignIfValid(&end_offset) || + end_offset > entry_size) buf_len = entry_size - offset; UpdateRank(false); @@ -1120,12 +1123,12 @@ int max_file_size = backend_->MaxFileSize(); - // offset or buf_len could be negative numbers. + int end_offset; if (offset > max_file_size || buf_len > max_file_size || - offset + buf_len > max_file_size) { - int size = offset + buf_len; - if (size <= max_file_size) - size = std::numeric_limits<int32_t>::max(); + !base::CheckAdd(offset, buf_len).AssignIfValid(&end_offset) || + end_offset > max_file_size) { + int size = base::CheckAdd(offset, buf_len) + .ValueOrDefault(std::numeric_limits<int32_t>::max()); backend_->TooMuchStorageRequested(size); return net::ERR_FAILED; }
diff --git a/net/disk_cache/memory/mem_entry_impl.cc b/net/disk_cache/memory/mem_entry_impl.cc index 74d28467..d329623 100644 --- a/net/disk_cache/memory/mem_entry_impl.cc +++ b/net/disk_cache/memory/mem_entry_impl.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" +#include "base/numerics/safe_math.h" #include "base/strings/stringprintf.h" #include "base/values.h" #include "net/base/interval.h" @@ -359,7 +360,9 @@ if (offset >= entry_size || offset < 0 || !buf_len) return 0; - if (offset + buf_len > entry_size) + int end_offset; + if (!base::CheckAdd(offset, buf_len).AssignIfValid(&end_offset) || + end_offset > entry_size) buf_len = entry_size - offset; UpdateStateOnUse(ENTRY_WAS_NOT_MODIFIED); @@ -390,16 +393,17 @@ int max_file_size = backend_->MaxFileSize(); - // offset of buf_len could be negative numbers. + int end_offset; if (offset > max_file_size || buf_len > max_file_size || - offset + buf_len > max_file_size) { + !base::CheckAdd(offset, buf_len).AssignIfValid(&end_offset) || + end_offset > max_file_size) { RecordWriteResult(MEM_ENTRY_WRITE_RESULT_OVER_MAX_ENTRY_SIZE); return net::ERR_FAILED; } int old_data_size = data_[index].size(); - if (truncate || old_data_size < offset + buf_len) { - int delta = offset + buf_len - old_data_size; + if (truncate || old_data_size < end_offset) { + int delta = end_offset - old_data_size; backend_->ModifyStorageSize(delta); if (backend_->HasExceededStorageSize()) { backend_->ModifyStorageSize(-delta); @@ -407,7 +411,7 @@ return net::ERR_INSUFFICIENT_RESOURCES; } - data_[index].resize(offset + buf_len); + data_[index].resize(end_offset); // Zero fill any hole. if (old_data_size < offset) { @@ -434,7 +438,9 @@ if (!InitSparseInfo()) return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; - if (offset < 0 || buf_len < 0) + // Check that offset + buf_len does not overflow. This ensures that + // offset + io_buf->BytesConsumed() never overflows below. + if (offset < 0 || buf_len < 0 || !base::CheckAdd(offset, buf_len).IsValid()) return net::ERR_INVALID_ARGUMENT; // We will keep using this buffer and adjust the offset in this buffer. @@ -497,7 +503,9 @@ if (!backend_) return net::ERR_FAILED; - if (offset < 0 || buf_len < 0) + // Check that offset + buf_len does not overflow. This ensures that + // offset + io_buf->BytesConsumed() never overflows below. + if (offset < 0 || buf_len < 0 || !base::CheckAdd(offset, buf_len).IsValid()) return net::ERR_INVALID_ARGUMENT; scoped_refptr<net::DrainableIOBuffer> io_buf = @@ -566,6 +574,7 @@ if (offset < 0 || len < 0 || !start) return net::ERR_INVALID_ARGUMENT; + // If offset + len overflows, this will just be the empty interval. net::Interval<int64_t> requested(offset, offset + len); // Find the first relevant child, if any --- may have to skip over
diff --git a/net/disk_cache/simple/simple_entry_impl.cc b/net/disk_cache/simple/simple_entry_impl.cc index 75a1285..ee55cd5 100644 --- a/net/disk_cache/simple/simple_entry_impl.cc +++ b/net/disk_cache/simple/simple_entry_impl.cc
@@ -474,7 +474,9 @@ RecordWriteResult(cache_type_, SIMPLE_ENTRY_WRITE_RESULT_INVALID_ARGUMENT); return net::ERR_INVALID_ARGUMENT; } - if (backend_.get() && offset + buf_len > backend_->MaxFileSize()) { + int end_offset; + if (!base::CheckAdd(offset, buf_len).AssignIfValid(&end_offset) || + (backend_.get() && end_offset > backend_->MaxFileSize())) { if (net_log_.IsCapturing()) { net_log_.AddEvent(net::NetLogEventType::SIMPLE_CACHE_ENTRY_WRITE_END, CreateNetLogReadWriteCompleteCallback(net::ERR_FAILED));
diff --git a/net/disk_cache/simple/simple_synchronous_entry.cc b/net/disk_cache/simple/simple_synchronous_entry.cc index 3ce539c..74d7045 100644 --- a/net/disk_cache/simple/simple_synchronous_entry.cc +++ b/net/disk_cache/simple/simple_synchronous_entry.cc
@@ -800,10 +800,18 @@ return; } - uint64_t sparse_data_size = out_entry_stat->sparse_data_size(); + int32_t sparse_data_size = out_entry_stat->sparse_data_size(); + int32_t future_sparse_data_size; + if (!base::CheckAdd(sparse_data_size, buf_len) + .AssignIfValid(&future_sparse_data_size) || + future_sparse_data_size < 0) { + Doom(); + *out_result = net::ERR_CACHE_WRITE_FAILURE; + return; + } // This is a pessimistic estimate; it assumes the entire buffer is going to // be appended as a new range, not written over existing ranges. - if (sparse_data_size + buf_len > max_sparse_data_size) { + if (static_cast<uint64_t>(future_sparse_data_size) > max_sparse_data_size) { DVLOG(1) << "Truncating sparse data file (" << sparse_data_size << " + " << buf_len << " > " << max_sparse_data_size << ")"; TruncateSparseFile(sparse_file.get());
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store.cc b/net/extras/sqlite/sqlite_persistent_cookie_store.cc index 4438f44..9959f9f 100644 --- a/net/extras/sqlite/sqlite_persistent_cookie_store.cc +++ b/net/extras/sqlite/sqlite_persistent_cookie_store.cc
@@ -1486,9 +1486,9 @@ // This store never discards session-only cookies, so this call has no effect. } -void SQLitePersistentCookieStore::SetBeforeFlushCallback( +void SQLitePersistentCookieStore::SetBeforeCommitCallback( base::RepeatingClosure callback) { - backend_->SetBeforeFlushCallback(std::move(callback)); + backend_->SetBeforeCommitCallback(std::move(callback)); } void SQLitePersistentCookieStore::Flush(base::OnceClosure callback) {
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store.h b/net/extras/sqlite/sqlite_persistent_cookie_store.h index 7ea56e2..5322f6f 100644 --- a/net/extras/sqlite/sqlite_persistent_cookie_store.h +++ b/net/extras/sqlite/sqlite_persistent_cookie_store.h
@@ -63,7 +63,7 @@ void UpdateCookieAccessTime(const CanonicalCookie& cc) override; void DeleteCookie(const CanonicalCookie& cc) override; void SetForceKeepSessionState() override; - void SetBeforeFlushCallback(base::RepeatingClosure callback) override; + void SetBeforeCommitCallback(base::RepeatingClosure callback) override; void Flush(base::OnceClosure callback) override; // Returns how many operations are currently queued. For test use only;
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc b/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc index 656faf6c..0043b78d 100644 --- a/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc +++ b/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
@@ -466,7 +466,7 @@ NetLogEventPhase::NONE); } -TEST_F(SQLitePersistentCookieStoreTest, TestBeforeFlushCallback) { +TEST_F(SQLitePersistentCookieStoreTest, TestBeforeCommitCallback) { InitializeStore(false, false); struct Counter { @@ -475,8 +475,8 @@ }; Counter counter; - store_->SetBeforeFlushCallback( - base::Bind(&Counter::increment, base::Unretained(&counter))); + store_->SetBeforeCommitCallback( + base::BindRepeating(&Counter::increment, base::Unretained(&counter))); // The implementation of SQLitePersistentCookieStore::Backend flushes changes // after 30s or 512 pending operations. Add 512 cookies to the store to test
diff --git a/net/extras/sqlite/sqlite_persistent_store_backend_base.cc b/net/extras/sqlite/sqlite_persistent_store_backend_base.cc index 8437a06c..805d5ee9 100644 --- a/net/extras/sqlite/sqlite_persistent_store_backend_base.cc +++ b/net/extras/sqlite/sqlite_persistent_store_backend_base.cc
@@ -58,10 +58,10 @@ } } -void SQLitePersistentStoreBackendBase::SetBeforeFlushCallback( +void SQLitePersistentStoreBackendBase::SetBeforeCommitCallback( base::RepeatingClosure callback) { - base::AutoLock locked(before_flush_callback_lock_); - before_flush_callback_ = std::move(callback); + base::AutoLock locked(before_commit_callback_lock_); + before_commit_callback_ = std::move(callback); } bool SQLitePersistentStoreBackendBase::InitializeDatabase() { @@ -149,9 +149,9 @@ DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); { - base::AutoLock locked(before_flush_callback_lock_); - if (!before_flush_callback_.is_null()) - before_flush_callback_.Run(); + base::AutoLock locked(before_commit_callback_lock_); + if (!before_commit_callback_.is_null()) + before_commit_callback_.Run(); } DoCommit();
diff --git a/net/extras/sqlite/sqlite_persistent_store_backend_base.h b/net/extras/sqlite/sqlite_persistent_store_backend_base.h index 7e29bed..f9d9306 100644 --- a/net/extras/sqlite/sqlite_persistent_store_backend_base.h +++ b/net/extras/sqlite/sqlite_persistent_store_backend_base.h
@@ -59,7 +59,7 @@ void Close(); // Set the callback that will be run at the beginning of Commit. - void SetBeforeFlushCallback(base::RepeatingClosure callback); + void SetBeforeCommitCallback(base::RepeatingClosure callback); protected: friend class base::RefCountedThreadSafe<SQLitePersistentStoreBackendBase>; @@ -116,7 +116,7 @@ void Reset(); // Commit pending operations to the database. First runs - // |before_flush_callback_|. Should be called on the background thread. + // |before_commit_callback_|. Should be called on the background thread. void Commit(); // Embedder-specific logic to commit pending operations. (This base class has @@ -186,10 +186,10 @@ const scoped_refptr<base::SequencedTaskRunner> client_task_runner_; // Callback to be run before Commit. - base::RepeatingClosure before_flush_callback_ - GUARDED_BY(before_flush_callback_lock_); - // Guards |before_flush_callback_|. - base::Lock before_flush_callback_lock_; + base::RepeatingClosure before_commit_callback_ + GUARDED_BY(before_commit_callback_lock_); + // Guards |before_commit_callback_|. + base::Lock before_commit_callback_lock_; DISALLOW_COPY_AND_ASSIGN(SQLitePersistentStoreBackendBase); };
diff --git a/net/filter/gzip_source_stream_fuzzer.cc b/net/filter/gzip_source_stream_fuzzer.cc index a7cbbadb..1fde1d8a 100644 --- a/net/filter/gzip_source_stream_fuzzer.cc +++ b/net/filter/gzip_source_stream_fuzzer.cc
@@ -24,10 +24,9 @@ // Gzip has a maximum compression ratio of 1032x. While, strictly speaking, // linear, this means the fuzzer will often get stuck. Stop reading at a more - // modest compression ratio of 10x, or 2 MiB, whichever is larger. See + // modest compression ratio of 2x, or 512 KiB, whichever is larger. See // https://crbug.com/921075. - size_t max_output = - std::max(10u * size, static_cast<size_t>(2 * 1024 * 1024)); + size_t max_output = std::max(2u * size, static_cast<size_t>(512 * 1024)); const net::SourceStream::SourceType kGzipTypes[] = { net::SourceStream::TYPE_GZIP, net::SourceStream::TYPE_DEFLATE};
diff --git a/net/url_request/redirect_info.cc b/net/url_request/redirect_info.cc index 45c246b..74395cf 100644 --- a/net/url_request/redirect_info.cc +++ b/net/url_request/redirect_info.cc
@@ -125,8 +125,7 @@ const GURL& new_location, const base::Optional<std::string>& referrer_policy_header, bool insecure_scheme_was_upgraded, - bool copy_fragment, - bool is_signed_exchange_fallback_redirect) { + bool copy_fragment) { RedirectInfo redirect_info; redirect_info.status_code = http_status_code; @@ -150,8 +149,6 @@ } redirect_info.insecure_scheme_was_upgraded = insecure_scheme_was_upgraded; - redirect_info.is_signed_exchange_fallback_redirect = - is_signed_exchange_fallback_redirect; // Update the first-party URL if appropriate. if (original_first_party_url_policy ==
diff --git a/net/url_request/redirect_info.h b/net/url_request/redirect_info.h index 524adf95..7236455 100644 --- a/net/url_request/redirect_info.h +++ b/net/url_request/redirect_info.h
@@ -44,9 +44,7 @@ // by default. Set false only when the network delegate has set the // desired redirect URL (with or without fragment), so it must not be // changed any more. - bool copy_fragment = true, - // Whether the redirect is caused by a failure of signed exchange loading. - bool is_signed_exchange_fallback_redirect = false); + bool copy_fragment = true); // The status code for the redirect response. This is almost redundant with // the response headers, but some URLRequestJobs emit redirects without @@ -72,9 +70,6 @@ // upgrade-insecure-requests policy. bool insecure_scheme_was_upgraded; - // True if this is a redirect from Signed Exchange to its fallback URL. - bool is_signed_exchange_fallback_redirect; - // The new referrer policy that should be obeyed if there are // subsequent redirects. URLRequest::ReferrerPolicy new_referrer_policy;
diff --git a/pdf/pdfium/fuzzers/BUILD.gn b/pdf/pdfium/fuzzers/BUILD.gn index b9b45dcf..628fd6d 100644 --- a/pdf/pdfium/fuzzers/BUILD.gn +++ b/pdf/pdfium/fuzzers/BUILD.gn
@@ -254,7 +254,7 @@ fuzzer_test("pdf_formcalc_context_fuzzer") { sources = [] deps = [ - "//third_party/pdfium/testing/fuzzers:pdf_formcalc_fuzzer_src", + "//third_party/pdfium/testing/fuzzers:pdf_formcalc_context_fuzzer_src", ] dict = "dicts/pdf_xfa_js.dict" }
diff --git a/remoting/android/client_java_tmpl.gni b/remoting/android/client_java_tmpl.gni index 33f82da8..6a1db68e 100644 --- a/remoting/android/client_java_tmpl.gni +++ b/remoting/android/client_java_tmpl.gni
@@ -82,9 +82,9 @@ "//remoting/android:remoting_android_client_java_resources", "//remoting/android:remoting_apk_manifest", "//third_party/android_deps:android_arch_lifecycle_common_java", - "//third_party/android_deps:android_support_annotations_java", "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:android_support_v7_mediarouter_java", + "//third_party/android_deps:com_android_support_mediarouter_v7_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//ui/android:ui_utils_java", ]
diff --git a/services/BUILD.gn b/services/BUILD.gn index 334b054b..094989d 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn
@@ -118,7 +118,7 @@ "//services/device/public/mojom:mojom_java", "//services/shape_detection:shape_detection_java", "//skia/public/interfaces:interfaces_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] }
diff --git a/services/metrics/public/cpp/metrics_utils_unittest.cc b/services/metrics/public/cpp/metrics_utils_unittest.cc index 27cdca32..2176f3f 100644 --- a/services/metrics/public/cpp/metrics_utils_unittest.cc +++ b/services/metrics/public/cpp/metrics_utils_unittest.cc
@@ -61,3 +61,31 @@ << " with bucket_size: " << test.bucket_size; } } + +TEST(MetricsUtilsTest, GetExponentialBucketMinForUserTiming) { + struct { + int64_t expected_result; + int64_t sample; + } int_test_cases[] = { + // Typical positive cases. + {1, 1}, + {32, 38}, + {32, 51}, + {64, 99}, + {16, 25}, + {512, 1023}, + {1024, 1024}, + {1024, 1025}, + // Negative samples. + {0, -45}, + // Zero samples. + {0, 0}, + }; + + // Test int64_t sample cases. + for (const auto& test : int_test_cases) { + EXPECT_EQ(test.expected_result, + ukm::GetExponentialBucketMinForUserTiming(test.sample)) + << "For sample: " << test.sample; + } +}
diff --git a/services/network/BUILD.gn b/services/network/BUILD.gn index dd858f0..20b30833 100644 --- a/services/network/BUILD.gn +++ b/services/network/BUILD.gn
@@ -125,8 +125,6 @@ "resource_scheduler_params_manager.h", "restricted_cookie_manager.cc", "restricted_cookie_manager.h", - "session_cleanup_channel_id_store.cc", - "session_cleanup_channel_id_store.h", "session_cleanup_cookie_store.cc", "session_cleanup_cookie_store.h", "socket_data_pump.cc", @@ -319,7 +317,6 @@ "resource_scheduler_params_manager_unittest.cc", "resource_scheduler_unittest.cc", "restricted_cookie_manager_unittest.cc", - "session_cleanup_channel_id_store_unittest.cc", "session_cleanup_cookie_store_unittest.cc", "socket_data_pump_unittest.cc", "ssl_config_service_mojo_unittest.cc",
diff --git a/services/network/cookie_manager.cc b/services/network/cookie_manager.cc index 0c7ce77a..8c792e5 100644 --- a/services/network/cookie_manager.cc +++ b/services/network/cookie_manager.cc
@@ -15,7 +15,6 @@ #include "net/cookies/cookie_store.h" #include "net/cookies/cookie_util.h" #include "services/network/cookie_managers_shared.h" -#include "services/network/session_cleanup_channel_id_store.h" #include "services/network/session_cleanup_cookie_store.h" #include "url/gurl.h" @@ -54,13 +53,9 @@ CookieManager::CookieManager( net::CookieStore* cookie_store, scoped_refptr<SessionCleanupCookieStore> session_cleanup_cookie_store, - scoped_refptr<SessionCleanupChannelIDStore> - session_cleanup_channel_id_store, mojom::CookieManagerParamsPtr params) : cookie_store_(cookie_store), - session_cleanup_cookie_store_(std::move(session_cleanup_cookie_store)), - session_cleanup_channel_id_store_( - std::move(session_cleanup_channel_id_store)) { + session_cleanup_cookie_store_(std::move(session_cleanup_cookie_store)) { if (params) { cookie_settings_.set_block_third_party_cookies( params->block_third_party_cookies); @@ -79,11 +74,6 @@ session_cleanup_cookie_store_->DeleteSessionCookies( cookie_settings_.CreateDeleteCookieOnExitPredicate()); } - if (session_cleanup_channel_id_store_) { - session_cleanup_channel_id_store_->DeleteSessionChannelIDs( - base::BindRepeating(&CookieSettings::IsCookieSessionOnly, - base::Unretained(&cookie_settings_))); - } } void CookieManager::AddRequest(mojom::CookieManagerRequest request) { @@ -221,8 +211,6 @@ void CookieManager::SetForceKeepSessionState() { cookie_store_->SetForceKeepSessionState(); - if (session_cleanup_channel_id_store_) - session_cleanup_channel_id_store_->SetForceKeepSessionState(); } void CookieManager::BlockThirdPartyCookies(bool block) {
diff --git a/services/network/cookie_manager.h b/services/network/cookie_manager.h index 9f19832e..6cef8ce 100644 --- a/services/network/cookie_manager.h +++ b/services/network/cookie_manager.h
@@ -26,7 +26,6 @@ namespace network { class SessionCleanupCookieStore; -class SessionCleanupChannelIDStore; // Wrap a cookie store in an implementation of the mojo cookie interface. @@ -41,8 +40,6 @@ CookieManager( net::CookieStore* cookie_store, scoped_refptr<SessionCleanupCookieStore> session_cleanup_cookie_store, - scoped_refptr<SessionCleanupChannelIDStore> - session_cleanup_channel_id_store, mojom::CookieManagerParamsPtr params); ~CookieManager() override; @@ -111,7 +108,6 @@ net::CookieStore* const cookie_store_; scoped_refptr<SessionCleanupCookieStore> session_cleanup_cookie_store_; - scoped_refptr<SessionCleanupChannelIDStore> session_cleanup_channel_id_store_; mojo::BindingSet<mojom::CookieManager> bindings_; std::vector<std::unique_ptr<ListenerRegistration>> listener_registrations_; // Note: RestrictedCookieManager stores pointers to |cookie_settings_|.
diff --git a/services/network/cookie_manager_unittest.cc b/services/network/cookie_manager_unittest.cc index 5b3afe6..53a0cbb 100644 --- a/services/network/cookie_manager_unittest.cc +++ b/services/network/cookie_manager_unittest.cc
@@ -23,7 +23,6 @@ #include "net/cookies/cookie_store_test_callbacks.h" #include "net/cookies/cookie_store_test_helpers.h" #include "services/network/public/mojom/cookie_manager.mojom.h" -#include "services/network/session_cleanup_channel_id_store.h" #include "services/network/session_cleanup_cookie_store.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -172,7 +171,7 @@ class CookieManagerTest : public testing::Test { public: - CookieManagerTest() { InitializeCookieService(nullptr, nullptr, nullptr); } + CookieManagerTest() { InitializeCookieService(nullptr, nullptr); } ~CookieManagerTest() override {} @@ -241,15 +240,13 @@ protected: void InitializeCookieService( scoped_refptr<net::CookieMonster::PersistentCookieStore> store, - scoped_refptr<SessionCleanupCookieStore> cleanup_store, - scoped_refptr<SessionCleanupChannelIDStore> channel_id_store) { + scoped_refptr<SessionCleanupCookieStore> cleanup_store) { connection_error_seen_ = false; cookie_monster_ = std::make_unique<net::CookieMonster>( std::move(store), nullptr /*channel_id_service */, nullptr /* netlog */); cookie_service_ = std::make_unique<CookieManager>( - cookie_monster_.get(), std::move(cleanup_store), - std::move(channel_id_store), nullptr); + cookie_monster_.get(), std::move(cleanup_store), nullptr); cookie_service_->AddRequest(mojo::MakeRequest(&cookie_service_ptr_)); service_wrapper_ = std::make_unique<SynchronousCookieManager>(cookie_service_ptr_.get()); @@ -1886,7 +1883,7 @@ public: FlushableCookieManagerTest() : store_(base::MakeRefCounted<net::FlushablePersistentStore>()) { - InitializeCookieService(store_, nullptr, nullptr); + InitializeCookieService(store_, nullptr); } ~FlushableCookieManagerTest() override {} @@ -1986,7 +1983,7 @@ void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); auto store = CreateCookieStore(); - InitializeCookieService(store, store, nullptr); + InitializeCookieService(store, store); } scoped_refptr<SessionCleanupCookieStore> CreateCookieStore() { @@ -2021,7 +2018,7 @@ // Re-create the cookie store to make sure cookies are persisted. auto store = CreateCookieStore(); - InitializeCookieService(store, store, nullptr); + InitializeCookieService(store, store); EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size()); } @@ -2036,7 +2033,7 @@ base::RunLoop().RunUntilIdle(); auto store = CreateCookieStore(); - InitializeCookieService(store, store, nullptr); + InitializeCookieService(store, store); EXPECT_EQ(0u, service_wrapper()->GetAllCookies().size()); } @@ -2051,7 +2048,7 @@ base::RunLoop().RunUntilIdle(); auto store = CreateCookieStore(); - InitializeCookieService(store, store, nullptr); + InitializeCookieService(store, store); EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size()); } @@ -2069,7 +2066,7 @@ base::RunLoop().RunUntilIdle(); auto store = CreateCookieStore(); - InitializeCookieService(store, store, nullptr); + InitializeCookieService(store, store); EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size()); } @@ -2085,7 +2082,7 @@ base::RunLoop().RunUntilIdle(); auto store = CreateCookieStore(); - InitializeCookieService(store, store, nullptr); + InitializeCookieService(store, store); EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size()); } @@ -2103,114 +2100,10 @@ base::RunLoop().RunUntilIdle(); auto store = CreateCookieStore(); - InitializeCookieService(store, store, nullptr); + InitializeCookieService(store, store); EXPECT_EQ(1u, service_wrapper()->GetAllCookies().size()); } -// A test class having a channel ID store with persistent backing. The channel -// ID store can be destroyed and recreated by calling InitializeCookieService -// again. -class SessionCleanupChannelIDCookieManagerTest : public CookieManagerTest { - protected: - using ChannelIDVector = - std::vector<std::unique_ptr<net::DefaultChannelIDStore::ChannelID>>; - - ~SessionCleanupChannelIDCookieManagerTest() override {} - - void SetUp() override { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - store_ = CreateChannelIDStore(); - ASSERT_EQ(0u, Load().size()); - InitializeCookieService(nullptr, nullptr, store_); - } - - void TearDown() override { - NukeService(); - store_ = nullptr; - base::RunLoop().RunUntilIdle(); - } - - scoped_refptr<SessionCleanupChannelIDStore> CreateChannelIDStore() { - return base::MakeRefCounted<SessionCleanupChannelIDStore>( - temp_dir_.GetPath().Append(kTestCookiesFilename), - scoped_task_environment_.GetMainThreadTaskRunner()); - } - - ChannelIDVector Load() { - ChannelIDVector channel_ids; - base::RunLoop run_loop; - store_->Load( - base::BindRepeating(&SessionCleanupChannelIDCookieManagerTest::OnLoaded, - base::Unretained(this), &run_loop, &channel_ids)); - run_loop.Run(); - return channel_ids; - } - - void OnLoaded(base::RunLoop* run_loop, - ChannelIDVector* channel_ids_out, - std::unique_ptr<ChannelIDVector> channel_ids) { - channel_ids_out->swap(*channel_ids); - run_loop->Quit(); - } - - scoped_refptr<SessionCleanupChannelIDStore> store_; - base::ScopedTempDir temp_dir_; -}; - -TEST_F(SessionCleanupChannelIDCookieManagerTest, PersistSessionChannelIDs) { - store_->AddChannelID(net::ChannelIDStore::ChannelID( - kCookieDomain, base::Time::Now(), crypto::ECPrivateKey::Create())); - - // Re-create the channel ID store to make sure channel IDs are persisted. - store_ = CreateChannelIDStore(); - InitializeCookieService(nullptr, nullptr, store_); - - EXPECT_EQ(1u, Load().size()); -} - -TEST_F(SessionCleanupChannelIDCookieManagerTest, DeleteSessionChannelIDs) { - store_->AddChannelID(net::ChannelIDStore::ChannelID( - kCookieDomain, base::Time::Now(), crypto::ECPrivateKey::Create())); - - cookie_service_client()->SetContentSettings( - {CreateSetting(CONTENT_SETTING_SESSION_ONLY, kCookieURL)}); - base::RunLoop().RunUntilIdle(); - - store_ = CreateChannelIDStore(); - InitializeCookieService(nullptr, nullptr, store_); - - EXPECT_EQ(0u, Load().size()); -} - -TEST_F(SessionCleanupChannelIDCookieManagerTest, SettingMustMatchDomain) { - store_->AddChannelID(net::ChannelIDStore::ChannelID( - kCookieDomain, base::Time::Now(), crypto::ECPrivateKey::Create())); - - cookie_service_client()->SetContentSettings( - {CreateSetting(CONTENT_SETTING_SESSION_ONLY, "http://other.com")}); - base::RunLoop().RunUntilIdle(); - - store_ = CreateChannelIDStore(); - InitializeCookieService(nullptr, nullptr, store_); - - EXPECT_EQ(1u, Load().size()); -} - -TEST_F(SessionCleanupChannelIDCookieManagerTest, ForceKeepSessionState) { - store_->AddChannelID(net::ChannelIDStore::ChannelID( - kCookieDomain, base::Time::Now(), crypto::ECPrivateKey::Create())); - - cookie_service_client()->SetContentSettings( - {CreateSetting(CONTENT_SETTING_SESSION_ONLY, kCookieURL)}); - cookie_service_client()->SetForceKeepSessionState(); - base::RunLoop().RunUntilIdle(); - - store_ = CreateChannelIDStore(); - InitializeCookieService(nullptr, nullptr, store_); - - EXPECT_EQ(1u, Load().size()); -} - } // namespace } // namespace network
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 6839958..d90c044 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -81,7 +81,6 @@ #include "services/network/resolve_host_request.h" #include "services/network/resource_scheduler_client.h" #include "services/network/restricted_cookie_manager.h" -#include "services/network/session_cleanup_channel_id_store.h" #include "services/network/session_cleanup_cookie_store.h" #include "services/network/ssl_config_service_mojo.h" #include "services/network/throttling/network_conditions.h" @@ -594,7 +593,6 @@ cookie_manager_( std::make_unique<CookieManager>(url_request_context->cookie_store(), nullptr, - nullptr, nullptr)), socket_factory_( std::make_unique<SocketFactory>(url_request_context_->net_log(), @@ -1734,7 +1732,6 @@ } scoped_refptr<SessionCleanupCookieStore> session_cleanup_cookie_store; - scoped_refptr<SessionCleanupChannelIDStore> session_cleanup_channel_id_store; if (params_->cookie_path) { scoped_refptr<base::SequencedTaskRunner> client_task_runner = base::MessageLoopCurrent::Get()->task_runner(); @@ -2078,7 +2075,6 @@ cookie_manager_ = std::make_unique<CookieManager>( result.url_request_context->cookie_store(), std::move(session_cleanup_cookie_store), - std::move(session_cleanup_channel_id_store), std::move(params_->cookie_manager_params)); return result;
diff --git a/services/network/public/cpp/BUILD.gn b/services/network/public/cpp/BUILD.gn index 11acf0ebe..1c9d3708 100644 --- a/services/network/public/cpp/BUILD.gn +++ b/services/network/public/cpp/BUILD.gn
@@ -30,6 +30,8 @@ "cross_thread_shared_url_loader_factory_info.h", "features.cc", "features.h", + "is_potentially_trustworthy.cc", + "is_potentially_trustworthy.h", "net_adapters.cc", "net_adapters.h", "network_connection_tracker.cc", @@ -74,6 +76,7 @@ ":cpp_base", "//net", "//services/network/public/mojom", + "//url", "//url/ipc:url_ipc", ] @@ -185,6 +188,7 @@ "digitally_signed_mojom_traits_unittest.cc", "host_resolver_mojom_traits_unittest.cc", "ip_address_mojom_traits_unittest.cc", + "is_potentially_trustworthy_unittest.cc", "mutable_network_traffic_annotation_tag_mojom_traits_unittest.cc", "mutable_partial_network_traffic_annotation_tag_mojom_traits_unittest.cc", "network_connection_tracker_unittest.cc",
diff --git a/services/network/public/cpp/is_potentially_trustworthy.cc b/services/network/public/cpp/is_potentially_trustworthy.cc new file mode 100644 index 0000000..30dc499 --- /dev/null +++ b/services/network/public/cpp/is_potentially_trustworthy.cc
@@ -0,0 +1,249 @@ +// 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 "services/network/public/cpp/is_potentially_trustworthy.h" + +#include "base/command_line.h" +#include "base/logging.h" +#include "base/metrics/histogram_macros.h" +#include "base/no_destructor.h" +#include "base/optional.h" +#include "base/sequence_checker.h" +#include "base/strings/pattern.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "build/build_config.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" +#include "net/base/url_util.h" +#include "services/network/public/cpp/network_switches.h" +#include "url/origin.h" +#include "url/scheme_host_port.h" +#include "url/url_canon.h" +#include "url/url_canon_ip.h" +#include "url/url_canon_stdstring.h" +#include "url/url_constants.h" +#include "url/url_util.h" + +namespace network { + +namespace { + +#if DCHECK_IS_ON() +base::Optional<base::SequenceChecker>& GetSequenceCheckerForAllowlist() { + static base::NoDestructor<base::Optional<base::SequenceChecker>> s_checker; + return *s_checker; +} +#endif + +#if DCHECK_IS_ON() +#define DCHECK_ALLOWLIST_USED_ON_VALID_SEQUENCE() \ + do { \ + if (GetSequenceCheckerForAllowlist().has_value()) { \ + DCHECK( \ + GetSequenceCheckerForAllowlist().value().CalledOnValidSequence()); \ + } \ + } while (false); +#else // DCHECK_IS_ON() +#define DCHECK_ALLOWLIST_USED_ON_VALID_SEQUENCE() EAT_STREAM_PARAMETERS +#endif + +// |g_should_reparse_secure_origin_allowlist_cmdline| is needed to allow tests +// to trigger reparsing of the cmdline switch. This global should remain set to +// |false| in production code. See also thread safety notes in +// GetSecureOriginAllowlist(). +bool g_should_reparse_secure_origin_allowlist_cmdline = false; + +// Given a hostname pattern with a wildcard such as "*.foo.com", returns +// true if |hostname_pattern| meets both of these conditions: +// 1.) A string matching |hostname_pattern| is a valid hostname. +// 2.) Wildcards only appear beyond the eTLD+1. "*.foo.com" is considered +// valid but "*.com" is not. +bool IsValidWildcardPattern(const std::string& hostname_pattern) { + // Replace wildcards with dummy values to check whether a matching origin is + // valid. + std::string wildcards_replaced; + if (!base::ReplaceChars(hostname_pattern, "*", "a", &wildcards_replaced)) + return false; + // Construct a SchemeHostPort with a dummy scheme and port to check that the + // hostname is valid. + url::SchemeHostPort scheme_host_port( + GURL(base::StringPrintf("http://%s:80", wildcards_replaced.c_str()))); + if (scheme_host_port.IsInvalid()) + return false; + + // Check that wildcards only appear beyond the eTLD+1. + size_t registry_length = + net::registry_controlled_domains::PermissiveGetHostRegistryLength( + hostname_pattern, + net::registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES, + net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); + // std::string::npos should only be returned for empty inputs, which should be + // filtered out by the IsInvalid() check above. + CHECK(registry_length != std::string::npos); + // If there is no registrar portion, the pattern is considered invalid. + if (registry_length == 0) + return false; + // If there is no component before the registrar portion, or if the component + // immediately preceding the registrar portion contains a wildcard, the + // pattern is not considered valid. + std::string host_before_registrar = + hostname_pattern.substr(0, hostname_pattern.size() - registry_length); + std::vector<std::string> components = + base::SplitString(host_before_registrar, ".", base::KEEP_WHITESPACE, + base::SPLIT_WANT_NONEMPTY); + if (components.size() == 0) + return false; + if (components.back().find("*") != std::string::npos) + return false; + return true; +} + +// Canonicalizes each component of |hostname_pattern|, making no changes to +// wildcard components or components that fail canonicalization. For example, +// given a |hostname_pattern| of "TeSt.*.%46oo.com", the output will be +// "test.*.foo.com". +std::string CanonicalizePatternComponents(const std::string& hostname_pattern) { + std::string canonical_host; // Do not modify outside of canon_output. + canonical_host.reserve(hostname_pattern.length()); + url::StdStringCanonOutput canon_output(&canonical_host); + + for (size_t current = 0; current < hostname_pattern.length(); current++) { + size_t begin = current; + + // Advance to next "." or end. + current = hostname_pattern.find('.', begin); + if (current == std::string::npos) + current = hostname_pattern.length(); + + // Try to append the canonicalized version of this component. + int current_len = base::checked_cast<int>(current - begin); + if (hostname_pattern.substr(begin, current_len) == "*" || + !url::CanonicalizeHostSubstring( + hostname_pattern.data(), + url::Component(base::checked_cast<int>(begin), current_len), + &canon_output)) { + // Failed to canonicalize this component; append as-is. + canon_output.Append(hostname_pattern.substr(begin, current_len).data(), + current_len); + } + + if (current < hostname_pattern.length()) + canon_output.push_back('.'); + } + canon_output.Complete(); + return canonical_host; +} + +std::vector<std::string> ParseSecureOriginAllowlistFromCmdline() { + // If kUnsafelyTreatInsecureOriginAsSecure option is given, then treat the + // value as a comma-separated list of origins or origin patterns. Callers + // that need to also check the kUnsafelyTreatInsecureOriginAsSecure pref + // value must instead use ParseAllowlist directly (as there is no way for + // CreateAllowlist() to access prefs). For renderer processes the pref and + // the switch will match, but for non-renderer processes the switch may + // not be set. + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + std::string origins_str = ""; + if (command_line.HasSwitch(switches::kUnsafelyTreatInsecureOriginAsSecure)) { + origins_str = command_line.GetSwitchValueASCII( + switches::kUnsafelyTreatInsecureOriginAsSecure); + } + return ParseSecureOriginAllowlist(origins_str); +} + +} // namespace + +const std::vector<std::string>& GetSecureOriginAllowlist() { + // This function will initialize |s_allowlist| in a thread-safe way because of + // the way how |static| works - invoking base::NoDestructor's constructor and + // ParseSecureOriginAllowlistFromCmdline in a thread-safe way and only once. + // + // OTOH, if ResetSecureOriginAllowlistForTesting forces reinitialization, then + // things are not thread-safe anymore. The DCHECK_ALLOWLIST_... below is + // trying to making sure that tests behave correctly. + DCHECK_ALLOWLIST_USED_ON_VALID_SEQUENCE(); + static base::NoDestructor<std::vector<std::string>> s_allowlist( + ParseSecureOriginAllowlistFromCmdline()); + + // If unit tests set |g_should_reparse_secure_origin_allowlist_cmdline| then + // reading |g_should_reparse_secure_origin_allowlist_cmdline| as well as + // reinitializing |s_allowlist| are NOT THREAD SAFE. This seems okay for unit + // tests (+ correct usage is verified by DCHECK_ALLOWLIST... above). + if (g_should_reparse_secure_origin_allowlist_cmdline) { + g_should_reparse_secure_origin_allowlist_cmdline = false; + *s_allowlist = ParseSecureOriginAllowlistFromCmdline(); + } + + return *s_allowlist; +} + +void ResetSecureOriginAllowlistForTesting() { +#if DCHECK_IS_ON() + DCHECK_ALLOWLIST_USED_ON_VALID_SEQUENCE(); + // Enforce sequence-affinity only *after* the first call to + // ResetSecureOriginAllowlistForTesting. + if (!GetSequenceCheckerForAllowlist().has_value()) { + // Construct a new base::SequenceChecked emplacing it into base::Optional. + GetSequenceCheckerForAllowlist().emplace(); + } +#endif + + g_should_reparse_secure_origin_allowlist_cmdline = true; +} + +bool IsAllowlistedAsSecureOrigin(const url::Origin& origin, + const std::vector<std::string>& allowlist) { + if (base::ContainsValue(allowlist, origin.Serialize())) + return true; + + for (const std::string& origin_or_pattern : allowlist) { + if (base::MatchPattern(origin.host(), origin_or_pattern)) + return true; + } + + return false; +} + +std::vector<std::string> ParseSecureOriginAllowlist( + const std::string& origins_str) { + std::vector<std::string> origin_patterns; + for (const std::string& origin_str : base::SplitString( + origins_str, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { + if (origin_str.find("*") != std::string::npos) { + if (IsValidWildcardPattern(origin_str)) { + std::string canonicalized_pattern = + CanonicalizePatternComponents(origin_str); + if (!canonicalized_pattern.empty()) { + origin_patterns.push_back(canonicalized_pattern); + continue; + } + } + LOG(ERROR) << "Allowlisted secure origin pattern " << origin_str + << " is not valid; ignoring."; + continue; + } + + // Drop .unique() origins, as they are unequal to any other origins. + url::Origin origin(url::Origin::Create(GURL(origin_str))); + if (!origin.opaque()) + origin_patterns.push_back(origin.Serialize()); + } + + UMA_HISTOGRAM_COUNTS_100("Security.TreatInsecureOriginAsSecure", + origin_patterns.size()); + +#if defined(OS_CHROMEOS) + // For Crostini, we allow access to the default VM/container as a secure + // origin via the hostname penguin.linux.test. We are required to use a + // wildcard for the prefix because we do not know what the port number is. + // https://chromium.googlesource.com/chromiumos/docs/+/master/containers_and_vms.md + origin_patterns.push_back("*.linux.test"); +#endif + + return origin_patterns; +} + +} // namespace network
diff --git a/services/network/public/cpp/is_potentially_trustworthy.h b/services/network/public/cpp/is_potentially_trustworthy.h new file mode 100644 index 0000000..279f6c4 --- /dev/null +++ b/services/network/public/cpp/is_potentially_trustworthy.h
@@ -0,0 +1,65 @@ +// 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 SERVICES_NETWORK_PUBLIC_CPP_IS_POTENTIALLY_TRUSTWORTHY_H_ +#define SERVICES_NETWORK_PUBLIC_CPP_IS_POTENTIALLY_TRUSTWORTHY_H_ + +#include <string> +#include <vector> + +#include "base/component_export.h" +#include "url/gurl.h" + +namespace url { +class Origin; +} // namespace url + +namespace network { + +// Return an allowlist of origins and hostname patterns that need to be +// considered trustworthy. The allowlist is given by the +// --unsafely-treat-insecure-origin-as-secure command-line option. See +// https://www.w3.org/TR/powerful-features/#is-origin-trustworthy. +// +// The allowlist can contain origins and wildcard hostname patterns up to +// eTLD+1. For example, the list may contain "http://foo.com", +// "http://foo.com:8000", "*.foo.com", "*.foo.*.bar.com", and +// "http://*.foo.bar.com", but not "*.co.uk", "*.com", or "test.*.com". Hostname +// patterns must contain a wildcard somewhere (so "test.com" is not a valid +// pattern) and wildcards can only replace full components ("test*.foo.com" is +// not valid). +// +// Plain origins ("http://foo.com") are canonicalized when they are inserted +// into this list by converting to url::Origin and serializing. For hostname +// patterns, each component is individually canonicalized. +// +// This function is safe to be called from any thread in production code (tests +// should see the warning in the ResetSecureOriginAllowlistForTesting comments +// below). +COMPONENT_EXPORT(NETWORK_CPP) +const std::vector<std::string>& GetSecureOriginAllowlist(); + +// Empties the secure origin allowlist. +// +// Thread-safety warning: Caller needs to ensure that all calls to +// GetSecureOriginAllowlist, IsAllowlistedAsSecureOrigin and +// ResetSecureOriginAllowlistForTesting are done from the same thread. +COMPONENT_EXPORT(NETWORK_CPP) void ResetSecureOriginAllowlistForTesting(); + +// Returns true if |origin| has a match in |allowlist|. |allowlist| is usually +// retrieved by GetSecureOriginAllowlist above. +COMPONENT_EXPORT(NETWORK_CPP) +bool IsAllowlistedAsSecureOrigin(const url::Origin& origin, + const std::vector<std::string>& allowlist); + +// Parses a comma-separated list of origins and wildcard hostname patterns. +// This separate function allows callers other than GetSecureOriginAllowlist() +// to explicitly pass an allowlist to be parsed. +COMPONENT_EXPORT(NETWORK_CPP) +std::vector<std::string> ParseSecureOriginAllowlist( + const std::string& origins_str); + +} // namespace network + +#endif // SERVICES_NETWORK_PUBLIC_CPP_IS_POTENTIALLY_TRUSTWORTHY_H_
diff --git a/services/network/public/cpp/is_potentially_trustworthy_unittest.cc b/services/network/public/cpp/is_potentially_trustworthy_unittest.cc new file mode 100644 index 0000000..ec7ced4 --- /dev/null +++ b/services/network/public/cpp/is_potentially_trustworthy_unittest.cc
@@ -0,0 +1,112 @@ +// 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 "services/network/public/cpp/is_potentially_trustworthy.h" + +#include "base/test/scoped_command_line.h" +#include "services/network/public/cpp/network_switches.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace network { + +bool IsAllowlistedAsSecureOrigin(const url::Origin& origin) { + return IsAllowlistedAsSecureOrigin(origin, + network::GetSecureOriginAllowlist()); +} + +class SecureOriginAllowlistTest : public testing::Test { + void TearDown() override { + // Ensure that we reset the allowlisted origins without any flags applied. + ResetSecureOriginAllowlistForTesting(); + } +}; + +TEST_F(SecureOriginAllowlistTest, UnsafelyTreatInsecureOriginAsSecure) { + EXPECT_FALSE(IsAllowlistedAsSecureOrigin( + url::Origin::Create(GURL("http://example.com/a.html")))); + EXPECT_FALSE(IsAllowlistedAsSecureOrigin( + url::Origin::Create(GURL("http://127.example.com/a.html")))); + // TODO(lukasza): Reintegrate this test with IsPotentiallyTrustworthy + // function (temporarily still in the //content layer) + // EXPECT_FALSE(IsPotentiallyTrustworthy("http://example.com/a.html")); + // EXPECT_FALSE(IsPotentiallyTrustworthy("http://127.example.com/a.html")); + + // Add http://example.com and http://127.example.com to allowlist by + // command-line and see if they are now considered secure origins. + // (The command line is applied via + // ChromeContentClient::AddSecureSchemesAndOrigins) + base::test::ScopedCommandLine scoped_command_line; + base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine(); + command_line->AppendSwitchASCII( + switches::kUnsafelyTreatInsecureOriginAsSecure, + "http://example.com,http://127.example.com"); + ResetSecureOriginAllowlistForTesting(); + + // They should be now allow-listed. + EXPECT_TRUE(IsAllowlistedAsSecureOrigin( + url::Origin::Create(GURL("http://example.com/a.html")))); + EXPECT_TRUE(IsAllowlistedAsSecureOrigin( + url::Origin::Create(GURL("http://127.example.com/a.html")))); + // TODO(lukasza): Reintegrate this test with IsPotentiallyTrustworthy + // function (temporarily still in the //content layer) + // EXPECT_TRUE(IsPotentiallyTrustworthy("http://example.com/a.html")); + // EXPECT_TRUE(IsPotentiallyTrustworthy("http://127.example.com/a.html")); + + // Check that similarly named sites are not considered secure. + // TODO(lukasza): Reintegrate this test with IsPotentiallyTrustworthy + // function (temporarily still in the //content layer) + // EXPECT_FALSE(IsPotentiallyTrustworthy("http://128.example.com/a.html")); + // EXPECT_FALSE( + // IsPotentiallyTrustworthy("http://foobar.127.example.com/a.html")); +} + +TEST_F(SecureOriginAllowlistTest, HostnamePatterns) { + const struct HostnamePatternCase { + const char* pattern; + const char* test_input; + bool expected_secure; + } kTestCases[] = { + {"*.foo.com", "http://bar.foo.com", true}, + {"*.foo.*.bar.com", "http://a.foo.b.bar.com:8000", true}, + // For parsing/canonicalization simplicity, wildcard patterns can be + // hostnames only, not full origins. + {"http://*.foo.com", "http://bar.foo.com", false}, + {"*://foo.com", "http://foo.com", false}, + // Wildcards must be beyond eTLD+1. + {"*.co.uk", "http://foo.co.uk", false}, + {"*.co.uk", "http://co.uk", false}, + {"*.baz", "http://foo.baz", false}, + {"foo.*.com", "http://foo.bar.com", false}, + {"*.foo.baz", "http://a.foo.baz", true}, + // Hostname patterns should be canonicalized. + {"*.FoO.com", "http://a.foo.com", true}, + {"%2A.foo.com", "http://a.foo.com", false}, + // Hostname patterns must contain a wildcard and a wildcard can only + // replace a component, not a part of a component. + {"foo.com", "http://foo.com", false}, + {"test*.foo.com", "http://testblah.foo.com", false}, + {"*foo.com", "http://testfoo.com", false}, + {"foo*.com", "http://footest.com", false}, + }; + + for (const auto& test : kTestCases) { + base::test::ScopedCommandLine scoped_command_line; + base::CommandLine* command_line = + scoped_command_line.GetProcessCommandLine(); + command_line->AppendSwitchASCII( + switches::kUnsafelyTreatInsecureOriginAsSecure, test.pattern); + ResetSecureOriginAllowlistForTesting(); + GURL input_url(test.test_input); + url::Origin input_origin = url::Origin::Create(input_url); + EXPECT_EQ(test.expected_secure, IsAllowlistedAsSecureOrigin(input_origin)); + // TODO(lukasza): Reintegrate this test with IsPotentiallyTrustworthy + // function (temporarily still in the //content layer) + // EXPECT_EQ(test.expected_secure, + // IsPotentiallyTrustworthy(test.test_input)); + } +} + +} // namespace network
diff --git a/services/network/public/cpp/net_ipc_param_traits.h b/services/network/public/cpp/net_ipc_param_traits.h index 3cff701..8db5f62c 100644 --- a/services/network/public/cpp/net_ipc_param_traits.h +++ b/services/network/public/cpp/net_ipc_param_traits.h
@@ -278,7 +278,6 @@ IPC_STRUCT_TRAITS_MEMBER(new_top_frame_origin) IPC_STRUCT_TRAITS_MEMBER(new_referrer) IPC_STRUCT_TRAITS_MEMBER(insecure_scheme_was_upgraded) - IPC_STRUCT_TRAITS_MEMBER(is_signed_exchange_fallback_redirect) IPC_STRUCT_TRAITS_MEMBER(new_referrer_policy) IPC_STRUCT_TRAITS_END()
diff --git a/services/network/public/cpp/network_switches.cc b/services/network/public/cpp/network_switches.cc index 60859bc4..7505008b 100644 --- a/services/network/public/cpp/network_switches.cc +++ b/services/network/public/cpp/network_switches.cc
@@ -53,6 +53,16 @@ // list of port numbers. const char kExplicitlyAllowedPorts[] = "explicitly-allowed-ports"; +// Treat given (insecure) origins as secure origins. Multiple origins can be +// supplied as a comma-separated list. For the definition of secure contexts, +// see https://w3c.github.io/webappsec-secure-contexts/ and +// https://www.w3.org/TR/powerful-features/#is-origin-trustworthy +// +// Example: +// --unsafely-treat-insecure-origin-as-secure=http://a.test,http://b.test +const char kUnsafelyTreatInsecureOriginAsSecure[] = + "unsafely-treat-insecure-origin-as-secure"; + } // namespace switches } // namespace network
diff --git a/services/network/public/cpp/network_switches.h b/services/network/public/cpp/network_switches.h index db64e5a..42de65482 100644 --- a/services/network/public/cpp/network_switches.h +++ b/services/network/public/cpp/network_switches.h
@@ -21,6 +21,8 @@ COMPONENT_EXPORT(NETWORK_CPP) extern const char kSSLKeyLogFile[]; COMPONENT_EXPORT(NETWORK_CPP) extern const char kNoReferrers[]; COMPONENT_EXPORT(NETWORK_CPP) extern const char kExplicitlyAllowedPorts[]; +COMPONENT_EXPORT(NETWORK_CPP) +extern const char kUnsafelyTreatInsecureOriginAsSecure[]; } // namespace switches
diff --git a/services/network/public/mojom/url_loader.mojom b/services/network/public/mojom/url_loader.mojom index 1d46b702..049da805 100644 --- a/services/network/public/mojom/url_loader.mojom +++ b/services/network/public/mojom/url_loader.mojom
@@ -340,8 +340,8 @@ // For kRawFile mojo_base.mojom.File? file; // For kBlob - // TODO(richard.li): Deprecate this once NetworkService is fully shipped. - string? blob_uuid; + // TODO(Richard): Deprecate this once NetworkService is fully shipped. + string blob_uuid; // For kDataPipe network.mojom.DataPipeGetter? data_pipe_getter; // For kChunkedDataPipe
diff --git a/services/network/session_cleanup_channel_id_store.cc b/services/network/session_cleanup_channel_id_store.cc deleted file mode 100644 index e3de7d99..0000000 --- a/services/network/session_cleanup_channel_id_store.cc +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "services/network/session_cleanup_channel_id_store.h" - -#include <list> - -#include "base/bind.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/string_util.h" -#include "base/threading/thread.h" -#include "base/threading/thread_restrictions.h" -#include "net/cookies/cookie_util.h" -#include "net/extras/sqlite/sqlite_channel_id_store.h" -#include "url/gurl.h" - -namespace network { - -SessionCleanupChannelIDStore::SessionCleanupChannelIDStore( - const base::FilePath& path, - const scoped_refptr<base::SequencedTaskRunner>& background_task_runner) - : persistent_store_( - new net::SQLiteChannelIDStore(path, background_task_runner)) { - DCHECK(background_task_runner.get()); -} - -SessionCleanupChannelIDStore::~SessionCleanupChannelIDStore() {} - -void SessionCleanupChannelIDStore::DeleteSessionChannelIDs( - DeleteChannelIDPredicate delete_channel_id_predicate) { - if (force_keep_session_state_ || !delete_channel_id_predicate) - return; - - std::list<std::string> session_only_server_identifiers; - for (const std::string& server_identifier : server_identifiers_) { - GURL url(net::cookie_util::CookieOriginToURL(server_identifier, true)); - if (delete_channel_id_predicate.Run(url)) - session_only_server_identifiers.push_back(server_identifier); - } - persistent_store_->DeleteAllInList(session_only_server_identifiers); -} - -void SessionCleanupChannelIDStore::Load(const LoadedCallback& loaded_callback) { - persistent_store_->Load(base::BindRepeating( - &SessionCleanupChannelIDStore::OnLoad, this, loaded_callback)); -} - -void SessionCleanupChannelIDStore::AddChannelID( - const net::DefaultChannelIDStore::ChannelID& channel_id) { - server_identifiers_.insert(channel_id.server_identifier()); - persistent_store_->AddChannelID(channel_id); -} - -void SessionCleanupChannelIDStore::DeleteChannelID( - const net::DefaultChannelIDStore::ChannelID& channel_id) { - server_identifiers_.erase(channel_id.server_identifier()); - persistent_store_->DeleteChannelID(channel_id); -} - -void SessionCleanupChannelIDStore::Flush() { - persistent_store_->Flush(); -} - -void SessionCleanupChannelIDStore::SetForceKeepSessionState() { - force_keep_session_state_ = true; -} - -void SessionCleanupChannelIDStore::OnLoad( - const LoadedCallback& loaded_callback, - std::unique_ptr<ChannelIDVector> channel_ids) { - for (const auto& channel_id : *channel_ids) - server_identifiers_.insert(channel_id->server_identifier()); - loaded_callback.Run(std::move(channel_ids)); -} - -} // namespace network
diff --git a/services/network/session_cleanup_channel_id_store.h b/services/network/session_cleanup_channel_id_store.h deleted file mode 100644 index e32a493..0000000 --- a/services/network/session_cleanup_channel_id_store.h +++ /dev/null
@@ -1,80 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SERVICES_NETWORK_SESSION_CLEANUP_CHANNEL_ID_STORE_H_ -#define SERVICES_NETWORK_SESSION_CLEANUP_CHANNEL_ID_STORE_H_ - -#include <set> -#include <string> -#include <vector> - -#include "base/callback_forward.h" -#include "base/compiler_specific.h" -#include "base/component_export.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "net/extras/sqlite/sqlite_channel_id_store.h" -#include "net/ssl/default_channel_id_store.h" - -class GURL; - -namespace base { -class FilePath; -class SequencedTaskRunner; -} // namespace base - -namespace network { - -// Implements a PersistentStore that keeps an in-memory map of channel IDs, and -// allows deletion of channel IDs using the DeleteChannelIDPredicate. This is -// used to clear channel IDs with session-only policy at the end of a session. -class COMPONENT_EXPORT(NETWORK_SERVICE) SessionCleanupChannelIDStore - : public net::DefaultChannelIDStore::PersistentStore { - public: - // Returns true if the channel ID for the URL should be deleted. - using DeleteChannelIDPredicate = base::RepeatingCallback<bool(const GURL&)>; - - // Create or open persistent store in file |path|. All I/O tasks are performed - // in background using |background_task_runner|. - SessionCleanupChannelIDStore( - const base::FilePath& path, - const scoped_refptr<base::SequencedTaskRunner>& background_task_runner); - - // net::DefaultChannelIDStore::PersistentStore: - void Load(const LoadedCallback& loaded_callback) override; - void AddChannelID( - const net::DefaultChannelIDStore::ChannelID& channel_id) override; - void DeleteChannelID( - const net::DefaultChannelIDStore::ChannelID& channel_id) override; - void Flush() override; - void SetForceKeepSessionState() override; - - // Should be called at the end of a session. Deletes all channel IDs that - // |delete_channel_id_predicate| returns true for. - void DeleteSessionChannelIDs( - DeleteChannelIDPredicate delete_channel_id_predicate); - - protected: - ~SessionCleanupChannelIDStore() override; - - private: - using ChannelIDVector = - std::vector<std::unique_ptr<net::DefaultChannelIDStore::ChannelID>>; - - void OnLoad(const LoadedCallback& loaded_callback, - std::unique_ptr<ChannelIDVector> channel_ids); - - scoped_refptr<net::SQLiteChannelIDStore> persistent_store_; - // Cache of server identifiers we have channel IDs stored for. - std::set<std::string> server_identifiers_; - // When set to true, DeleteSessionChannelIDs will be a no-op, and all channel - // IDs will be kept. - bool force_keep_session_state_ = false; - - DISALLOW_COPY_AND_ASSIGN(SessionCleanupChannelIDStore); -}; - -} // namespace network - -#endif // SERVICES_NETWORK_SESSION_CLEANUP_CHANNEL_ID_STORE_H_
diff --git a/services/network/session_cleanup_channel_id_store_unittest.cc b/services/network/session_cleanup_channel_id_store_unittest.cc deleted file mode 100644 index 512be9f2..0000000 --- a/services/network/session_cleanup_channel_id_store_unittest.cc +++ /dev/null
@@ -1,186 +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. - -#include "services/network/session_cleanup_channel_id_store.h" - -#include <vector> - -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/memory/ref_counted.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/test/scoped_task_environment.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/time/time.h" -#include "net/test/channel_id_test_util.h" -#include "net/test/test_data_directory.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -namespace network { -namespace { - -using ChannelIDVector = - std::vector<std::unique_ptr<net::DefaultChannelIDStore::ChannelID>>; - -const base::FilePath::CharType kTestChannelIDFilename[] = - FILE_PATH_LITERAL("ChannelID"); - -class SessionCleanupChannelIDStoreTest : public testing::Test { - public: - ChannelIDVector Load() { - ChannelIDVector channel_ids; - base::RunLoop run_loop; - store_->Load( - base::BindRepeating(&SessionCleanupChannelIDStoreTest::OnLoaded, - base::Unretained(this), &run_loop, &channel_ids)); - run_loop.Run(); - return channel_ids; - } - - void OnLoaded(base::RunLoop* run_loop, - ChannelIDVector* channel_ids_out, - std::unique_ptr<ChannelIDVector> channel_ids) { - channel_ids_out->swap(*channel_ids); - run_loop->Quit(); - } - - ChannelIDVector CreateAndLoad() { - store_ = base::MakeRefCounted<SessionCleanupChannelIDStore>( - temp_dir_.GetPath().Append(kTestChannelIDFilename), - scoped_task_environment_.GetMainThreadTaskRunner()); - return Load(); - } - - protected: - void SetUp() override { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - ChannelIDVector channel_ids = CreateAndLoad(); - ASSERT_EQ(0u, channel_ids.size()); - } - - void TearDown() override { - store_ = nullptr; - scoped_task_environment_.RunUntilIdle(); - } - - base::ScopedTempDir temp_dir_; - scoped_refptr<SessionCleanupChannelIDStore> store_; - base::test::ScopedTaskEnvironment scoped_task_environment_; -}; - -TEST_F(SessionCleanupChannelIDStoreTest, TestPersistence) { - std::unique_ptr<crypto::ECPrivateKey> goog_key( - crypto::ECPrivateKey::Create()); - std::unique_ptr<crypto::ECPrivateKey> foo_key(crypto::ECPrivateKey::Create()); - store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( - "google.com", base::Time::FromDoubleT(1), goog_key->Copy())); - store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( - "foo.com", base::Time::FromDoubleT(3), foo_key->Copy())); - - // Replace the store effectively destroying the current one and forcing it - // to write its data to disk. Then we can see if after loading it again it - // is still there. - store_ = nullptr; - // Make sure we wait until the destructor has run. - scoped_task_environment_.RunUntilIdle(); - - // Reload and test for persistence - ChannelIDVector channel_ids = CreateAndLoad(); - ASSERT_EQ(2u, channel_ids.size()); - net::DefaultChannelIDStore::ChannelID* goog_channel_id; - net::DefaultChannelIDStore::ChannelID* foo_channel_id; - if (channel_ids[0]->server_identifier() == "google.com") { - goog_channel_id = channel_ids[0].get(); - foo_channel_id = channel_ids[1].get(); - } else { - goog_channel_id = channel_ids[1].get(); - foo_channel_id = channel_ids[0].get(); - } - EXPECT_EQ("google.com", goog_channel_id->server_identifier()); - EXPECT_TRUE(net::KeysEqual(goog_key.get(), goog_channel_id->key())); - EXPECT_EQ(1, goog_channel_id->creation_time().ToDoubleT()); - EXPECT_EQ("foo.com", foo_channel_id->server_identifier()); - EXPECT_TRUE(net::KeysEqual(foo_key.get(), foo_channel_id->key())); - EXPECT_EQ(3, foo_channel_id->creation_time().ToDoubleT()); - - // Now delete the channel ID and check persistence again. - store_->DeleteChannelID(*channel_ids[0]); - store_->DeleteChannelID(*channel_ids[1]); - store_ = nullptr; - // Make sure we wait until the destructor has run. - scoped_task_environment_.RunUntilIdle(); - - // Reload and check if the channel ID has been removed. - channel_ids = CreateAndLoad(); - EXPECT_EQ(0u, channel_ids.size()); -} - -TEST_F(SessionCleanupChannelIDStoreTest, TestDeleteSessionChannelIDs) { - store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( - "google.com", base::Time::FromDoubleT(1), - crypto::ECPrivateKey::Create())); - store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( - "nonpersistent.com", base::Time::FromDoubleT(3), - crypto::ECPrivateKey::Create())); - - // Replace the store and force it to write to disk. - store_ = nullptr; - scoped_task_environment_.RunUntilIdle(); - ChannelIDVector channel_ids = CreateAndLoad(); - EXPECT_EQ(2u, channel_ids.size()); - - // Add another two channel IDs before closing the store. Because additions are - // delayed and committed to disk in batches, these will not be committed until - // the store is destroyed, which is after the policy is applied. The pending - // operation pruning logic should prevent the "nonpersistent.com" ID from - // being committed to disk. - store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( - "nonpersistent.com", base::Time::FromDoubleT(5), - crypto::ECPrivateKey::Create())); - store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( - "persistent.com", base::Time::FromDoubleT(7), - crypto::ECPrivateKey::Create())); - - store_->DeleteSessionChannelIDs(base::BindRepeating( - [](const GURL& url) { return url.host() == "nonpersistent.com"; })); - scoped_task_environment_.RunUntilIdle(); - // Now close the store, and the nonpersistent.com channel IDs should have been - // deleted. - store_ = nullptr; - scoped_task_environment_.RunUntilIdle(); - - // Reload and check that the nonpersistent.com channel IDs have been removed. - channel_ids = CreateAndLoad(); - EXPECT_EQ(2u, channel_ids.size()); - for (const auto& id : channel_ids) { - EXPECT_NE("nonpersistent.com", id->server_identifier()); - } -} - -TEST_F(SessionCleanupChannelIDStoreTest, TestForceKeepSessionState) { - store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( - "google.com", base::Time::FromDoubleT(1), - crypto::ECPrivateKey::Create())); - store_->AddChannelID(net::DefaultChannelIDStore::ChannelID( - "nonpersistent.com", base::Time::FromDoubleT(3), - crypto::ECPrivateKey::Create())); - - store_->SetForceKeepSessionState(); - store_->DeleteSessionChannelIDs(base::BindRepeating( - [](const GURL& url) { return url.host() == "nonpersistent.com"; })); - scoped_task_environment_.RunUntilIdle(); - - store_ = nullptr; - scoped_task_environment_.RunUntilIdle(); - - // Reload and check that the all channel IDs are still present. - ChannelIDVector channel_ids = CreateAndLoad(); - EXPECT_EQ(2u, channel_ids.size()); -} - -} // namespace -} // namespace network
diff --git a/services/network/session_cleanup_cookie_store.cc b/services/network/session_cleanup_cookie_store.cc index 74939b56..8cd780da 100644 --- a/services/network/session_cleanup_cookie_store.cc +++ b/services/network/session_cleanup_cookie_store.cc
@@ -119,9 +119,9 @@ force_keep_session_state_ = true; } -void SessionCleanupCookieStore::SetBeforeFlushCallback( +void SessionCleanupCookieStore::SetBeforeCommitCallback( base::RepeatingClosure callback) { - persistent_store_->SetBeforeFlushCallback(std::move(callback)); + persistent_store_->SetBeforeCommitCallback(std::move(callback)); } void SessionCleanupCookieStore::Flush(base::OnceClosure callback) {
diff --git a/services/network/session_cleanup_cookie_store.h b/services/network/session_cleanup_cookie_store.h index 2443984..6cbdea17 100644 --- a/services/network/session_cleanup_cookie_store.h +++ b/services/network/session_cleanup_cookie_store.h
@@ -52,7 +52,7 @@ void UpdateCookieAccessTime(const net::CanonicalCookie& cc) override; void DeleteCookie(const net::CanonicalCookie& cc) override; void SetForceKeepSessionState() override; - void SetBeforeFlushCallback(base::RepeatingClosure callback) override; + void SetBeforeCommitCallback(base::RepeatingClosure callback) override; void Flush(base::OnceClosure callback) override; // Should be called at the end of a session. Deletes all cookies that
diff --git a/services/viz/public/cpp/compositing/shared_quad_state_struct_traits.h b/services/viz/public/cpp/compositing/shared_quad_state_struct_traits.h index 247087f..fe9ba92 100644 --- a/services/viz/public/cpp/compositing/shared_quad_state_struct_traits.h +++ b/services/viz/public/cpp/compositing/shared_quad_state_struct_traits.h
@@ -7,6 +7,7 @@ #include "components/viz/common/quads/shared_quad_state.h" #include "services/viz/public/interfaces/compositing/shared_quad_state.mojom-shared.h" +#include "ui/gfx/mojo/rrect_f_struct_traits.h" namespace mojo { @@ -34,6 +35,11 @@ return input.sqs->visible_quad_layer_rect; } + static const gfx::RRectF& rounded_corner_bounds( + const OptSharedQuadState& input) { + return input.sqs->rounded_corner_bounds; + } + static const gfx::Rect& clip_rect(const OptSharedQuadState& input) { return input.sqs->clip_rect; } @@ -75,6 +81,11 @@ return sqs.visible_quad_layer_rect; } + static const gfx::RRectF& rounded_corner_bounds( + const viz::SharedQuadState& sqs) { + return sqs.rounded_corner_bounds; + } + static const gfx::Rect& clip_rect(const viz::SharedQuadState& sqs) { return sqs.clip_rect; } @@ -102,6 +113,7 @@ if (!data.ReadQuadToTargetTransform(&out->quad_to_target_transform) || !data.ReadQuadLayerRect(&out->quad_layer_rect) || !data.ReadVisibleQuadLayerRect(&out->visible_quad_layer_rect) || + !data.ReadRoundedCornerBounds(&out->rounded_corner_bounds) || !data.ReadClipRect(&out->clip_rect)) { return false; }
diff --git a/services/viz/public/cpp/compositing/struct_traits_perftest.cc b/services/viz/public/cpp/compositing/struct_traits_perftest.cc index 421beb9..7207f7d 100644 --- a/services/viz/public/cpp/compositing/struct_traits_perftest.cc +++ b/services/viz/public/cpp/compositing/struct_traits_perftest.cc
@@ -157,6 +157,8 @@ gfx::RectF arbitrary_rectf1(4.2f, -922.1f, 15.6f, 29.5f); gfx::RRectF arbitrary_rrectf1(4.2f, -922.1f, 15.6f, 29.5f, 1.2f, 2.3f, 3.4f, 4.5f, 5.6f, 6.7f, 7.8f, 8.9f); + gfx::RRectF arbitrary_rrectf2(gfx::RectF(1.f, 2.f, 30.f, 45.f), 5.f); + gfx::RRectF arbitrary_rrectf3(gfx::RectF(5.f, 6.f, 20.f, 35.f), 2.f, 3.f); gfx::PointF arbitrary_pointf1(31.4f, 15.9f); gfx::PointF arbitrary_pointf2(26.5f, -35.8f); float arbitrary_float1 = 0.7f; @@ -209,9 +211,9 @@ SharedQuadState* shared_state1_in = pass_in->CreateAndAppendSharedQuadState(); shared_state1_in->SetAll( - arbitrary_matrix1, arbitrary_rect1, arbitrary_rect1, arbitrary_rect2, - arbitrary_bool1, arbitrary_bool1, arbitrary_float1, - arbitrary_blend_mode1, arbitrary_context_id1); + arbitrary_matrix1, arbitrary_rect1, arbitrary_rect1, + arbitrary_rrectf1, arbitrary_rect2, arbitrary_bool1, arbitrary_bool1, + arbitrary_float1, arbitrary_blend_mode1, arbitrary_context_id1); auto* texture_in = pass_in->CreateAndAppendDrawQuad<TextureDrawQuad>(); texture_in->SetAll( @@ -251,9 +253,9 @@ SharedQuadState* shared_state2_in = pass_in->CreateAndAppendSharedQuadState(); shared_state2_in->SetAll( - arbitrary_matrix2, arbitrary_rect2, arbitrary_rect2, arbitrary_rect3, - arbitrary_bool1, arbitrary_bool1, arbitrary_float2, - arbitrary_blend_mode2, arbitrary_context_id2); + arbitrary_matrix2, arbitrary_rect2, arbitrary_rect2, + arbitrary_rrectf2, arbitrary_rect3, arbitrary_bool1, arbitrary_bool1, + arbitrary_float2, arbitrary_blend_mode2, arbitrary_context_id2); for (uint32_t j = 0; j < 6; ++j) { auto* tile_in = pass_in->CreateAndAppendDrawQuad<TileDrawQuad>(); tile_in->SetAll(shared_state2_in, arbitrary_rect2, @@ -269,9 +271,9 @@ SharedQuadState* shared_state3_in = pass_in->CreateAndAppendSharedQuadState(); shared_state3_in->SetAll( - arbitrary_matrix1, arbitrary_rect3, arbitrary_rect3, arbitrary_rect1, - arbitrary_bool1, arbitrary_bool1, arbitrary_float3, - arbitrary_blend_mode3, arbitrary_context_id3); + arbitrary_matrix1, arbitrary_rect3, arbitrary_rect3, + arbitrary_rrectf3, arbitrary_rect1, arbitrary_bool1, arbitrary_bool1, + arbitrary_float3, arbitrary_blend_mode3, arbitrary_context_id3); for (uint32_t j = 0; j < 5; ++j) { auto* solidcolor_in = pass_in->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
diff --git a/services/viz/public/cpp/compositing/struct_traits_unittest.cc b/services/viz/public/cpp/compositing/struct_traits_unittest.cc index d552e6ee..c8f50569 100644 --- a/services/viz/public/cpp/compositing/struct_traits_unittest.cc +++ b/services/viz/public/cpp/compositing/struct_traits_unittest.cc
@@ -413,6 +413,7 @@ 13.f, 14.f, 15.f, 16.f); const gfx::Rect layer_rect(1234, 5678); const gfx::Rect visible_layer_rect(12, 34, 56, 78); + const gfx::RRectF rounded_corner_bounds(gfx::RectF(1.f, 2.f, 30.f, 40.f), 5); const gfx::Rect clip_rect(123, 456, 789, 101112); const bool is_clipped = true; bool are_contents_opaque = true; @@ -421,14 +422,16 @@ const int sorting_context_id = 1337; SharedQuadState input_sqs; input_sqs.SetAll(quad_to_target_transform, layer_rect, visible_layer_rect, - clip_rect, is_clipped, are_contents_opaque, opacity, - blend_mode, sorting_context_id); + rounded_corner_bounds, clip_rect, is_clipped, + are_contents_opaque, opacity, blend_mode, + sorting_context_id); SharedQuadState output_sqs; mojo::test::SerializeAndDeserialize<mojom::SharedQuadState>(&input_sqs, &output_sqs); EXPECT_EQ(quad_to_target_transform, output_sqs.quad_to_target_transform); EXPECT_EQ(layer_rect, output_sqs.quad_layer_rect); EXPECT_EQ(visible_layer_rect, output_sqs.visible_quad_layer_rect); + EXPECT_EQ(rounded_corner_bounds, output_sqs.rounded_corner_bounds); EXPECT_EQ(clip_rect, output_sqs.clip_rect); EXPECT_EQ(is_clipped, output_sqs.is_clipped); EXPECT_EQ(opacity, output_sqs.opacity); @@ -449,6 +452,8 @@ 15.f, 16.f); const gfx::Rect sqs_layer_rect(1234, 5678); const gfx::Rect sqs_visible_layer_rect(12, 34, 56, 78); + const gfx::RRectF sqs_rounded_corner_bounds(gfx::RectF(3.f, 4.f, 50.f, 15.f), + 3); const gfx::Rect sqs_clip_rect(123, 456, 789, 101112); const bool sqs_is_clipped = true; bool sqs_are_contents_opaque = false; @@ -457,9 +462,9 @@ const int sqs_sorting_context_id = 1337; SharedQuadState* sqs = render_pass->CreateAndAppendSharedQuadState(); sqs->SetAll(sqs_quad_to_target_transform, sqs_layer_rect, - sqs_visible_layer_rect, sqs_clip_rect, sqs_is_clipped, - sqs_are_contents_opaque, sqs_opacity, sqs_blend_mode, - sqs_sorting_context_id); + sqs_visible_layer_rect, sqs_rounded_corner_bounds, sqs_clip_rect, + sqs_is_clipped, sqs_are_contents_opaque, sqs_opacity, + sqs_blend_mode, sqs_sorting_context_id); // DebugBorderDrawQuad. const gfx::Rect rect1(1234, 4321, 1357, 7531); @@ -540,6 +545,7 @@ EXPECT_EQ(sqs_quad_to_target_transform, out_sqs->quad_to_target_transform); EXPECT_EQ(sqs_layer_rect, out_sqs->quad_layer_rect); EXPECT_EQ(sqs_visible_layer_rect, out_sqs->visible_quad_layer_rect); + EXPECT_EQ(sqs_rounded_corner_bounds, out_sqs->rounded_corner_bounds); EXPECT_EQ(sqs_clip_rect, out_sqs->clip_rect); EXPECT_EQ(sqs_is_clipped, out_sqs->is_clipped); EXPECT_EQ(sqs_are_contents_opaque, out_sqs->are_contents_opaque); @@ -762,6 +768,7 @@ gfx::Transform(16.1f, 15.3f, 14.3f, 13.7f, 12.2f, 11.4f, 10.4f, 9.8f, 8.1f, 7.3f, 6.3f, 5.7f, 4.8f, 3.4f, 2.4f, 1.2f), gfx::Rect(1, 2), gfx::Rect(1337, 5679, 9101112, 131415), + gfx::RRectF(gfx::RectF(5.f, 6.f, 70.f, 89.f), 10.f), gfx::Rect(1357, 2468, 121314, 1337), true, true, 2, SkBlendMode::kSrcOver, 1); @@ -770,6 +777,7 @@ gfx::Transform(1.1f, 2.3f, 3.3f, 4.7f, 5.2f, 6.4f, 7.4f, 8.8f, 9.1f, 10.3f, 11.3f, 12.7f, 13.8f, 14.4f, 15.4f, 16.2f), gfx::Rect(1337, 1234), gfx::Rect(1234, 5678, 9101112, 13141516), + gfx::RRectF(gfx::RectF(23.f, 45.f, 60.f, 70.f), 8.f), gfx::Rect(1357, 2468, 121314, 1337), true, true, 2, SkBlendMode::kSrcOver, 1); @@ -826,6 +834,8 @@ EXPECT_EQ(shared_state_1->quad_layer_rect, out_sqs1->quad_layer_rect); EXPECT_EQ(shared_state_1->visible_quad_layer_rect, out_sqs1->visible_quad_layer_rect); + EXPECT_EQ(shared_state_1->rounded_corner_bounds, + out_sqs1->rounded_corner_bounds); EXPECT_EQ(shared_state_1->clip_rect, out_sqs1->clip_rect); EXPECT_EQ(shared_state_1->is_clipped, out_sqs1->is_clipped); EXPECT_EQ(shared_state_1->opacity, out_sqs1->opacity); @@ -838,6 +848,8 @@ EXPECT_EQ(shared_state_2->quad_layer_rect, out_sqs2->quad_layer_rect); EXPECT_EQ(shared_state_2->visible_quad_layer_rect, out_sqs2->visible_quad_layer_rect); + EXPECT_EQ(shared_state_2->rounded_corner_bounds, + out_sqs2->rounded_corner_bounds); EXPECT_EQ(shared_state_2->clip_rect, out_sqs2->clip_rect); EXPECT_EQ(shared_state_2->is_clipped, out_sqs2->is_clipped); EXPECT_EQ(shared_state_2->opacity, out_sqs2->opacity);
diff --git a/services/viz/public/interfaces/compositing/shared_quad_state.mojom b/services/viz/public/interfaces/compositing/shared_quad_state.mojom index a6d8222..6ca90c7 100644 --- a/services/viz/public/interfaces/compositing/shared_quad_state.mojom +++ b/services/viz/public/interfaces/compositing/shared_quad_state.mojom
@@ -5,6 +5,7 @@ module viz.mojom; import "ui/gfx/geometry/mojo/geometry.mojom"; +import "ui/gfx/mojo/rrect_f.mojom"; import "ui/gfx/mojo/transform.mojom"; struct SharedQuadState { @@ -18,6 +19,10 @@ // of the quad rects. gfx.mojom.Rect visible_quad_layer_rect; + // This rect lives in the target content space. It defines the corner radius + // to clip the quads with. + gfx.mojom.RRectF rounded_corner_bounds; + // This rect lives in the target content space. gfx.mojom.Rect clip_rect;
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index e93ca30..618714e 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -3909,9 +3909,9 @@ ], "experiments": [ { - "name": "SlowPageTriggeringFor3G_20181204", + "name": "SlowPageTriggeringFor4G_20190312", "params": { - "session_max_ect_trigger": "3G" + "session_max_ect_trigger": "4G" }, "enable_features": [ "PreviewsSlowPageTriggering"
diff --git a/third_party/android_deps/BUILD.gn b/third_party/android_deps/BUILD.gn index 80f1162..6aad7aa 100644 --- a/third_party/android_deps/BUILD.gn +++ b/third_party/android_deps/BUILD.gn
@@ -24,91 +24,7 @@ ] } -java_group("android_support_multidex_java") { - deps = [ - ":com_android_support_multidex_java", - ] -} -java_group("android_support_annotations_java") { - deps = [ - ":com_android_support_support_annotations_java", - ] -} -java_group("android_support_cardview_java") { - deps = [ - ":com_android_support_cardview_v7_java", - ] -} -java_group("android_support_compat_java") { - deps = [ - ":com_android_support_support_compat_java", - ] -} -java_group("android_support_core_ui_java") { - deps = [ - ":com_android_support_support_core_ui_java", - ] -} -java_group("android_support_core_utils_java") { - deps = [ - ":com_android_support_support_core_utils_java", - ] -} -java_group("android_support_design_java") { - deps = [ - ":com_android_support_design_java", - ] -} -java_group("android_support_fragment_java") { - deps = [ - ":com_android_support_support_fragment_java", - ] -} -java_group("android_support_media_compat_java") { - deps = [ - ":com_android_support_support_media_compat_java", - ] -} -java_group("android_support_transition_java") { - deps = [ - ":com_android_support_transition_java", - ] -} -java_group("android_support_v7_appcompat_java_internal") { - deps = [ - ":com_android_support_appcompat_v7_java", - ] -} -java_group("android_support_v7_gridlayout_java") { - deps = [ - ":com_android_support_gridlayout_v7_java", - ] -} -java_group("android_support_v7_mediarouter_java") { - deps = [ - ":com_android_support_mediarouter_v7_java", - ] -} -java_group("android_support_v7_palette_java") { - deps = [ - ":com_android_support_palette_v7_java", - ] -} -java_group("android_support_v7_recyclerview_java") { - deps = [ - ":com_android_support_recyclerview_v7_java", - ] -} -java_group("android_support_v13_java") { - deps = [ - ":com_android_support_support_v13_java", - ] -} -java_group("android_support_vector_drawable_java") { - deps = [ - ":com_android_support_support_vector_drawable_java", - ] -} +# Aliases java_group("google_play_services_basement_java") { deps = [ ":com_google_android_gms_play_services_basement_java", @@ -185,8 +101,7 @@ ] } -# The dependencies below don't seem to be used but break downstream builds -# when not defined. +# The dependencies below are used by chromecast internal. java_group("android_support_v7_preference_java") { deps = [ ":com_android_support_preference_v7_java",
diff --git a/third_party/android_media/BUILD.gn b/third_party/android_media/BUILD.gn index 9e85c8ff..75a1082d 100644 --- a/third_party/android_media/BUILD.gn +++ b/third_party/android_media/BUILD.gn
@@ -11,7 +11,7 @@ resource_dirs = [ "java/res" ] deps = [ "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:android_support_v7_mediarouter_java", + "//third_party/android_deps:com_android_support_mediarouter_v7_java", ] } @@ -21,6 +21,6 @@ deps = [ ":android_media_resources", "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:android_support_v7_mediarouter_java", + "//third_party/android_deps:com_android_support_mediarouter_v7_java", ] }
diff --git a/third_party/android_swipe_refresh/BUILD.gn b/third_party/android_swipe_refresh/BUILD.gn index d9c19f28..dd07f426 100644 --- a/third_party/android_swipe_refresh/BUILD.gn +++ b/third_party/android_swipe_refresh/BUILD.gn
@@ -14,6 +14,6 @@ "java/src/org/chromium/third_party/android/swiperefresh/SwipeRefreshLayout.java", ] deps = [ - "//third_party/android_deps:android_support_core_ui_java", + "//third_party/android_deps:com_android_support_support_core_ui_java", ] }
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 0694a2a..37b6b0b 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -90,7 +90,7 @@ android_library("blink_headers_java") { deps = [ "//services/network/public/mojom:mojom_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] srcjar_deps = [ ":blink_headers_java_enums_srcjar" ] }
diff --git a/third_party/blink/public/mojom/background_sync/background_sync.mojom b/third_party/blink/public/mojom/background_sync/background_sync.mojom index 8ec2bb4..a11fb0bcd 100644 --- a/third_party/blink/public/mojom/background_sync/background_sync.mojom +++ b/third_party/blink/public/mojom/background_sync/background_sync.mojom
@@ -6,6 +6,10 @@ struct SyncRegistrationOptions { string tag = ""; + // Minimum interval guaranteed between two Periodic Background Sync events, + // in ms. This must be -1 for One-Shot Sync registrations, and must be >=0 + // for Periodic Sync registrations. + int64 min_interval = -1; }; enum BackgroundSyncError { @@ -15,7 +19,7 @@ NO_SERVICE_WORKER, NOT_ALLOWED, PERMISSION_DENIED, - MAX=PERMISSION_DENIED + MAX=PERMISSION_DENIED, }; enum BackgroundSyncState { @@ -26,13 +30,19 @@ enum BackgroundSyncEventLastChance { IS_NOT_LAST_CHANCE, - IS_LAST_CHANCE + IS_LAST_CHANCE, +}; + +enum BackgroundSyncType { + ONE_SHOT, + PERIODIC, }; interface BackgroundSyncService { Register(SyncRegistrationOptions options, int64 service_worker_registration_id) => (BackgroundSyncError err, SyncRegistrationOptions options); - DidResolveRegistration(int64 service_worker_registration_id, string tag); + DidResolveRegistration(int64 service_worker_registration_id, string tag, + BackgroundSyncType sync_type); GetRegistrations(int64 service_worker_registration_id) => (BackgroundSyncError err, array<SyncRegistrationOptions> registrations); };
diff --git a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom index b6ace2f..622426f 100644 --- a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom +++ b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom
@@ -272,28 +272,23 @@ }; struct IDBCursorValue { - IDBKey key; - IDBKey primary_key; - IDBValue value; + array<IDBKey> keys; + array<IDBKey> primary_keys; + array<IDBValue> values; }; +// Advance(), CursorContinue(), and Prefetch() can call its return callback in +// one of 3 ways: +// * with |error| set and |value| unset, if an error occurs +// * with |error| unset and |value| set, under normal operation +// * with |error| unset and |value| unset, under normal operation when the end +// of the source being iterated is reached interface IDBCursor { - // Advance() can call its return callback in one of 3 ways: - // * with |error| set and |value| unset, if an error occurs - // * with |error| unset and |value| set, under normal operation - // * with |error| unset and |value| unset, under normal operation when the end - // of the source being iterated is reached Advance(uint32 count) => (IDBError? error, IDBCursorValue? value); - - // CursorContinue() can call its return callback in one of 3 ways: - // * with |error| set and |value| unset, if an error occurs - // * with |error| unset and |value| set, under normal operation - // * with |error| unset and |value| unset, under normal operation when the end - // of the source being iterated is reached CursorContinue(IDBKey key, IDBKey primary_key) => (IDBError? error, IDBCursorValue? value); - - Prefetch(int32 count, associated IDBCallbacks callbacks); + Prefetch(int32 count) + => (IDBError? error, IDBCursorValue? value); PrefetchReset(int32 used_prefetches, int32 unused_prefetches); };
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl index e4a93776b..535370b 100644 --- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl +++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
@@ -250,7 +250,7 @@ {% call(property) apply_value(property, header) %} CSS{{animation}}Data& data = state.Style()->Access{{animation}}s(); data.{{vector}}.clear(); - for (auto& listValue : ToCSSValueList(value)) + for (auto& listValue : To<CSSValueList>(value)) data.{{vector}}.push_back(CSSToStyleMap::MapAnimation{{attribute}}(*listValue)); {% endcall %} {% elif property.style_builder_template == 'svg_paint' %} @@ -320,13 +320,13 @@ {% call(property) apply_value(property, header) %} FillLayer* curr_child = &state.Style()->Access{{layer_type}}Layers(); FillLayer* prev_child = 0; - if (value.IsValueList() && !value.IsImageSetValue()) { + const auto* value_list = DynamicTo<CSSValueList>(value); + if (value_list && !value.IsImageSetValue()) { // Walk each value and put it into a layer, creating new layers as needed. - const CSSValueList& valueList = ToCSSValueList(value); - for (unsigned int i = 0; i < valueList.length(); i++) { + for (unsigned int i = 0; i < value_list->length(); i++) { if (!curr_child) curr_child = prev_child->EnsureNext(); - CSSToStyleMap::MapFill{{fill_type}}(state, curr_child, valueList.Item(i)); + CSSToStyleMap::MapFill{{fill_type}}(state, curr_child, value_list->Item(i)); prev_child = curr_child; curr_child = curr_child->Next(); } @@ -394,16 +394,15 @@ {% call(property) apply_value(property, header) %} state.Style()->Clear{{action}}Directives(); - if (!value.IsValueList()) { + const auto* list = DynamicTo<CSSValueList>(value); + if (!list) { DCHECK_EQ(To<CSSIdentifierValue>(value).GetValueID(), CSSValueNone); return; } CounterDirectiveMap& map = state.Style()->AccessCounterDirectives(); - const CSSValueList& list = ToCSSValueList(value); - - for (const CSSValue* item : list) { + for (const CSSValue* item : *list) { const auto& pair = To<CSSValuePair>(*item); AtomicString identifier(To<CSSCustomIdentValue>(pair.First()).Value()); int counter_value = To<CSSPrimitiveValue>(pair.Second()).GetIntValue();
diff --git a/third_party/blink/renderer/core/animation/animation_input_helpers.cc b/third_party/blink/renderer/core/animation/animation_input_helpers.cc index dd479937..76a5eb4 100644 --- a/third_party/blink/renderer/core/animation/animation_input_helpers.cc +++ b/third_party/blink/renderer/core/animation/animation_input_helpers.cc
@@ -253,13 +253,13 @@ const CSSValue* value = CSSParser::ParseSingleValue(CSSPropertyTransitionTimingFunction, string, StrictCSSParserContext(secure_context_mode)); - if (!value || !value->IsValueList()) { + const auto* value_list = DynamicTo<CSSValueList>(value); + if (!value_list) { DCHECK(!value || value->IsCSSWideKeyword()); exception_state.ThrowTypeError("'" + string + "' is not a valid value for easing"); return nullptr; } - const CSSValueList* value_list = ToCSSValueList(value); if (value_list->length() > 1) { exception_state.ThrowTypeError("Easing may not be set to a list of values"); return nullptr;
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc index 71407ff..4c4699e2 100644 --- a/third_party/blink/renderer/core/animation/css/css_animations.cc +++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -115,9 +115,9 @@ scoped_refptr<TimingFunction> timing_function; if (value.IsInheritedValue() && parent_style->Animations()) { timing_function = parent_style->Animations()->TimingFunctionList()[0]; - } else if (value.IsValueList()) { - timing_function = CSSToStyleMap::MapAnimationTimingFunction( - ToCSSValueList(value).Item(0)); + } else if (auto* value_list = DynamicTo<CSSValueList>(value)) { + timing_function = + CSSToStyleMap::MapAnimationTimingFunction(value_list->Item(0)); } else { DCHECK(value.IsCSSWideKeyword()); timing_function = CSSTimingData::InitialTimingFunction();
diff --git a/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc index 404e53c..128c3c4 100644 --- a/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_basic_shape_interpolation_type.cc
@@ -129,7 +129,7 @@ if (!value.IsBaseValueList()) return basic_shape_interpolation_functions::MaybeConvertCSSValue(value); - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); if (list.length() != 1) return nullptr; return basic_shape_interpolation_functions::MaybeConvertCSSValue(
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 de0cc3a..2f20993e 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
@@ -39,16 +39,16 @@ const CSSValue& value, const StyleResolverState* state, ConversionCheckers&) const { - if (!value.IsValueList()) + const auto* list = DynamicTo<CSSValueList>(value); + if (!list) return nullptr; ConversionCheckers null_checkers; - const CSSValueList& list = ToCSSValueList(value); return ListInterpolationFunctions::CreateList( - list.length(), [this, &list, state, &null_checkers](size_t index) { + list->length(), [this, list, state, &null_checkers](size_t index) { return this->inner_interpolation_type_->MaybeConvertValue( - list.Item(index), state, null_checkers); + list->Item(index), state, null_checkers); }); }
diff --git a/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc index 571baf5..2c4be5a 100644 --- a/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_filter_list_interpolation_type.cc
@@ -175,7 +175,7 @@ if (!value.IsBaseValueList()) return nullptr; - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); wtf_size_t length = list.length(); std::unique_ptr<InterpolableList> interpolable_list = InterpolableList::Create(length);
diff --git a/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc index f97ed973..ce4ea07 100644 --- a/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_font_variation_settings_interpolation_type.cc
@@ -145,15 +145,15 @@ const CSSValue& value, const StyleResolverState*, ConversionCheckers&) const { - if (!value.IsValueList()) { + const auto* list = DynamicTo<CSSValueList>(value); + if (!list) { return nullptr; } - const CSSValueList& list = ToCSSValueList(value); - wtf_size_t length = list.length(); + wtf_size_t length = list->length(); std::unique_ptr<InterpolableList> numbers = InterpolableList::Create(length); Vector<AtomicString> tags; for (wtf_size_t i = 0; i < length; ++i) { - const auto& item = To<cssvalue::CSSFontVariationValue>(list.Item(i)); + const auto& item = To<cssvalue::CSSFontVariationValue>(list->Item(i)); numbers->Set(i, std::make_unique<InterpolableNumber>(item.Value())); tags.push_back(item.Tag()); }
diff --git a/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc index 6dae2c8a..bf46181 100644 --- a/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_image_list_interpolation_type.cc
@@ -120,8 +120,7 @@ temp_list = CSSValueList::CreateCommaSeparated(); temp_list->Append(value); } - const CSSValueList& value_list = - temp_list ? *temp_list : ToCSSValueList(value); + const auto& value_list = temp_list ? *temp_list : To<CSSValueList>(value); const wtf_size_t length = value_list.length(); std::unique_ptr<InterpolableList> interpolable_list =
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 c813b1f..1bc611a 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
@@ -108,7 +108,7 @@ if (!value.IsBaseValueList()) return nullptr; - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); return ListInterpolationFunctions::CreateList( list.length(), [&list](wtf_size_t index) { return LengthInterpolationFunctions::MaybeConvertCSSValue(
diff --git a/third_party/blink/renderer/core/animation/css_position_axis_list_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_position_axis_list_interpolation_type.cc index 9d2db0e..e02ae25 100644 --- a/third_party/blink/renderer/core/animation/css_position_axis_list_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_position_axis_list_interpolation_type.cc
@@ -55,7 +55,7 @@ 1, [&value](size_t) { return ConvertPositionAxisCSSValue(value); }); } - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); return ListInterpolationFunctions::CreateList( list.length(), [&list](wtf_size_t index) { return ConvertPositionAxisCSSValue(list.Item(index));
diff --git a/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc index 7b5efd8..b7e5e95 100644 --- a/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_scale_interpolation_type.cc
@@ -171,7 +171,7 @@ if (!value.IsBaseValueList()) return Scale().CreateInterpolationValue(); - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); DCHECK(list.length() >= 1 && list.length() <= 3); Scale scale(1, 1, 1);
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 ec601e89..5794827b 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
@@ -120,7 +120,7 @@ if (!value.IsBaseValueList()) return nullptr; - const CSSValueList& value_list = ToCSSValueList(value); + const auto& value_list = To<CSSValueList>(value); return ListInterpolationFunctions::CreateList( value_list.length(), [&value_list](wtf_size_t index) { return ShadowInterpolationFunctions::MaybeConvertCSSValue(
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 4732510..181f65e 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
@@ -87,7 +87,7 @@ temp_list->Append(value); list = temp_list; } else { - list = ToCSSValueList(&value); + list = To<CSSValueList>(&value); } // Flatten pairs of width/height into individual items, even for contain and
diff --git a/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc index 4aa53c4..ed33d1de 100644 --- a/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_text_indent_interpolation_type.cc
@@ -167,7 +167,7 @@ TextIndentLine line = ComputedStyleInitialValues::InitialTextIndentLine(); TextIndentType type = ComputedStyleInitialValues::InitialTextIndentType(); - for (const auto& item : ToCSSValueList(value)) { + for (const auto& item : To<CSSValueList>(value)) { auto* identifier_value = DynamicTo<CSSIdentifierValue>(item.Get()); if (identifier_value && identifier_value->GetValueID() == CSSValueEachLine) line = TextIndentLine::kEachLine;
diff --git a/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc index 0ff7756..635e3b9 100644 --- a/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_transform_interpolation_type.cc
@@ -182,9 +182,9 @@ const StyleResolverState* state, ConversionCheckers& conversion_checkers) const { DCHECK(state); - if (value.IsValueList()) { + if (auto* list_value = DynamicTo<CSSValueList>(value)) { CSSLengthArray length_array; - for (const CSSValue* item : ToCSSValueList(value)) { + for (const CSSValue* item : *list_value) { const auto& transform_function = To<CSSFunctionValue>(*item); if (transform_function.FunctionType() == CSSValueMatrix || transform_function.FunctionType() == CSSValueMatrix3d) {
diff --git a/third_party/blink/renderer/core/animation/css_transform_origin_interpolation_type.h b/third_party/blink/renderer/core/animation/css_transform_origin_interpolation_type.h index 98779ab..1dd8f99d 100644 --- a/third_party/blink/renderer/core/animation/css_transform_origin_interpolation_type.h +++ b/third_party/blink/renderer/core/animation/css_transform_origin_interpolation_type.h
@@ -23,7 +23,7 @@ InterpolationValue MaybeConvertValue(const CSSValue& value, const StyleResolverState*, ConversionCheckers&) const final { - const CSSValueList& list = ToCSSValueList(value); + const CSSValueList& list = To<CSSValueList>(value); DCHECK_GE(list.length(), 2u); return ListInterpolationFunctions::CreateList( 3, [&list](wtf_size_t index) {
diff --git a/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc index 69a4e5e..dd9842ae 100644 --- a/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc +++ b/third_party/blink/renderer/core/animation/css_translate_interpolation_type.cc
@@ -128,7 +128,7 @@ return CreateNoneValue(); } - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); if (list.length() < 1 || list.length() > 3) return nullptr;
diff --git a/third_party/blink/renderer/core/css/css_value.cc b/third_party/blink/renderer/core/css/css_value.cc index 57448d2..5c57d38 100644 --- a/third_party/blink/renderer/core/css/css_value.cc +++ b/third_party/blink/renderer/core/css/css_value.cc
@@ -106,7 +106,7 @@ bool CSSValue::HasFailedOrCanceledSubresources() const { if (IsValueList()) - return ToCSSValueList(this)->HasFailedOrCanceledSubresources(); + return To<CSSValueList>(this)->HasFailedOrCanceledSubresources(); if (GetClassType() == kFontFaceSrcClass) return To<CSSFontFaceSrcValue>(this)->HasFailedOrCanceledSubresources(); if (GetClassType() == kImageClass) @@ -121,7 +121,7 @@ bool CSSValue::MayContainUrl() const { if (IsValueList()) - return ToCSSValueList(*this).MayContainUrl(); + return To<CSSValueList>(*this).MayContainUrl(); return IsImageValue() || IsURIValue(); } @@ -136,7 +136,7 @@ return; } if (IsValueList()) { - ToCSSValueList(*this).ReResolveUrl(document); + To<CSSValueList>(*this).ReResolveUrl(document); return; } } @@ -348,7 +348,7 @@ case kValuePairClass: return To<CSSValuePair>(this)->CustomCSSText(); case kValueListClass: - return ToCSSValueList(this)->CustomCSSText(); + return To<CSSValueList>(this)->CustomCSSText(); case kImageSetClass: return To<CSSImageSetValue>(this)->CustomCSSText(); case kCSSContentDistributionClass: @@ -496,7 +496,7 @@ To<CSSURIValue>(this)->~CSSURIValue(); return; case kValueListClass: - ToCSSValueList(this)->~CSSValueList(); + To<CSSValueList>(this)->~CSSValueList(); return; case kValuePairClass: To<CSSValuePair>(this)->~CSSValuePair(); @@ -652,7 +652,7 @@ To<CSSURIValue>(this)->TraceAfterDispatch(visitor); return; case kValueListClass: - ToCSSValueList(this)->TraceAfterDispatch(visitor); + To<CSSValueList>(this)->TraceAfterDispatch(visitor); return; case kValuePairClass: To<CSSValuePair>(this)->TraceAfterDispatch(visitor);
diff --git a/third_party/blink/renderer/core/css/css_value.h b/third_party/blink/renderer/core/css/css_value.h index 22407d8..855c2239 100644 --- a/third_party/blink/renderer/core/css/css_value.h +++ b/third_party/blink/renderer/core/css/css_value.h
@@ -297,10 +297,6 @@ return true; } -#define DEFINE_CSS_VALUE_TYPE_CASTS(thisType, predicate) \ - DEFINE_TYPE_CASTS(thisType, CSSValue, value, value->predicate, \ - value.predicate) - } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_VALUE_H_
diff --git a/third_party/blink/renderer/core/css/css_value_list.h b/third_party/blink/renderer/core/css/css_value_list.h index 090786ff..6184ad5 100644 --- a/third_party/blink/renderer/core/css/css_value_list.h +++ b/third_party/blink/renderer/core/css/css_value_list.h
@@ -25,6 +25,7 @@ #include "base/macros.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/css/css_value.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" #include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { @@ -80,7 +81,10 @@ DISALLOW_COPY_AND_ASSIGN(CSSValueList); }; -DEFINE_CSS_VALUE_TYPE_CASTS(CSSValueList, IsValueList()); +template <> +struct DowncastTraits<CSSValueList> { + static bool AllowFrom(const CSSValue& value) { return value.IsValueList(); } +}; } // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/css_transform_value.cc b/third_party/blink/renderer/core/css/cssom/css_transform_value.cc index 3247963..4876fa3 100644 --- a/third_party/blink/renderer/core/css/cssom/css_transform_value.cc +++ b/third_party/blink/renderer/core/css/cssom/css_transform_value.cc
@@ -32,12 +32,13 @@ } CSSTransformValue* CSSTransformValue::FromCSSValue(const CSSValue& css_value) { - if (!css_value.IsValueList()) { + auto* css_value_list = DynamicTo<CSSValueList>(css_value); + if (!css_value_list) { // TODO(meade): Also need to check the separator here if we care. return nullptr; } HeapVector<Member<CSSTransformComponent>> components; - for (const CSSValue* value : ToCSSValueList(css_value)) { + for (const CSSValue* value : *css_value_list) { CSSTransformComponent* component = CSSTransformComponent::FromCSSValue(*value); if (!component)
diff --git a/third_party/blink/renderer/core/css/cssom/style_property_map.cc b/third_party/blink/renderer/core/css/cssom/style_property_map.cc index 7e20dff..4e905bb 100644 --- a/third_party/blink/renderer/core/css/cssom/style_property_map.cc +++ b/third_party/blink/renderer/core/css/cssom/style_property_map.cc
@@ -486,20 +486,20 @@ CSSValueList* current_value = nullptr; if (const CSSValue* css_value = GetProperty(property_id)) { - DCHECK(css_value->IsValueList()); - current_value = ToCSSValueList(css_value)->Copy(); + current_value = To<CSSValueList>(css_value)->Copy(); } else { current_value = CssValueListForPropertyID(property_id); } const CSSValue* result = CoerceStyleValuesOrStrings( property, g_null_atom, nullptr, values, *execution_context); - if (!result || !result->IsValueList()) { + const auto* result_value_list = DynamicTo<CSSValueList>(result); + if (!result_value_list) { exception_state.ThrowTypeError("Invalid type for property"); return; } - for (const auto& value : *ToCSSValueList(result)) { + for (const auto& value : *result_value_list) { current_value->Append(*value); }
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 28962379..54d70e80 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
@@ -110,7 +110,7 @@ return CreateStyleValue(value); // Only single values are supported in level 1. - const auto& value_list = ToCSSValueList(value); + const auto& value_list = To<CSSValueList>(value); if (value_list.length() == 1U) return CreateStyleValue(value_list.Item(0)); return nullptr; @@ -119,7 +119,7 @@ case CSSPropertyFontVariantLigatures: case CSSPropertyFontVariantNumeric: { // Only single keywords are supported in level 1. - if (const auto* value_list = ToCSSValueListOrNull(value)) { + if (const auto* value_list = DynamicTo<CSSValueList>(value)) { if (value_list->length() != 1U) return nullptr; return CreateStyleValue(value_list->Item(0)); @@ -127,7 +127,7 @@ return CreateStyleValue(value); } case CSSPropertyGridAutoFlow: { - const auto& value_list = ToCSSValueList(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)); @@ -146,7 +146,7 @@ case CSSPropertyTransformOrigin: return CSSPositionValue::FromCSSValue(value); case CSSPropertyOffsetRotate: { - const auto& value_list = ToCSSValueList(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)); @@ -156,11 +156,10 @@ // Computed align-items is a ValueList of either length 1 or 2. // Typed OM level 1 can't support "pairs", so we only return // a Typed OM object for length 1 lists. - if (value.IsValueList()) { - const auto& value_list = ToCSSValueList(value); - if (value_list.length() != 1U) + if (const auto* value_list = DynamicTo<CSSValueList>(value)) { + if (value_list->length() != 1U) return nullptr; - return CreateStyleValue(value_list.Item(0)); + return CreateStyleValue(value_list->Item(0)); } return CreateStyleValue(value); } @@ -168,7 +167,7 @@ if (value.IsIdentifierValue()) return CreateStyleValue(value); - const auto& value_list = ToCSSValueList(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)); @@ -178,7 +177,7 @@ if (value.IsIdentifierValue()) return CreateStyleValue(value); - const auto& value_list = ToCSSValueList(value); + 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)); @@ -186,7 +185,7 @@ } case CSSPropertyTransitionProperty: case CSSPropertyTouchAction: { - const auto& value_list = ToCSSValueList(value); + 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)); @@ -197,7 +196,7 @@ if (value.IsIdentifierValue()) return CreateStyleValue(value); - const auto& value_list = ToCSSValueList(value); + const auto& value_list = To<CSSValueList>(value); if (value_list.length() == 1U) { const auto* ident = DynamicTo<CSSIdentifierValue>(value_list.Item(0)); if (ident && ident->GetValueID() == CSSValueAuto) @@ -357,7 +356,9 @@ return style_value_vector; } - if (!css_value.IsValueList() || + // We assume list-valued properties are always stored as a list. + const auto* css_value_list = DynamicTo<CSSValueList>(css_value); + if (!css_value_list || // TODO(andruud): Custom properties claim to not be repeated, even though // they may be. Therefore we must ignore "IsRepeated" for custom // properties. @@ -373,9 +374,7 @@ return UnsupportedCSSValue(name, css_value); } - // We assume list-valued properties are always stored as a list. - const CSSValueList& css_value_list = ToCSSValueList(css_value); - for (const CSSValue* inner_value : css_value_list) { + for (const CSSValue* inner_value : *css_value_list) { style_value = CreateStyleValueWithProperty(property_id, *inner_value); if (!style_value) return UnsupportedCSSValue(name, css_value);
diff --git a/third_party/blink/renderer/core/css/font_face.cc b/third_party/blink/renderer/core/css/font_face.cc index 63442a7..ddf99ab 100644 --- a/third_party/blink/renderer/core/css/font_face.cc +++ b/third_party/blink/renderer/core/css/font_face.cc
@@ -84,7 +84,7 @@ CSSFontFace* CreateCSSFontFace(FontFace* font_face, const CSSValue* unicode_range) { Vector<UnicodeRange> ranges; - if (const CSSValueList* range_list = ToCSSValueList(unicode_range)) { + if (const auto* range_list = To<CSSValueList>(unicode_range)) { unsigned num_ranges = range_list->length(); for (unsigned i = 0; i < num_ranges; i++) { const auto& range = @@ -534,12 +534,12 @@ default: break; } - } else if (stretch_->IsValueList()) { + } else if (const auto* stretch_list = + DynamicTo<CSSValueList>(stretch_.Get())) { // Transition FontFace interpretation of parsed values from // CSSIdentifierValue to CSSValueList or CSSPrimitiveValue. // TODO(drott) crbug.com/739139: Update the parser to only produce // CSSPrimitiveValue or CSSValueList. - const CSSValueList* stretch_list = ToCSSValueList(stretch_); if (stretch_list->length() != 2) return normal_capabilities; const auto* stretch_from = @@ -636,8 +636,8 @@ NOTREACHED(); break; } - } else if (weight_->IsValueList()) { - const CSSValueList* weight_list = ToCSSValueList(weight_); + } else if (const auto* weight_list = + DynamicTo<CSSValueList>(weight_.Get())) { if (weight_list->length() != 2) return normal_capabilities; const auto* weight_from = @@ -693,8 +693,7 @@ // Each item in the src property's list is a single CSSFontFaceSource. Put // them all into a CSSFontFace. - DCHECK(src.IsValueList()); - const CSSValueList& src_list = ToCSSValueList(src); + const auto& src_list = To<CSSValueList>(src); int src_length = src_list.length(); for (int i = 0; i < src_length; i++) {
diff --git a/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc b/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc index 054684ea..87c6d401 100644 --- a/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc +++ b/third_party/blink/renderer/core/css/parser/css_property_parser_test.cc
@@ -93,36 +93,28 @@ const CSSValue* value = CSSParser::ParseSingleValue( CSSPropertyGridTemplateColumns, "repeat(999, 20px)", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 999); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 999); } TEST(CSSPropertyParserTest, GridTrackLimit2) { const CSSValue* value = CSSParser::ParseSingleValue( CSSPropertyGridTemplateRows, "repeat(999, 20px)", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 999); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 999); } TEST(CSSPropertyParserTest, GridTrackLimit3) { const CSSValue* value = CSSParser::ParseSingleValue( CSSPropertyGridTemplateColumns, "repeat(1000000, 10%)", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 1000); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit4) { const CSSValue* value = CSSParser::ParseSingleValue( CSSPropertyGridTemplateRows, "repeat(1000000, 10%)", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 1000); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit5) { @@ -130,9 +122,7 @@ CSSPropertyGridTemplateColumns, "repeat(1000000, [first] min-content [last])", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 1000); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit6) { @@ -140,27 +130,21 @@ CSSPropertyGridTemplateRows, "repeat(1000000, [first] min-content [last])", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 1000); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit7) { const CSSValue* value = CSSParser::ParseSingleValue( CSSPropertyGridTemplateColumns, "repeat(1000001, auto)", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 1000); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit8) { const CSSValue* value = CSSParser::ParseSingleValue( CSSPropertyGridTemplateRows, "repeat(1000001, auto)", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 1000); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit9) { @@ -168,9 +152,7 @@ CSSPropertyGridTemplateColumns, "repeat(400000, 2em minmax(10px, max-content) 0.5fr)", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 999); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 999); } TEST(CSSPropertyParserTest, GridTrackLimit10) { @@ -178,9 +160,7 @@ CSSPropertyGridTemplateRows, "repeat(400000, 2em minmax(10px, max-content) 0.5fr)", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 999); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 999); } TEST(CSSPropertyParserTest, GridTrackLimit11) { @@ -188,9 +168,7 @@ CSSPropertyGridTemplateColumns, "repeat(600000, [first] 3vh 10% 2fr [nav] 10px auto 1fr 6em [last])", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 994); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 994); } TEST(CSSPropertyParserTest, GridTrackLimit12) { @@ -198,27 +176,21 @@ CSSPropertyGridTemplateRows, "repeat(600000, [first] 3vh 10% 2fr [nav] 10px auto 1fr 6em [last])", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 994); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 994); } TEST(CSSPropertyParserTest, GridTrackLimit13) { const CSSValue* value = CSSParser::ParseSingleValue( CSSPropertyGridTemplateColumns, "repeat(100000000000000000000, 10% 1fr)", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 1000); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit14) { const CSSValue* value = CSSParser::ParseSingleValue( CSSPropertyGridTemplateRows, "repeat(100000000000000000000, 10% 1fr)", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 1000); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 1000); } TEST(CSSPropertyParserTest, GridTrackLimit15) { @@ -226,9 +198,7 @@ CSSPropertyGridTemplateColumns, "repeat(100000000000000000000, 10% 5em 1fr auto auto 15px min-content)", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 994); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 994); } TEST(CSSPropertyParserTest, GridTrackLimit16) { @@ -236,14 +206,11 @@ CSSPropertyGridTemplateRows, "repeat(100000000000000000000, 10% 5em 1fr auto auto 15px min-content)", StrictCSSParserContext(SecureContextMode::kSecureContext)); - ASSERT_TRUE(value); - ASSERT_TRUE(value->IsValueList()); - EXPECT_EQ(ComputeNumberOfTracks(ToCSSValueList(value)), 994); + EXPECT_EQ(ComputeNumberOfTracks(To<CSSValueList>(value)), 994); } static int GetGridPositionInteger(const CSSValue& value) { - DCHECK(value.IsValueList()); - const auto& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); DCHECK_EQ(list.length(), static_cast<size_t>(1)); const auto& primitive_value = To<CSSPrimitiveValue>(list.Item(0)); DCHECK(primitive_value.IsNumber()); @@ -365,8 +332,7 @@ const CSSValue* value = CSSParser::ParseSingleValue( CSSPropertyScrollCustomization, "pan-down", StrictCSSParserContext(SecureContextMode::kSecureContext)); - DCHECK(value); - const CSSValueList* list = ToCSSValueList(value); + const auto* list = To<CSSValueList>(value); EXPECT_EQ(1U, list->length()); EXPECT_EQ(CSSValuePanDown, To<CSSIdentifierValue>(list->Item(0U)).GetValueID()); @@ -377,7 +343,7 @@ const CSSValue* value = CSSParser::ParseSingleValue( CSSPropertyScrollCustomization, "pan-left pan-y", StrictCSSParserContext(SecureContextMode::kSecureContext)); - const CSSValueList* list = ToCSSValueList(value); + const auto* list = To<CSSValueList>(value); EXPECT_EQ(2U, list->length()); EXPECT_EQ(CSSValuePanLeft, To<CSSIdentifierValue>(list->Item(0U)).GetValueID());
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 dc2e36c..ee0a5dac8 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
@@ -1865,7 +1865,7 @@ if (show_vertical_bottom_left) vertical_radii->Append(bottom_left_radius->Item(1)); - if (!vertical_radii->Equals(ToCSSValueList(list->Item(0)))) + if (!vertical_radii->Equals(To<CSSValueList>(list->Item(0)))) list->Append(*vertical_radii); return list;
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc index c425cb4..ffe3ec7 100644 --- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc +++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -606,9 +606,9 @@ if (!list->IsBaseValueList()) { CSSValue* first_value = list; list = CSSValueList::CreateCommaSeparated(); - ToCSSValueList(list)->Append(*first_value); + To<CSSValueList>(list)->Append(*first_value); } - ToCSSValueList(list)->Append(*value); + To<CSSValueList>(list)->Append(*value); } else { // To conserve memory we don't actually wrap a single value in a list. list = value;
diff --git a/third_party/blink/renderer/core/css/properties/longhands/content_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/content_custom.cc index f1c0063..0da8b1d4 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/content_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/content_custom.cc
@@ -142,7 +142,7 @@ ContentData* first_content = nullptr; ContentData* prev_content = nullptr; - for (auto& item : ToCSSValueList(value)) { + for (auto& item : To<CSSValueList>(value)) { ContentData* next_content = nullptr; if (item->IsImageGeneratorValue() || item->IsImageSetValue() || item->IsImageValue()) {
diff --git a/third_party/blink/renderer/core/css/properties/longhands/cursor_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/cursor_custom.cc index ca8b8b8..9ce3b12 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/cursor_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/cursor_custom.cc
@@ -113,9 +113,9 @@ void Cursor::ApplyValue(StyleResolverState& state, const CSSValue& value) const { state.Style()->ClearCursorList(); - if (value.IsValueList()) { + if (auto* value_list = DynamicTo<CSSValueList>(value)) { state.Style()->SetCursor(ECursor::kAuto); - for (const auto& item : ToCSSValueList(value)) { + for (const auto& item : *value_list) { if (const auto* cursor = DynamicTo<cssvalue::CSSCursorImageValue>(*item)) { const CSSValue& image = cursor->ImageValue();
diff --git a/third_party/blink/renderer/core/css/properties/longhands/size_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/size_custom.cc index 6543dd53..be6e4e2 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/size_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/size_custom.cc
@@ -92,7 +92,7 @@ state.Style()->ResetPageSizeType(); FloatSize size; EPageSizeType page_size_type = EPageSizeType::kAuto; - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); if (list.length() == 2) { // <length>{2} | <page-size> <orientation> const CSSValue& first = list.Item(0);
diff --git a/third_party/blink/renderer/core/css/properties/longhands/text_indent_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/text_indent_custom.cc index 7afdefc..c5b62b0 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/text_indent_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/text_indent_custom.cc
@@ -101,7 +101,7 @@ TextIndentType text_indent_type_value = ComputedStyleInitialValues::InitialTextIndentType(); - for (auto& list_value : ToCSSValueList(value)) { + for (auto& list_value : To<CSSValueList>(value)) { if (auto* list_primitive_value = DynamicTo<CSSPrimitiveValue>(*list_value)) { length_or_percentage_value = list_primitive_value->ConvertToLength(
diff --git a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_style_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_style_custom.cc index 9306ac5..0a50412 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_style_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/webkit_text_emphasis_style_custom.cc
@@ -98,11 +98,10 @@ void WebkitTextEmphasisStyle::ApplyValue(StyleResolverState& state, const CSSValue& value) const { - if (value.IsValueList()) { - const CSSValueList& list = ToCSSValueList(value); - DCHECK_EQ(list.length(), 2U); + if (const auto* list = DynamicTo<CSSValueList>(value)) { + DCHECK_EQ(list->length(), 2U); for (unsigned i = 0; i < 2; ++i) { - const auto& ident_value = To<CSSIdentifierValue>(list.Item(i)); + const auto& ident_value = To<CSSIdentifierValue>(list->Item(i)); if (ident_value.GetValueID() == CSSValueFilled || ident_value.GetValueID() == CSSValueOpen) { state.Style()->SetTextEmphasisFill(
diff --git a/third_party/blink/renderer/core/css/properties/longhands/will_change_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/will_change_custom.cc index 57e2088..b7dfd03 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/will_change_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/will_change_custom.cc
@@ -109,8 +109,7 @@ if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) { DCHECK_EQ(identifier_value->GetValueID(), CSSValueAuto); } else { - DCHECK(value.IsValueList()); - for (auto& will_change_value : ToCSSValueList(value)) { + for (auto& will_change_value : To<CSSValueList>(value)) { if (auto* ident_value = DynamicTo<CSSCustomIdentValue>(will_change_value.Get())) { will_change_properties.push_back(ident_value->ValueAsPropertyID());
diff --git a/third_party/blink/renderer/core/css/property_registration.cc b/third_party/blink/renderer/core/css/property_registration.cc index c094ac72..2bfeb21 100644 --- a/third_party/blink/renderer/core/css/property_registration.cc +++ b/third_party/blink/renderer/core/css/property_registration.cc
@@ -61,8 +61,8 @@ ->NeedsVariableResolution(); } - if (value.IsValueList()) { - for (const CSSValue* inner_value : ToCSSValueList(value)) { + if (auto* value_list = DynamicTo<CSSValueList>(value)) { + for (const CSSValue* inner_value : *value_list) { if (!ComputationallyIndependent(*inner_value)) return false; }
diff --git a/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc b/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc index d2827d7..6c9dc83 100644 --- a/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc +++ b/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc
@@ -469,14 +469,14 @@ CSSPropertyID property, const CSSValue& value, NinePieceImage& image) { + // Retrieve the border image value. + const auto* border_image = DynamicTo<CSSValueList>(value); + // If we're not a value list, then we are "none" and don't need to alter the // empty image at all. - if (!value.IsValueList()) + if (!border_image) return; - // Retrieve the border image value. - const CSSValueList& border_image = ToCSSValueList(value); - // Set the image (this kicks off the load). CSSPropertyID image_property; if (property == CSSPropertyWebkitBorderImage) @@ -486,28 +486,29 @@ else image_property = property; - for (unsigned i = 0; i < border_image.length(); ++i) { - const CSSValue& current = border_image.Item(i); + for (unsigned i = 0; i < border_image->length(); ++i) { + const CSSValue& current = border_image->Item(i); if (current.IsImageValue() || current.IsImageGeneratorValue() || current.IsImageSetValue()) { image.SetImage(state.GetStyleImage(image_property, current)); } else if (current.IsBorderImageSliceValue()) { MapNinePieceImageSlice(state, current, image); - } else if (current.IsValueList()) { - const CSSValueList& slash_list = ToCSSValueList(current); - size_t length = slash_list.length(); + } else if (const auto* slash_list = DynamicTo<CSSValueList>(current)) { + size_t length = slash_list->length(); // Map in the image slices. - if (length && slash_list.Item(0).IsBorderImageSliceValue()) - MapNinePieceImageSlice(state, slash_list.Item(0), image); + if (length && slash_list->Item(0).IsBorderImageSliceValue()) + MapNinePieceImageSlice(state, slash_list->Item(0), image); // Map in the border slices. - if (length > 1) - image.SetBorderSlices(MapNinePieceImageQuad(state, slash_list.Item(1))); + if (length > 1) { + image.SetBorderSlices( + MapNinePieceImageQuad(state, slash_list->Item(1))); + } // Map in the outset. if (length > 2) - image.SetOutset(MapNinePieceImageQuad(state, slash_list.Item(2))); + image.SetOutset(MapNinePieceImageQuad(state, slash_list->Item(2))); } else if (current.IsPrimitiveValue() || current.IsValuePair()) { // Set the appropriate rules for stretch/round/repeat of the slices. MapNinePieceImageRepeat(state, current, image);
diff --git a/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc b/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc index 507537b..f96da74 100644 --- a/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc
@@ -165,7 +165,7 @@ const CSSToLengthConversionData& conversion_data = state.CssToLengthConversionData(); - for (auto& curr_value : ToCSSValueList(in_value)) { + for (auto& curr_value : To<CSSValueList>(in_value)) { if (const auto* url_value = DynamicTo<CSSURIValue>(curr_value.Get())) { CountFilterUse(FilterOperation::REFERENCE, state.GetDocument()); @@ -256,7 +256,7 @@ font_sizes, viewport_size, 1); // zoom - for (auto& curr_value : ToCSSValueList(in_value)) { + for (auto& curr_value : To<CSSValueList>(in_value)) { if (curr_value->IsURIValue()) continue;
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc index beb78539..08c2bf8 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -218,12 +218,10 @@ const CSSValue& value, FontBuilder* font_builder, const Document* document_for_count) { - DCHECK(value.IsValueList()); - FontDescription::FamilyDescription desc(FontDescription::kNoFamily); FontFamily* curr_family = nullptr; - for (auto& family : ToCSSValueList(value)) { + for (auto& family : To<CSSValueList>(value)) { FontDescription::GenericFamilyType generic_family = FontDescription::kNoFamily; AtomicString family_name; @@ -265,7 +263,7 @@ if (identifier_value && identifier_value->GetValueID() == CSSValueNormal) return FontBuilder::InitialFeatureSettings(); - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); scoped_refptr<FontFeatureSettings> settings = FontFeatureSettings::Create(); int len = list.length(); for (int i = 0; i < len; ++i) { @@ -282,7 +280,7 @@ if (identifier_value && identifier_value->GetValueID() == CSSValueNormal) return FontBuilder::InitialVariationSettings(); - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); scoped_refptr<FontVariationSettings> settings = FontVariationSettings::Create(); int len = list.length(); @@ -510,11 +508,10 @@ FontDescription::VariantLigatures StyleBuilderConverter::ConvertFontVariantLigatures(StyleResolverState&, const CSSValue& value) { - if (value.IsValueList()) { + if (const auto* value_list = DynamicTo<CSSValueList>(value)) { FontDescription::VariantLigatures ligatures; - const CSSValueList& value_list = ToCSSValueList(value); - for (wtf_size_t i = 0; i < value_list.length(); ++i) { - const CSSValue& item = value_list.Item(i); + for (wtf_size_t i = 0; i < value_list->length(); ++i) { + const CSSValue& item = value_list->Item(i); switch (To<CSSIdentifierValue>(item).GetValueID()) { case CSSValueNoCommonLigatures: ligatures.common = FontDescription::kDisabledLigaturesState; @@ -566,7 +563,7 @@ } FontVariantNumeric variant_numeric; - for (const CSSValue* feature : ToCSSValueList(value)) { + for (const CSSValue* feature : To<CSSValueList>(value)) { switch (To<CSSIdentifierValue>(feature)->GetValueID()) { case CSSValueLiningNums: variant_numeric.SetNumericFigure(FontVariantNumeric::kLiningNums); @@ -612,7 +609,7 @@ } FontVariantEastAsian variant_east_asian; - for (const CSSValue* feature : ToCSSValueList(value)) { + for (const CSSValue* feature : To<CSSValueList>(value)) { switch (To<CSSIdentifierValue>(feature)->GetValueID()) { case CSSValueJis78: variant_east_asian.SetForm(FontVariantEastAsian::kJis78); @@ -706,7 +703,7 @@ GridAutoFlow StyleBuilderConverter::ConvertGridAutoFlow(StyleResolverState&, const CSSValue& value) { - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); DCHECK_GE(list.length(), 1u); const CSSIdentifierValue& first = To<CSSIdentifierValue>(list.Item(0)); @@ -750,7 +747,7 @@ return position; } - const CSSValueList& values = ToCSSValueList(value); + const auto& values = To<CSSValueList>(value); DCHECK(values.length()); bool is_span_position = false; @@ -819,7 +816,7 @@ OrderedNamedGridLines& ordered_named_grid_lines) { DCHECK(value.IsGridLineNamesValue()); - for (auto& named_grid_line_value : ToCSSValueList(value)) { + for (auto& named_grid_line_value : To<CSSValueList>(value)) { String named_grid_line = To<CSSCustomIdentValue>(*named_grid_line_value).Value(); NamedGridLinesMap::AddResult result = @@ -835,9 +832,8 @@ Vector<GridTrackSize> StyleBuilderConverter::ConvertGridTrackSizeList( StyleResolverState& state, const CSSValue& value) { - DCHECK(value.IsValueList()); Vector<GridTrackSize> track_sizes; - for (auto& curr_value : ToCSSValueList(value)) { + for (auto& curr_value : To<CSSValueList>(value)) { DCHECK(!curr_value->IsGridLineNamesValue()); DCHECK(!curr_value->IsGridAutoRepeatValue()); track_sizes.push_back(ConvertGridTrackSize(state, *curr_value)); @@ -862,7 +858,7 @@ } size_t current_named_grid_line = 0; - for (auto curr_value : ToCSSValueList(value)) { + for (auto curr_value : To<CSSValueList>(value)) { if (curr_value->IsGridLineNamesValue()) { ConvertGridLineNamesList(*curr_value, current_named_grid_line, named_grid_lines, ordered_named_grid_lines); @@ -879,7 +875,7 @@ auto_repeat_type = auto_repeat_id == CSSValueAutoFill ? AutoRepeatType::kAutoFill : AutoRepeatType::kAutoFit; - for (auto auto_repeat_value : ToCSSValueList(*curr_value)) { + for (auto auto_repeat_value : To<CSSValueList>(*curr_value)) { if (auto_repeat_value->IsGridLineNamesValue()) { ConvertGridLineNamesList(*auto_repeat_value, auto_repeat_index, auto_repeat_named_grid_lines, @@ -1109,7 +1105,7 @@ const CSSValue& value) { StyleOffsetRotation result(0, OffsetRotationType::kFixed); - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); DCHECK(list.length() == 1 || list.length() == 2); for (const auto& item : list) { auto* identifier_value = DynamicTo<CSSIdentifierValue>(item.Get()); @@ -1165,18 +1161,17 @@ EPaintOrder StyleBuilderConverter::ConvertPaintOrder( StyleResolverState&, const CSSValue& css_paint_order) { - if (css_paint_order.IsValueList()) { - const CSSValueList& order_type_list = ToCSSValueList(css_paint_order); - switch (To<CSSIdentifierValue>(order_type_list.Item(0)).GetValueID()) { + if (const auto* order_type_list = DynamicTo<CSSValueList>(css_paint_order)) { + switch (To<CSSIdentifierValue>(order_type_list->Item(0)).GetValueID()) { case CSSValueFill: - return order_type_list.length() > 1 ? kPaintOrderFillMarkersStroke - : kPaintOrderFillStrokeMarkers; + return order_type_list->length() > 1 ? kPaintOrderFillMarkersStroke + : kPaintOrderFillStrokeMarkers; case CSSValueStroke: - return order_type_list.length() > 1 ? kPaintOrderStrokeMarkersFill - : kPaintOrderStrokeFillMarkers; + return order_type_list->length() > 1 ? kPaintOrderStrokeMarkersFill + : kPaintOrderStrokeFillMarkers; case CSSValueMarkers: - return order_type_list.length() > 1 ? kPaintOrderMarkersStrokeFill - : kPaintOrderMarkersFillStroke; + return order_type_list->length() > 1 ? kPaintOrderMarkersStrokeFill + : kPaintOrderMarkersFillStroke; default: NOTREACHED(); return kPaintOrderNormal; @@ -1198,12 +1193,11 @@ scoped_refptr<QuotesData> StyleBuilderConverter::ConvertQuotes( StyleResolverState&, const CSSValue& value) { - if (value.IsValueList()) { - const CSSValueList& list = ToCSSValueList(value); + if (const auto* list = DynamicTo<CSSValueList>(value)) { scoped_refptr<QuotesData> quotes = QuotesData::Create(); - for (wtf_size_t i = 0; i < list.length(); i += 2) { - String start_quote = To<CSSStringValue>(list.Item(i)).Value(); - String end_quote = To<CSSStringValue>(list.Item(i + 1)).Value(); + for (wtf_size_t i = 0; i < list->length(); i += 2) { + String start_quote = To<CSSStringValue>(list->Item(i)).Value(); + String end_quote = To<CSSStringValue>(list->Item(i + 1)).Value(); quotes->AddPair(std::make_pair(start_quote, end_quote)); } return quotes; @@ -1279,7 +1273,7 @@ } ShadowDataVector shadows; - for (const auto& item : ToCSSValueList(value)) { + for (const auto& item : To<CSSValueList>(value)) { shadows.push_back( ConvertShadow(state.CssToLengthConversionData(), &state, *item)); } @@ -1301,7 +1295,7 @@ scoped_refptr<BasicShape> shape; CSSBoxType css_box = CSSBoxType::kMissing; - const CSSValueList& value_list = ToCSSValueList(value); + const auto& value_list = To<CSSValueList>(value); for (unsigned i = 0; i < value_list.length(); ++i) { const CSSValue& item_value = value_list.Item(i); if (item_value.IsBasicShapeValue()) { @@ -1330,16 +1324,15 @@ scoped_refptr<SVGDashArray> StyleBuilderConverter::ConvertStrokeDasharray( StyleResolverState& state, const CSSValue& value) { - if (!value.IsValueList()) + const auto* dashes = DynamicTo<CSSValueList>(value); + if (!dashes) return SVGComputedStyle::InitialStrokeDashArray(); - const CSSValueList& dashes = ToCSSValueList(value); - scoped_refptr<SVGDashArray> array = SVGDashArray::Create(); - wtf_size_t length = dashes.length(); + wtf_size_t length = dashes->length(); for (wtf_size_t i = 0; i < length; ++i) { array->push_back( - ConvertLength(state, To<CSSPrimitiveValue>(dashes.Item(i)))); + ConvertLength(state, To<CSSPrimitiveValue>(dashes->Item(i)))); } return array; @@ -1374,11 +1367,10 @@ const CSSValue& value) { const CSSValue* local_value = &value; SVGPaint paint; - if (value.IsValueList()) { - const CSSValueList& list = ToCSSValueList(value); - DCHECK_EQ(list.length(), 2u); - paint.resource = ConvertElementReference(state, list.Item(0)); - local_value = &list.Item(1); + if (const auto* list = DynamicTo<CSSValueList>(value)) { + DCHECK_EQ(list->length(), 2u); + paint.resource = ConvertElementReference(state, list->Item(0)); + local_value = &list->Item(1); } if (local_value->IsURIValue()) { @@ -1407,7 +1399,7 @@ TextEmphasisPosition StyleBuilderConverter::ConvertTextTextEmphasisPosition( StyleResolverState& state, const CSSValue& value) { - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); CSSValueID first = To<CSSIdentifierValue>(list.Item(0)).GetValueID(); CSSValueID second = To<CSSIdentifierValue>(list.Item(1)).GetValueID(); if (first == CSSValueOver && second == CSSValueRight) @@ -1458,8 +1450,8 @@ To<CSSIdentifierValue>(identifier).ConvertTo<TextUnderlinePosition>(); }; - if (value.IsValueList()) { - for (auto& entry : ToCSSValueList(value)) { + if (auto* value_list = DynamicTo<CSSValueList>(value)) { + for (auto& entry : *value_list) { process(*entry); } } else { @@ -1478,7 +1470,7 @@ TransformOrigin StyleBuilderConverter::ConvertTransformOrigin( StyleResolverState& state, const CSSValue& value) { - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); DCHECK_GE(list.length(), 2u); DCHECK(list.Item(0).IsPrimitiveValue() || list.Item(0).IsIdentifierValue()); DCHECK(list.Item(1).IsPrimitiveValue() || list.Item(1).IsIdentifierValue()); @@ -1544,7 +1536,7 @@ DCHECK_EQ(identifier_value->GetValueID(), CSSValueNone); return nullptr; } - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); DCHECK_LE(list.length(), 3u); Length tx = ConvertLength(state, list.Item(0)); Length ty = Length::Fixed(0); @@ -1565,7 +1557,7 @@ return Rotation(FloatPoint3D(0, 0, 1), 0); } - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); DCHECK(list.length() == 1 || list.length() == 2); double x = 0; double y = 0; @@ -1602,7 +1594,7 @@ return nullptr; } - const CSSValueList& list = ToCSSValueList(value); + const auto& list = To<CSSValueList>(value); DCHECK_LE(list.length(), 3u); double sx = To<CSSPrimitiveValue>(list.Item(0)).GetDoubleValue(); double sy = sx; @@ -1650,17 +1642,16 @@ if (const auto* function_value = DynamicTo<CSSFunctionValue>(value)) { CSSFunctionValue* new_function = CSSFunctionValue::Create(function_value->FunctionType()); - for (const CSSValue* inner_value : ToCSSValueList(value)) { + for (const CSSValue* inner_value : To<CSSValueList>(value)) { new_function->Append(ComputeRegisteredPropertyValue( document, css_to_length_conversion_data, *inner_value)); } return *new_function; } - if (value.IsValueList()) { - const CSSValueList& old_list = ToCSSValueList(value); - CSSValueList* new_list = CSSValueList::CreateWithSeparatorFrom(old_list); - for (const CSSValue* inner_value : old_list) { + if (const auto* old_list = DynamicTo<CSSValueList>(value)) { + CSSValueList* new_list = CSSValueList::CreateWithSeparatorFrom(*old_list); + for (const CSSValue* inner_value : *old_list) { new_list->Append(ComputeRegisteredPropertyValue( document, css_to_length_conversion_data, *inner_value)); }
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h index 2eedb03..e3460da 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h
@@ -287,7 +287,7 @@ auto* identifier_value = DynamicTo<CSSIdentifierValue>(value); if (identifier_value && identifier_value->GetValueID() == CSSValueNone) return flags; - for (auto& flag_value : ToCSSValueList(value)) + for (auto& flag_value : To<CSSValueList>(value)) flags |= To<CSSIdentifierValue>(*flag_value).ConvertTo<T>(); return flags; }
diff --git a/third_party/blink/renderer/core/css/resolver/transform_builder.cc b/third_party/blink/renderer/core/css/resolver/transform_builder.cc index 0e35559..72424f1 100644 --- a/third_party/blink/renderer/core/css/resolver/transform_builder.cc +++ b/third_party/blink/renderer/core/css/resolver/transform_builder.cc
@@ -131,13 +131,14 @@ const CSSValue& in_value, const CSSToLengthConversionData& conversion_data) { TransformOperations operations; - if (!in_value.IsValueList()) { + auto* in_value_list = DynamicTo<CSSValueList>(in_value); + if (!in_value_list) { DCHECK_EQ(To<CSSIdentifierValue>(in_value).GetValueID(), CSSValueNone); return operations; } float zoom_factor = conversion_data.Zoom(); - for (auto& value : ToCSSValueList(in_value)) { + for (auto& value : *in_value_list) { const auto* transform_value = To<CSSFunctionValue>(value.Get()); TransformOperation::OperationType transform_type = GetTransformOperationType(transform_value->FunctionType());
diff --git a/third_party/blink/renderer/core/css/style_property_serializer.cc b/third_party/blink/renderer/core/css/style_property_serializer.cc index 3f96d69..43eba69 100644 --- a/third_party/blink/renderer/core/css/style_property_serializer.cc +++ b/third_party/blink/renderer/core/css/style_property_serializer.cc
@@ -889,7 +889,7 @@ for (unsigned i = 0; i < size; i++) { values[i] = property_set_.GetPropertyCSSValue(*shorthand.properties()[i]); if (values[i]->IsBaseValueList()) { - const CSSValueList* value_list = ToCSSValueList(values[i]); + const CSSValueList* value_list = To<CSSValueList>(values[i].Get()); num_layers = std::max(num_layers, value_list->length()); } } @@ -911,8 +911,8 @@ // Get a CSSValue for this property and layer. if (values[property_index]->IsBaseValueList()) { - const CSSValueList* property_values = - ToCSSValueList(values[property_index]); + const auto* property_values = + To<CSSValueList>(values[property_index].Get()); // There might not be an item for this layer for this property. if (layer < property_values->length()) value = &property_values->Item(layer); @@ -935,10 +935,10 @@ CSSPropertyBackgroundRepeatY) || shorthand.properties()[property_index + 1]->IDEquals( CSSPropertyWebkitMaskRepeatY)); + auto* value_list = + DynamicTo<CSSValueList>(values[property_index + 1].Get()); const CSSValue& y_value = - values[property_index + 1]->IsValueList() - ? ToCSSValueList(values[property_index + 1])->Item(layer) - : *values[property_index + 1]; + value_list ? value_list->Item(layer) : *values[property_index + 1]; // FIXME: At some point we need to fix this code to avoid returning an // invalid shorthand, since some longhand combinations are not @@ -1116,23 +1116,19 @@ const CSSValue& repeat_y = *property_set_.GetPropertyCSSValue(GetCSSPropertyBackgroundRepeatY()); - const CSSValueList* repeat_x_list = nullptr; + const auto* repeat_x_list = DynamicTo<CSSValueList>(repeat_x); int repeat_x_length = 1; - if (repeat_x.IsValueList()) { - repeat_x_list = &ToCSSValueList(repeat_x); + if (repeat_x_list) repeat_x_length = repeat_x_list->length(); - } else if (!repeat_x.IsIdentifierValue()) { + else if (!repeat_x.IsIdentifierValue()) return String(); - } - const CSSValueList* repeat_y_list = nullptr; + const auto* repeat_y_list = DynamicTo<CSSValueList>(repeat_y); int repeat_y_length = 1; - if (repeat_y.IsValueList()) { - repeat_y_list = &ToCSSValueList(repeat_y); + if (repeat_y_list) repeat_y_length = repeat_y_list->length(); - } else if (!repeat_y.IsIdentifierValue()) { + else if (!repeat_y.IsIdentifierValue()) return String(); - } size_t shorthand_length = lowestCommonMultiple(repeat_x_length, repeat_y_length);
diff --git a/third_party/blink/renderer/core/editing/commands/style_commands.cc b/third_party/blink/renderer/core/editing/commands/style_commands.cc index f2bd307..6bc15205 100644 --- a/third_party/blink/renderer/core/editing/commands/style_commands.cc +++ b/third_party/blink/renderer/core/editing/commands/style_commands.cc
@@ -285,9 +285,9 @@ const CSSValue& value) { const CSSValue& selected_css_value = *selection_style.Style()->GetPropertyCSSValue(property_id); - if (selected_css_value.IsValueList()) { + if (IsA<CSSValueList>(selected_css_value)) { CSSValueList& selected_css_value_list = - *ToCSSValueList(selected_css_value).Copy(); + *To<CSSValueList>(selected_css_value).Copy(); if (!selected_css_value_list.RemoveAll(value)) selected_css_value_list.Append(value); if (selected_css_value_list.length())
diff --git a/third_party/blink/renderer/core/editing/editing_style.cc b/third_party/blink/renderer/core/editing/editing_style.cc index 6b2a173..36e0a9fb 100644 --- a/third_party/blink/renderer/core/editing/editing_style.cc +++ b/third_party/blink/renderer/core/editing/editing_style.cc
@@ -293,8 +293,10 @@ style->GetPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect); if (!style_value) style_value = style->GetPropertyCSSValue(CSSPropertyTextDecorationLine); - return Matches(element) && style_value && style_value->IsValueList() && - ToCSSValueList(style_value)->HasValue(*identifier_value_); + if (!Matches(element)) + return false; + auto* style_value_list = DynamicTo<CSSValueList>(style_value); + return style_value_list && style_value_list->HasValue(*identifier_value_); } class HTMLAttributeEquivalent : public HTMLElementEquivalent { @@ -1362,12 +1364,13 @@ const CSSValue* value = mutable_style_->GetPropertyCSSValue(property.Id()); // text decorations never override values + const auto* property_value_list = DynamicTo<CSSValueList>(property.Value()); if ((property.Id() == CSSPropertyTextDecorationLine || property.Id() == CSSPropertyWebkitTextDecorationsInEffect) && - property.Value().IsValueList() && value) { - if (value->IsValueList()) { - const CSSValueList& result = MergeTextDecorationValues( - *ToCSSValueList(value), ToCSSValueList(property.Value())); + property_value_list && value) { + if (const auto* value_list = DynamicTo<CSSValueList>(value)) { + const CSSValueList& result = + MergeTextDecorationValues(*value_list, *property_value_list); mutable_style_->SetProperty(property.Id(), result, property.IsImportant()); continue; @@ -1670,12 +1673,13 @@ // property is always a CSSValueList. const CSSValue* text_decoration = style->GetPropertyCSSValue(CSSPropertyTextDecorationLine); - if (text_decoration && text_decoration->IsValueList()) { + if (const auto* text_decoration_value_list = + DynamicTo<CSSValueList>(text_decoration)) { DEFINE_STATIC_LOCAL(Persistent<CSSIdentifierValue>, underline, (CSSIdentifierValue::Create(CSSValueUnderline))); DEFINE_STATIC_LOCAL(Persistent<CSSIdentifierValue>, line_through, (CSSIdentifierValue::Create(CSSValueLineThrough))); - CSSValueList* new_text_decoration = ToCSSValueList(text_decoration)->Copy(); + CSSValueList* new_text_decoration = text_decoration_value_list->Copy(); if (new_text_decoration->RemoveAll(*underline)) apply_underline_ = true; if (new_text_decoration->RemoveAll(*line_through)) @@ -1729,13 +1733,14 @@ const CSSValue* ref_text_decoration, SecureContextMode secure_context_mode) { const CSSValue* text_decoration = style->GetPropertyCSSValue(property_id); - if (!text_decoration || !text_decoration->IsValueList() || - !ref_text_decoration || !ref_text_decoration->IsValueList()) + const auto* values_in_text_decoration = + DynamicTo<CSSValueList>(text_decoration); + const auto* values_in_ref_text_decoration = + DynamicTo<CSSValueList>(ref_text_decoration); + if (!values_in_text_decoration || !values_in_ref_text_decoration) return; - CSSValueList* new_text_decoration = ToCSSValueList(text_decoration)->Copy(); - const CSSValueList* values_in_ref_text_decoration = - ToCSSValueList(ref_text_decoration); + CSSValueList* new_text_decoration = values_in_text_decoration->Copy(); for (wtf_size_t i = 0; i < values_in_ref_text_decoration->length(); i++) new_text_decoration->RemoveAll(values_in_ref_text_decoration->Item(i));
diff --git a/third_party/blink/renderer/core/editing/selection_modifier_character.cc b/third_party/blink/renderer/core/editing/selection_modifier_character.cc index 648ffd3..a88c0db 100644 --- a/third_party/blink/renderer/core/editing/selection_modifier_character.cc +++ b/third_party/blink/renderer/core/editing/selection_modifier_character.cc
@@ -38,6 +38,8 @@ #include "third_party/blink/renderer/core/editing/visible_units.h" #include "third_party/blink/renderer/core/layout/api/line_layout_api_shim.h" #include "third_party/blink/renderer/core/layout/api/line_layout_item.h" +#include "third_party/blink/renderer/core/layout/layout_block_flow.h" +#include "third_party/blink/renderer/core/layout/layout_text_fragment.h" #include "third_party/blink/renderer/core/layout/line/inline_text_box.h" #include "third_party/blink/renderer/core/layout/line/root_inline_box.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.h" @@ -159,6 +161,18 @@ DCHECK(RuntimeEnabledFeatures::BidiCaretAffinityEnabled()); return caret_navigator.LeftPositionOf(caret_position); } + + static NGCaretNavigator::Position MostBackwardPositionInFirstLine( + const NGCaretNavigator& caret_navigator) { + DCHECK(RuntimeEnabledFeatures::BidiCaretAffinityEnabled()); + return caret_navigator.RightmostPositionInFirstLine(); + } + + static NGCaretNavigator::Position MostBackwardPositionInLastLine( + const NGCaretNavigator& caret_navigator) { + DCHECK(RuntimeEnabledFeatures::BidiCaretAffinityEnabled()); + return caret_navigator.RightmostPositionInLastLine(); + } }; // The traversal strategy for |RightPositionOf()|. @@ -272,6 +286,18 @@ DCHECK(RuntimeEnabledFeatures::BidiCaretAffinityEnabled()); return caret_navigator.RightPositionOf(caret_position); } + + static NGCaretNavigator::Position MostBackwardPositionInFirstLine( + const NGCaretNavigator& caret_navigator) { + DCHECK(RuntimeEnabledFeatures::BidiCaretAffinityEnabled()); + return caret_navigator.LeftmostPositionInFirstLine(); + } + + static NGCaretNavigator::Position MostBackwardPositionInLastLine( + const NGCaretNavigator& caret_navigator) { + DCHECK(RuntimeEnabledFeatures::BidiCaretAffinityEnabled()); + return caret_navigator.LeftmostPositionInLastLine(); + } }; template <typename Traversal> @@ -496,8 +522,64 @@ } template <typename Strategy, typename Traversal> +PositionWithAffinityTemplate<Strategy> TraverseIntoChildContext( + const PositionTemplate<Strategy>& position) { + DCHECK(position.IsNotNull()); + DCHECK(position.IsBeforeAnchor() || position.IsAfterAnchor()) << position; + DCHECK(position.AnchorNode()->GetLayoutObject()) << position; + DCHECK(position.AnchorNode()->GetLayoutObject()->IsLayoutBlockFlow()) + << position; + + LayoutBlockFlow& target_block = + *ToLayoutBlockFlow(position.AnchorNode()->GetLayoutObject()); + + if (!target_block.IsLayoutNGMixin()) { + // In most cases, we reach here by crossing editing boundary, in which case + // returning null position suffices. + // TODO(xiaochengh): Investigate if there are other cases that need a + // non-trivial legacy fallback. + return PositionWithAffinityTemplate<Strategy>(); + } + + if (!target_block.ChildrenInline() || !target_block.HasNGInlineNodeData() || + !target_block.GetNGInlineNodeData()->text_content.length()) { + // TODO(xiaochengh): Implement when |target_block| has its own child blocks, + // or when |target_block| is empty. + return PositionWithAffinityTemplate<Strategy>(); + } + + NGCaretNavigator caret_navigator(target_block); + DCHECK(caret_navigator.GetText().length()); + + const NGCaretNavigator::Position position_in_target = + position.IsBeforeAnchor() + ? Traversal::MostBackwardPositionInFirstLine(caret_navigator) + : Traversal::MostBackwardPositionInLastLine(caret_navigator); + + // When moving into inline block, the caret moves over the first character + // seamlessly as if there's no inline block boundary. For example: + // RightPositionOf(foo|<inline-block>bar</inline-block>) + // -> foo<inline-block>b|ar</inline-block> + const NGCaretNavigator::VisualCaretMovementResult result_position = + Traversal::ForwardPositionOf(caret_navigator, position_in_target); + + if (!result_position.IsWithinContext()) { + // TODO(xiaochengh): We reach here if |target_block| starts with an + // enterable child context. Fix it with proper block navigation. + // Also investigate if we reach here for other reasons. + return PositionWithAffinityTemplate<Strategy>(); + } + + const NGOffsetMapping* mapping = + NGInlineNode::GetOffsetMapping(&target_block); + return FromPositionInDOMTree<Strategy>( + mapping->GetPositionWithAffinity(*result_position.position)); +} + +template <typename Strategy, typename Traversal> PositionWithAffinityTemplate<Strategy> TraverseWithBidiCaretAffinity( - const PositionWithAffinityTemplate<Strategy> start_position_with_affinity) { + const PositionWithAffinityTemplate<Strategy>& + start_position_with_affinity) { const PositionTemplate<Strategy> start_position = start_position_with_affinity.GetPosition(); const Position start_position_in_dom = ToPositionInDOMTree(start_position); @@ -547,6 +629,16 @@ result_caret_position.position.value())); } + if (result_caret_position.HasEnteredChildContext()) { + DCHECK(result_caret_position.position.has_value()); + const PositionTemplate<Strategy> outside_child_context = + FromPositionInDOMTree<Strategy>( + mapping->GetPositionWithAffinity(*result_caret_position.position)) + .GetPosition(); + + return TraverseIntoChildContext<Strategy, Traversal>(outside_child_context); + } + // We reach here if we need to move out of the current block. if (result_caret_position.IsBeforeContext()) { // TODO(xiaochengh): Move to the visual end of the previous block.
diff --git a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc index 73736ec..d91b304 100644 --- a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc +++ b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc
@@ -492,12 +492,14 @@ it.value->DispatchBufferedTouchEvents(); } -bool WebDevToolsAgentImpl::HandleInputEvent(const WebInputEvent& event) { +WebInputEventResult WebDevToolsAgentImpl::HandleInputEvent( + const WebInputEvent& event) { for (auto& it : overlay_agents_) { - if (it.value->HandleInputEvent(event)) - return true; + auto result = it.value->HandleInputEvent(event); + if (result != WebInputEventResult::kNotHandled) + return result; } - return false; + return WebInputEventResult::kNotHandled; } String WebDevToolsAgentImpl::NavigationInitiatorInfo(LocalFrame* frame) {
diff --git a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h index 8039d45..a55e5c52 100644 --- a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h +++ b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h
@@ -33,6 +33,7 @@ #include <memory> +#include "third_party/blink/public/platform/web_input_event_result.h" #include "third_party/blink/public/platform/web_size.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/inspector/devtools_agent.h" @@ -85,7 +86,7 @@ void UpdateOverlays(); void PaintOverlays(GraphicsContext&); // For CompositeAfterPaint. - bool HandleInputEvent(const WebInputEvent&); + WebInputEventResult HandleInputEvent(const WebInputEvent&); void DispatchBufferedTouchEvents(); void BindRequest(mojom::blink::DevToolsAgentHostAssociatedPtrInfo, mojom::blink::DevToolsAgentAssociatedRequest);
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 9b583fa..bff13003 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -1685,8 +1685,9 @@ return WebInputEventResult::kHandledSuppressed; if (WebDevToolsAgentImpl* devtools = MainFrameDevToolsAgentImpl()) { - if (devtools->HandleInputEvent(input_event)) - return WebInputEventResult::kHandledSuppressed; + auto result = devtools->HandleInputEvent(input_event); + if (result != WebInputEventResult::kNotHandled) + return result; } // Report the event to be NOT processed by WebKit, so that the browser can
diff --git a/third_party/blink/renderer/core/frame/frame_serializer.cc b/third_party/blink/renderer/core/frame/frame_serializer.cc index d443704..e2333d9 100644 --- a/third_party/blink/renderer/core/frame/frame_serializer.cc +++ b/third_party/blink/renderer/core/frame/frame_serializer.cc
@@ -558,10 +558,9 @@ return; AddFontToResources(font_face_src_value->Fetch(&document, nullptr)); - } else if (css_value.IsValueList()) { - const CSSValueList& css_value_list = ToCSSValueList(css_value); - for (unsigned i = 0; i < css_value_list.length(); i++) - RetrieveResourcesForCSSValue(css_value_list.Item(i), document); + } else if (const auto* css_value_list = DynamicTo<CSSValueList>(css_value)) { + for (unsigned i = 0; i < css_value_list->length(); i++) + RetrieveResourcesForCSSValue(css_value_list->Item(i), document); } }
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 70ccd91..2cb2430 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
@@ -414,8 +414,9 @@ if (LocalRootImpl()) { if (WebDevToolsAgentImpl* devtools = LocalRootImpl()->DevToolsAgentImpl()) { - if (devtools->HandleInputEvent(input_event)) - return WebInputEventResult::kHandledSuppressed; + auto result = devtools->HandleInputEvent(input_event); + if (result != WebInputEventResult::kNotHandled) + return result; } }
diff --git a/third_party/blink/renderer/core/geometry/dom_matrix_read_only.cc b/third_party/blink/renderer/core/geometry/dom_matrix_read_only.cc index b516155..87e251c 100644 --- a/third_party/blink/renderer/core/geometry/dom_matrix_read_only.cc +++ b/third_party/blink/renderer/core/geometry/dom_matrix_read_only.cc
@@ -488,7 +488,7 @@ return; } - if (TransformBuilder::HasRelativeLengths(ToCSSValueList(*value))) { + if (TransformBuilder::HasRelativeLengths(To<CSSValueList>(*value))) { exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError, "Lengths must be absolute, not relative"); return;
diff --git a/third_party/blink/renderer/core/html/html_font_element.cc b/third_party/blink/renderer/core/html/html_font_element.cc index d61a02c0..fb2526c 100644 --- a/third_party/blink/renderer/core/html/html_font_element.cc +++ b/third_party/blink/renderer/core/html/html_font_element.cc
@@ -128,8 +128,8 @@ const CSSValue* parsed_value = CSSParser::ParseSingleValue( CSSPropertyFontFamily, string, StrictCSSParserContext(secure_context_mode)); - if (parsed_value && parsed_value->IsValueList()) - entry.stored_value->value = ToCSSValueList(parsed_value); + if (auto* parsed_value_list = DynamicTo<CSSValueList>(parsed_value)) + entry.stored_value->value = parsed_value_list; } return entry.stored_value->value; }
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc index 8d4902b..621a17c 100644 --- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
@@ -31,6 +31,7 @@ #include <algorithm> #include <memory> #include <utility> +#include <vector> #include "base/auto_reset.h" #include "build/build_config.h" @@ -143,6 +144,175 @@ } // namespace +// InspectTool ----------------------------------------------------------------- + +void InspectTool::Init(InspectorOverlayAgent* overlay, + OverlayFrontend* frontend) { + overlay_ = overlay; + frontend_ = frontend; + DoInit(); +} + +bool InspectTool::HandleMouseDown(const WebMouseEvent&, + bool* swallow_next_mouse_up) { + return false; +} + +bool InspectTool::HandleMouseUp(const WebMouseEvent&) { + return false; +} + +bool InspectTool::HandleMouseMove(const WebMouseEvent&) { + return false; +} + +bool InspectTool::HandleGestureTapEvent(const WebGestureEvent&) { + return false; +} + +bool InspectTool::HandlePointerEvent(const WebPointerEvent&) { + return false; +} + +bool InspectTool::HandleKeyboardEvent(const WebKeyboardEvent&, + bool* swallow_next_escape_up) { + return false; +} + +void InspectTool::Trace(blink::Visitor* visitor) { + visitor->Trace(overlay_); +} + +// SearchingForNodeTool -------------------------------------------------------- + +class SearchingForNodeTool : public InspectTool { + public: + SearchingForNodeTool(InspectorDOMAgent* dom_agent, + bool ua_shadow, + const String& highlight_config); + + private: + bool HandleMouseDown(const WebMouseEvent& event, + bool* swallow_next_mouse_up) override; + bool HandleMouseMove(const WebMouseEvent& event) override; + bool HandleGestureTapEvent(const WebGestureEvent&) override; + bool HandlePointerEvent(const WebPointerEvent&) override; + void NodeHighlightRequested(Node*); + void Trace(blink::Visitor* visitor) override; + + Member<InspectorDOMAgent> dom_agent_; + bool ua_shadow_; + Member<Node> hovered_node_for_inspect_mode_; + std::unique_ptr<InspectorHighlightConfig> inspect_mode_highlight_config_; +}; + +SearchingForNodeTool::SearchingForNodeTool(InspectorDOMAgent* dom_agent, + bool ua_shadow, + const String& config) + : dom_agent_(dom_agent), ua_shadow_(ua_shadow) { + std::unique_ptr<protocol::Value> value = + protocol::StringUtil::parseJSON(config); + if (!value) + return; + protocol::ErrorSupport errors; + std::unique_ptr<protocol::Overlay::HighlightConfig> highlight_config = + protocol::Overlay::HighlightConfig::fromValue(value.get(), &errors); + overlay_->HighlightConfigFromInspectorObject(std::move(highlight_config), + &inspect_mode_highlight_config_); +} + +void SearchingForNodeTool::Trace(blink::Visitor* visitor) { + InspectTool::Trace(visitor); + visitor->Trace(dom_agent_); + visitor->Trace(hovered_node_for_inspect_mode_); +} + +// ScreenshotTool -------------------------------------------------------------- + +class ScreenshotTool : public InspectTool { + public: + ScreenshotTool() = default; + + private: + bool HandleKeyboardEvent(const WebKeyboardEvent&, + bool* swallow_next_escape_up) override; + bool HandleMouseDown(const WebMouseEvent& event, + bool* swallow_next_mouse_up) override; + bool HandleMouseMove(const WebMouseEvent& event) override; + bool HandleMouseUp(const WebMouseEvent& event) override; + void Draw(float scale) override; + void DoInit() override; + + IntPoint screenshot_anchor_; + IntPoint screenshot_position_; +}; + +void ScreenshotTool::DoInit() { + auto& client = overlay_->GetFrame()->GetPage()->GetChromeClient(); + client.SetCursorOverridden(false); + client.SetCursor(CrossCursor(), overlay_->GetFrame()); + client.SetCursorOverridden(true); +} + +bool ScreenshotTool::HandleKeyboardEvent(const WebKeyboardEvent& event, + bool* swallow_next_escape_up) { + if (event.GetType() == WebInputEvent::kRawKeyDown && + event.windows_key_code == VKEY_ESCAPE && + screenshot_anchor_ != IntPoint::Zero()) { + screenshot_anchor_ = IntPoint::Zero(); + *swallow_next_escape_up = true; + return true; + } + return false; +} + +bool ScreenshotTool::HandleMouseDown(const WebMouseEvent& event, + bool* swallow_next_mouse_up) { + screenshot_anchor_ = RoundedIntPoint(event.PositionInRootFrame()); + screenshot_position_ = screenshot_anchor_; + return true; +} + +bool ScreenshotTool::HandleMouseMove(const WebMouseEvent& event) { + screenshot_position_ = RoundedIntPoint(event.PositionInRootFrame()); + return true; +} + +void ScreenshotTool::Draw(float scale) { + if (screenshot_anchor_ == IntPoint::Zero()) + return; + const VisualViewport& visual_viewport = + overlay_->GetFrame()->GetPage()->GetVisualViewport(); + IntPoint p1 = visual_viewport.RootFrameToViewport(screenshot_anchor_); + IntPoint p2 = visual_viewport.RootFrameToViewport(screenshot_position_); + p1.Scale(scale, scale); + p2.Scale(scale, scale); + std::unique_ptr<protocol::DictionaryValue> data = + protocol::DictionaryValue::create(); + data->setInteger("x1", p1.X()); + data->setInteger("y1", p1.Y()); + data->setInteger("x2", p2.X()); + data->setInteger("y2", p2.Y()); + overlay_->EvaluateInOverlay("drawScreenshotBorder", std::move(data)); +} + +// PausedInDebuggerTool -------------------------------------------------------- + +class PausedInDebuggerTool : public InspectTool { + public: + PausedInDebuggerTool(const String& message) : message_(message) {} + + private: + void Draw(float scale) override; + String message_; +}; + +void PausedInDebuggerTool::Draw(float scale) { + overlay_->EvaluateInOverlay("drawPausedInDebuggerMessage", message_); +} + +// InspectorOverlayAgent ------------------------------------------------------- + class InspectorOverlayAgent::InspectorPageOverlayDelegate final : public FrameOverlay::Delegate, public cc::ContentLayerClient { @@ -225,12 +395,8 @@ } void SetCursor(const Cursor& cursor, LocalFrame* local_root) override { - if (overlay_->inspect_mode_.Get() == - protocol::Overlay::InspectModeEnum::CaptureAreaScreenshot) { - return; - } client_->SetCursorOverridden(false); - client_->SetCursor(cursor, overlay_->frame_impl_->GetFrame()); + client_->SetCursor(cursor, overlay_->GetFrame()); client_->SetCursorOverridden(true); } @@ -238,7 +404,7 @@ const String& tooltip, TextDirection direction) override { DCHECK_EQ(&frame, overlay_->OverlayMainFrame()); - client_->SetToolTip(*overlay_->frame_impl_->GetFrame(), tooltip, direction); + client_->SetToolTip(*overlay_->GetFrame(), tooltip, direction); } void InvalidateRect(const IntRect&) override { overlay_->Invalidate(); } @@ -295,7 +461,7 @@ visitor->Trace(overlay_chrome_client_); visitor->Trace(overlay_host_); visitor->Trace(dom_agent_); - visitor->Trace(hovered_node_for_inspect_mode_); + visitor->Trace(inspect_tool_); InspectorBaseAgent::Trace(visitor); } @@ -307,20 +473,8 @@ setShowScrollBottleneckRects(show_scroll_bottleneck_rects_.Get()); setShowHitTestBorders(show_hit_test_borders_.Get()); setShowViewportSizeOnResize(show_size_on_resize_.Get()); - if (paused_in_debugger_message_.Get().IsNull()) - setPausedInDebuggerMessage(paused_in_debugger_message_.Get()); setSuspended(suspended_.Get()); - if (inspect_mode_.Get() != protocol::Overlay::InspectModeEnum::None) { - std::unique_ptr<protocol::Value> value = - protocol::StringUtil::parseJSON(inspect_mode_protocol_config_.Get()); - std::unique_ptr<protocol::Overlay::HighlightConfig> highlight_config; - protocol::ErrorSupport errors; - if (value) { - highlight_config = - protocol::Overlay::HighlightConfig::fromValue(value.get(), &errors); - } - SetSearchingForNode(inspect_mode_.Get(), std::move(highlight_config)); - } + PickTheRightTool(); } void InspectorOverlayAgent::Dispose() { @@ -351,10 +505,11 @@ setShowScrollBottleneckRects(false); setShowHitTestBorders(false); setShowViewportSizeOnResize(false); - setPausedInDebuggerMessage(String()); setSuspended(false); - SetSearchingForNode(protocol::Overlay::InspectModeEnum::None, - Maybe<protocol::Overlay::HighlightConfig>()); + paused_in_debugger_message_.Clear(); + inspect_mode_.Set(protocol::Overlay::InspectModeEnum::None); + inspect_mode_protocol_config_.Set(String()); + PickTheRightTool(); SetNeedsUnbufferedInput(false); return Response::OK(); } @@ -455,7 +610,7 @@ Response InspectorOverlayAgent::setPausedInDebuggerMessage( Maybe<String> message) { paused_in_debugger_message_.Set(message.fromMaybe(String())); - ScheduleUpdate(); + PickTheRightTool(); return Response::OK(); } @@ -467,19 +622,6 @@ return Response::OK(); } -Response InspectorOverlayAgent::setInspectMode( - const String& mode, - Maybe<protocol::Overlay::HighlightConfig> highlight_config) { - if (mode != protocol::Overlay::InspectModeEnum::SearchForNode && - mode != protocol::Overlay::InspectModeEnum::SearchForUAShadowDOM && - mode != protocol::Overlay::InspectModeEnum::CaptureAreaScreenshot && - mode != protocol::Overlay::InspectModeEnum::None) { - return Response::Error( - String("Unknown mode \"" + mode + "\" was provided.")); - } - return SetSearchingForNode(mode, std::move(highlight_config)); -} - Response InspectorOverlayAgent::highlightRect( int x, int y, @@ -553,6 +695,7 @@ Response InspectorOverlayAgent::hideHighlight() { InnerHideHighlight(); + ScheduleUpdate(); return Response::OK(); } @@ -575,8 +718,7 @@ if (!frame_overlay_) { frame_overlay_ = FrameOverlay::Create( - frame_impl_->GetFrame(), - std::make_unique<InspectorPageOverlayDelegate>(*this)); + GetFrame(), std::make_unique<InspectorPageOverlayDelegate>(*this)); } frame_overlay_->Update(); @@ -620,17 +762,22 @@ return layer == frame_overlay_->GetGraphicsLayer()->CcLayer(); } +LocalFrame* InspectorOverlayAgent::GetFrame() const { + return frame_impl_->GetFrame(); +} + void InspectorOverlayAgent::DispatchBufferedTouchEvents() { if (IsEmpty()) return; OverlayMainFrame()->GetEventHandler().DispatchBufferedTouchEvents(); } -bool InspectorOverlayAgent::HandleInputEvent(const WebInputEvent& input_event) { +WebInputEventResult InspectorOverlayAgent::HandleInputEvent( + const WebInputEvent& input_event) { if (input_event.GetType() == WebInputEvent::kMouseUp && swallow_next_mouse_up_) { swallow_next_mouse_up_ = false; - return true; + return WebInputEventResult::kHandledSuppressed; } if (input_event.GetType() == WebInputEvent::kKeyUp && @@ -638,44 +785,24 @@ auto keyboard_event = static_cast<const WebKeyboardEvent&>(input_event); if (keyboard_event.windows_key_code == VKEY_ESCAPE) { swallow_next_escape_up_ = false; - return true; + return WebInputEventResult::kHandledSuppressed; } } - if (IsEmpty()) - return false; - - // In the inspect mode, after clicking, keyboard events are dispatched here. - // Handle Escape below. - - if (inspect_mode_.Get() != protocol::Overlay::InspectModeEnum::None && - input_event.GetType() == WebInputEvent::kRawKeyDown) { - auto keyboard_event = static_cast<const WebKeyboardEvent&>(input_event); - if (keyboard_event.windows_key_code == VKEY_ESCAPE) { - // If we are in the process of dragging, reset the dragging. - // Otherwise, cancel searching. - if (screenshot_anchor_ != IntPoint::Zero()) { - screenshot_anchor_ = IntPoint::Zero(); - ScheduleUpdate(); - } else { - GetFrontend()->inspectModeCanceled(); - } - swallow_next_escape_up_ = true; - return true; - } - } - - bool handled = false; + if (IsEmpty() || !inspect_tool_) + return WebInputEventResult::kNotHandled; if (input_event.GetType() == WebInputEvent::kGestureTap) { // We only have a use for gesture tap. WebGestureEvent transformed_event = TransformWebGestureEvent( frame_impl_->GetFrameView(), static_cast<const WebGestureEvent&>(input_event)); - handled = HandleGestureEvent(transformed_event); - if (handled) - return true; - OverlayMainFrame()->GetEventHandler().HandleGestureEvent(transformed_event); + if (inspect_tool_->HandleGestureTapEvent(transformed_event)) { + ScheduleUpdate(); + return WebInputEventResult::kHandledSuppressed; + } + return OverlayMainFrame()->GetEventHandler().HandleGestureEvent( + transformed_event); } if (WebInputEvent::IsMouseEventType(input_event.GetType())) { @@ -683,34 +810,36 @@ TransformWebMouseEvent(frame_impl_->GetFrameView(), static_cast<const WebMouseEvent&>(input_event)); - if (mouse_event.GetType() == WebInputEvent::kMouseMove) - handled = HandleMouseMove(mouse_event); - else if (mouse_event.GetType() == WebInputEvent::kMouseDown) - handled = HandleMouseDown(mouse_event); - else if (mouse_event.GetType() == WebInputEvent::kMouseUp) - handled = HandleMouseUp(mouse_event); + bool handled = false; + if (mouse_event.GetType() == WebInputEvent::kMouseMove) { + handled = inspect_tool_->HandleMouseMove(mouse_event); + } else if (mouse_event.GetType() == WebInputEvent::kMouseDown) { + handled = + inspect_tool_->HandleMouseDown(mouse_event, &swallow_next_mouse_up_); + } else if (mouse_event.GetType() == WebInputEvent::kMouseUp) { + handled = inspect_tool_->HandleMouseUp(mouse_event); + } - if (handled) - return true; + if (handled) { + ScheduleUpdate(); + return WebInputEventResult::kHandledSuppressed; + } if (mouse_event.GetType() == WebInputEvent::kMouseMove) { - handled = - OverlayMainFrame()->GetEventHandler().HandleMouseMoveEvent( - mouse_event, - TransformWebMouseEventVector(frame_impl_->GetFrameView(), - std::vector<const WebInputEvent*>()), - TransformWebMouseEventVector( - frame_impl_->GetFrameView(), - std::vector<const WebInputEvent*>())) != - WebInputEventResult::kNotHandled; + return OverlayMainFrame()->GetEventHandler().HandleMouseMoveEvent( + mouse_event, + TransformWebMouseEventVector(frame_impl_->GetFrameView(), + std::vector<const WebInputEvent*>()), + TransformWebMouseEventVector(frame_impl_->GetFrameView(), + std::vector<const WebInputEvent*>())); } if (mouse_event.GetType() == WebInputEvent::kMouseDown) { - handled = OverlayMainFrame()->GetEventHandler().HandleMousePressEvent( - mouse_event) != WebInputEventResult::kNotHandled; + return OverlayMainFrame()->GetEventHandler().HandleMousePressEvent( + mouse_event); } if (mouse_event.GetType() == WebInputEvent::kMouseUp) { - handled = OverlayMainFrame()->GetEventHandler().HandleMouseReleaseEvent( - mouse_event) != WebInputEventResult::kNotHandled; + return OverlayMainFrame()->GetEventHandler().HandleMouseReleaseEvent( + mouse_event); } } @@ -718,15 +847,35 @@ WebPointerEvent transformed_event = TransformWebPointerEvent( frame_impl_->GetFrameView(), static_cast<const WebPointerEvent&>(input_event)); - handled = HandlePointerEvent(transformed_event); - if (handled) - return true; - OverlayMainFrame()->GetEventHandler().HandlePointerEvent( + bool handled = inspect_tool_->HandlePointerEvent(transformed_event); + if (handled) { + ScheduleUpdate(); + return WebInputEventResult::kHandledSuppressed; + } + return OverlayMainFrame()->GetEventHandler().HandlePointerEvent( transformed_event, Vector<WebPointerEvent>(), Vector<WebPointerEvent>()); } + if (WebInputEvent::IsKeyboardEventType(input_event.GetType())) { - OverlayMainFrame()->GetEventHandler().KeyEvent( + bool handled = inspect_tool_->HandleKeyboardEvent( + static_cast<const WebKeyboardEvent&>(input_event), + &swallow_next_escape_up_); + if (handled) { + ScheduleUpdate(); + return WebInputEventResult::kHandledSuppressed; + } + + // Exit tool upon unhandled Esc. + if (input_event.GetType() == WebInputEvent::kRawKeyDown) { + auto keyboard_event = static_cast<const WebKeyboardEvent&>(input_event); + if (keyboard_event.windows_key_code == VKEY_ESCAPE) { + GetFrontend()->inspectModeCanceled(); + swallow_next_escape_up_ = true; + return WebInputEventResult::kHandledSuppressed; + } + } + return OverlayMainFrame()->GetEventHandler().KeyEvent( static_cast<const WebKeyboardEvent&>(input_event)); } @@ -734,11 +883,11 @@ WebMouseWheelEvent transformed_event = TransformWebMouseWheelEvent( frame_impl_->GetFrameView(), static_cast<const WebMouseWheelEvent&>(input_event)); - handled = OverlayMainFrame()->GetEventHandler().HandleWheelEvent( - transformed_event) != WebInputEventResult::kNotHandled; + return OverlayMainFrame()->GetEventHandler().HandleWheelEvent( + transformed_event); } - return handled; + return WebInputEventResult::kNotHandled; } void InspectorOverlayAgent::InnerHideHighlight() { @@ -746,7 +895,6 @@ event_target_node_.Clear(); highlight_quad_.reset(); highlight_node_contrast_ = InspectorHighlightContrastInfo(); - ScheduleUpdate(); } void InspectorOverlayAgent::InnerHighlightNode( @@ -798,31 +946,29 @@ return true; bool has_visible_elements = highlight_node_ || event_target_node_ || highlight_quad_ || - (resize_timer_active_ && show_size_on_resize_.Get()) || - !paused_in_debugger_message_.Get().IsNull(); - return !has_visible_elements && - inspect_mode_.Get() == protocol::Overlay::InspectModeEnum::None; + (resize_timer_active_ && show_size_on_resize_.Get()); + return !has_visible_elements && !inspect_tool_; } void InspectorOverlayAgent::ScheduleUpdate() { - auto& client = frame_impl_->GetFrame()->GetPage()->GetChromeClient(); + auto& client = GetFrame()->GetPage()->GetChromeClient(); if (IsEmpty()) { if (frame_overlay_) { frame_overlay_.reset(); client.SetCursorOverridden(false); - client.SetCursor(PointerCursor(), frame_impl_->GetFrame()); + client.SetCursor(PointerCursor(), GetFrame()); if (auto* frame_view = frame_impl_->GetFrameView()) frame_view->SetPaintArtifactCompositorNeedsUpdate(); } return; } needs_update_ = true; - client.ScheduleAnimation(frame_impl_->GetFrame()->View()); + client.ScheduleAnimation(GetFrame()->View()); } void InspectorOverlayAgent::RebuildOverlayPage() { LocalFrameView* view = frame_impl_->GetFrameView(); - LocalFrame* frame = frame_impl_->GetFrame(); + LocalFrame* frame = GetFrame(); if (!view || !frame) return; @@ -835,9 +981,9 @@ DrawMatchingSelector(); DrawNodeHighlight(); DrawQuadHighlight(); - DrawPausedInDebuggerMessage(); DrawViewSize(); - DrawScreenshotBorder(); + if (inspect_tool_) + inspect_tool_->Draw(1.f / WindowToViewportScale()); } static std::unique_ptr<protocol::DictionaryValue> BuildObjectForSize( @@ -902,40 +1048,13 @@ EvaluateInOverlay("drawHighlight", highlight.AsProtocolValue()); } -void InspectorOverlayAgent::DrawPausedInDebuggerMessage() { - if (inspect_mode_.Get() == protocol::Overlay::InspectModeEnum::None && - !paused_in_debugger_message_.Get().IsNull()) { - EvaluateInOverlay("drawPausedInDebuggerMessage", - paused_in_debugger_message_.Get()); - } -} - void InspectorOverlayAgent::DrawViewSize() { if (resize_timer_active_ && show_size_on_resize_.Get()) EvaluateInOverlay("drawViewSize", ""); } -void InspectorOverlayAgent::DrawScreenshotBorder() { - if (screenshot_anchor_ == IntPoint::Zero()) - return; - const VisualViewport& visual_viewport = - frame_impl_->GetFrame()->GetPage()->GetVisualViewport(); - IntPoint p1 = visual_viewport.RootFrameToViewport(screenshot_anchor_); - IntPoint p2 = visual_viewport.RootFrameToViewport(screenshot_position_); - float scale = 1.f / WindowToViewportScale(); - p1.Scale(scale, scale); - p2.Scale(scale, scale); - std::unique_ptr<protocol::DictionaryValue> data = - protocol::DictionaryValue::create(); - data->setInteger("x1", p1.X()); - data->setInteger("y1", p1.Y()); - data->setInteger("x2", p2.X()); - data->setInteger("y2", p2.Y()); - EvaluateInOverlay("drawScreenshotBorder", std::move(data)); -} - float InspectorOverlayAgent::WindowToViewportScale() const { - LocalFrame* frame = frame_impl_->GetFrame(); + LocalFrame* frame = GetFrame(); if (!frame) return 1.0f; return frame->GetPage()->GetChromeClient().WindowToViewportScalar(1.0f); @@ -953,12 +1072,12 @@ FillWithEmptyClients(page_clients); DCHECK(!overlay_chrome_client_); overlay_chrome_client_ = InspectorOverlayChromeClient::Create( - frame_impl_->GetFrame()->GetPage()->GetChromeClient(), *this); + GetFrame()->GetPage()->GetChromeClient(), *this); page_clients.chrome_client = overlay_chrome_client_.Get(); overlay_page_ = Page::Create(page_clients); overlay_host_ = MakeGarbageCollected<InspectorOverlayHost>(this); - Settings& settings = frame_impl_->GetFrame()->GetPage()->GetSettings(); + Settings& settings = GetFrame()->GetPage()->GetSettings(); Settings& overlay_settings = overlay_page_->GetSettings(); overlay_settings.GetGenericFontFamilySettings().UpdateStandard( @@ -1022,24 +1141,21 @@ void InspectorOverlayAgent::Reset(const IntSize& viewport_size) { std::unique_ptr<protocol::DictionaryValue> reset_data = protocol::DictionaryValue::create(); - reset_data->setDouble( - "deviceScaleFactor", - frame_impl_->GetFrame()->GetPage()->DeviceScaleFactorDeprecated()); - reset_data->setDouble( - "pageScaleFactor", - frame_impl_->GetFrame()->GetPage()->GetVisualViewport().Scale()); + reset_data->setDouble("deviceScaleFactor", + GetFrame()->GetPage()->DeviceScaleFactorDeprecated()); + reset_data->setDouble("pageScaleFactor", + GetFrame()->GetPage()->GetVisualViewport().Scale()); IntRect viewport_in_screen = - frame_impl_->GetFrame()->GetPage()->GetChromeClient().ViewportToScreen( - IntRect(IntPoint(), viewport_size), frame_impl_->GetFrame()->View()); + GetFrame()->GetPage()->GetChromeClient().ViewportToScreen( + IntRect(IntPoint(), viewport_size), GetFrame()->View()); reset_data->setObject("viewportSize", BuildObjectForSize(viewport_in_screen.Size())); // The zoom factor in the overlay frame already has been multiplied by the // window to viewport scale (aka device scale factor), so cancel it. - reset_data->setDouble( - "pageZoomFactor", - frame_impl_->GetFrame()->PageZoomFactor() / WindowToViewportScale()); + reset_data->setDouble("pageZoomFactor", + GetFrame()->PageZoomFactor() / WindowToViewportScale()); // TODO(szager): These values have been zero since root layer scrolling // landed. Probably they should be derived from @@ -1111,7 +1227,7 @@ inspect_mode_protocol_config_.Set(String()); timer_.Stop(); frame_overlay_.reset(); - InnerHideHighlight(); + PickTheRightTool(); } void InspectorOverlayAgent::OverlayResumed() { @@ -1132,26 +1248,15 @@ ScheduleUpdate(); } -bool InspectorOverlayAgent::HandleMouseMove(const WebMouseEvent& event) { - if (!InSomeInspectMode()) - return false; - - if (inspect_mode_.Get() == - protocol::Overlay::InspectModeEnum::CaptureAreaScreenshot) { - screenshot_position_ = RoundedIntPoint(event.PositionInRootFrame()); - ScheduleUpdate(); - return true; - } - - LocalFrame* frame = frame_impl_->GetFrame(); +bool SearchingForNodeTool::HandleMouseMove(const WebMouseEvent& event) { + LocalFrame* frame = overlay_->GetFrame(); if (!frame || !frame->View() || !frame->ContentLayoutObject()) return false; Node* node = HoveredNodeForEvent( frame, event, event.GetModifiers() & WebInputEvent::kShiftKey); // Do not highlight within user agent shadow root unless requested. - if (inspect_mode_.Get() != - protocol::Overlay::InspectModeEnum::SearchForUAShadowDOM) { + if (!ua_shadow_) { ShadowRoot* shadow_root = InspectorDOMAgent::UserAgentShadowRoot(node); if (shadow_root) node = &shadow_root->host(); @@ -1167,7 +1272,7 @@ if (auto* frame_owner = DynamicTo<HTMLFrameOwnerElement>(node)) { if (!IsA<LocalFrame>(frame_owner->ContentFrame())) { // Do not consume event so that remote frame can handle it. - InnerHideHighlight(); + overlay_->hideHighlight(); hovered_node_for_inspect_mode_.Clear(); return false; } @@ -1184,46 +1289,30 @@ NodeHighlightRequested(node); bool omit_tooltip = event.GetModifiers() & (WebInputEvent::kControlKey | WebInputEvent::kMetaKey); - InnerHighlightNode(node, event_target, String(), - *inspect_mode_highlight_config_, omit_tooltip); + overlay_->InnerHighlightNode(node, event_target, String(), + *inspect_mode_highlight_config_, omit_tooltip); } return true; } -bool InspectorOverlayAgent::HandleMouseDown(const WebMouseEvent& event) { - swallow_next_mouse_up_ = false; - if (!InSomeInspectMode()) - return false; - - if (inspect_mode_.Get() == - protocol::Overlay::InspectModeEnum::CaptureAreaScreenshot) { - screenshot_anchor_ = RoundedIntPoint(event.PositionInRootFrame()); - screenshot_position_ = screenshot_anchor_; - ScheduleUpdate(); - return true; - } - +bool SearchingForNodeTool::HandleMouseDown(const WebMouseEvent& event, + bool* swallow_next_mouse_up) { if (hovered_node_for_inspect_mode_) { - swallow_next_mouse_up_ = true; - Inspect(hovered_node_for_inspect_mode_.Get()); + *swallow_next_mouse_up = true; + overlay_->Inspect(hovered_node_for_inspect_mode_.Get()); hovered_node_for_inspect_mode_.Clear(); return true; } return false; } -bool InspectorOverlayAgent::HandleMouseUp(const WebMouseEvent& event) { - if (inspect_mode_.Get() != - protocol::Overlay::InspectModeEnum::CaptureAreaScreenshot) { - return false; - } - +bool ScreenshotTool::HandleMouseUp(const WebMouseEvent& event) { if (screenshot_anchor_ == IntPoint::Zero()) return true; float scale = 1.0f; IntPoint p1 = screenshot_anchor_; IntPoint p2 = screenshot_position_; - if (LocalFrame* frame = frame_impl_->GetFrame()) { + if (LocalFrame* frame = overlay_->GetFrame()) { scale = frame->GetPage()->PageScaleFactor(); p1 = frame->View()->ConvertFromRootFrame(p1); p2 = frame->View()->ConvertFromRootFrame(p2); @@ -1235,9 +1324,9 @@ p2 += scroll_offset; } } - float dp_to_dip = 1.f / WindowToViewportScale(); - p1.Scale(dp_to_dip, dp_to_dip); - p2.Scale(dp_to_dip, dp_to_dip); + float dp_to_dip = 1.f / overlay_->WindowToViewportScale(); + p1.Scale(scale, dp_to_dip); + p2.Scale(scale, dp_to_dip); // Points are in device independent pixels (dip) now. IntRect rect = UnionRectEvenIfEmpty(IntRect(p1, IntSize()), IntRect(p2, IntSize())); @@ -1245,37 +1334,33 @@ screenshot_anchor_ = IntPoint::Zero(); return true; } - GetFrontend()->screenshotRequested(protocol::Page::Viewport::create() - .setX(rect.X()) - .setY(rect.Y()) - .setWidth(rect.Width()) - .setHeight(rect.Height()) - .setScale(scale) - .build()); + frontend_->screenshotRequested(protocol::Page::Viewport::create() + .setX(rect.X()) + .setY(rect.Y()) + .setWidth(rect.Width()) + .setHeight(rect.Height()) + .setScale(scale) + .build()); return true; } -bool InspectorOverlayAgent::HandleGestureEvent(const WebGestureEvent& event) { - if (!InSomeInspectMode() || event.GetType() != WebInputEvent::kGestureTap) - return false; - Node* node = HoveredNodeForEvent(frame_impl_->GetFrame(), event, false); +bool SearchingForNodeTool::HandleGestureTapEvent(const WebGestureEvent& event) { + Node* node = HoveredNodeForEvent(overlay_->GetFrame(), event, false); if (node && inspect_mode_highlight_config_) { - InnerHighlightNode(node, nullptr, String(), *inspect_mode_highlight_config_, - false); - Inspect(node); + overlay_->InnerHighlightNode(node, nullptr, String(), + *inspect_mode_highlight_config_, false); + overlay_->Inspect(node); return true; } return false; } -bool InspectorOverlayAgent::HandlePointerEvent(const WebPointerEvent& event) { - if (!InSomeInspectMode()) - return false; - Node* node = HoveredNodeForEvent(frame_impl_->GetFrame(), event, false); +bool SearchingForNodeTool::HandlePointerEvent(const WebPointerEvent& event) { + Node* node = HoveredNodeForEvent(overlay_->GetFrame(), event, false); if (node && inspect_mode_highlight_config_) { - InnerHighlightNode(node, nullptr, String(), *inspect_mode_highlight_config_, - false); - Inspect(node); + overlay_->InnerHighlightNode(node, nullptr, String(), + *inspect_mode_highlight_config_, false); + overlay_->Inspect(node); return true; } return false; @@ -1315,10 +1400,7 @@ GetFrontend()->inspectNodeRequested(IdentifiersFactory::IntIdForNode(node)); } -void InspectorOverlayAgent::NodeHighlightRequested(Node* node) { - if (!enabled_.Get()) - return; - +void SearchingForNodeTool::NodeHighlightRequested(Node* node) { while (node && !node->IsElementNode() && !node->IsDocumentNode() && !node->IsDocumentFragment()) node = node->ParentOrShadowHostNode(); @@ -1328,19 +1410,18 @@ int node_id = dom_agent_->PushNodePathToFrontend(node); if (node_id) - GetFrontend()->nodeHighlightRequested(node_id); + frontend_->nodeHighlightRequested(node_id); } -Response InspectorOverlayAgent::SetSearchingForNode( - String search_mode, +Response InspectorOverlayAgent::setInspectMode( + const String& mode, Maybe<protocol::Overlay::HighlightConfig> highlight_inspector_object) { - if (search_mode == protocol::Overlay::InspectModeEnum::None) { - inspect_mode_.Set(search_mode); - hovered_node_for_inspect_mode_.Clear(); - screenshot_anchor_ = IntPoint::Zero(); - screenshot_position_ = IntPoint::Zero(); - InnerHideHighlight(); - return Response::OK(); + if (mode != protocol::Overlay::InspectModeEnum::None && + mode != protocol::Overlay::InspectModeEnum::SearchForNode && + mode != protocol::Overlay::InspectModeEnum::SearchForUAShadowDOM && + mode != protocol::Overlay::InspectModeEnum::CaptureAreaScreenshot) { + return Response::Error( + String("Unknown mode \"" + mode + "\" was provided.")); } String serialized_config = @@ -1352,24 +1433,43 @@ std::move(highlight_inspector_object), &config); if (!response.isSuccess()) return response; - inspect_mode_.Set(search_mode); + inspect_mode_.Set(mode); inspect_mode_protocol_config_.Set(serialized_config); - inspect_mode_highlight_config_ = std::move(config); - if (search_mode == - protocol::Overlay::InspectModeEnum::CaptureAreaScreenshot) { - auto& client = frame_impl_->GetFrame()->GetPage()->GetChromeClient(); - client.SetCursorOverridden(false); - client.SetCursor(CrossCursor(), frame_impl_->GetFrame()); - client.SetCursorOverridden(true); - hovered_node_for_inspect_mode_.Clear(); - InnerHideHighlight(); - } else { - ScheduleUpdate(); - } + PickTheRightTool(); return Response::OK(); } +void InspectorOverlayAgent::PickTheRightTool() { + InspectTool* inspect_tool = nullptr; + + String inspect_mode = inspect_mode_.Get(); + if (inspect_mode == protocol::Overlay::InspectModeEnum::SearchForNode || + inspect_mode == + protocol::Overlay::InspectModeEnum::SearchForUAShadowDOM) { + inspect_tool = MakeGarbageCollected<SearchingForNodeTool>( + dom_agent_, + inspect_mode == + protocol::Overlay::InspectModeEnum::SearchForUAShadowDOM, + inspect_mode_protocol_config_.Get()); + } else if (inspect_mode == + protocol::Overlay::InspectModeEnum::CaptureAreaScreenshot) { + inspect_tool = MakeGarbageCollected<ScreenshotTool>(); + } else if (!paused_in_debugger_message_.Get().IsNull()) { + inspect_tool = MakeGarbageCollected<PausedInDebuggerTool>( + paused_in_debugger_message_.Get()); + } + + // Setting inspect tool clears existing highlight. + InnerHideHighlight(); + if (inspect_tool_) + inspect_tool_->Dispose(); + inspect_tool_ = inspect_tool; + if (inspect_tool_) + inspect_tool_->Init(this, GetFrontend()); + ScheduleUpdate(); +} + Response InspectorOverlayAgent::HighlightConfigFromInspectorObject( Maybe<protocol::Overlay::HighlightConfig> highlight_inspector_object, std::unique_ptr<InspectorHighlightConfig>* out_config) { @@ -1408,7 +1508,7 @@ } void InspectorOverlayAgent::SetNeedsUnbufferedInput(bool unbuffered) { - LocalFrame* frame = frame_impl_->GetFrame(); + LocalFrame* frame = GetFrame(); if (frame) { frame->GetPage()->GetChromeClient().SetNeedsUnbufferedInputForDebugger( frame, unbuffered);
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h index d02a6d4c..5e3b6b1 100644 --- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h +++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.h
@@ -34,6 +34,7 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "third_party/blink/public/platform/web_input_event.h" +#include "third_party/blink/public/platform/web_input_event_result.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/dom_node_ids.h" #include "third_party/blink/renderer/core/inspector/inspector_base_agent.h" @@ -62,10 +63,37 @@ class Page; class FrameOverlay; class WebGestureEvent; +class WebKeyboardEvent; class WebMouseEvent; class WebLocalFrameImpl; class WebPointerEvent; +class InspectorOverlayAgent; + +using OverlayFrontend = protocol::Overlay::Metainfo::FrontendClass; + +class CORE_EXPORT InspectTool : public GarbageCollectedFinalized<InspectTool> { + public: + virtual ~InspectTool() = default; + void Init(InspectorOverlayAgent* overlay, OverlayFrontend* frontend); + virtual bool HandleMouseDown(const WebMouseEvent&, + bool* swallow_next_mouse_up); + virtual bool HandleMouseUp(const WebMouseEvent&); + virtual bool HandleMouseMove(const WebMouseEvent&); + virtual bool HandleGestureTapEvent(const WebGestureEvent&); + virtual bool HandlePointerEvent(const WebPointerEvent&); + virtual bool HandleKeyboardEvent(const WebKeyboardEvent&, + bool* swallow_next_escape_up); + virtual void Draw(float scale) {} + virtual void Trace(blink::Visitor* visitor); + virtual void Dispose() {} + + protected: + virtual void DoInit() {} + Member<InspectorOverlayAgent> overlay_; + OverlayFrontend* frontend_ = nullptr; +}; + class CORE_EXPORT InspectorOverlayAgent final : public InspectorBaseAgent<protocol::Overlay::Metainfo>, public InspectorOverlayHost::Listener { @@ -127,8 +155,11 @@ void Inspect(Node*); void DispatchBufferedTouchEvents(); - bool HandleInputEvent(const WebInputEvent&); + WebInputEventResult HandleInputEvent(const WebInputEvent&); void PageLayoutInvalidated(bool resized); + void EvaluateInOverlay(const String& method, const String& argument); + void EvaluateInOverlay(const String& method, + std::unique_ptr<protocol::Value> argument); String EvaluateInOverlayForTest(const String&); // Update the complete lifecycle (e.g., layout, paint) for the overlay. @@ -138,6 +169,18 @@ bool IsInspectorLayer(const cc::Layer*) const; + LocalFrame* GetFrame() const; + float WindowToViewportScale() const; + void InnerHighlightNode(Node*, + Node* event_target, + String selector, + const InspectorHighlightConfig&, + bool omit_tooltip); + protocol::Response HighlightConfigFromInspectorObject( + protocol::Maybe<protocol::Overlay::HighlightConfig> + highlight_inspector_object, + std::unique_ptr<InspectorHighlightConfig>*); + private: class InspectorOverlayChromeClient; class InspectorPageOverlayDelegate; @@ -150,52 +193,28 @@ void DrawMatchingSelector(); void DrawNodeHighlight(); void DrawQuadHighlight(); - void DrawPausedInDebuggerMessage(); void DrawViewSize(); - void DrawScreenshotBorder(); - float WindowToViewportScale() const; Page* OverlayPage(); LocalFrame* OverlayMainFrame(); void Reset(const IntSize& viewport_size); - void EvaluateInOverlay(const String& method, const String& argument); - void EvaluateInOverlay(const String& method, - std::unique_ptr<protocol::Value> argument); void OnTimer(TimerBase*); void RebuildOverlayPage(); void Invalidate(); void ScheduleUpdate(); void ClearInternal(); - bool HandleMouseDown(const WebMouseEvent&); - bool HandleMouseUp(const WebMouseEvent&); - bool HandleGestureEvent(const WebGestureEvent&); - bool HandlePointerEvent(const WebPointerEvent&); - bool HandleMouseMove(const WebMouseEvent&); - protocol::Response CompositingEnabled(); bool InSomeInspectMode(); - void NodeHighlightRequested(Node*); - protocol::Response SetSearchingForNode( - String search_mode, - protocol::Maybe<protocol::Overlay::HighlightConfig>); - protocol::Response HighlightConfigFromInspectorObject( - protocol::Maybe<protocol::Overlay::HighlightConfig> - highlight_inspector_object, - std::unique_ptr<InspectorHighlightConfig>*); void InnerHighlightQuad(std::unique_ptr<FloatQuad>, protocol::Maybe<protocol::DOM::RGBA> color, protocol::Maybe<protocol::DOM::RGBA> outline_color); - void InnerHighlightNode(Node*, - Node* event_target, - String selector, - const InspectorHighlightConfig&, - bool omit_tooltip); void InnerHideHighlight(); void SetNeedsUnbufferedInput(bool unbuffered); + void PickTheRightTool(); Member<WebLocalFrameImpl> frame_impl_; Member<InspectedFrames> inspected_frames_; @@ -219,13 +238,10 @@ v8_inspector::V8InspectorSession* v8_session_; Member<InspectorDOMAgent> dom_agent_; std::unique_ptr<FrameOverlay> frame_overlay_; - Member<Node> hovered_node_for_inspect_mode_; + Member<InspectTool> inspect_tool_; bool swallow_next_mouse_up_; bool swallow_next_escape_up_; - std::unique_ptr<InspectorHighlightConfig> inspect_mode_highlight_config_; DOMNodeId backend_node_id_to_inspect_; - IntPoint screenshot_anchor_; - IntPoint screenshot_position_; InspectorAgentState::Boolean enabled_; InspectorAgentState::Boolean suspended_; InspectorAgentState::Boolean show_ad_highlights_;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.cc index 7590ce303..5f15caa 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.cc
@@ -194,6 +194,24 @@ index != VisualLastCharacterOf(ContainingLineOf(index)); } +bool NGCaretNavigator::IsEnterableChildContext(unsigned index) const { + DCHECK_LT(index, GetText().length()); + if (GetText()[index] != kObjectReplacementCharacter) + return false; + + const NGInlineItem& item = GetData().FindItemForTextOffset(index); + if (item.Type() != NGInlineItem::kAtomicInline) + return false; + DCHECK(item.GetLayoutObject()); + const LayoutObject* object = item.GetLayoutObject(); + if (!object->IsLayoutBlockFlow()) + return false; + if (!object->NonPseudoNode() || !object->GetNode()->IsElementNode()) + return false; + const Element* node = ToElement(object->GetNode()); + return !node->GetShadowRoot() || !node->GetShadowRoot()->IsUserAgent(); +} + NGCaretNavigator::Position NGCaretNavigator::LeftEdgeOf(unsigned index) const { return EdgeOfInternal(index, MoveDirection::kTowardsLeft); } @@ -354,9 +372,14 @@ if (next.type != VisualMovementResultType::kWithinContext) return {next.type, base::nullopt}; - if (next.has_passed_character) + if (next.has_passed_character) { has_passed_character = true; + const unsigned last_passed_character = next.position->index; + if (IsEnterableChildContext(last_passed_character)) + return {VisualMovementResultType::kEnteredChildContext, runner}; + } + runner = *next.position; last_position = runner; @@ -367,4 +390,40 @@ return {VisualMovementResultType::kWithinContext, *last_position}; } +NGCaretNavigator::Position NGCaretNavigator::LeftmostPositionInFirstLine() + const { + Line first_line = ContainingLineOf(0); + unsigned leftmost_character = + VisualMostForwardCharacterOf(first_line, MoveDirection::kTowardsLeft); + // TODO(xiaochengh): Handle if the caret position is invalid. + return LeftEdgeOf(leftmost_character); +} + +NGCaretNavigator::Position NGCaretNavigator::RightmostPositionInFirstLine() + const { + Line first_line = ContainingLineOf(0); + unsigned rightmost_character = + VisualMostForwardCharacterOf(first_line, MoveDirection::kTowardsRight); + // TODO(xiaochengh): Handle if the caret position is invalid. + return RightEdgeOf(rightmost_character); +} + +NGCaretNavigator::Position NGCaretNavigator::LeftmostPositionInLastLine() + const { + Line last_line = ContainingLineOf(GetText().length() - 1); + unsigned leftmost_character = + VisualMostForwardCharacterOf(last_line, MoveDirection::kTowardsLeft); + // TODO(xiaochengh): Handle if the caret position is invalid. + return LeftEdgeOf(leftmost_character); +} + +NGCaretNavigator::Position NGCaretNavigator::RightmostPositionInLastLine() + const { + Line last_line = ContainingLineOf(GetText().length() - 1); + unsigned rightmost_character = + VisualMostForwardCharacterOf(last_line, MoveDirection::kTowardsRight); + // TODO(xiaochengh): Handle if the caret position is invalid. + return RightEdgeOf(rightmost_character); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.h b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.h index f4e61d4..6c60d7f 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator.h
@@ -76,12 +76,12 @@ // Left/right visual movements // TODO(xiaochengh): Handle the following // - Grapheme clusters - // - Enterable atomic inlines enum class VisualMovementResultType { kWithinContext, kBeforeContext, - kAfterContext + kAfterContext, + kEnteredChildContext }; // Given the character at the logical |index|, returns the logical index of @@ -105,6 +105,13 @@ // Given a caret position, moves it left/right by one grapheme cluster and // returns the result. + // Note: If we end up entering an inline block, the result |Position| is + // either before or after the inline block, depending on from which side the + // inline block is entered. For example: + // RightPositionOf(abc|<inline-block>def</inline-block>ghi) + // -> {inline-block, PositionAnchorType::kBefore} + // LeftPositionOf(abc<inline-block>def</inline-block>|ghi) + // -> {inline-block, PositionAnchorType::kAfter} struct VisualCaretMovementResult { bool IsWithinContext() const { return type == VisualMovementResultType::kWithinContext; @@ -115,6 +122,9 @@ bool IsAfterContext() const { return type == VisualMovementResultType::kAfterContext; } + bool HasEnteredChildContext() const { + return type == VisualMovementResultType::kEnteredChildContext; + } VisualMovementResultType type; base::Optional<Position> position; @@ -122,19 +132,30 @@ VisualCaretMovementResult LeftPositionOf(const Position&) const; VisualCaretMovementResult RightPositionOf(const Position&) const; + // TODO(xiaochengh): Specify and implement the behavior in edge cases, e.g., + // when the leftmost character of the first line is CSS-generated. + Position LeftmostPositionInFirstLine() const; + Position RightmostPositionInFirstLine() const; + Position LeftmostPositionInLastLine() const; + Position RightmostPositionInLastLine() const; + private: // A caret position is invalid if it is: // - kAfter to a line break character. // - Anchored to a collapsible space that's removed by line wrap. // - Anchored to a character that's ignored in caret movement. - // TODO(xiaochengh): Handle the the following: - // - Enterable atomic inlines bool IsValidCaretPosition(const Position&) const; bool IsLineBreak(unsigned index) const; bool IsCollapsibleWhitespace(unsigned index) const; bool IsCollapsedSpaceByLineWrap(unsigned index) const; bool IsIgnoredInCaretMovement(unsigned index) const; + // Returns true if the character at |index| represents a child block + // formatting context that can be entered by caret navigation. Such contexts + // must be atomic inlines (inline block, inline table, ...) and must not host + // user agent shadow tree (which excludes, e.g., <input> and image alt text). + bool IsEnterableChildContext(unsigned index) const; + enum class MoveDirection { kTowardsLeft, kTowardsRight }; static MoveDirection OppositeDirectionOf(MoveDirection); static bool TowardsSameDirection(MoveDirection, TextDirection);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator_test.cc index 1192a8e..1beb7a4a 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_navigator_test.cc
@@ -420,4 +420,42 @@ EXPECT_EQ(CaretAfter(9), *LeftPositionOf(CaretBefore(14)).position); } +TEST_F(NGCaretNavigatorTest, EnterableInlineBlock) { + SetupHtml("container", + "<div id=container>foo" + "<span style='display:inline-block'>bar</span>" + "baz</div>"); + + // Moving right from "foo|" should enter the span from front. + EXPECT_TRUE(RightPositionOf(CaretAfter(2)).HasEnteredChildContext()); + EXPECT_EQ(CaretBefore(3), *RightPositionOf(CaretAfter(2)).position); + EXPECT_TRUE(RightPositionOf(CaretBefore(3)).HasEnteredChildContext()); + EXPECT_EQ(CaretBefore(3), *RightPositionOf(CaretBefore(3)).position); + + // Moving left from "|baz" should enter the span from behind. + EXPECT_TRUE(LeftPositionOf(CaretBefore(4)).HasEnteredChildContext()); + EXPECT_EQ(CaretAfter(3), *LeftPositionOf(CaretBefore(4)).position); + EXPECT_TRUE(LeftPositionOf(CaretAfter(3)).HasEnteredChildContext()); + EXPECT_EQ(CaretAfter(3), *LeftPositionOf(CaretAfter(3)).position); +} + +TEST_F(NGCaretNavigatorTest, UnenterableInlineBlock) { + SetupHtml("container", + "<div id=container>foo" + "<input value=bar>" + "baz</div>"); + + // Moving right from "foo|" should reach "<input>|". + EXPECT_TRUE(RightPositionOf(CaretAfter(2)).IsWithinContext()); + EXPECT_EQ(CaretAfter(3), *RightPositionOf(CaretAfter(2)).position); + EXPECT_TRUE(RightPositionOf(CaretBefore(3)).IsWithinContext()); + EXPECT_EQ(CaretAfter(3), *RightPositionOf(CaretBefore(3)).position); + + // Moving left from "|baz" should reach "|<input>". + EXPECT_TRUE(LeftPositionOf(CaretBefore(4)).IsWithinContext()); + EXPECT_EQ(CaretBefore(3), *LeftPositionOf(CaretBefore(4)).position); + EXPECT_TRUE(LeftPositionOf(CaretAfter(3)).IsWithinContext()); + EXPECT_EQ(CaretBefore(3), *LeftPositionOf(CaretAfter(3)).position); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc index 86a5d56..6f90707 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.cc
@@ -61,7 +61,7 @@ } void NGFlexLayoutAlgorithm::ConstructAndAppendFlexItems() { - const bool is_horizontal_flow = algorithm->IsHorizontalFlow(); + const bool is_horizontal_flow = algorithm_->IsHorizontalFlow(); for (NGLayoutInputNode generic_child = Node().FirstChild(); generic_child; generic_child = generic_child.NextSibling()) { NGBlockNode child = ToNGBlockNode(generic_child); @@ -98,7 +98,7 @@ // only ever use it if the child's inline axis is our main axis. MinMaxSizeInput input( /* percentage_resolution_block_size */ content_box_size_.block_size); - MinMaxSize min_max_sizes_border_box = child.ComputeMinMaxSize( + MinMaxSize intrinsic_sizes_border_box = child.ComputeMinMaxSize( child_style.GetWritingMode(), input, &child_space); // TODO(dgrogan): Don't layout every time, just when you need to. scoped_refptr<const NGLayoutResult> layout_result = @@ -112,7 +112,7 @@ const Length& flex_basis = child_style.FlexBasis(); if (flex_basis.IsAuto() && length_in_main_axis.IsAuto()) { if (MainAxisIsInlineAxis(child)) - flex_base_border_box = min_max_sizes_border_box.max_size; + flex_base_border_box = intrinsic_sizes_border_box.max_size; else flex_base_border_box = fragment_in_child_writing_mode.BlockSize(); } else { @@ -123,7 +123,7 @@ if (MainAxisIsInlineAxis(child)) { flex_base_border_box = ResolveInlineLength( child_space, child_style, border_padding_in_child_writing_mode, - min_max_sizes_border_box, length_to_resolve, + intrinsic_sizes_border_box, length_to_resolve, LengthResolveType::kContentSize, LengthResolvePhase::kLayout); } else { // Flex container's main axis is in child's block direction. Child's @@ -155,7 +155,7 @@ if (MainAxisIsInlineAxis(child)) { min_max_sizes_in_main_axis_direction.max_size = ResolveInlineLength( child_space, child_style, border_padding_in_child_writing_mode, - min_max_sizes_border_box, max, LengthResolveType::kMaxSize, + intrinsic_sizes_border_box, max, LengthResolveType::kMaxSize, LengthResolvePhase::kLayout); } else { min_max_sizes_in_main_axis_direction.max_size = ResolveBlockLength( @@ -167,7 +167,7 @@ const Length& min = is_horizontal_flow ? child.Style().MinWidth() : child.Style().MinHeight(); if (min.IsAuto()) { - if (algorithm->ShouldApplyMinSizeAutoForChild(*child.GetLayoutBox())) { + if (algorithm_->ShouldApplyMinSizeAutoForChild(*child.GetLayoutBox())) { // TODO(dgrogan): Port logic from // https://www.w3.org/TR/css-flexbox-1/#min-size-auto and // LayoutFlexibleBox::ComputeMinAndMaxSizesForChild @@ -175,7 +175,7 @@ } else if (MainAxisIsInlineAxis(child)) { min_max_sizes_in_main_axis_direction.min_size = ResolveInlineLength( child_space, child_style, border_padding_in_child_writing_mode, - min_max_sizes_border_box, min, LengthResolveType::kMinSize, + intrinsic_sizes_border_box, min, LengthResolveType::kMinSize, LengthResolvePhase::kLayout); } else { min_max_sizes_in_main_axis_direction.min_size = ResolveBlockLength( @@ -184,7 +184,7 @@ LengthResolveType::kMinSize, LengthResolvePhase::kLayout); } - algorithm + algorithm_ ->emplace_back(child.GetLayoutBox(), flex_base_content_size, min_max_sizes_in_main_axis_direction, main_axis_border_and_padding, main_axis_margin) @@ -199,8 +199,8 @@ ShrinkAvailableSize(border_box_size_, border_scrollbar_padding_); const LayoutUnit line_break_length = MainAxisContentExtent(LayoutUnit::Max()); - algorithm.emplace(&Style(), line_break_length); - const bool is_horizontal_flow = algorithm->IsHorizontalFlow(); + algorithm_.emplace(&Style(), line_break_length); + const bool is_horizontal_flow = algorithm_->IsHorizontalFlow(); ConstructAndAppendFlexItems(); @@ -213,7 +213,7 @@ FlexLine* line; LayoutUnit max_main_axis_extent; while ( - (line = algorithm->ComputeNextFlexLine(border_box_size_.inline_size))) { + (line = algorithm_->ComputeNextFlexLine(border_box_size_.inline_size))) { line->SetContainerMainInnerSize( MainAxisContentExtent(line->sum_hypothetical_main_size)); line->FreezeInflexibleItems(); @@ -294,10 +294,10 @@ final_content_cross_size = border_box_size_.inline_size - border_scrollbar_padding_.InlineSum(); } - if (!algorithm->IsMultiline() && !algorithm->FlexLines().IsEmpty()) - algorithm->FlexLines()[0].cross_axis_extent = final_content_cross_size; + if (!algorithm_->IsMultiline() && !algorithm_->FlexLines().IsEmpty()) + algorithm_->FlexLines()[0].cross_axis_extent = final_content_cross_size; - for (FlexLine& line_context : algorithm->FlexLines()) { + for (FlexLine& line_context : algorithm_->FlexLines()) { for (wtf_size_t child_number = 0; child_number < line_context.line_items.size(); ++child_number) { FlexItem& flex_item = line_context.line_items[child_number];
diff --git a/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.h index d94b2c4..a85d041 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.h +++ b/third_party/blink/renderer/core/layout/ng/ng_flex_layout_algorithm.h
@@ -54,7 +54,7 @@ NGLogicalSize content_box_size_; // This is populated at the top of Layout(), so isn't available in // ComputeMinMaxSize() or anything it calls. - base::Optional<FlexLayoutAlgorithm> algorithm; + base::Optional<FlexLayoutAlgorithm> algorithm_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc index 88189e1..f14ebf89 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -735,18 +735,37 @@ if (!line_boxes.size()) return; - // TODO(layout-dev): Early return if no line intersects cull rect. + const bool is_horizontal = + IsHorizontalWritingMode(box_fragment_.Style().GetWritingMode()); + for (const NGPaintFragment* line : line_boxes) { - if (line->PhysicalFragment().IsFloatingOrOutOfFlowPositioned()) + const NGPhysicalFragment& child_fragment = line->PhysicalFragment(); + if (child_fragment.IsFloatingOrOutOfFlowPositioned()) continue; + + // Check if CullRect intersects with this child, only in block direction + // because soft-wrap and <br> needs to paint outside of InkOverflow() in + // inline direction. const LayoutPoint child_offset = paint_offset + line->Offset().ToLayoutPoint(); - if (line->PhysicalFragment().IsListMarker()) { + NGPhysicalOffsetRect child_rect = line->InkOverflow(); + if (is_horizontal) { + LayoutUnit y = child_rect.offset.top + child_offset.Y(); + if (!paint_info.GetCullRect().IntersectsVerticalRange( + y, y + child_rect.size.height)) + continue; + } else { + LayoutUnit x = child_rect.offset.left + child_offset.X(); + if (!paint_info.GetCullRect().IntersectsHorizontalRange( + x, x + child_rect.size.width)) + continue; + } + + if (child_fragment.IsListMarker()) { PaintAtomicInlineChild(*line, paint_info); continue; } - DCHECK(line->PhysicalFragment().IsLineBox()) - << line->PhysicalFragment().ToString(); + DCHECK(child_fragment.IsLineBox()); if (paint_info.phase == PaintPhase::kForeground && NGFragmentPainter::ShouldRecordHitTestData(paint_info,
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn index efa8a76d..26ed9a0d 100644 --- a/third_party/blink/renderer/modules/BUILD.gn +++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -356,6 +356,7 @@ "worklet/animation_and_paint_worklet_thread_test.cc", "worklet/worklet_thread_test_common.cc", "worklet/worklet_thread_test_common.h", + "xr/xr_rigid_transform_test.cc", ] configs += [
diff --git a/third_party/blink/renderer/modules/background_sync/sync_manager.cc b/third_party/blink/renderer/modules/background_sync/sync_manager.cc index 4551366..6fd0ba5 100644 --- a/third_party/blink/renderer/modules/background_sync/sync_manager.cc +++ b/third_party/blink/renderer/modules/background_sync/sync_manager.cc
@@ -83,7 +83,8 @@ // Let the service know that the registration promise is resolved so that // it can fire the event. GetBackgroundSyncServicePtr()->DidResolveRegistration( - registration_->RegistrationId(), options->tag); + registration_->RegistrationId(), options->tag, + mojom::blink::BackgroundSyncType::ONE_SHOT); break; case mojom::blink::BackgroundSyncError::NOT_FOUND: NOTREACHED();
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc b/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc index dff51d7..26cdc33 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc
@@ -11,6 +11,7 @@ #include "base/single_thread_task_runner.h" #include "mojo/public/cpp/bindings/strong_associated_binding.h" +#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h" #include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h" #include "third_party/blink/renderer/modules/indexeddb/indexed_db_dispatcher.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -65,7 +66,7 @@ mojom::blink::IDBErrorPtr error, mojom::blink::IDBCursorValuePtr cursor_value) { if (error) { - callbacks->Error(error->error_code, error->error_message); + callbacks->Error(error->error_code, std::move(error->error_message)); callbacks.reset(); return; } @@ -76,9 +77,18 @@ return; } - callbacks->SuccessCursorContinue(std::move(cursor_value->key), - std::move(cursor_value->primary_key), - std::move(cursor_value->value)); + if (cursor_value->keys.size() != 1u || + cursor_value->primary_keys.size() != 1u || + cursor_value->values.size() != 1u) { + callbacks->Error(blink::kWebIDBDatabaseExceptionUnknownError, + "Invalid response"); + callbacks.reset(); + return; + } + + callbacks->SuccessCursorContinue(std::move(cursor_value->keys[0]), + std::move(cursor_value->primary_keys[0]), + std::move(cursor_value->values[0])); callbacks.reset(); } @@ -105,7 +115,8 @@ callbacks->SetState(weak_factory_.GetWeakPtr(), transaction_id_); cursor_->Prefetch(prefetch_amount_, - GetCallbacksProxy(std::move(callbacks))); + WTF::Bind(&WebIDBCursorImpl::PrefetchCallback, + WTF::Unretained(this), std::move(callbacks))); // Increase prefetch_amount_ exponentially. prefetch_amount_ *= 2; @@ -133,7 +144,7 @@ mojom::blink::IDBErrorPtr error, mojom::blink::IDBCursorValuePtr value) { if (error) { - callbacks->Error(error->error_code, error->error_message); + callbacks->Error(error->error_code, std::move(error->error_message)); callbacks.reset(); return; } @@ -144,9 +155,47 @@ return; } - callbacks->SuccessCursorContinue(std::move(value->key), - std::move(value->primary_key), - std::move(value->value)); + if (value->keys.size() != 1u || value->primary_keys.size() != 1u || + value->values.size() != 1u) { + callbacks->Error(blink::kWebIDBDatabaseExceptionUnknownError, + "Invalid response"); + callbacks.reset(); + return; + } + + callbacks->SuccessCursorContinue(std::move(value->keys[0]), + std::move(value->primary_keys[0]), + std::move(value->values[0])); + callbacks.reset(); +} + +void WebIDBCursorImpl::PrefetchCallback( + std::unique_ptr<WebIDBCallbacks> callbacks, + mojom::blink::IDBErrorPtr error, + mojom::blink::IDBCursorValuePtr value) { + if (error) { + callbacks->Error(error->error_code, std::move(error->error_message)); + callbacks.reset(); + return; + } + + if (!value) { + callbacks->SuccessValue(nullptr); + callbacks.reset(); + return; + } + + if (value->keys.size() != value->primary_keys.size() || + value->keys.size() != value->values.size()) { + callbacks->Error(blink::kWebIDBDatabaseExceptionUnknownError, + "Invalid response"); + callbacks.reset(); + return; + } + + callbacks->SuccessCursorPrefetch(std::move(value->keys), + std::move(value->primary_keys), + std::move(value->values)); callbacks.reset(); }
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.h b/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.h index a5a8405..e37de34 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.h +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.h
@@ -33,6 +33,9 @@ void CursorContinueCallback(std::unique_ptr<WebIDBCallbacks> callbacks, mojom::blink::IDBErrorPtr error, mojom::blink::IDBCursorValuePtr value); + void PrefetchCallback(std::unique_ptr<WebIDBCallbacks> callbacks, + mojom::blink::IDBErrorPtr error, + mojom::blink::IDBCursorValuePtr value); void PostSuccessHandlerCallback() override;
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl_unittest.cc b/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl_unittest.cc index 15183d3..13599d7 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl_unittest.cc +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl_unittest.cc
@@ -31,11 +31,12 @@ &MockCursorImpl::CursorDestroyed, base::Unretained(this))); } - void Prefetch( - int32_t count, - mojom::blink::IDBCallbacksAssociatedPtrInfo callbacks) override { + void Prefetch(int32_t count, + mojom::blink::IDBCursor::PrefetchCallback callback) override { ++prefetch_calls_; last_prefetch_count_ = count; + std::move(callback).Run(mojom::blink::IDBErrorPtr(), + mojom::blink::IDBCursorValuePtr()); } void PrefetchReset(int32_t used_prefetches,
diff --git a/third_party/blink/renderer/modules/mediastream/video_track_adapter.cc b/third_party/blink/renderer/modules/mediastream/video_track_adapter.cc index 40b9252..6fe738e 100644 --- a/third_party/blink/renderer/modules/mediastream/video_track_adapter.cc +++ b/third_party/blink/renderer/modules/mediastream/video_track_adapter.cc
@@ -732,13 +732,11 @@ // Remove the track. for (auto it = adapters_.begin(); it != adapters_.end(); ++it) { track_callbacks = (*it)->RemoveAndGetCallbacks(track); - if (track_callbacks.frame_callback.is_null()) - continue; if ((*it)->IsEmpty()) { DCHECK(!track_callbacks.frame_callback.is_null()); adapters_.erase(it); + break; } - break; } // If the track was found, re-add it with new settings.
diff --git a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc index 1035bdd..fb5f296e 100644 --- a/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc +++ b/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
@@ -334,11 +334,11 @@ AssertGraphOwner(); // Quick exit if there are no handlers that need to be deleted so that we - // don't unecessarily post a task. Be onsistent with + // don't unecessarily post a task. Be consistent with // |DeleteHandlersOnMainThread()| so we don't accidentally return early when // there are handlers that could be deleted. if (rendering_orphan_handlers_.IsEmpty() && - finished_tail_processing_handlers_.size()) { + finished_tail_processing_handlers_.size() == 0) { return; }
diff --git a/third_party/blink/renderer/modules/webgpu/webgpu_device.cc b/third_party/blink/renderer/modules/webgpu/webgpu_device.cc index 3d78a0c..111a129 100644 --- a/third_party/blink/renderer/modules/webgpu/webgpu_device.cc +++ b/third_party/blink/renderer/modules/webgpu/webgpu_device.cc
@@ -42,10 +42,6 @@ return adapter_; } -void WebGPUDevice::dummy() const { - Interface()->Dummy(); -} - void WebGPUDevice::Trace(blink::Visitor* visitor) { visitor->Trace(adapter_); ScriptWrappable::Trace(visitor);
diff --git a/third_party/blink/renderer/modules/webgpu/webgpu_device.h b/third_party/blink/renderer/modules/webgpu/webgpu_device.h index 0275962..2d86aef 100644 --- a/third_party/blink/renderer/modules/webgpu/webgpu_device.h +++ b/third_party/blink/renderer/modules/webgpu/webgpu_device.h
@@ -24,8 +24,6 @@ WebGPUAdapter* adapter() const; - void dummy() const; - void Trace(blink::Visitor*) override; private:
diff --git a/third_party/blink/renderer/modules/webgpu/webgpu_device.idl b/third_party/blink/renderer/modules/webgpu/webgpu_device.idl index 793ffad9..47f1b690 100644 --- a/third_party/blink/renderer/modules/webgpu/webgpu_device.idl +++ b/third_party/blink/renderer/modules/webgpu/webgpu_device.idl
@@ -6,6 +6,4 @@ RuntimeEnabled=WebGPU ] interface WebGPUDevice { readonly attribute WebGPUAdapter adapter; - - void dummy(); };
diff --git a/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc b/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc index 261c5500..c4e4b2eb 100644 --- a/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc +++ b/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc
@@ -33,9 +33,13 @@ position_ = DOMPointReadOnly::Create(decomposed.translate_x, decomposed.translate_y, decomposed.translate_z, 1.0); + + // TODO(https://crbug.com/929841): Minuses are needed as a workaround for + // bug in TransformationMatrix so that callers can still pass non-inverted + // quaternions. orientation_ = makeNormalizedQuaternion( - decomposed.quaternion_x, decomposed.quaternion_y, - decomposed.quaternion_z, decomposed.quaternion_w); + -decomposed.quaternion_x, -decomposed.quaternion_y, + -decomposed.quaternion_z, decomposed.quaternion_w); } else { // TODO: Is this the correct way to handle a failure here? position_ = DOMPointReadOnly::Create(0.0, 0.0, 0.0, 1.0);
diff --git a/third_party/blink/renderer/modules/xr/xr_rigid_transform.h b/third_party/blink/renderer/modules/xr/xr_rigid_transform.h index aba47f7..13175de 100644 --- a/third_party/blink/renderer/modules/xr/xr_rigid_transform.h +++ b/third_party/blink/renderer/modules/xr/xr_rigid_transform.h
@@ -11,12 +11,15 @@ #include "third_party/blink/renderer/core/geometry/dom_point_init.h" #include "third_party/blink/renderer/core/geometry/dom_point_read_only.h" #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" +#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" namespace blink { -class XRRigidTransform : public ScriptWrappable { +// MODULES_EXPORT is required for unit tests using XRRigidTransform (currently +// just xr_rigid_transform_test.cc) to build without linker errors. +class MODULES_EXPORT XRRigidTransform : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: @@ -29,6 +32,8 @@ XRRigidTransform(DOMPointInit*, DOMPointInit*); static XRRigidTransform* Create(DOMPointInit*, DOMPointInit*); + ~XRRigidTransform() override = default; + DOMPointReadOnly* position() const { return position_; } DOMPointReadOnly* orientation() const { return orientation_; } DOMFloat32Array* matrix();
diff --git a/third_party/blink/renderer/modules/xr/xr_rigid_transform_test.cc b/third_party/blink/renderer/modules/xr/xr_rigid_transform_test.cc new file mode 100644 index 0000000..4a09aa9 --- /dev/null +++ b/third_party/blink/renderer/modules/xr/xr_rigid_transform_test.cc
@@ -0,0 +1,129 @@ +// 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/modules/xr/xr_rigid_transform.h" + +#include <vector> + +#include "third_party/blink/renderer/modules/xr/xr_utils.h" + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/script_value.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/platform/bindings/script_state.h" + +namespace blink { +namespace { + +constexpr double kEpsilon = 0.0001; + +static void AssertDOMPointsEqualForTest(const DOMPointReadOnly* a, + const DOMPointReadOnly* b) { + ASSERT_NEAR(a->x(), b->x(), kEpsilon); + ASSERT_NEAR(a->y(), b->y(), kEpsilon); + ASSERT_NEAR(a->z(), b->z(), kEpsilon); + ASSERT_NEAR(a->w(), b->w(), kEpsilon); +} + +std::vector<double> GetMatrixDataForTest(const TransformationMatrix& matrix) { + std::vector<double> data{ + matrix.M11(), matrix.M12(), matrix.M13(), matrix.M14(), + matrix.M21(), matrix.M22(), matrix.M23(), matrix.M24(), + matrix.M31(), matrix.M32(), matrix.M33(), matrix.M34(), + matrix.M41(), matrix.M42(), matrix.M43(), matrix.M44()}; + return data; +} + +static void AssertMatricesEqualForTest(const TransformationMatrix& a, + const TransformationMatrix& b) { + const std::vector<double> a_data = GetMatrixDataForTest(a); + const std::vector<double> b_data = GetMatrixDataForTest(b); + for (int i = 0; i < 16; ++i) { + ASSERT_NEAR(a_data[i], b_data[i], kEpsilon); + } +} + +static void AssertTransformsEqualForTest(XRRigidTransform& a, + XRRigidTransform& b) { + AssertDOMPointsEqualForTest(a.position(), b.position()); + AssertDOMPointsEqualForTest(a.orientation(), b.orientation()); + AssertMatricesEqualForTest(a.TransformMatrix(), b.TransformMatrix()); +} + +static DOMPointInit* MakePointForTest(double x, double y, double z, double w) { + DOMPointInit* point = DOMPointInit::Create(); + point->setX(x); + point->setY(y); + point->setZ(z); + point->setW(w); + return point; +} + +static void TestComposeDecompose(DOMPointInit* position, + DOMPointInit* orientation) { + XRRigidTransform transform_1(position, orientation); + XRRigidTransform transform_2(transform_1.TransformMatrix()); + AssertTransformsEqualForTest(transform_1, transform_2); +} + +static void TestDoubleInverse(DOMPointInit* position, + DOMPointInit* orientation) { + XRRigidTransform transform(position, orientation); + XRRigidTransform inverse_transform(transform.InverseTransformMatrix()); + XRRigidTransform inverse_inverse_transform( + inverse_transform.InverseTransformMatrix()); + AssertTransformsEqualForTest(transform, inverse_inverse_transform); +} + +TEST(XRRigidTransformTest, Compose) { + DOMPointInit* position = MakePointForTest(1.0, 2.0, 3.0, 1.0); + DOMPointInit* orientation = MakePointForTest(0.7071068, 0.0, 0.0, 0.7071068); + XRRigidTransform transform(position, orientation); + const std::vector<double> actual_matrix = + GetMatrixDataForTest(transform.TransformMatrix()); + const std::vector<double> expected_matrix{1.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, + 1.0, 2.0, 3.0, 1.0}; + for (int i = 0; i < 16; ++i) { + ASSERT_NEAR(actual_matrix[i], expected_matrix[i], kEpsilon); + } +} + +TEST(XRRigidTransformTest, Decompose) { + XRRigidTransform transform( + TransformationMatrix::Create(1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, + -1.0, 0.0, 0.0, 1.0, 2.0, 3.0, 1.0)); + const DOMPointReadOnly expected_position(1.0, 2.0, 3.0, 1.0); + const DOMPointReadOnly expected_orientation(0.7071068, 0.0, 0.0, 0.7071068); + AssertDOMPointsEqualForTest(transform.position(), &expected_position); + AssertDOMPointsEqualForTest(transform.orientation(), &expected_orientation); +} + +TEST(XRRigidTransformTest, ComposeDecompose) { + TestComposeDecompose(MakePointForTest(1.0, -1.0, 4.0, 1.0), + MakePointForTest(1.0, 0.0, 0.0, 1.0)); +} + +TEST(XRRigidTransformTest, ComposeDecompose2) { + TestComposeDecompose( + MakePointForTest(1.0, -1.0, 4.0, 1.0), + MakePointForTest(0.3701005885691383, -0.5678993882056005, + 0.31680366148754113, 0.663438979322567)); +} + +TEST(XRRigidTransformTest, DoubleInverse) { + TestDoubleInverse(MakePointForTest(1.0, -1.0, 4.0, 1.0), + MakePointForTest(1.0, 0.0, 0.0, 1.0)); +} + +TEST(XRRigidTransformTest, DoubleInverse2) { + TestDoubleInverse(MakePointForTest(1.0, -1.0, 4.0, 1.0), + MakePointForTest(0.3701005885691383, -0.5678993882056005, + 0.31680366148754113, 0.663438979322567)); +} + +} // namespace +} // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc index 73643de7..55c9b06d 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.cc
@@ -233,8 +233,8 @@ gfx::Transform()); viz::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); - sqs->SetAll(gfx::Transform(), bounds, bounds, bounds, is_clipped, is_opaque, - 1.f, SkBlendMode::kSrcOver, 0); + sqs->SetAll(gfx::Transform(), bounds, bounds, gfx::RRectF(), bounds, + is_clipped, is_opaque, 1.f, SkBlendMode::kSrcOver, 0); viz::TransferableResource resource; auto frame_resource = std::make_unique<FrameResource>();
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc b/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc index 1a0b606..77a674a 100644 --- a/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc +++ b/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc
@@ -110,13 +110,15 @@ gfx::Rect visible_quad_rect = quad_rect; gfx::Rect clip_rect; + gfx::RRectF rounded_corner_bounds; bool is_clipped = false; float draw_opacity = 1.0f; int sorting_context_id = 0; - resource_updater_->AppendQuads( - render_pass, std::move(frame), transform, quad_rect, visible_quad_rect, - clip_rect, is_clipped, is_opaque, draw_opacity, sorting_context_id); + resource_updater_->AppendQuads(render_pass, std::move(frame), transform, + quad_rect, visible_quad_rect, + rounded_corner_bounds, clip_rect, is_clipped, + is_opaque, draw_opacity, sorting_context_id); } void VideoFrameResourceProvider::ReleaseFrameResources() {
diff --git a/third_party/blink/renderer/platform/mojo/blink_typemaps.gni b/third_party/blink/renderer/platform/mojo/blink_typemaps.gni index ea6a911a..4c17940 100644 --- a/third_party/blink/renderer/platform/mojo/blink_typemaps.gni +++ b/third_party/blink/renderer/platform/mojo/blink_typemaps.gni
@@ -22,7 +22,6 @@ "//third_party/blink/renderer/platform/mojo/security_origin.typemap", "//third_party/blink/renderer/platform/mojo/string.typemap", "//third_party/blink/renderer/platform/mojo/time.typemap", - "//third_party/blink/renderer/platform/network/encoded_form_data.typemap", "//third_party/blink/renderer/platform/network/http_request_headers.typemap", "//third_party/blink/public/platform/modules/bluetooth/bluetooth.typemap", "//third_party/blink/public/common/manifest/display_mode.typemap",
diff --git a/third_party/blink/renderer/platform/network/BUILD.gn b/third_party/blink/renderer/platform/network/BUILD.gn index d895fca..27e11b8 100644 --- a/third_party/blink/renderer/platform/network/BUILD.gn +++ b/third_party/blink/renderer/platform/network/BUILD.gn
@@ -31,8 +31,6 @@ "content_security_policy_response_headers.h", "encoded_form_data.cc", "encoded_form_data.h", - "encoded_form_data_mojom_traits.cc", - "encoded_form_data_mojom_traits.h", "form_data_encoder.cc", "form_data_encoder.h", "header_field_tokenizer.cc", @@ -90,8 +88,6 @@ deps = [ "//testing/gtest", - ] - public_deps = [ "//third_party/blink/renderer/platform:platform", ] }
diff --git a/third_party/blink/renderer/platform/network/DEPS b/third_party/blink/renderer/platform/network/DEPS index b2afd512..17d7eb3 100644 --- a/third_party/blink/renderer/platform/network/DEPS +++ b/third_party/blink/renderer/platform/network/DEPS
@@ -16,7 +16,6 @@ # For URLRequestDataJob::BuildResponse(). "+net/url_request/url_request_data_job.h", - "+services/network/public/cpp/features.h", "+third_party/blink/renderer/platform/blob/blob_data.h", "+third_party/blink/renderer/platform/cross_thread_copier.h", "+third_party/blink/renderer/platform/cross_thread_functional.h",
diff --git a/third_party/blink/renderer/platform/network/encoded_form_data.typemap b/third_party/blink/renderer/platform/network/encoded_form_data.typemap deleted file mode 100644 index 8e0e849..0000000 --- a/third_party/blink/renderer/platform/network/encoded_form_data.typemap +++ /dev/null
@@ -1,10 +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. - -mojom = "//services/network/public/mojom/url_loader.mojom" -public_headers = - [ "//third_party/blink/renderer/platform/network/encoded_form_data.h" ] -traits_headers = [ "//third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.h" ] -type_mappings = - [ "network.mojom.DataElement = blink::FormDataElement[move_only]" ]
diff --git a/third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.cc b/third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.cc deleted file mode 100644 index 03cc4be..0000000 --- a/third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.cc +++ /dev/null
@@ -1,164 +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 <utility> - -#include "third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.h" - -#include "mojo/public/cpp/base/file_mojom_traits.h" -#include "mojo/public/cpp/base/file_path_mojom_traits.h" -#include "mojo/public/cpp/base/time_mojom_traits.h" -#include "mojo/public/cpp/bindings/array_traits_wtf_vector.h" -#include "mojo/public/cpp/bindings/string_traits_wtf.h" -#include "services/network/public/mojom/data_pipe_getter.mojom-blink.h" -#include "third_party/blink/public/mojom/blob/blob_registry.mojom-blink.h" -#include "third_party/blink/public/platform/interface_provider.h" -#include "third_party/blink/public/platform/platform.h" - -namespace mojo { - -// static -network::mojom::DataElementType -StructTraits<network::mojom::DataElementDataView, blink::FormDataElement>::type( - const blink::FormDataElement& data) { - switch (data.type_) { - case blink::FormDataElement::kData: - return network::mojom::DataElementType::kBytes; - case blink::FormDataElement::kEncodedFile: - return network::mojom::DataElementType::kFile; - case blink::FormDataElement::kEncodedBlob: { - if (data.optional_blob_data_handle_) - return network::mojom::DataElementType::kDataPipe; - return network::mojom::DataElementType::kBlob; - } - case blink::FormDataElement::kDataPipe: - return network::mojom::DataElementType::kDataPipe; - } - NOTREACHED(); - return network::mojom::DataElementType::kUnknown; -} - -// static -base::span<const uint8_t> -StructTraits<network::mojom::DataElementDataView, blink::FormDataElement>::buf( - const blink::FormDataElement& data) { - return base::make_span(reinterpret_cast<const uint8_t*>(data.data_.data()), - data.data_.size()); -} - -// static -base::File -StructTraits<network::mojom::DataElementDataView, blink::FormDataElement>::file( - const blink::FormDataElement& data) { - return base::File(); -} - -// static -base::FilePath -StructTraits<network::mojom::DataElementDataView, blink::FormDataElement>::path( - const blink::FormDataElement& data) { - return base::FilePath::FromUTF8Unsafe( - std::string(data.filename_.Utf8().data())); -} - -// static -network::mojom::blink::DataPipeGetterPtrInfo -StructTraits<network::mojom::DataElementDataView, blink::FormDataElement>:: - data_pipe_getter(const blink::FormDataElement& data) { - if (data.type_ == blink::FormDataElement::kDataPipe) { - if (!data.data_pipe_getter_) - return nullptr; - network::mojom::blink::DataPipeGetterPtr data_pipe_getter; - (*data.data_pipe_getter_->GetPtr()) - ->Clone(mojo::MakeRequest(&data_pipe_getter)); - return data_pipe_getter.PassInterface(); - } - if (data.type_ == blink::FormDataElement::kEncodedBlob) { - if (data.optional_blob_data_handle_) { - blink::mojom::blink::BlobPtr blob_ptr(blink::mojom::blink::BlobPtrInfo( - data.optional_blob_data_handle_->CloneBlobPtr() - .PassInterface() - .PassHandle(), - blink::mojom::blink::Blob::Version_)); - network::mojom::blink::DataPipeGetterPtr data_pipe_getter_ptr; - blob_ptr->AsDataPipeGetter(MakeRequest(&data_pipe_getter_ptr)); - return data_pipe_getter_ptr.PassInterface(); - } - } - return nullptr; -} - -// static -base::Time -StructTraits<network::mojom::DataElementDataView, blink::FormDataElement>:: - expected_modification_time(const blink::FormDataElement& data) { - return base::Time::FromDoubleT(data.expected_file_modification_time_); -} - -// static -bool StructTraits<network::mojom::DataElementDataView, blink::FormDataElement>:: - Read(network::mojom::DataElementDataView data, - blink::FormDataElement* out) { - network::mojom::DataElementType data_type; - if (!data.ReadType(&data_type)) { - return false; - } - out->file_start_ = data.offset(); - out->file_length_ = data.length(); - - switch (data_type) { - case network::mojom::DataElementType::kBytes: { - out->type_ = blink::FormDataElement::kData; - // TODO:(richard.li) Delete this workaround when type of - // blink::FormDataElement::data_ is changed to WTF::Vector<uint8_t> - WTF::Vector<uint8_t> buf; - if (!data.ReadBuf(&buf)) { - return false; - } - out->data_.AppendRange(buf.begin(), buf.end()); - break; - } - case network::mojom::DataElementType::kFile: { - out->type_ = blink::FormDataElement::kEncodedFile; - base::FilePath file_path; - base::Time expected_time; - if (!data.ReadPath(&file_path) || - !data.ReadExpectedModificationTime(&expected_time)) { - return false; - } - out->expected_file_modification_time_ = expected_time.ToDoubleT(); - out->filename_ = - WTF::String(file_path.value().data(), file_path.value().size()); - break; - } - case network::mojom::DataElementType::kBlob: { - out->type_ = blink::FormDataElement::kEncodedBlob; - if (!data.ReadBlobUuid(&out->blob_uuid_)) { - return false; - } - break; - } - case network::mojom::DataElementType::kDataPipe: { - out->type_ = blink::FormDataElement::kDataPipe; - auto data_pipe_ptr_info = data.TakeDataPipeGetter< - network::mojom::blink::DataPipeGetterPtrInfo>(); - DCHECK(data_pipe_ptr_info.is_valid()); - - network::mojom::blink::DataPipeGetterPtr data_pipe_getter; - data_pipe_getter.Bind(std::move(data_pipe_ptr_info)); - out->data_pipe_getter_ = - base::MakeRefCounted<blink::WrappedDataPipeGetter>( - std::move(data_pipe_getter)); - break; - } - case network::mojom::DataElementType::kUnknown: - case network::mojom::DataElementType::kChunkedDataPipe: - case network::mojom::DataElementType::kRawFile: - NOTREACHED(); - return false; - } - return true; -} - -} // namespace mojo
diff --git a/third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.h b/third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.h deleted file mode 100644 index 313a8d43..0000000 --- a/third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.h +++ /dev/null
@@ -1,60 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_ENCODED_FORM_DATA_MOJOM_TRAITS_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_ENCODED_FORM_DATA_MOJOM_TRAITS_H_ - -#include <string> - -#include "services/network/public/mojom/url_loader.mojom-blink.h" -#include "third_party/blink/renderer/platform/network/encoded_form_data.h" - -namespace mojo { - -template <> -struct PLATFORM_EXPORT - StructTraits<network::mojom::DataElementDataView, blink::FormDataElement> { - static network::mojom::DataElementType type( - const blink::FormDataElement& data); - - static base::span<const uint8_t> buf(const blink::FormDataElement& data); - - static base::File file(const blink::FormDataElement& data); - - static base::FilePath path(const blink::FormDataElement& data); - - static const WTF::String& blob_uuid(const blink::FormDataElement& data) { - return data.blob_uuid_; - } - - static network::mojom::blink::DataPipeGetterPtrInfo data_pipe_getter( - const blink::FormDataElement& data); - - static network::mojom::blink::ChunkedDataPipeGetterPtrInfo - chunked_data_pipe_getter(const blink::FormDataElement& data) { - return nullptr; - } - - static uint64_t offset(const blink::FormDataElement& data) { - return data.file_start_; - } - - static uint64_t length(const blink::FormDataElement& data) { - if (data.type_ == blink::FormDataElement::kEncodedBlob && - data.optional_blob_data_handle_) { - return data.optional_blob_data_handle_->size(); - } - return data.file_length_; - } - - static base::Time expected_modification_time( - const blink::FormDataElement& data); - - static bool Read(network::mojom::DataElementDataView data, - blink::FormDataElement* out); -}; - -} // namespace mojo - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_ENCODED_FORM_DATA_MOJOM_TRAITS_H_
diff --git a/third_party/blink/renderer/platform/network/encoded_form_data_test.cc b/third_party/blink/renderer/platform/network/encoded_form_data_test.cc index 5619caa..3349b1cb 100644 --- a/third_party/blink/renderer/platform/network/encoded_form_data_test.cc +++ b/third_party/blink/renderer/platform/network/encoded_form_data_test.cc
@@ -2,17 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/platform/network/encoded_form_data_mojom_traits.h" - -#include "base/sequenced_task_runner.h" -#include "base/test/scoped_task_environment.h" -#include "mojo/public/cpp/base/file_mojom_traits.h" -#include "mojo/public/cpp/base/file_path_mojom_traits.h" -#include "mojo/public/cpp/base/time_mojom_traits.h" -#include "mojo/public/cpp/bindings/string_traits_wtf.h" -#include "mojo/public/cpp/test_support/test_utils.h" -#include "services/network/public/mojom/url_loader.mojom-blink.h" -#include "third_party/blink/public/mojom/blob/blob.mojom-blink.h" #include "third_party/blink/renderer/platform/network/encoded_form_data.h" #include "testing/gtest/include/gtest/gtest.h" @@ -105,62 +94,6 @@ } } -TEST(EncodedFormDataMojomTraitsTest, Roundtrips_FormDataElement) { - base::test::ScopedTaskEnvironment scoped_task_environment_; - - FormDataElement original1; - original1.type_ = blink::FormDataElement::kData; - original1.data_ = {'a', 'b', 'c', 'd'}; - FormDataElement copied1; - EXPECT_TRUE( - mojo::test::SerializeAndDeserialize<network::mojom::blink::DataElement>( - &original1, &copied1)); - EXPECT_EQ(original1.type_, copied1.type_); - EXPECT_EQ(original1.data_, copied1.data_); - - FormDataElement original2; - original2.type_ = blink::FormDataElement::kEncodedFile; - original2.file_start_ = 0; - original2.file_length_ = 4; - original2.filename_ = "file.name"; - original2.expected_file_modification_time_ = base::Time::Now().ToDoubleT(); - FormDataElement copied2; - EXPECT_TRUE( - mojo::test::SerializeAndDeserialize<network::mojom::blink::DataElement>( - &original2, &copied2)); - EXPECT_EQ(original2.type_, copied2.type_); - EXPECT_EQ(original2.file_start_, copied2.file_start_); - EXPECT_EQ(original2.file_length_, copied2.file_length_); - EXPECT_EQ(original2.filename_, copied2.filename_); - EXPECT_EQ(original2.expected_file_modification_time_, - copied2.expected_file_modification_time_); - - FormDataElement original3; - original3.type_ = blink::FormDataElement::kEncodedBlob; - original3.blob_uuid_ = "uuid-test"; - mojo::MessagePipe pipe; - original3.optional_blob_data_handle_ = BlobDataHandle::Create( - original3.blob_uuid_, "type-test", 100, - mojom::blink::BlobPtrInfo(std::move(pipe.handle0), 0)); - FormDataElement copied3; - EXPECT_TRUE( - mojo::test::SerializeAndDeserialize<network::mojom::blink::DataElement>( - &original3, &copied3)); - EXPECT_EQ(copied3.type_, blink::FormDataElement::kDataPipe); - - FormDataElement original4; - original4.type_ = blink::FormDataElement::kDataPipe; - network::mojom::blink::DataPipeGetterPtr data_pipe_getter; - auto request = mojo::MakeRequest(&data_pipe_getter); - original4.data_pipe_getter_ = - base::MakeRefCounted<blink::WrappedDataPipeGetter>( - std::move(data_pipe_getter)); - FormDataElement copied4; - EXPECT_TRUE( - mojo::test::SerializeAndDeserialize<network::mojom::blink::DataElement>( - &original4, &copied4)); - EXPECT_TRUE(copied4.data_pipe_getter_); -} - } // namespace + } // namespace blink
diff --git a/third_party/blink/renderer/platform/wtf/BUILD.gn b/third_party/blink/renderer/platform/wtf/BUILD.gn index 54e9954..bbc7f1d 100644 --- a/third_party/blink/renderer/platform/wtf/BUILD.gn +++ b/third_party/blink/renderer/platform/wtf/BUILD.gn
@@ -147,7 +147,6 @@ "text/string_hash.h", "text/string_impl.cc", "text/string_impl.h", - "text/string_impl_cf.cc", "text/string_impl_mac.mm", "text/string_mac.mm", "text/string_operators.h", @@ -274,10 +273,7 @@ "Foundation.framework", ] } else { - sources -= [ - "text/atomic_string_cf.cc", - "text/string_impl_cf.cc", - ] + sources -= [ "text/atomic_string_cf.cc" ] } configs -= [ "//build/config/compiler:default_symbols" ]
diff --git a/third_party/blink/renderer/platform/wtf/text/string_impl_cf.cc b/third_party/blink/renderer/platform/wtf/text/string_impl_cf.cc deleted file mode 100644 index 2498c654..0000000 --- a/third_party/blink/renderer/platform/wtf/text/string_impl_cf.cc +++ /dev/null
@@ -1,166 +0,0 @@ -/* - * Copyright (C) 2006, 2009, 2012 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "third_party/blink/renderer/platform/wtf/text/string_impl.h" - -#include "build/build_config.h" - -#if defined(OS_MACOSX) - -#include <CoreFoundation/CoreFoundation.h> -#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h" -#include "third_party/blink/renderer/platform/wtf/threading.h" -#include "third_party/blink/renderer/platform/wtf/wtf.h" - -namespace WTF { - -namespace string_wrapper_cf_allocator { - -static StringImpl* g_current_string; - -static const void* Retain(const void* info) { - return info; -} - -static void Release(const void*) { - NOTREACHED(); -} - -static CFStringRef CopyDescription(const void*) { - return CFSTR("WTF::String-based allocator"); -} - -static void* Allocate(CFIndex size, CFOptionFlags, void*) { - StringImpl* underlying_string = 0; - if (IsMainThread()) { - underlying_string = g_current_string; - if (underlying_string) { - g_current_string = 0; - underlying_string - ->AddRef(); // Balanced by call to deref in deallocate below. - } - } - StringImpl** header = static_cast<StringImpl**>(WTF::Partitions::FastMalloc( - sizeof(StringImpl*) + size, WTF_HEAP_PROFILER_TYPE_NAME(StringImpl*))); - *header = underlying_string; - return header + 1; -} - -static void* Reallocate(void* pointer, CFIndex new_size, CFOptionFlags, void*) { - size_t new_allocation_size = sizeof(StringImpl*) + new_size; - StringImpl** header = static_cast<StringImpl**>(pointer) - 1; - DCHECK(!*header); - header = static_cast<StringImpl**>(WTF::Partitions::FastRealloc( - header, new_allocation_size, WTF_HEAP_PROFILER_TYPE_NAME(StringImpl*))); - return header + 1; -} - -static void DeallocateOnMainThread(void* header_pointer) { - StringImpl** header = static_cast<StringImpl**>(header_pointer); - StringImpl* underlying_string = *header; - DCHECK(underlying_string); - underlying_string->Release(); // Balanced by call to ref in allocate above. - WTF::Partitions::FastFree(header); -} - -static void Deallocate(void* pointer, void*) { - StringImpl** header = static_cast<StringImpl**>(pointer) - 1; - StringImpl* underlying_string = *header; - if (!underlying_string) { - WTF::Partitions::FastFree(header); - } else { - if (!IsMainThread()) { - internal::CallOnMainThread(&DeallocateOnMainThread, header); - } else { - underlying_string - ->Release(); // Balanced by call to ref in allocate above. - WTF::Partitions::FastFree(header); - } - } -} - -static CFIndex PreferredSize(CFIndex size, CFOptionFlags, void*) { - // FIXME: If FastMalloc provided a "good size" callback, we'd want to use it - // here. Note that this optimization would help performance for strings - // created with the allocator that are mutable, and those typically are only - // created by callers who make a new string using the old string's allocator, - // such as some of the call sites in CFURL. - return size; -} - -static CFAllocatorRef Create() { - CFAllocatorContext context = { - 0, 0, Retain, Release, CopyDescription, - Allocate, Reallocate, Deallocate, PreferredSize}; - return CFAllocatorCreate(0, &context); -} - -static CFAllocatorRef Allocator() { - static CFAllocatorRef allocator = Create(); - return allocator; -} - -} // namespace string_wrapper_cf_allocator - -base::ScopedCFTypeRef<CFStringRef> StringImpl::CreateCFString() { - // Since garbage collection isn't compatible with custom allocators, we - // can't use the NoCopy variants of CFStringCreate*() when GC is enabled. - if (!length_ || !IsMainThread()) { - if (Is8Bit()) - return base::ScopedCFTypeRef<CFStringRef>(CFStringCreateWithBytes( - 0, reinterpret_cast<const UInt8*>(Characters8()), length_, - kCFStringEncodingISOLatin1, false)); - return base::ScopedCFTypeRef<CFStringRef>(CFStringCreateWithCharacters( - 0, reinterpret_cast<const UniChar*>(Characters16()), length_)); - } - CFAllocatorRef allocator = string_wrapper_cf_allocator::Allocator(); - - // Put pointer to the StringImpl in a global so the allocator can store it - // with the CFString. - DCHECK(!string_wrapper_cf_allocator::g_current_string); - string_wrapper_cf_allocator::g_current_string = this; - - CFStringRef string; - if (Is8Bit()) - string = CFStringCreateWithBytesNoCopy( - allocator, reinterpret_cast<const UInt8*>(Characters8()), length_, - kCFStringEncodingISOLatin1, false, kCFAllocatorNull); - else - string = CFStringCreateWithCharactersNoCopy( - allocator, reinterpret_cast<const UniChar*>(Characters16()), length_, - kCFAllocatorNull); - // CoreFoundation might not have to allocate anything, we clear currentString - // in case we did not execute allocate(). - string_wrapper_cf_allocator::g_current_string = 0; - - return base::ScopedCFTypeRef<CFStringRef>(string); -} - -// On StringImpl creation we could check if the allocator is the -// string_wrapper_cf_allocator. If it is, then we could find the original -// StringImpl and just return that. But to do that we'd have to compute the -// offset from CFStringRef to the allocated block; the CFStringRef is *not* at -// the start of an allocated block. Testing shows 1000x more calls to -// createCFString than calls to the create functions with the appropriate -// allocator, so it's probably not urgent optimize that case. - -} // namespace WTF - -#endif // defined(OS_MACOSX)
diff --git a/third_party/blink/renderer/platform/wtf/text/string_impl_mac.mm b/third_party/blink/renderer/platform/wtf/text/string_impl_mac.mm index 2e8d7d8..b4372ea 100644 --- a/third_party/blink/renderer/platform/wtf/text/string_impl_mac.mm +++ b/third_party/blink/renderer/platform/wtf/text/string_impl_mac.mm
@@ -25,6 +25,18 @@ namespace WTF { +base::ScopedCFTypeRef<CFStringRef> StringImpl::CreateCFString() { + return base::ScopedCFTypeRef<CFStringRef>( + Is8Bit() + ? CFStringCreateWithBytes( + kCFAllocatorDefault, + reinterpret_cast<const UInt8*>(Characters8()), length_, + kCFStringEncodingISOLatin1, false) + : CFStringCreateWithCharacters( + kCFAllocatorDefault, + reinterpret_cast<const UniChar*>(Characters16()), length_)); +} + StringImpl::operator NSString*() { return [base::mac::CFToNSCast(CreateCFString().release()) autorelease]; }
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 01b6695..467cbc9 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1786,6 +1786,9 @@ crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_forward_line_br.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_forward_line_range.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_forward_line_small_line.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_into_inline_block_multiline.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_into_inline_block_nested.html [ Failure ] +crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_into_inline_block_one_line.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_23_ltr.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_23_rtl.html [ Failure ] crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_left_character_24_ltr.html [ Failure ] @@ -6063,8 +6066,13 @@ crbug.com/931533 media/video-played-collapse.html [ Pass Failure ] crbug.com/931533 virtual/video-surface-layer/media/video-played-collapse.html [ Pass Failure ] +# Flaky failures due to <object> resources not always appearing in the timeline. +crbug.com/941482 external/wpt/resource-timing/nested-context-navigations.html [ Pass Failure ] + # Sheriff 2019-03-11 crbug.com/940136 virtual/outofblink-cors/http/tests/fetch/serviceworker/thorough/auth.html [ Pass Failure ] # Test was blocking WPT importer crbug.com/941471 external/wpt/css/css-transforms/transform-flattening-001.html [ Pass Failure ] + +crbug.com/940829 external/wpt/pointerevents/pointerevent_touch-action-table-test_touch-manual.html [ Timeout Pass ]
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_into_inline_block_multiline.html b/third_party/blink/web_tests/editing/selection/modify_move/move_into_inline_block_multiline.html new file mode 100644 index 0000000..0c12fbd --- /dev/null +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_into_inline_block_multiline.html
@@ -0,0 +1,125 @@ +<!DOCTYPE html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../../assert_selection.js"></script> +<script> +// Variations: +// 1. Entering the inline block from left or right side +// 2. Resolved direction of the inline block in the parent context +// 3. Direction of the first line text inside the inline block +// 4. Direction of the last line text inside the inline block + +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + +selection_test( + '<div contenteditable>foo|<span style="display:inline-block">bar<br>qux</span>baz</div>', + selection => selection.modify('move', 'right', 'character'), + '<div contenteditable>foo<span style="display:inline-block">b|ar<br>qux</span>baz</div>', + 'Move right, LTR resolved direction, LTR/LTR text inside'); + +selection_test( + '<div contenteditable>foo<span style="display:inline-block">bar<br>qux</span>|baz</div>', + selection => selection.modify('move', 'left', 'character'), + '<div contenteditable>foo<span style="display:inline-block">bar<br>qu|x</span>baz</div>', + 'Move left, LTR resolved direction, LTR/LTR text inside'); + +selection_test( + '<div contenteditable>foo|<span style="display:inline-block">\u05D0\u05D1\u05D2<br>qux</span>baz</div>', + selection => selection.modify('move', 'right', 'character'), + usesBidiAffinity + ? '<div contenteditable>foo<span style="display:inline-block">\u05D0\u05D1|\u05D2<br>qux</span>baz</div>' + : '<div contenteditable>foo<span style="display:inline-block">\u05D0|\u05D1\u05D2<br>qux</span>baz</div>', + 'Move right, LTR resolved direction, RTL/LTR text inside'); + +selection_test( + '<div contenteditable>foo<span style="display:inline-block">\u05D0\u05D1\u05D2<br>qux</span>|baz</div>', + selection => selection.modify('move', 'left', 'character'), + '<div contenteditable>foo<span style="display:inline-block">\u05D0\u05D1\u05D2<br>qu|x</span>baz</div>', + 'Move left, LTR resolved direction, RTL/LTR text inside'); + +selection_test( + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5|<span style="display:inline-block">bar<br>qux</span>\u05D6\u05D7\u05D8</div>', + selection => selection.modify('move', 'left', 'character'), + usesBidiAffinity + ? '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">ba|r<br>qux</span>\u05D6\u05D7\u05D8</div>' + : '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">b|ar<br>qux</span>\u05D6\u05D7\u05D8</div>', + 'Move left, RTL resolved direction, LTR/LTR text inside'); + +// TODO(crbug.com/923087): BidiCaretAffinity currently fails this test case, as +// VisiblePosition incorrectly moves the input position to "qux|". +selection_test( + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">bar<br>qux</span>|\u05D6\u05D7\u05D8</div>', + selection => selection.modify('move', 'right', 'character'), + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">bar<br>q|ux</span>\u05D6\u05D7\u05D8</div>', + 'Move right, RTL resolved direction, LTR/LTR text inside'); + +selection_test( + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5|<span style="display:inline-block">\u05D0\u05D1\u05D2<br>qux</span>\u05D6\u05D7\u05D8</div>', + selection => selection.modify('move', 'left', 'character'), + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">\u05D0|\u05D1\u05D2<br>qux</span>\u05D6\u05D7\u05D8</div>', + 'Move left, RTL resolved direction, RTL/LTR text inside'); + +// TODO(crbug.com/923087): BidiCaretAffinity currently fails this test case, as +// VisiblePosition incorrectly moves the input position to "qux|". +selection_test( + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">\u05D0\u05D1\u05D2<br>qux</span>|\u05D6\u05D7\u05D8</div>', + selection => selection.modify('move', 'right', 'character'), + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">\u05D0\u05D1\u05D2<br>q|ux</span>\u05D6\u05D7\u05D8</div>', + 'Move right, RTL resolved direction, RTL/LTR text inside'); + +selection_test( + '<div contenteditable>foo|<span style="display:inline-block">bar<br>\u05D9\u05DA\u05DB</span>baz</div>', + selection => selection.modify('move', 'right', 'character'), + '<div contenteditable>foo<span style="display:inline-block">b|ar<br>\u05D9\u05DA\u05DB</span>baz</div>', + 'Move right, LTR resolved direction, LTR/RTL text inside'); + +selection_test( + '<div contenteditable>foo<span style="display:inline-block">bar<br>\u05D9\u05DA\u05DB</span>|baz</div>', + selection => selection.modify('move', 'left', 'character'), + '<div contenteditable>foo<span style="display:inline-block">bar<br>\u05D9|\u05DA\u05DB</span>baz</div>', + 'Move left, LTR resolved direction, LTR/RTL text inside'); + +selection_test( + '<div contenteditable>foo|<span style="display:inline-block">\u05D0\u05D1\u05D2<br>\u05D9\u05DA\u05DB</span>baz</div>', + selection => selection.modify('move', 'right', 'character'), + usesBidiAffinity + ? '<div contenteditable>foo<span style="display:inline-block">\u05D0\u05D1|\u05D2<br>\u05D9\u05DA\u05DB</span>baz</div>' + : '<div contenteditable>foo<span style="display:inline-block">\u05D0|\u05D1\u05D2<br>\u05D9\u05DA\u05DB</span>baz</div>', + 'Move right, LTR resolved direction, RTL/RTL text inside'); + +// TODO(crbug.com/923087): BidiCaretAffinity currently fails this test case, as +// VisiblePosition incorrectly moves the input position to "JKL|". +selection_test( + '<div contenteditable>foo<span style="display:inline-block">\u05D0\u05D1\u05D2<br>\u05D9\u05DA\u05DB</span>|baz</div>', + selection => selection.modify('move', 'left', 'character'), + '<div contenteditable>foo<span style="display:inline-block">\u05D0\u05D1\u05D2<br>\u05D9|\u05DA\u05DB</span>baz</div>', + 'Move left, LTR resolved direction, RTL/RTL text inside'); + +selection_test( + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5|<span style="display:inline-block">bar<br>\u05D9\u05DA\u05DB</span>\u05D6\u05D7\u05D8</div>', + selection => selection.modify('move', 'left', 'character'), + usesBidiAffinity + ? '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">ba|r<br>\u05D9\u05DA\u05DB</span>\u05D6\u05D7\u05D8</div>' + : '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">b|ar<br>\u05D9\u05DA\u05DB</span>\u05D6\u05D7\u05D8</div>', + 'Move left, RTL resolved direction, LTR/RTL text inside'); + +// TODO(crbug.com/923087): BidiCaretAffinity currently fails this test case, as +// VisiblePosition incorrectly moves the input position to "JKL|". +selection_test( + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">bar<br>\u05D9\u05DA\u05DB</span>|\u05D6\u05D7\u05D8</div>', + selection => selection.modify('move', 'right', 'character'), + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">bar<br>\u05D9\u05DA|\u05DB</span>\u05D6\u05D7\u05D8</div>', + 'Move right, RTL resolved direction, LTR/RTL text inside'); + +selection_test( + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5|<span style="display:inline-block">\u05D0\u05D1\u05D2<br>\u05D9\u05DA\u05DB</span>\u05D6\u05D7\u05D8</div>', + selection => selection.modify('move', 'left', 'character'), + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">\u05D0|\u05D1\u05D2<br>\u05D9\u05DA\u05DB</span>\u05D6\u05D7\u05D8</div>', + 'Move left, RTL resolved direction, RTL/RTL text inside'); + +selection_test( + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">\u05D0\u05D1\u05D2<br>\u05D9\u05DA\u05DB</span>|\u05D6\u05D7\u05D8</div>', + selection => selection.modify('move', 'right', 'character'), + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">\u05D0\u05D1\u05D2<br>\u05D9\u05DA|\u05DB</span>\u05D6\u05D7\u05D8</div>', + 'Move right, RTL resolved direction, RTL/RTL text inside'); +</script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_into_inline_block_nested.html b/third_party/blink/web_tests/editing/selection/modify_move/move_into_inline_block_nested.html new file mode 100644 index 0000000..36741be --- /dev/null +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_into_inline_block_nested.html
@@ -0,0 +1,101 @@ +<!DOCTYPE html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../../assert_selection.js"></script> +<script> +selection_test( + [ + '<div contenteditable>foo|', + '<span style="display:inline-block">', + '<div>bar</div><div>baz</div>', + '</span>qux</div>' + ].join(''), + selection => selection.modify('move', 'right', 'character'), + [ + '<div contenteditable>foo', + '<span style="display:inline-block">', + '<div>|bar</div><div>baz</div>', + '</span>qux</div>' + ].join(''), + 'Move right into inline block with child blocks'); + +selection_test( + [ + '<div contenteditable>foo', + '<span style="display:inline-block">', + '<div>bar</div><div>baz</div>', + '</span>|qux</div>' + ].join(''), + selection => selection.modify('move', 'left', 'character'), + [ + '<div contenteditable>foo', + '<span style="display:inline-block">', + '<div>bar</div><div>baz|</div>', + '</span>qux</div>' + ].join(''), + 'Move left into inline block with child blocks'); + +selection_test( + [ + '<div contenteditable>foo|', + '<table style="display:inline"><tbody>', + '<tr><td>bar</td></tr><tr><td>baz</td></tr>', + '</tbody></table>qux</div>' + ].join(''), + selection => selection.modify('move', 'right', 'character'), + [ + '<div contenteditable>foo', + '<table style="display:inline"><tbody>', + '<tr><td>|bar</td></tr><tr><td>baz</td></tr>', + '</tbody></table>qux</div>' + ].join(''), + 'Move right into inline table'); + +selection_test( + [ + '<div contenteditable>foo', + '<table style="display:inline"><tbody>', + '<tr><td>bar</td></tr><tr><td>baz</td></tr>', + '</tbody></table>|qux</div>' + ].join(''), + selection => selection.modify('move', 'left', 'character'), + [ + '<div contenteditable>foo', + '<table style="display:inline"><tbody>', + '<tr><td>bar</td></tr><tr><td>baz|</td></tr>', + '</tbody></table>qux</div>' + ].join(''), + 'Move left into inline table'); + +selection_test( + [ + '<div contenteditable>foo|', + '<div style="display:inline-flex">', + '<div>bar</div><div>baz</div>', + '</div>qux</div>' + ].join(''), + selection => selection.modify('move', 'right', 'character'), + [ + '<div contenteditable>foo', + '<div style="display:inline-flex">', + '<div>|bar</div><div>baz</div>', + '</div>qux</div>' + ].join(''), + 'Move right into inline flex'); + +selection_test( + [ + '<div contenteditable>foo', + '<div style="display:inline-flex">', + '<div>bar</div><div>baz</div>', + '</div>|qux</div>' + ].join(''), + selection => selection.modify('move', 'left', 'character'), + [ + '<div contenteditable>foo', + '<div style="display:inline-flex">', + '<div>bar</div><div>baz|</div>', + '</div>qux</div>' + ].join(''), + 'Move left into inline flex'); +</script>
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_into_inline_block_one_line.html b/third_party/blink/web_tests/editing/selection/modify_move/move_into_inline_block_one_line.html new file mode 100644 index 0000000..5d0a388 --- /dev/null +++ b/third_party/blink/web_tests/editing/selection/modify_move/move_into_inline_block_one_line.html
@@ -0,0 +1,68 @@ +<!DOCTYPE html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../../assert_selection.js"></script> +<script> +// Variations: +// 1. Entering the inline block from left or right side +// 2. Resolved direction of the inline block in the parent context +// 3. Direction of text inside the inline block + +const usesBidiAffinity = window.internals && internals.runtimeFlags.bidiCaretAffinityEnabled; + +selection_test( + '<div contenteditable>foo|<span style="display:inline-block">bar</span>baz</div>', + selection => selection.modify('move', 'right', 'character'), + '<div contenteditable>foo<span style="display:inline-block">b|ar</span>baz</div>', + 'Move right, LTR resolved direction, LTR text inside'); + +selection_test( + '<div contenteditable>foo<span style="display:inline-block">bar</span>|baz</div>', + selection => selection.modify('move', 'left', 'character'), + '<div contenteditable>foo<span style="display:inline-block">ba|r</span>baz</div>', + 'Move left, LTR resolved direction, LTR text inside'); + +selection_test( + '<div contenteditable>foo|<span style="display:inline-block">\u05D0\u05D1\u05D2</span>baz</div>', + selection => selection.modify('move', 'right', 'character'), + usesBidiAffinity + ? '<div contenteditable>foo<span style="display:inline-block">\u05D0\u05D1|\u05D2</span>baz</div>' + : '<div contenteditable>foo<span style="display:inline-block">\u05D0|\u05D1\u05D2</span>baz</div>', + 'Move right, LTR resolved direction, RTL text inside'); + +// TODO(crbug.com/923087): BidiCaretAffinity currently fails this test case, as +// VisiblePosition incorrectly moves the input position to "ABC|". +selection_test( + '<div contenteditable>foo<span style="display:inline-block">\u05D0\u05D1\u05D2</span>|baz</div>', + selection => selection.modify('move', 'left', 'character'), + '<div contenteditable>foo<span style="display:inline-block">\u05D0|\u05D1\u05D2</span>baz</div>', + 'Move left, LTR resolved direction, RTL text inside'); + +selection_test( + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5|<span style="display:inline-block">bar</span>\u05D6\u05D7\u05D8</div>', + selection => selection.modify('move', 'left', 'character'), + usesBidiAffinity + ? '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">ba|r</span>\u05D6\u05D7\u05D8</div>' + : '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">b|ar</span>\u05D6\u05D7\u05D8</div>', + 'Move left, RTL resolved direction, LTR text inside'); + +// TODO(crbug.com/923087): BidiCaretAffinity currently fails this test case, as +// VisiblePosition incorrectly moves the input position to "bar|". +selection_test( + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">bar</span>|\u05D6\u05D7\u05D8</div>', + selection => selection.modify('move', 'right', 'character'), + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">b|ar</span>\u05D6\u05D7\u05D8</div>', + 'Move right, RTL resolved direction, LTR text inside'); + +selection_test( + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5|<span style="display:inline-block">\u05D0\u05D1\u05D2</span>\u05D6\u05D7\u05D8</div>', + selection => selection.modify('move', 'left', 'character'), + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">\u05D0|\u05D1\u05D2</span>\u05D6\u05D7\u05D8</div>', + 'Move left, RTL resolved direction, RTL text inside'); + +selection_test( + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">\u05D0\u05D1\u05D2</span>|\u05D6\u05D7\u05D8</div>', + selection => selection.modify('move', 'right', 'character'), + '<div contenteditable dir="rtl">\u05D3\u05D4\u05D5<span style="display:inline-block">\u05D0\u05D1|\u05D2</span>\u05D6\u05D7\u05D8</div>', + 'Move right, RTL resolved direction, RTL text inside'); +</script>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/xhr-post-replay-cors-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/xhr-post-replay-cors-expected.txt index 1f6f986..4d962af 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/xhr-post-replay-cors-expected.txt +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/xhr-post-replay-cors-expected.txt
@@ -1,16 +1,11 @@ Verifies that replayed CORS XHRs still have post data -request 0: { - "method": "OPTIONS", - "url": "http://127.0.0.1:8000/inspector-protocol/network/resources/cors-return-post.php", - "responseData": "replied to options with Access-Control-Allow headers" -} -request 1: { +POST request 0: { "method": "POST", "url": "http://127.0.0.1:8000/inspector-protocol/network/resources/cors-return-post.php", "postData": "{\"data\":\"test post data\"}", "responseData": "post data: {\"data\":\"test post data\"}" } -request 2: { +POST request 1: { "method": "POST", "url": "http://127.0.0.1:8000/inspector-protocol/network/resources/cors-return-post.php", "postData": "{\"data\":\"test post data\"}",
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/xhr-post-replay-cors.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/xhr-post-replay-cors.js index b75ecdf..3bb260c0 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/xhr-post-replay-cors.js +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/xhr-post-replay-cors.js
@@ -9,10 +9,7 @@ function replayOptionsXhr() { sentReplayXhr = true; - const optionsRequestId = - Object.keys(requestsById) - .find(id => requestsById[id].method === 'OPTIONS'); - dp.Network.replayXHR({requestId: optionsRequestId}); + dp.Network.replayXHR({requestId: Object.keys(requestsById)[0]}); } function printResultsAndFinish() { @@ -22,8 +19,14 @@ delete request.wallTime; return request; }); - for (let i = 0; i < requests.length; i++) { - testRunner.log(`request ${i}: ${JSON.stringify(requests[i], null, 2)}`); + + // Ignore OPTIONS preflight requests. + // TODO(crbug.com/941297): Add the OPTIONS request back to the test results once this bug is fixed. + let postIndex = 0; + for (const request of requests) { + if (request.method !== 'POST') + continue; + testRunner.log(`POST request ${postIndex++}: ${JSON.stringify(request, null, 2)}`); } testRunner.completeTest(); }
diff --git a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png index bd478a62..af5f21f1 100644 --- a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png +++ b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png index 7c7e327..f2469d0 100644 --- a/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png +++ b/third_party/blink/web_tests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/12-55-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/12-55-expected.png index 1f91feda..f38df4d 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/12-55-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/12-55-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/182-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/182-expected.png index 61887f59..f9ea39f 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/182-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/182-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/2-dht-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/2-dht-expected.png index a3f6eaf..483b603 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/2-dht-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/2-dht-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/23-55-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/23-55-expected.png index fedf2451..06fa592 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/23-55-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/23-55-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/55-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/55-expected.png index a388772..6762251 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/55-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/55-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png index 1acaaf0..2368484 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png index bea8973..746dd01 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/color-profile-munsell-srgb-to-srgb-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png index 43f64621..a2a7e4f 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png index fb927f7..71492a8 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-css-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-css-expected.png index a3018ee..5f34bcf 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-css-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-css-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-expected.png index ae08025b..de03609 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png index 26d18f7..ba74f14 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/exif-orientation-image-document-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/favicon-as-image-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/favicon-as-image-expected.png index f14e1330..3bf27c1 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/favicon-as-image-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/favicon-as-image-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-edge-cases-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-edge-cases-expected.png index 9879c7d..81a0dfa9 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-edge-cases-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-edge-cases-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png index aa60ad5..da6882a 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-forced-layout-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-forced-layout-expected.png index ad4cdc6..c2ca27a3 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-forced-layout-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-forced-layout-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-responsive-image-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-responsive-image-expected.png index 6cb1553..0e70bc8 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-responsive-image-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-responsive-image-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-styles-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-styles-expected.png index 21cb653..5c18807 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-styles-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/feature-policy-oversized-images-styles-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/image-map-anchor-children-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/image-map-anchor-children-expected.png index 1557bdf5..5da2590 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/image-map-anchor-children-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/image-map-anchor-children-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png index 8bc8e30..d18d15c 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png index b855fae2..9e0c2cc 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png index 6df2bc3..8521d6ba 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png index d11b4b18..7db3caa 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png index 2123c16..7bc1471 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png index 368152fc..80ae5b78 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png index 2a102ee..6e0a7aa 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png index b023864..41cdec4 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zero-outline-width-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png index d08378ab..4a7edaee 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png index 201244f5..97253a14 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png index eb32dbc..aada43e 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png index b47f876..db6cafd 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/pixel-crack-image-background-webkit-transform-scale-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/pixel-crack-image-background-webkit-transform-scale-expected.png index b3939dc..c9b5810 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/pixel-crack-image-background-webkit-transform-scale-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/pixel-crack-image-background-webkit-transform-scale-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png index d62551f..f6aac27 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png index 6c0766a..7a901aeb 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-0px-images-quirk-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png index 23e531e..5e04d3c 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-10px-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png index ee9b5c5f..fedf2f9 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-16px-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png index 8bbb7e4..d96e05d6 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-1px-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png index 42fa90e..64b9c59b 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-block-flow-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-expected.png index ad300ea..92dfb008 100644 --- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-expected.png +++ b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/rendering-broken-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/scroll_customization/fast/events/touch/multi-touch-user-gesture-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/scroll_customization/fast/events/touch/multi-touch-user-gesture-expected.txt new file mode 100644 index 0000000..61a5134 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/virtual/scroll_customization/fast/events/touch/multi-touch-user-gesture-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Test user gesture behavior during multi-finger touch events. assert_equals: expected "touchstart@target1(false), touchstart@target2(false), touchmove@target1(false), touchmove@target2(false), touchend@target1(true), touchend@target2(true)" but got "touchstart@target1(false), touchstart@target2(false), touchmove@target2(false), touchmove@target1(false), touchend@target1(true), touchend@target2(true)" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.txt new file mode 100644 index 0000000..e294d225 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.txt
@@ -0,0 +1,12 @@ +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
diff --git a/third_party/blink/web_tests/platform/mac/fast/events/touch/multi-touch-user-gesture-expected.txt b/third_party/blink/web_tests/platform/mac/fast/events/touch/multi-touch-user-gesture-expected.txt new file mode 100644 index 0000000..61a5134 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/fast/events/touch/multi-touch-user-gesture-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Test user gesture behavior during multi-finger touch events. assert_equals: expected "touchstart@target1(false), touchstart@target2(false), touchmove@target1(false), touchmove@target2(false), touchend@target1(true), touchend@target2(true)" but got "touchstart@target1(false), touchstart@target2(false), touchmove@target2(false), touchmove@target1(false), touchend@target1(true), touchend@target2(true)" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png b/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png index 396cceda0..5bbaf24 100644 --- a/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png +++ b/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png b/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png index b0ce6b9..e3d3e15 100644 --- a/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png +++ b/third_party/blink/web_tests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png index a736ed1..ca93bc953 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png index 1caf1f5..fdb18a28 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png index 1918867..d42a7941 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/image-map-anchor-children-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/image-map-anchor-children-expected.png index 4f1c80e..30a3c0ba 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/image-map-anchor-children-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/image-map-anchor-children-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png index db7d836f..f5c8a71 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png index 1ff122a..2b82dcf 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png index 03884e6..e727603 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png index 7e7ff5b7..3d9b736 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png index 96e8a35..6ab669dd 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-explicitly-inherited-from-map-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png index 0c6a756..705df7f 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png index 7a4bdb74..890e7744 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png index 47a71898..fa4e40f3 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png index 281176ed..3de2dbf 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png index 50a38bc..a3d58a6 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png index 1495b74..a3a6752 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png index 9b79ee5..44982e9 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png b/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png index 0aeb2da..e59f7e4f 100644 --- a/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png +++ b/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png b/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png index 356ea4f85..eb1456c4 100644 --- a/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png +++ b/third_party/blink/web_tests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-05-f-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png index 5bdaf81..2616aa00 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-diff-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png index c631562..c7bd016 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/cross-fade-svg-size-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png index 4769870..3c75d67 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-circle-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png index 3be9597..94ac255 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png index e713bcb..8f58f48 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-in-positioned-container-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png index 2834530..5b6e63e 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-outline-color-not-inherited-from-map-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png index 49d3b534..efca9837 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-paint-root-offset-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png index 4c4385c..425e555e 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-with-scale-transform-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png index cccfc99..7e99a0be 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-focus-ring-zoom-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png index 2858fa6..b3756a6 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-circle-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png index 6929b29..4274da1 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-overflowing-polygon-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png index 066f33b..8414dc3 100644 --- a/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png +++ b/third_party/blink/web_tests/platform/win/virtual/exotic-color-space/images/imagemap-polygon-focus-ring-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png b/third_party/blink/web_tests/platform/win7/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png new file mode 100644 index 0000000..266834369 --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.txt new file mode 100644 index 0000000..e294d225 --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/virtual/exotic-color-space/images/feature-policy-oversized-images-expected.txt
@@ -0,0 +1,12 @@ +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document. +CONSOLE ERROR: Feature policy violation: oversized-images is not allowed in this document.
diff --git a/third_party/blink/web_tests/svg/filters/feImage-preserveAspectRatio-all-expected.png b/third_party/blink/web_tests/svg/filters/feImage-preserveAspectRatio-all-expected.png index 7c626e7..d52e71d 100644 --- a/third_party/blink/web_tests/svg/filters/feImage-preserveAspectRatio-all-expected.png +++ b/third_party/blink/web_tests/svg/filters/feImage-preserveAspectRatio-all-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/svg/filters/feImage-preserveAspectratio-expected.png b/third_party/blink/web_tests/svg/filters/feImage-preserveAspectratio-expected.png index cfe069d..6336afe1 100644 --- a/third_party/blink/web_tests/svg/filters/feImage-preserveAspectratio-expected.png +++ b/third_party/blink/web_tests/svg/filters/feImage-preserveAspectratio-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/svg/filters/filteredImage-expected.png b/third_party/blink/web_tests/svg/filters/filteredImage-expected.png index fec75dc..aa1a9b3 100644 --- a/third_party/blink/web_tests/svg/filters/filteredImage-expected.png +++ b/third_party/blink/web_tests/svg/filters/filteredImage-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/dark-mode/paint/dark-mode/image-filter-all/image-invert-expected.png b/third_party/blink/web_tests/virtual/dark-mode/paint/dark-mode/image-filter-all/image-invert-expected.png index bc6b96e..2aa2c0b8 100644 --- a/third_party/blink/web_tests/virtual/dark-mode/paint/dark-mode/image-filter-all/image-invert-expected.png +++ b/third_party/blink/web_tests/virtual/dark-mode/paint/dark-mode/image-filter-all/image-invert-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png b/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png index 212a5e11..e2cbbdf 100644 --- a/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png +++ b/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-invalidation-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png b/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png index 0e6cc0a..42c84084 100644 --- a/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png +++ b/third_party/blink/web_tests/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png b/third_party/blink/web_tests/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png index 45c5653..3a286c2 100644 --- a/third_party/blink/web_tests/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png +++ b/third_party/blink/web_tests/virtual/exotic-color-space/images/exif-orientation-height-image-document-expected.png Binary files differ
diff --git a/third_party/custom_tabs_client/BUILD.gn b/third_party/custom_tabs_client/BUILD.gn index fd873ac9..61f9e6e9 100644 --- a/third_party/custom_tabs_client/BUILD.gn +++ b/third_party/custom_tabs_client/BUILD.gn
@@ -33,8 +33,8 @@ ":custom_tabs_client_shared_java", ":custom_tabs_support_java", "//third_party/android_deps:android_arch_lifecycle_common_java", - "//third_party/android_deps:android_support_annotations_java", "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] chromium_code = false } @@ -80,9 +80,9 @@ ] deps = [ ":custom_tabs_support_resources", - "//third_party/android_deps:android_support_annotations_java", - "//third_party/android_deps:android_support_compat_java", "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:com_android_support_support_annotations_java", + "//third_party/android_deps:com_android_support_support_compat_java", ] srcjar_deps = [ ":chrome_custom_tabs_service_aidl" ] android_manifest_for_lint = "src/customtabs/AndroidManifest.xml"
diff --git a/third_party/espresso/BUILD.gn b/third_party/espresso/BUILD.gn index 1307e3f9..6439e726 100644 --- a/third_party/espresso/BUILD.gn +++ b/third_party/espresso/BUILD.gn
@@ -33,7 +33,7 @@ jar_path = "lib/espresso-core-release-no-dep.jar" deps = [ ":espresso_idling_java", - "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/android_deps:javax_inject_javax_inject_java", "//third_party/android_support_test_runner:runner_java", "//third_party/guava:guava_android_java",
diff --git a/third_party/feed/BUILD.gn b/third_party/feed/BUILD.gn index 66f3819f..ea77c29 100644 --- a/third_party/feed/BUILD.gn +++ b/third_party/feed/BUILD.gn
@@ -59,10 +59,10 @@ ":piet_resources", ":shared_stream_publicapi_menumeasurer_resources", ":sharedstream_contextmenumanager_resources", - "//third_party/android_deps:android_support_annotations_java", - "//third_party/android_deps:android_support_cardview_java", "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:android_support_v7_recyclerview_java", + "//third_party/android_deps:com_android_support_cardview_v7_java", + "//third_party/android_deps:com_android_support_recyclerview_v7_java", + "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/android_deps:com_google_protobuf_protobuf_lite_java", "//third_party/android_deps:javax_inject_javax_inject_java", "//third_party/jsr-305:jsr_305_javalib",
diff --git a/third_party/inspector_protocol/BUILD.gn b/third_party/inspector_protocol/BUILD.gn index 0cf1a98..ddbe626 100644 --- a/third_party/inspector_protocol/BUILD.gn +++ b/third_party/inspector_protocol/BUILD.gn
@@ -2,109 +2,15 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -# All build targets below are experimental and not used within the -# Chromium / V8 / etc. trees yet thus far. Do not depend on anything. - -import("//testing/test.gni") - -static_library("json_parser") { +static_library("encoding") { sources = [ - "encoding/json_parser.cc", - "encoding/json_parser.h", - "encoding/json_parser_handler.h", - "encoding/platform.h", - "encoding/span.h", - "encoding/status.h", - "encoding/str_util.cc", - "encoding/str_util.h", + "encoding/encoding.cc", + "encoding/encoding.h", ] } -static_library("linux_dev_platform") { - sources = [ - "encoding/linux_dev_platform.cc", - "encoding/linux_dev_platform.h", - "encoding/platform.h", - ] -} +# encoding/encoding_test.cc: +# There's no target for this file here, instead it is included +# in //content/test:content_unittest +# via //content/browser/devtools:inspector_protocol_encoding_test. -test("json_parser_test") { - sources = [ - "encoding/json_parser_test.cc", - ] - deps = [ - ":json_parser", - ":linux_dev_platform", - "//base", - "//third_party/googletest:gmock", - "//third_party/googletest:gtest", - "//third_party/googletest:gtest_main", - ] -} - -static_library("cbor") { - sources = [ - "encoding/cbor.cc", - "encoding/cbor.h", - "encoding/json_parser_handler.h", - "encoding/span.h", - "encoding/status.h", - ] - deps = [ - ":json_parser", - ] -} - -test("cbor_test") { - sources = [ - "encoding/cbor_test.cc", - ] - deps = [ - ":cbor", - ":json_parser", - ":json_std_string_writer", - ":linux_dev_platform", - "//base", - "//third_party/googletest:gmock", - "//third_party/googletest:gtest", - "//third_party/googletest:gtest_main", - ] -} - -test("span_test") { - sources = [ - "encoding/span.h", - "encoding/span_test.cc", - ] - deps = [ - "//base", - "//third_party/googletest:gmock", - "//third_party/googletest:gtest", - "//third_party/googletest:gtest_main", - ] -} - -static_library("json_std_string_writer") { - sources = [ - "encoding/json_parser_handler.h", - "encoding/json_std_string_writer.cc", - "encoding/json_std_string_writer.h", - "encoding/platform.h", - "encoding/span.h", - "encoding/status.h", - ] -} - -test("json_std_string_writer_test") { - sources = [ - "encoding/json_std_string_writer_test.cc", - ] - deps = [ - ":json_std_string_writer", - ":linux_dev_platform", - "//base", - "//third_party/googletest:gmock", - "//third_party/googletest:gtest", - "//third_party/googletest:gtest_main", - ] -}
diff --git a/third_party/inspector_protocol/DEPS b/third_party/inspector_protocol/DEPS index 81c9b082..20785c0 100644 --- a/third_party/inspector_protocol/DEPS +++ b/third_party/inspector_protocol/DEPS
@@ -6,7 +6,7 @@ specific_include_rules = { '^.*_test\.cc$': [ '+base', - '+gmock', - '+gtest', + '+testing/gtest/include', + '+testing/gmock/include', ], }
diff --git a/third_party/inspector_protocol/README.chromium b/third_party/inspector_protocol/README.chromium index 89f754b6..f68de23 100644 --- a/third_party/inspector_protocol/README.chromium +++ b/third_party/inspector_protocol/README.chromium
@@ -2,7 +2,7 @@ Short Name: inspector_protocol URL: https://chromium.googlesource.com/deps/inspector_protocol/ Version: 0 -Revision: be5f927f77f7d4670a02f16ed026db0a3768980a +Revision: a6bdf8a7cc95ee954ba2f701d10f4ecf03e86539 License: BSD License File: LICENSE Security Critical: no
diff --git a/third_party/inspector_protocol/code_generator.py b/third_party/inspector_protocol/code_generator.py index fb9959d..18777d0f 100755 --- a/third_party/inspector_protocol/code_generator.py +++ b/third_party/inspector_protocol/code_generator.py
@@ -632,7 +632,7 @@ "Array_h.template", "DispatcherBase_h.template", "Parser_h.template", - "CBOR_h.template", + "encoding_h.template", ] protocol_cpp_templates = [ @@ -642,7 +642,7 @@ "Object_cpp.template", "DispatcherBase_cpp.template", "Parser_cpp.template", - "CBOR_cpp.template", + "encoding_cpp.template", ] forward_h_templates = [
diff --git a/third_party/inspector_protocol/encoding/cbor.cc b/third_party/inspector_protocol/encoding/cbor.cc deleted file mode 100644 index f771f5b..0000000 --- a/third_party/inspector_protocol/encoding/cbor.cc +++ /dev/null
@@ -1,821 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "cbor.h" - -#include <cassert> -#include <limits> -#include "json_parser_handler.h" - -namespace inspector_protocol { -using namespace cbor; - -namespace { - -// See RFC 7049 Section 2.3, Table 2. -static constexpr uint8_t kEncodedTrue = - EncodeInitialByte(MajorType::SIMPLE_VALUE, 21); -static constexpr uint8_t kEncodedFalse = - EncodeInitialByte(MajorType::SIMPLE_VALUE, 20); -static constexpr uint8_t kEncodedNull = - EncodeInitialByte(MajorType::SIMPLE_VALUE, 22); -static constexpr uint8_t kInitialByteForDouble = - EncodeInitialByte(MajorType::SIMPLE_VALUE, 27); - -} // namespace - -uint8_t EncodeTrue() { return kEncodedTrue; } -uint8_t EncodeFalse() { return kEncodedFalse; } -uint8_t EncodeNull() { return kEncodedNull; } - -uint8_t EncodeIndefiniteLengthArrayStart() { - return kInitialByteIndefiniteLengthArray; -} - -uint8_t EncodeIndefiniteLengthMapStart() { - return kInitialByteIndefiniteLengthMap; -} - -uint8_t EncodeStop() { return kStopByte; } - -namespace { -// See RFC 7049 Table 3 and Section 2.4.4.2. This is used as a prefix for -// arbitrary binary data encoded as BYTE_STRING. -static constexpr uint8_t kExpectedConversionToBase64Tag = - EncodeInitialByte(MajorType::TAG, 22); - -// When parsing CBOR, we limit recursion depth for objects and arrays -// to this constant. -static constexpr int kStackLimit = 1000; - -// Writes the bytes for |v| to |out|, starting with the most significant byte. -// See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html -template <typename T> -void WriteBytesMostSignificantByteFirst(T v, std::vector<uint8_t>* out) { - for (int shift_bytes = sizeof(T) - 1; shift_bytes >= 0; --shift_bytes) - out->push_back(0xff & (v >> (shift_bytes * 8))); -} -} // namespace - -namespace cbor_internals { -// Writes the start of a token with |type|. The |value| may indicate the size, -// or it may be the payload if the value is an unsigned integer. -void WriteTokenStart(MajorType type, uint64_t value, - std::vector<uint8_t>* encoded) { - if (value < 24) { - // Values 0-23 are encoded directly into the additional info of the - // initial byte. - encoded->push_back(EncodeInitialByte(type, /*additional_info=*/value)); - return; - } - if (value <= std::numeric_limits<uint8_t>::max()) { - // Values 24-255 are encoded with one initial byte, followed by the value. - encoded->push_back(EncodeInitialByte(type, kAdditionalInformation1Byte)); - encoded->push_back(value); - return; - } - if (value <= std::numeric_limits<uint16_t>::max()) { - // Values 256-65535: 1 initial byte + 2 bytes payload. - encoded->push_back(EncodeInitialByte(type, kAdditionalInformation2Bytes)); - WriteBytesMostSignificantByteFirst<uint16_t>(value, encoded); - return; - } - if (value <= std::numeric_limits<uint32_t>::max()) { - // 32 bit uint: 1 initial byte + 4 bytes payload. - encoded->push_back(EncodeInitialByte(type, kAdditionalInformation4Bytes)); - WriteBytesMostSignificantByteFirst<uint32_t>(static_cast<uint32_t>(value), - encoded); - return; - } - // 64 bit uint: 1 initial byte + 8 bytes payload. - encoded->push_back(EncodeInitialByte(type, kAdditionalInformation8Bytes)); - WriteBytesMostSignificantByteFirst<uint64_t>(value, encoded); -} -} // namespace cbor_internals - -namespace { -// Extracts sizeof(T) bytes from |in| to extract a value of type T -// (e.g. uint64_t, uint32_t, ...), most significant byte first. -// See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html -template <typename T> -T ReadBytesMostSignificantByteFirst(span<uint8_t> in) { - assert(static_cast<std::size_t>(in.size()) >= sizeof(T)); - T result = 0; - for (std::size_t shift_bytes = 0; shift_bytes < sizeof(T); ++shift_bytes) - result |= T(in[sizeof(T) - 1 - shift_bytes]) << (shift_bytes * 8); - return result; -} -} // namespace - -namespace cbor_internals { -int8_t ReadTokenStart(span<uint8_t> bytes, MajorType* type, uint64_t* value) { - if (bytes.empty()) return -1; - uint8_t initial_byte = bytes[0]; - *type = MajorType((initial_byte & kMajorTypeMask) >> kMajorTypeBitShift); - - uint8_t additional_information = initial_byte & kAdditionalInformationMask; - if (additional_information < 24) { - // Values 0-23 are encoded directly into the additional info of the - // initial byte. - *value = additional_information; - return 1; - } - if (additional_information == kAdditionalInformation1Byte) { - // Values 24-255 are encoded with one initial byte, followed by the value. - if (bytes.size() < 2) return -1; - *value = ReadBytesMostSignificantByteFirst<uint8_t>(bytes.subspan(1)); - return 2; - } - if (additional_information == kAdditionalInformation2Bytes) { - // Values 256-65535: 1 initial byte + 2 bytes payload. - if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint16_t)) - return -1; - *value = ReadBytesMostSignificantByteFirst<uint16_t>(bytes.subspan(1)); - return 3; - } - if (additional_information == kAdditionalInformation4Bytes) { - // 32 bit uint: 1 initial byte + 4 bytes payload. - if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint32_t)) - return -1; - *value = ReadBytesMostSignificantByteFirst<uint32_t>(bytes.subspan(1)); - return 5; - } - if (additional_information == kAdditionalInformation8Bytes) { - // 64 bit uint: 1 initial byte + 8 bytes payload. - if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint64_t)) - return -1; - *value = ReadBytesMostSignificantByteFirst<uint64_t>(bytes.subspan(1)); - return 9; - } - return -1; -} -} // namespace cbor_internals - -using cbor_internals::WriteTokenStart; -using cbor_internals::ReadTokenStart; - -void EncodeInt32(int32_t value, std::vector<uint8_t>* out) { - if (value >= 0) { - WriteTokenStart(MajorType::UNSIGNED, value, out); - } else { - uint64_t representation = static_cast<uint64_t>(-(value + 1)); - WriteTokenStart(MajorType::NEGATIVE, representation, out); - } -} - -void EncodeString16(span<uint16_t> in, std::vector<uint8_t>* out) { - uint64_t byte_length = static_cast<uint64_t>(in.size_bytes()); - WriteTokenStart(MajorType::BYTE_STRING, byte_length, out); - // When emitting UTF16 characters, we always write the least significant byte - // first; this is because it's the native representation for X86. - // TODO(johannes): Implement a more efficient thing here later, e.g. - // casting *iff* the machine has this byte order. - // The wire format for UTF16 chars will probably remain the same - // (least significant byte first) since this way we can have - // golden files, unittests, etc. that port easily and universally. - // See also: - // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html - for (const uint16_t two_bytes : in) { - out->push_back(two_bytes); - out->push_back(two_bytes >> 8); - } -} - -void EncodeString8(span<uint8_t> in, std::vector<uint8_t>* out) { - WriteTokenStart(MajorType::STRING, static_cast<uint64_t>(in.size_bytes()), - out); - out->insert(out->end(), in.begin(), in.end()); -} - -void EncodeFromLatin1(span<uint8_t> latin1, std::vector<uint8_t>* out) { - for (std::ptrdiff_t ii = 0; ii < latin1.size(); ++ii) { - if (latin1[ii] <= 127) - continue; - // If there's at least one non-ASCII char, convert to UTF8. - std::vector<uint8_t> utf8(latin1.begin(), latin1.begin() + ii); - for (; ii < latin1.size(); ++ii) { - if (latin1[ii] <= 127) { - utf8.push_back(latin1[ii]); - } else { - // 0xC0 means it's a UTF8 sequence with 2 bytes. - utf8.push_back((latin1[ii] >> 6) | 0xc0); - utf8.push_back((latin1[ii] | 0x80) & 0xbf); - } - } - EncodeString8(span<uint8_t>(utf8.data(), utf8.size()), out); - return; - } - EncodeString8(latin1, out); -} - -void EncodeFromUTF16(span<uint16_t> utf16, std::vector<uint8_t>* out) { - // If there's at least one non-ASCII char, encode as STRING16 (UTF16). - for (uint16_t ch : utf16) { - if (ch <= 127) - continue; - EncodeString16(utf16, out); - return; - } - // It's all US-ASCII, strip out every second byte and encode as UTF8. - WriteTokenStart(MajorType::STRING, static_cast<uint64_t>(utf16.size()), out); - out->insert(out->end(), utf16.begin(), utf16.end()); -} - -void EncodeBinary(span<uint8_t> in, std::vector<uint8_t>* out) { - out->push_back(kExpectedConversionToBase64Tag); - uint64_t byte_length = static_cast<uint64_t>(in.size_bytes()); - WriteTokenStart(MajorType::BYTE_STRING, byte_length, out); - out->insert(out->end(), in.begin(), in.end()); -} - -// A double is encoded with a specific initial byte -// (kInitialByteForDouble) plus the 64 bits of payload for its value. -constexpr std::ptrdiff_t kEncodedDoubleSize = 1 + sizeof(uint64_t); - -// An envelope is encoded with a specific initial byte -// (kInitialByteForEnvelope), plus the start byte for a BYTE_STRING with a 32 -// bit wide length, plus a 32 bit length for that string. -constexpr std::ptrdiff_t kEncodedEnvelopeHeaderSize = 1 + 1 + sizeof(uint32_t); - -void EncodeDouble(double value, std::vector<uint8_t>* out) { - // The additional_info=27 indicates 64 bits for the double follow. - // See RFC 7049 Section 2.3, Table 1. - out->push_back(kInitialByteForDouble); - union { - double from_double; - uint64_t to_uint64; - } reinterpret; - reinterpret.from_double = value; - WriteBytesMostSignificantByteFirst<uint64_t>(reinterpret.to_uint64, out); -} - -void EnvelopeEncoder::EncodeStart(std::vector<uint8_t>* out) { - assert(byte_size_pos_ == 0); - out->push_back(kInitialByteForEnvelope); - out->push_back(kInitialByteFor32BitLengthByteString); - byte_size_pos_ = out->size(); - out->resize(out->size() + sizeof(uint32_t)); -} - -bool EnvelopeEncoder::EncodeStop(std::vector<uint8_t>* out) { - assert(byte_size_pos_ != 0); - // The byte size is the size of the payload, that is, all the - // bytes that were written past the byte size position itself. - uint64_t byte_size = out->size() - (byte_size_pos_ + sizeof(uint32_t)); - // We store exactly 4 bytes, so at most INT32MAX, with most significant - // byte first. - if (byte_size > std::numeric_limits<uint32_t>::max()) return false; - for (int shift_bytes = sizeof(uint32_t) - 1; shift_bytes >= 0; - --shift_bytes) { - (*out)[byte_size_pos_++] = 0xff & (byte_size >> (shift_bytes * 8)); - } - return true; -} - -namespace { -class JSONToCBOREncoder : public JSONParserHandler { - public: - JSONToCBOREncoder(std::vector<uint8_t>* out, Status* status) - : out_(out), status_(status) { - *status_ = Status(); - } - - void HandleObjectBegin() override { - envelopes_.emplace_back(); - envelopes_.back().EncodeStart(out_); - out_->push_back(kInitialByteIndefiniteLengthMap); - } - - void HandleObjectEnd() override { - out_->push_back(kStopByte); - assert(!envelopes_.empty()); - envelopes_.back().EncodeStop(out_); - envelopes_.pop_back(); - } - - void HandleArrayBegin() override { - envelopes_.emplace_back(); - envelopes_.back().EncodeStart(out_); - out_->push_back(kInitialByteIndefiniteLengthArray); - } - - void HandleArrayEnd() override { - out_->push_back(kStopByte); - assert(!envelopes_.empty()); - envelopes_.back().EncodeStop(out_); - envelopes_.pop_back(); - } - - void HandleString8(span<uint8_t> chars) override { - EncodeString8(chars, out_); - } - - void HandleString16(span<uint16_t> chars) override { - for (uint16_t ch : chars) { - if (ch >= 0x7f) { - // If there's at least one non-7bit character, we encode as UTF16. - EncodeString16(chars, out_); - return; - } - } - std::vector<uint8_t> sevenbit_chars(chars.begin(), chars.end()); - EncodeString8(span<uint8_t>(sevenbit_chars.data(), sevenbit_chars.size()), - out_); - } - - void HandleBinary(std::vector<uint8_t> bytes) override { - EncodeBinary(span<uint8_t>(bytes.data(), bytes.size()), out_); - } - - void HandleDouble(double value) override { EncodeDouble(value, out_); } - - void HandleInt32(int32_t value) override { EncodeInt32(value, out_); } - - void HandleBool(bool value) override { - // See RFC 7049 Section 2.3, Table 2. - out_->push_back(value ? kEncodedTrue : kEncodedFalse); - } - - void HandleNull() override { - // See RFC 7049 Section 2.3, Table 2. - out_->push_back(kEncodedNull); - } - - void HandleError(Status error) override { - assert(!error.ok()); - *status_ = error; - out_->clear(); - } - - private: - std::vector<uint8_t>* out_; - std::vector<EnvelopeEncoder> envelopes_; - Status* status_; -}; -} // namespace - -std::unique_ptr<JSONParserHandler> NewJSONToCBOREncoder( - std::vector<uint8_t>* out, Status* status) { - return std::unique_ptr<JSONParserHandler>(new JSONToCBOREncoder(out, status)); -} - -namespace { -// Below are three parsing routines for CBOR, which cover enough -// to roundtrip JSON messages. -bool ParseMap(int32_t stack_depth, CBORTokenizer* tokenizer, - JSONParserHandler* out); -bool ParseArray(int32_t stack_depth, CBORTokenizer* tokenizer, - JSONParserHandler* out); -bool ParseValue(int32_t stack_depth, CBORTokenizer* tokenizer, - JSONParserHandler* out); - -void ParseUTF16String(CBORTokenizer* tokenizer, JSONParserHandler* out) { - std::vector<uint16_t> value; - span<uint8_t> rep = tokenizer->GetString16WireRep(); - for (std::ptrdiff_t ii = 0; ii < rep.size(); ii += 2) - value.push_back((rep[ii + 1] << 8) | rep[ii]); - out->HandleString16(span<uint16_t>(value.data(), value.size())); - tokenizer->Next(); -} - -bool ParseUTF8String(CBORTokenizer* tokenizer, JSONParserHandler* out) { - assert(tokenizer->TokenTag() == CBORTokenTag::STRING8); - out->HandleString8(tokenizer->GetString8()); - tokenizer->Next(); - return true; -} - -bool ParseValue(int32_t stack_depth, CBORTokenizer* tokenizer, - JSONParserHandler* out) { - if (stack_depth > kStackLimit) { - out->HandleError( - Status{Error::CBOR_STACK_LIMIT_EXCEEDED, tokenizer->Status().pos}); - return false; - } - // Skip past the envelope to get to what's inside. - if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE) - tokenizer->EnterEnvelope(); - switch (tokenizer->TokenTag()) { - case CBORTokenTag::ERROR_VALUE: - out->HandleError(tokenizer->Status()); - return false; - case CBORTokenTag::DONE: - out->HandleError(Status{Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE, - tokenizer->Status().pos}); - return false; - case CBORTokenTag::TRUE_VALUE: - out->HandleBool(true); - tokenizer->Next(); - return true; - case CBORTokenTag::FALSE_VALUE: - out->HandleBool(false); - tokenizer->Next(); - return true; - case CBORTokenTag::NULL_VALUE: - out->HandleNull(); - tokenizer->Next(); - return true; - case CBORTokenTag::INT32: - out->HandleInt32(tokenizer->GetInt32()); - tokenizer->Next(); - return true; - case CBORTokenTag::DOUBLE: - out->HandleDouble(tokenizer->GetDouble()); - tokenizer->Next(); - return true; - case CBORTokenTag::STRING8: - return ParseUTF8String(tokenizer, out); - case CBORTokenTag::STRING16: - ParseUTF16String(tokenizer, out); - return true; - case CBORTokenTag::BINARY: { - span<uint8_t> binary = tokenizer->GetBinary(); - out->HandleBinary(std::vector<uint8_t>(binary.begin(), binary.end())); - tokenizer->Next(); - return true; - } - case CBORTokenTag::MAP_START: - return ParseMap(stack_depth + 1, tokenizer, out); - case CBORTokenTag::ARRAY_START: - return ParseArray(stack_depth + 1, tokenizer, out); - default: - out->HandleError( - Status{Error::CBOR_UNSUPPORTED_VALUE, tokenizer->Status().pos}); - return false; - } -} - -// |bytes| must start with the indefinite length array byte, so basically, -// ParseArray may only be called after an indefinite length array has been -// detected. -bool ParseArray(int32_t stack_depth, CBORTokenizer* tokenizer, - JSONParserHandler* out) { - assert(tokenizer->TokenTag() == CBORTokenTag::ARRAY_START); - tokenizer->Next(); - out->HandleArrayBegin(); - while (tokenizer->TokenTag() != CBORTokenTag::STOP) { - if (tokenizer->TokenTag() == CBORTokenTag::DONE) { - out->HandleError( - Status{Error::CBOR_UNEXPECTED_EOF_IN_ARRAY, tokenizer->Status().pos}); - return false; - } - if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) { - out->HandleError(tokenizer->Status()); - return false; - } - // Parse value. - if (!ParseValue(stack_depth, tokenizer, out)) return false; - } - out->HandleArrayEnd(); - tokenizer->Next(); - return true; -} - -// |bytes| must start with the indefinite length array byte, so basically, -// ParseArray may only be called after an indefinite length array has been -// detected. -bool ParseMap(int32_t stack_depth, CBORTokenizer* tokenizer, - JSONParserHandler* out) { - assert(tokenizer->TokenTag() == CBORTokenTag::MAP_START); - out->HandleObjectBegin(); - tokenizer->Next(); - while (tokenizer->TokenTag() != CBORTokenTag::STOP) { - if (tokenizer->TokenTag() == CBORTokenTag::DONE) { - out->HandleError( - Status{Error::CBOR_UNEXPECTED_EOF_IN_MAP, tokenizer->Status().pos}); - return false; - } - if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) { - out->HandleError(tokenizer->Status()); - return false; - } - // Parse key. - if (tokenizer->TokenTag() == CBORTokenTag::STRING8) { - if (!ParseUTF8String(tokenizer, out)) - return false; - } else if (tokenizer->TokenTag() == CBORTokenTag::STRING16) { - ParseUTF16String(tokenizer, out); - } else { - out->HandleError( - Status{Error::CBOR_INVALID_MAP_KEY, tokenizer->Status().pos}); - return false; - } - // Parse value. - if (!ParseValue(stack_depth, tokenizer, out)) return false; - } - out->HandleObjectEnd(); - tokenizer->Next(); - return true; -} -} // namespace - -void ParseCBOR(span<uint8_t> bytes, JSONParserHandler* json_out) { - if (bytes.empty()) { - json_out->HandleError(Status{Error::CBOR_NO_INPUT, 0}); - return; - } - if (bytes[0] != kInitialByteForEnvelope) { - json_out->HandleError(Status{Error::CBOR_INVALID_START_BYTE, 0}); - return; - } - CBORTokenizer tokenizer(bytes); - if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) { - json_out->HandleError(tokenizer.Status()); - return; - } - // We checked for the envelope start byte above, so the tokenizer - // must agree here, since it's not an error. - assert(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE); - tokenizer.EnterEnvelope(); - if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) { - json_out->HandleError( - Status{Error::CBOR_MAP_START_EXPECTED, tokenizer.Status().pos}); - return; - } - if (!ParseMap(/*stack_depth=*/1, &tokenizer, json_out)) return; - if (tokenizer.TokenTag() == CBORTokenTag::DONE) return; - if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) { - json_out->HandleError(tokenizer.Status()); - return; - } - json_out->HandleError( - Status{Error::CBOR_TRAILING_JUNK, tokenizer.Status().pos}); -} - -CBORTokenizer::CBORTokenizer(span<uint8_t> bytes) : bytes_(bytes) { - ReadNextToken(/*enter_envelope=*/false); -} -CBORTokenizer::~CBORTokenizer() {} - -CBORTokenTag CBORTokenizer::TokenTag() const { return token_tag_; } - -void CBORTokenizer::Next() { - if (token_tag_ == CBORTokenTag::ERROR_VALUE || token_tag_ == CBORTokenTag::DONE) - return; - ReadNextToken(/*enter_envelope=*/false); -} - -void CBORTokenizer::EnterEnvelope() { - assert(token_tag_ == CBORTokenTag::ENVELOPE); - ReadNextToken(/*enter_envelope=*/true); -} - -Status CBORTokenizer::Status() const { return status_; } - -int32_t CBORTokenizer::GetInt32() const { - assert(token_tag_ == CBORTokenTag::INT32); - // The range checks happen in ::ReadNextToken(). - return static_cast<uint32_t>( - token_start_type_ == MajorType::UNSIGNED - ? token_start_internal_value_ - : -static_cast<int64_t>(token_start_internal_value_) - 1); -} - -double CBORTokenizer::GetDouble() const { - assert(token_tag_ == CBORTokenTag::DOUBLE); - union { - uint64_t from_uint64; - double to_double; - } reinterpret; - reinterpret.from_uint64 = ReadBytesMostSignificantByteFirst<uint64_t>( - bytes_.subspan(status_.pos + 1)); - return reinterpret.to_double; -} - -span<uint8_t> CBORTokenizer::GetString8() const { - assert(token_tag_ == CBORTokenTag::STRING8); - auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); - return bytes_.subspan(status_.pos + (token_byte_length_ - length), length); -} - -span<uint8_t> CBORTokenizer::GetString16WireRep() const { - assert(token_tag_ == CBORTokenTag::STRING16); - auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); - return bytes_.subspan(status_.pos + (token_byte_length_ - length), length); -} - -span<uint8_t> CBORTokenizer::GetBinary() const { - assert(token_tag_ == CBORTokenTag::BINARY); - auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); - return bytes_.subspan(status_.pos + (token_byte_length_ - length), length); -} - -void CBORTokenizer::ReadNextToken(bool enter_envelope) { - if (enter_envelope) { - status_.pos += kEncodedEnvelopeHeaderSize; - } else { - status_.pos = - status_.pos == Status::npos() ? 0 : status_.pos + token_byte_length_; - } - status_.error = Error::OK; - if (status_.pos >= bytes_.size()) { - token_tag_ = CBORTokenTag::DONE; - return; - } - switch (bytes_[status_.pos]) { - case kStopByte: - SetToken(CBORTokenTag::STOP, 1); - return; - case kInitialByteIndefiniteLengthMap: - SetToken(CBORTokenTag::MAP_START, 1); - return; - case kInitialByteIndefiniteLengthArray: - SetToken(CBORTokenTag::ARRAY_START, 1); - return; - case kEncodedTrue: - SetToken(CBORTokenTag::TRUE_VALUE, 1); - return; - case kEncodedFalse: - SetToken(CBORTokenTag::FALSE_VALUE, 1); - return; - case kEncodedNull: - SetToken(CBORTokenTag::NULL_VALUE, 1); - return; - case kExpectedConversionToBase64Tag: { // BINARY - int8_t bytes_read = - ReadTokenStart(bytes_.subspan(status_.pos + 1), &token_start_type_, - &token_start_internal_value_); - int64_t token_byte_length = 1 + bytes_read + token_start_internal_value_; - if (-1 == bytes_read || token_start_type_ != MajorType::BYTE_STRING || - status_.pos + token_byte_length > bytes_.size()) { - SetError(Error::CBOR_INVALID_BINARY); - return; - } - SetToken(CBORTokenTag::BINARY, - static_cast<std::ptrdiff_t>(token_byte_length)); - return; - } - case kInitialByteForDouble: { // DOUBLE - if (status_.pos + kEncodedDoubleSize > bytes_.size()) { - SetError(Error::CBOR_INVALID_DOUBLE); - return; - } - SetToken(CBORTokenTag::DOUBLE, kEncodedDoubleSize); - return; - } - case kInitialByteForEnvelope: { // ENVELOPE - if (status_.pos + kEncodedEnvelopeHeaderSize > bytes_.size()) { - SetError(Error::CBOR_INVALID_ENVELOPE); - return; - } - // The envelope must be a byte string with 32 bit length. - if (bytes_[status_.pos + 1] != kInitialByteFor32BitLengthByteString) { - SetError(Error::CBOR_INVALID_ENVELOPE); - return; - } - // Read the length of the byte string. - token_start_internal_value_ = ReadBytesMostSignificantByteFirst<uint32_t>( - bytes_.subspan(status_.pos + 2)); - // Make sure the payload is contained within the message. - if (token_start_internal_value_ + kEncodedEnvelopeHeaderSize + - status_.pos > - static_cast<std::size_t>(bytes_.size())) { - SetError(Error::CBOR_INVALID_ENVELOPE); - return; - } - auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); - SetToken(CBORTokenTag::ENVELOPE, - kEncodedEnvelopeHeaderSize + length); - return; - } - default: { - span<uint8_t> remainder = - bytes_.subspan(status_.pos, bytes_.size() - status_.pos); - assert(!remainder.empty()); - int8_t token_start_length = ReadTokenStart(remainder, &token_start_type_, - &token_start_internal_value_); - bool success = token_start_length != -1; - switch (token_start_type_) { - case MajorType::UNSIGNED: // INT32. - if (!success || std::numeric_limits<int32_t>::max() < - token_start_internal_value_) { - SetError(Error::CBOR_INVALID_INT32); - return; - } - SetToken(CBORTokenTag::INT32, token_start_length); - return; - case MajorType::NEGATIVE: // INT32. - if (!success || - std::numeric_limits<int32_t>::min() > - -static_cast<int64_t>(token_start_internal_value_) - 1) { - SetError(Error::CBOR_INVALID_INT32); - return; - } - SetToken(CBORTokenTag::INT32, token_start_length); - return; - case MajorType::STRING: { // STRING8. - if (!success || remainder.size() < static_cast<int64_t>( - token_start_internal_value_)) { - SetError(Error::CBOR_INVALID_STRING8); - return; - } - auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); - SetToken(CBORTokenTag::STRING8, token_start_length + length); - return; - } - case MajorType::BYTE_STRING: { // STRING16. - if (!success || - remainder.size() < - static_cast<int64_t>(token_start_internal_value_) || - // Must be divisible by 2 since UTF16 is 2 bytes per character. - token_start_internal_value_ & 1) { - SetError(Error::CBOR_INVALID_STRING16); - return; - } - auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); - SetToken(CBORTokenTag::STRING16, token_start_length + length); - return; - } - case MajorType::ARRAY: - case MajorType::MAP: - case MajorType::TAG: - case MajorType::SIMPLE_VALUE: - SetError(Error::CBOR_UNSUPPORTED_VALUE); - return; - } - } - } -} - -void CBORTokenizer::SetToken(CBORTokenTag token_tag, - std::ptrdiff_t token_byte_length) { - token_tag_ = token_tag; - token_byte_length_ = token_byte_length; -} - -void CBORTokenizer::SetError(Error error) { - token_tag_ = CBORTokenTag::ERROR_VALUE; - status_.error = error; -} - -#if 0 -void DumpCBOR(span<uint8_t> cbor) { - std::string indent; - CBORTokenizer tokenizer(cbor); - while (true) { - fprintf(stderr, "%s", indent.c_str()); - switch (tokenizer.TokenTag()) { - case CBORTokenTag::ERROR_VALUE: - fprintf(stderr, "ERROR {status.error=%d, status.pos=%ld}\n", - tokenizer.Status().error, tokenizer.Status().pos); - return; - case CBORTokenTag::DONE: - fprintf(stderr, "DONE\n"); - return; - case CBORTokenTag::TRUE_VALUE: - fprintf(stderr, "TRUE_VALUE\n"); - break; - case CBORTokenTag::FALSE_VALUE: - fprintf(stderr, "FALSE_VALUE\n"); - break; - case CBORTokenTag::NULL_VALUE: - fprintf(stderr, "NULL_VALUE\n"); - break; - case CBORTokenTag::INT32: - fprintf(stderr, "INT32 [%d]\n", tokenizer.GetInt32()); - break; - case CBORTokenTag::DOUBLE: - fprintf(stderr, "DOUBLE [%lf]\n", tokenizer.GetDouble()); - break; - case CBORTokenTag::STRING8: { - span<uint8_t> v = tokenizer.GetString8(); - std::string t(v.begin(), v.end()); - fprintf(stderr, "STRING8 [%s]\n", t.c_str()); - break; - } - case CBORTokenTag::STRING16: { - span<uint8_t> v = tokenizer.GetString16WireRep(); - std::string t(v.begin(), v.end()); - fprintf(stderr, "STRING16 [%s]\n", t.c_str()); - break; - } - case CBORTokenTag::BINARY: { - span<uint8_t> v = tokenizer.GetBinary(); - std::string t(v.begin(), v.end()); - fprintf(stderr, "BINARY [%s]\n", t.c_str()); - break; - } - case CBORTokenTag::MAP_START: - fprintf(stderr, "MAP_START\n"); - indent += " "; - break; - case CBORTokenTag::ARRAY_START: - fprintf(stderr, "ARRAY_START\n"); - indent += " "; - break; - case CBORTokenTag::STOP: - fprintf(stderr, "STOP\n"); - indent.erase(0, 2); - break; - case CBORTokenTag::ENVELOPE: - fprintf(stderr, "ENVELOPE\n"); - tokenizer.EnterEnvelope(); - continue; - } - tokenizer.Next(); - } -} -#endif - -} // namespace inspector_protocol
diff --git a/third_party/inspector_protocol/encoding/cbor.h b/third_party/inspector_protocol/encoding/cbor.h deleted file mode 100644 index 2785f633..0000000 --- a/third_party/inspector_protocol/encoding/cbor.h +++ /dev/null
@@ -1,280 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef INSPECTOR_PROTOCOL_ENCODING_CBOR_H_ -#define INSPECTOR_PROTOCOL_ENCODING_CBOR_H_ - -#include <cstdint> -#include <memory> -#include <vector> -#include "cbor_internals.h" -#include "json_parser_handler.h" -#include "span.h" -#include "status.h" - -namespace inspector_protocol { - -namespace cbor { - -// The major types from RFC 7049 Section 2.1. -enum class MajorType { - UNSIGNED = 0, - NEGATIVE = 1, - BYTE_STRING = 2, - STRING = 3, - ARRAY = 4, - MAP = 5, - TAG = 6, - SIMPLE_VALUE = 7 -}; - -// Indicates the number of bits the "initial byte" needs to be shifted to the -// right after applying |kMajorTypeMask| to produce the major type in the -// lowermost bits. -static constexpr uint8_t kMajorTypeBitShift = 5u; -// Mask selecting the low-order 5 bits of the "initial byte", which is where -// the additional information is encoded. -static constexpr uint8_t kAdditionalInformationMask = 0x1f; -// Mask selecting the high-order 3 bits of the "initial byte", which indicates -// the major type of the encoded value. -static constexpr uint8_t kMajorTypeMask = 0xe0; -// Indicates the integer is in the following byte. -static constexpr uint8_t kAdditionalInformation1Byte = 24u; -// Indicates the integer is in the next 2 bytes. -static constexpr uint8_t kAdditionalInformation2Bytes = 25u; -// Indicates the integer is in the next 4 bytes. -static constexpr uint8_t kAdditionalInformation4Bytes = 26u; -// Indicates the integer is in the next 8 bytes. -static constexpr uint8_t kAdditionalInformation8Bytes = 27u; - -// Encodes the initial byte, consisting of the |type| in the first 3 bits -// followed by 5 bits of |additional_info|. -constexpr uint8_t EncodeInitialByte(MajorType type, uint8_t additional_info) { - return (static_cast<uint8_t>(type) << kMajorTypeBitShift) | - (additional_info & kAdditionalInformationMask); -} - -// TAG 24 indicates that what follows is a byte string which is -// encoded in CBOR format. We use this as a wrapper for -// maps and arrays, allowing us to skip them, because the -// byte string carries its size (byte length). -// https://tools.ietf.org/html/rfc7049#section-2.4.4.1 -static constexpr uint8_t kInitialByteForEnvelope = - EncodeInitialByte(MajorType::TAG, 24); -// The initial byte for a byte string with at most 2^32 bytes -// of payload. This is used for envelope encoding, even if -// the byte string is shorter. -static constexpr uint8_t kInitialByteFor32BitLengthByteString = - EncodeInitialByte(MajorType::BYTE_STRING, 26); - -// See RFC 7049 Section 2.2.1, indefinite length arrays / maps have additional -// info = 31. -static constexpr uint8_t kInitialByteIndefiniteLengthArray = - EncodeInitialByte(MajorType::ARRAY, 31); -static constexpr uint8_t kInitialByteIndefiniteLengthMap = - EncodeInitialByte(MajorType::MAP, 31); -// See RFC 7049 Section 2.3, Table 1; this is used for finishing indefinite -// length maps / arrays. -static constexpr uint8_t kStopByte = - EncodeInitialByte(MajorType::SIMPLE_VALUE, 31); - -} // namespace cbor - -// The binary encoding for the inspector protocol follows the CBOR specification -// (RFC 7049). Additional constraints: -// - Only indefinite length maps and arrays are supported. -// - Maps and arrays are wrapped with an envelope, that is, a -// CBOR tag with value 24 followed by a byte string specifying -// the byte length of the enclosed map / array. The byte string -// must use a 32 bit wide length. -// - At the top level, a message must be an indefinite length map -// wrapped by an envelope. -// - Maximal size for messages is 2^32 (4 GB). -// - For scalars, we support only the int32_t range, encoded as -// UNSIGNED/NEGATIVE (major types 0 / 1). -// - UTF16 strings, including with unbalanced surrogate pairs, are encoded -// as CBOR BYTE_STRING (major type 2). For such strings, the number of -// bytes encoded must be even. -// - UTF8 strings (major type 3) are supported. -// - 7 bit US-ASCII strings must always be encoded as UTF8 strings, not -// as UTF16 strings. -// - Arbitrary byte arrays, in the inspector protocol called 'binary', -// are encoded as BYTE_STRING (major type 2), prefixed with a byte -// indicating base64 when rendered as JSON. - -// Encodes |value| as |UNSIGNED| (major type 0) iff >= 0, or |NEGATIVE| -// (major type 1) iff < 0. -void EncodeInt32(int32_t value, std::vector<uint8_t>* out); - -// Encodes a UTF16 string as a BYTE_STRING (major type 2). Each utf16 -// character in |in| is emitted with most significant byte first, -// appending to |out|. -void EncodeString16(span<uint16_t> in, std::vector<uint8_t>* out); - -// Encodes a UTF8 string |in| as STRING (major type 3). -void EncodeString8(span<uint8_t> in, std::vector<uint8_t>* out); - -// Encodes the given |latin1| string as STRING8. -// If any non-ASCII character is present, it will be represented -// as a 2 byte UTF8 sequence. -void EncodeFromLatin1(span<uint8_t> latin1, std::vector<uint8_t>* out); - -// Encodes the given |utf16| string as STRING8 if it's entirely US-ASCII. -// Otherwise, encodes as STRING16. -void EncodeFromUTF16(span<uint16_t> utf16, std::vector<uint8_t>* out); - -// Encodes arbitrary binary data in |in| as a BYTE_STRING (major type 2) with -// definitive length, prefixed with tag 22 indicating expected conversion to -// base64 (see RFC 7049, Table 3 and Section 2.4.4.2). -void EncodeBinary(span<uint8_t> in, std::vector<uint8_t>* out); - -// Encodes / decodes a double as Major type 7 (SIMPLE_VALUE), -// with additional info = 27, followed by 8 bytes in big endian. -void EncodeDouble(double value, std::vector<uint8_t>* out); - -// Some constants for CBOR tokens that only take a single byte on the wire. -uint8_t EncodeTrue(); -uint8_t EncodeFalse(); -uint8_t EncodeNull(); -uint8_t EncodeIndefiniteLengthArrayStart(); -uint8_t EncodeIndefiniteLengthMapStart(); -uint8_t EncodeStop(); - -// An envelope indicates the byte length of a wrapped item. -// We use this for maps and array, which allows the decoder -// to skip such (nested) values whole sale. -// It's implemented as a CBOR tag (major type 6) with additional -// info = 24, followed by a byte string with a 32 bit length value; -// so the maximal structure that we can wrap is 2^32 bits long. -// See also: https://tools.ietf.org/html/rfc7049#section-2.4.4.1 -class EnvelopeEncoder { - public: - // Emits the envelope start bytes and records the position for the - // byte size in |byte_size_pos_|. Also emits empty bytes for the - // byte sisze so that encoding can continue. - void EncodeStart(std::vector<uint8_t>* out); - // This records the current size in |out| at position byte_size_pos_. - // Returns true iff successful. - bool EncodeStop(std::vector<uint8_t>* out); - - private: - std::size_t byte_size_pos_ = 0; -}; - -// This can be used to convert from JSON to CBOR, by passing the -// return value to the routines in json_parser.h. The handler will encode into -// |out|, and iff an error occurs it will set |status| to an error and clear -// |out|. Otherwise, |status.ok()| will be |true|. -std::unique_ptr<JSONParserHandler> NewJSONToCBOREncoder( - std::vector<uint8_t>* out, Status* status); - -// Parses a CBOR encoded message from |bytes|, sending JSON events to -// |json_out|. If an error occurs, sends |out->HandleError|, and parsing stops. -// The client is responsible for discarding the already received information in -// that case. -void ParseCBOR(span<uint8_t> bytes, JSONParserHandler* json_out); - -// Tags for the tokens within a CBOR message that CBORStream understands. -// Note that this is not the same terminology as the CBOR spec (RFC 7049), -// but rather, our adaptation. For instance, we lump unsigned and signed -// major type into INT32 here (and disallow values outside the int32_t range). -enum class CBORTokenTag { - // Encountered an error in the structure of the message. Consult - // status() for details. - ERROR_VALUE, - // Booleans and NULL. - TRUE_VALUE, - FALSE_VALUE, - NULL_VALUE, - // An int32_t (signed 32 bit integer). - INT32, - // A double (64 bit floating point). - DOUBLE, - // A UTF8 string. - STRING8, - // A UTF16 string. - STRING16, - // A binary string. - BINARY, - // Starts an indefinite length map; after the map start we expect - // alternating keys and values, followed by STOP. - MAP_START, - // Starts an indefinite length array; after the array start we - // expect values, followed by STOP. - ARRAY_START, - // Ends a map or an array. - STOP, - // An envelope indicator, wrapping a map or array. - // Internally this carries the byte length of the wrapped - // map or array. While CBORTokenizer::Next() will read / skip the entire - // envelope, CBORTokenizer::EnterEnvelope() reads the tokens - // inside of it. - ENVELOPE, - // We've reached the end there is nothing else to read. - DONE, -}; - -// CBORTokenizer segments a CBOR message, presenting the tokens therein as -// numbers, strings, etc. This is not a complete CBOR parser, but makes it much -// easier to implement one (e.g. ParseCBOR, above). It can also be used to parse -// messages partially. -class CBORTokenizer { - public: - explicit CBORTokenizer(span<uint8_t> bytes); - ~CBORTokenizer(); - - // Identifies the current token that we're looking at, - // or ERROR_VALUE (in which ase ::Status() has details) - // or DONE (if we're past the last token). - CBORTokenTag TokenTag() const; - - // Advances to the next token. - void Next(); - // Can only be called if TokenTag() == CBORTokenTag::ENVELOPE. - // While Next() would skip past the entire envelope / what it's - // wrapping, EnterEnvelope positions the cursor inside of the envelope, - // letting the client explore the nested structure. - void EnterEnvelope(); - - // If TokenTag() is CBORTokenTag::ERROR_VALUE, then Status().error describes - // the error more precisely; otherwise it'll be set to Error::OK. - // In either case, Status().pos is the current position. - struct Status Status() const; - - // The following methods retrieve the token values. They can only - // be called if TokenTag() matches. - - // To be called only if ::TokenTag() == CBORTokenTag::INT32. - int32_t GetInt32() const; - - // To be called only if ::TokenTag() == CBORTokenTag::DOUBLE. - double GetDouble() const; - - // To be called only if ::TokenTag() == CBORTokenTag::STRING8. - span<uint8_t> GetString8() const; - - // Wire representation for STRING16 is low byte first (little endian). - // To be called only if ::TokenTag() == CBORTokenTag::STRING16. - span<uint8_t> GetString16WireRep() const; - - // To be called only if ::TokenTag() == CBORTokenTag::BINARY. - span<uint8_t> GetBinary() const; - - private: - void ReadNextToken(bool enter_envelope); - void SetToken(CBORTokenTag token, std::ptrdiff_t token_byte_length); - void SetError(Error error); - - span<uint8_t> bytes_; - CBORTokenTag token_tag_; - struct Status status_; - std::ptrdiff_t token_byte_length_; - cbor::MajorType token_start_type_; - uint64_t token_start_internal_value_; -}; - -void DumpCBOR(span<uint8_t> cbor); - -} // namespace inspector_protocol -#endif // INSPECTOR_PROTOCOL_ENCODING_CBOR_H_
diff --git a/third_party/inspector_protocol/encoding/cbor_internals.h b/third_party/inspector_protocol/encoding/cbor_internals.h deleted file mode 100644 index e2621d89..0000000 --- a/third_party/inspector_protocol/encoding/cbor_internals.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef INSPECTOR_PROTOCOL_ENCODING_CBOR_INTERNALS_H_ -#define INSPECTOR_PROTOCOL_ENCODING_CBOR_INTERNALS_H_ - -#include <cstdint> -#include <vector> -#include "span.h" -#include "status.h" - -// These internals are exposed for testing and implementing cbor.h. -// Never directly depend on them from other production code. -namespace inspector_protocol { -namespace cbor { -enum class MajorType; -} - -namespace cbor_internals { - -// Reads the start of a token with definitive size from |bytes|. -// |type| is the major type as specified in RFC 7049 Section 2.1. -// |value| is the payload (e.g. for MajorType::UNSIGNED) or is the size -// (e.g. for BYTE_STRING). -// If successful, returns the number of bytes read. Otherwise returns -1. -int8_t ReadTokenStart(span<uint8_t> bytes, - cbor::MajorType* type, - uint64_t* value); - -// Writes the start of a token with |type|. The |value| may indicate the size, -// or it may be the payload if the value is an unsigned integer. -void WriteTokenStart(cbor::MajorType type, - uint64_t value, - std::vector<uint8_t>* encoded); -} // namespace cbor_internals -} // namespace inspector_protocol - -#endif // INSPECTOR_PROTOCOL_ENCODING_CBOR_H_
diff --git a/third_party/inspector_protocol/encoding/cbor_test.cc b/third_party/inspector_protocol/encoding/cbor_test.cc deleted file mode 100644 index 9f6201f..0000000 --- a/third_party/inspector_protocol/encoding/cbor_test.cc +++ /dev/null
@@ -1,994 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "cbor.h" - -#include <array> -#include <cmath> -#include <string> -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "json_parser.h" -#include "json_std_string_writer.h" -#include "linux_dev_platform.h" - -using testing::ElementsAreArray; - -namespace inspector_protocol { - -using cbor::MajorType; - -// -// EncodeInt32 / CBORTokenTag::INT32 -// -TEST(EncodeDecodeInt32Test, Roundtrips23) { - // This roundtrips the int32_t value 23 through the pair of EncodeInt32 / - // CBORTokenizer; this is interesting since 23 is encoded as a single byte. - std::vector<uint8_t> encoded; - EncodeInt32(23, &encoded); - // first three bits: major type = 0; remaining five bits: additional info = - // value 23. - EXPECT_THAT(encoded, ElementsAreArray(std::array<uint8_t, 1>{{23}})); - - // Reverse direction: decode with CBORTokenizer. - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag()); - EXPECT_EQ(23, tokenizer.GetInt32()); - tokenizer.Next(); - EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); -} - -TEST(EncodeDecodeInt32Test, RoundtripsUint8) { - // This roundtrips the int32_t value 42 through the pair of EncodeInt32 / - // CBORTokenizer. This is different from Roundtrip23 because 42 is encoded - // in an extra byte after the initial one. - std::vector<uint8_t> encoded; - EncodeInt32(42, &encoded); - // first three bits: major type = 0; - // remaining five bits: additional info = 24, indicating payload is uint8. - EXPECT_THAT(encoded, ElementsAreArray(std::array<uint8_t, 2>{{24, 42}})); - - // Reverse direction: decode with CBORTokenizer. - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag()); - EXPECT_EQ(42, tokenizer.GetInt32()); - tokenizer.Next(); - EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); -} - -TEST(EncodeDecodeInt32Test, RoundtripsUint16) { - // 500 is encoded as a uint16 after the initial byte. - std::vector<uint8_t> encoded; - EncodeInt32(500, &encoded); - // 1 for initial byte, 2 for uint16. - EXPECT_EQ(static_cast<std::size_t>(3), encoded.size()); - // first three bits: major type = 0; - // remaining five bits: additional info = 25, indicating payload is uint16. - EXPECT_EQ(25, encoded[0]); - EXPECT_EQ(0x01, encoded[1]); - EXPECT_EQ(0xf4, encoded[2]); - - // Reverse direction: decode with CBORTokenizer. - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag()); - EXPECT_EQ(500, tokenizer.GetInt32()); - tokenizer.Next(); - EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); -} - -TEST(EncodeDecodeInt32Test, RoundtripsInt32Max) { - // std::numeric_limits<int32_t> is encoded as a uint32 after the initial byte. - std::vector<uint8_t> encoded; - EncodeInt32(std::numeric_limits<int32_t>::max(), &encoded); - // 1 for initial byte, 4 for the uint32. - // first three bits: major type = 0; - // remaining five bits: additional info = 26, indicating payload is uint32. - EXPECT_THAT( - encoded, - ElementsAreArray(std::array<uint8_t, 5>{{26, 0x7f, 0xff, 0xff, 0xff}})); - - // Reverse direction: decode with CBORTokenizer. - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag()); - EXPECT_EQ(std::numeric_limits<int32_t>::max(), tokenizer.GetInt32()); - tokenizer.Next(); - EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); -} - -TEST(EncodeDecodeInt32Test, CantRoundtripUint32) { - // 0xdeadbeef is a value which does not fit below - // std::numerical_limits<int32_t>::max(), so we can't encode - // it with EncodeInt32. However, CBOR does support this, so we - // encode it here manually with the internal routine, just to observe - // that it's considered an invalid int32 by CBORTokenizer. - std::vector<uint8_t> encoded; - cbor_internals::WriteTokenStart(MajorType::UNSIGNED, 0xdeadbeef, &encoded); - // 1 for initial byte, 4 for the uint32. - // first three bits: major type = 0; - // remaining five bits: additional info = 26, indicating payload is uint32. - EXPECT_THAT( - encoded, - ElementsAreArray(std::array<uint8_t, 5>{{26, 0xde, 0xad, 0xbe, 0xef}})); - - // Now try to decode; we treat this as an invalid INT32. - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - // 0xdeadbeef is > std::numerical_limits<int32_t>::max(). - EXPECT_EQ(CBORTokenTag::ERROR_VALUE, tokenizer.TokenTag()); - EXPECT_EQ(Error::CBOR_INVALID_INT32, tokenizer.Status().error); -} - -TEST(EncodeDecodeInt32Test, DecodeErrorCases) { - struct TestCase { - std::vector<uint8_t> data; - std::string msg; - }; - std::vector<TestCase> tests{ - {TestCase{ - {24}, - "additional info = 24 would require 1 byte of payload (but it's 0)"}, - TestCase{{27, 0xaa, 0xbb, 0xcc}, - "additional info = 27 would require 8 bytes of payload (but " - "it's 3)"}, - TestCase{{29}, "additional info = 29 isn't recognized"}}}; - - for (const TestCase& test : tests) { - SCOPED_TRACE(test.msg); - span<uint8_t> encoded_bytes(&test.data[0], test.data.size()); - CBORTokenizer tokenizer( - span<uint8_t>(&encoded_bytes[0], encoded_bytes.size())); - EXPECT_EQ(CBORTokenTag::ERROR_VALUE, tokenizer.TokenTag()); - EXPECT_EQ(Error::CBOR_INVALID_INT32, tokenizer.Status().error); - } -} - -TEST(EncodeDecodeInt32Test, RoundtripsMinus24) { - // This roundtrips the int32_t value -24 through the pair of EncodeInt32 / - // CBORTokenizer; this is interesting since -24 is encoded as - // a single byte as NEGATIVE, and it tests the specific encoding - // (note how for unsigned the single byte covers values up to 23). - // Additional examples are covered in RoundtripsAdditionalExamples. - std::vector<uint8_t> encoded; - EncodeInt32(-24, &encoded); - // first three bits: major type = 1; remaining five bits: additional info = - // value 23. - EXPECT_THAT(encoded, ElementsAreArray(std::array<uint8_t, 1>{{1 << 5 | 23}})); - - // Reverse direction: decode with CBORTokenizer. - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag()); - EXPECT_EQ(-24, tokenizer.GetInt32()); - tokenizer.Next(); - EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); -} - -TEST(EncodeDecodeInt32Test, RoundtripsAdditionalNegativeExamples) { - std::vector<int32_t> examples = {-1, - -10, - -24, - -25, - -300, - -30000, - -300 * 1000, - -1000 * 1000, - -1000 * 1000 * 1000, - std::numeric_limits<int32_t>::min()}; - for (int32_t example : examples) { - SCOPED_TRACE(base::StringPrintf("example %d", example)); - std::vector<uint8_t> encoded; - EncodeInt32(example, &encoded); - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag()); - EXPECT_EQ(example, tokenizer.GetInt32()); - tokenizer.Next(); - EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); - } -} - -// -// EncodeString16 / CBORTokenTag::STRING16 -// -TEST(EncodeDecodeString16Test, RoundtripsEmpty) { - // This roundtrips the empty utf16 string through the pair of EncodeString16 / - // CBORTokenizer. - std::vector<uint8_t> encoded; - EncodeString16(span<uint16_t>(), &encoded); - EXPECT_EQ(static_cast<std::size_t>(1), encoded.size()); - // first three bits: major type = 2; remaining five bits: additional info = - // size 0. - EXPECT_EQ(2 << 5, encoded[0]); - - // Reverse direction: decode with CBORTokenizer. - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::STRING16, tokenizer.TokenTag()); - span<uint8_t> decoded_string16_wirerep = tokenizer.GetString16WireRep(); - EXPECT_TRUE(decoded_string16_wirerep.empty()); - tokenizer.Next(); - EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); -} - -// On the wire, we STRING16 is encoded as little endian (least -// significant byte first). The host may or may not be little endian, -// so this routine follows the advice in -// https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html. -std::vector<uint16_t> String16WireRepToHost(span<uint8_t> in) { - assert((in.size() & 1) == 0); // must be even number of bytes. - std::vector<uint16_t> host_out; - for (std::ptrdiff_t ii = 0; ii < in.size(); ii += 2) - host_out.push_back(in[ii + 1] << 8 | in[ii]); - return host_out; -} - -TEST(EncodeDecodeString16Test, RoundtripsHelloWorld) { - // This roundtrips the hello world message which is given here in utf16 - // characters. 0xd83c, 0xdf0e: UTF16 encoding for the "Earth Globe Americas" - // character, 🌎. - std::array<uint16_t, 10> msg{ - {'H', 'e', 'l', 'l', 'o', ',', ' ', 0xd83c, 0xdf0e, '.'}}; - std::vector<uint8_t> encoded; - EncodeString16(span<uint16_t>(msg.data(), msg.size()), &encoded); - // This will be encoded as BYTE_STRING of length 20, so the 20 is encoded in - // the additional info part of the initial byte. Payload is two bytes for each - // UTF16 character. - uint8_t initial_byte = /*major type=*/2 << 5 | /*additional info=*/20; - std::array<uint8_t, 21> encoded_expected = { - {initial_byte, 'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o', 0, - ',', 0, ' ', 0, 0x3c, 0xd8, 0x0e, 0xdf, '.', 0}}; - EXPECT_THAT(encoded, ElementsAreArray(encoded_expected)); - - // Now decode to complete the roundtrip. - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::STRING16, tokenizer.TokenTag()); - std::vector<uint16_t> decoded = - String16WireRepToHost(tokenizer.GetString16WireRep()); - EXPECT_THAT(decoded, ElementsAreArray(msg)); - tokenizer.Next(); - EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); - - // For bonus points, we look at the decoded message in UTF8 as well so we can - // easily see it on the terminal screen. - std::string utf8_decoded = - base::UTF16ToUTF8(base::StringPiece16(decoded.data(), decoded.size())); - EXPECT_EQ("Hello, 🌎.", utf8_decoded); -} - -TEST(EncodeDecodeString16Test, Roundtrips500) { - // We roundtrip a message that has 250 16 bit values. Each of these are just - // set to their index. 250 is interesting because the cbor spec uses a - // BYTE_STRING of length 500 for one of their examples of how to encode the - // start of it (section 2.1) so it's easy for us to look at the first three - // bytes closely. - std::vector<uint16_t> two_fifty; - for (uint16_t ii = 0; ii < 250; ++ii) two_fifty.push_back(ii); - std::vector<uint8_t> encoded; - EncodeString16(span<uint16_t>(two_fifty.data(), two_fifty.size()), &encoded); - EXPECT_EQ(static_cast<std::size_t>(3 + 250 * 2), encoded.size()); - // Now check the first three bytes: - // Major type: 2 (BYTE_STRING) - // Additional information: 25, indicating size is represented by 2 bytes. - // Bytes 1 and 2 encode 500 (0x01f4). - EXPECT_EQ(2 << 5 | 25, encoded[0]); - EXPECT_EQ(0x01, encoded[1]); - EXPECT_EQ(0xf4, encoded[2]); - - // Now decode to complete the roundtrip. - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::STRING16, tokenizer.TokenTag()); - std::vector<uint16_t> decoded = - String16WireRepToHost(tokenizer.GetString16WireRep()); - EXPECT_THAT(decoded, ElementsAreArray(two_fifty)); - tokenizer.Next(); - EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); -} - -TEST(EncodeDecodeString16Test, ErrorCases) { - struct TestCase { - std::vector<uint8_t> data; - std::string msg; - }; - std::vector<TestCase> tests{ - {TestCase{{2 << 5 | 1, 'a'}, - "length must be divisible by 2 (but it's 1)"}, - TestCase{{2 << 5 | 29}, "additional info = 29 isn't recognized"}}}; - for (const TestCase& test : tests) { - SCOPED_TRACE(test.msg); - CBORTokenizer tokenizer(span<uint8_t>(&test.data[0], test.data.size())); - EXPECT_EQ(CBORTokenTag::ERROR_VALUE, tokenizer.TokenTag()); - EXPECT_EQ(Error::CBOR_INVALID_STRING16, tokenizer.Status().error); - } -} - -// -// EncodeString8 / CBORTokenTag::STRING8 -// -TEST(EncodeDecodeString8Test, RoundtripsHelloWorld) { - // This roundtrips the hello world message which is given here in utf8 - // characters. 🌎 is a four byte utf8 character. - std::string utf8_msg = "Hello, 🌎."; - std::vector<uint8_t> msg(utf8_msg.begin(), utf8_msg.end()); - std::vector<uint8_t> encoded; - EncodeString8(span<uint8_t>(msg.data(), msg.size()), &encoded); - // This will be encoded as STRING of length 12, so the 12 is encoded in - // the additional info part of the initial byte. Payload is one byte per - // utf8 byte. - uint8_t initial_byte = /*major type=*/3 << 5 | /*additional info=*/12; - std::array<uint8_t, 13> encoded_expected = {{initial_byte, 'H', 'e', 'l', 'l', - 'o', ',', ' ', 0xF0, 0x9f, 0x8c, - 0x8e, '.'}}; - EXPECT_THAT(encoded, ElementsAreArray(encoded_expected)); - - // Now decode to complete the roundtrip. - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::STRING8, tokenizer.TokenTag()); - std::vector<uint8_t> decoded(tokenizer.GetString8().begin(), - tokenizer.GetString8().end()); - EXPECT_THAT(decoded, ElementsAreArray(msg)); - tokenizer.Next(); - EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); -} - -TEST(EncodeFromLatin1Test, ConvertsToUTF8IfNeeded) { - std::vector<std::pair<std::string, std::string>> examples = { - {"Hello, world.", "Hello, world."}, - {"Above: \xDC" - "ber", - "Above: Über"}, - {"\xA5 500 are about \xA3 3.50; a y with umlaut is \xFF", - "¥ 500 are about £ 3.50; a y with umlaut is ÿ"}}; - - for (const auto& example : examples) { - const std::string& latin1 = example.first; - const std::string& expected_utf8 = example.second; - std::vector<uint8_t> encoded; - EncodeFromLatin1( - span<uint8_t>(reinterpret_cast<const uint8_t*>(latin1.data()), - latin1.size()), - &encoded); - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::STRING8, tokenizer.TokenTag()); - std::vector<uint8_t> decoded(tokenizer.GetString8().begin(), - tokenizer.GetString8().end()); - std::string decoded_str(decoded.begin(), decoded.end()); - EXPECT_THAT(decoded_str, testing::Eq(expected_utf8)); - } -} - -TEST(EncodeFromUTF16Test, ConvertsToUTF8IfEasy) { - std::vector<uint16_t> ascii = {'e', 'a', 's', 'y'}; - std::vector<uint8_t> encoded; - EncodeFromUTF16(span<uint16_t>(ascii.data(), ascii.size()), &encoded); - - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::STRING8, tokenizer.TokenTag()); - std::vector<uint8_t> decoded(tokenizer.GetString8().begin(), - tokenizer.GetString8().end()); - std::string decoded_str(decoded.begin(), decoded.end()); - EXPECT_THAT(decoded_str, testing::Eq("easy")); -} - -TEST(EncodeFromUTF16Test, EncodesAsString16IfNeeded) { - // Since this message contains non-ASCII characters, the routine is - // forced to encode as UTF16. We see this below by checking that the - // token tag is STRING16. - std::vector<uint16_t> msg = {'H', 'e', 'l', 'l', 'o', - ',', ' ', 0xd83c, 0xdf0e, '.'}; - std::vector<uint8_t> encoded; - EncodeFromUTF16(span<uint16_t>(msg.data(), msg.size()), &encoded); - - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::STRING16, tokenizer.TokenTag()); - std::vector<uint16_t> decoded = - String16WireRepToHost(tokenizer.GetString16WireRep()); - std::string utf8_decoded = - base::UTF16ToUTF8(base::StringPiece16(decoded.data(), decoded.size())); - EXPECT_EQ("Hello, 🌎.", utf8_decoded); -} - -// -// EncodeBinary / CBORTokenTag::BINARY -// -TEST(EncodeDecodeBinaryTest, RoundtripsHelloWorld) { - std::vector<uint8_t> binary = {'H', 'e', 'l', 'l', 'o', ',', ' ', - 'w', 'o', 'r', 'l', 'd', '.'}; - std::vector<uint8_t> encoded; - EncodeBinary(span<uint8_t>(binary.data(), binary.size()), &encoded); - // So, on the wire we see that the binary blob travels unmodified. - EXPECT_THAT( - encoded, - ElementsAreArray(std::array<uint8_t, 15>{ - {(6 << 5 | 22), // tag 22 indicating base64 interpretation in JSON - (2 << 5 | 13), // BYTE_STRING (type 2) of length 13 - 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '.'}})); - std::vector<uint8_t> decoded; - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::BINARY, tokenizer.TokenTag()); - EXPECT_EQ(0, int(tokenizer.Status().error)); - decoded = std::vector<uint8_t>(tokenizer.GetBinary().begin(), - tokenizer.GetBinary().end()); - EXPECT_THAT(decoded, ElementsAreArray(binary)); - tokenizer.Next(); - EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); -} - -// -// EncodeDouble / CBORTokenTag::DOUBLE -// -TEST(EncodeDecodeDoubleTest, RoundtripsWikipediaExample) { - // https://en.wikipedia.org/wiki/Double-precision_floating-point_format - // provides the example of a hex representation 3FD5 5555 5555 5555, which - // approximates 1/3. - - const double kOriginalValue = 1.0 / 3; - std::vector<uint8_t> encoded; - EncodeDouble(kOriginalValue, &encoded); - // first three bits: major type = 7; remaining five bits: additional info = - // value 27. This is followed by 8 bytes of payload (which match Wikipedia). - EXPECT_THAT( - encoded, - ElementsAreArray(std::array<uint8_t, 9>{ - {7 << 5 | 27, 0x3f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55}})); - - // Reverse direction: decode and compare with original value. - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::DOUBLE, tokenizer.TokenTag()); - EXPECT_THAT(tokenizer.GetDouble(), testing::DoubleEq(kOriginalValue)); - tokenizer.Next(); - EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); -} - -TEST(EncodeDecodeDoubleTest, RoundtripsAdditionalExamples) { - std::vector<double> examples = {0.0, - 1.0, - -1.0, - 3.1415, - std::numeric_limits<double>::min(), - std::numeric_limits<double>::max(), - std::numeric_limits<double>::infinity(), - std::numeric_limits<double>::quiet_NaN()}; - for (double example : examples) { - SCOPED_TRACE(base::StringPrintf("example %lf", example)); - std::vector<uint8_t> encoded; - EncodeDouble(example, &encoded); - span<uint8_t> encoded_bytes(&encoded[0], encoded.size()); - CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size())); - EXPECT_EQ(CBORTokenTag::DOUBLE, tokenizer.TokenTag()); - if (std::isnan(example)) - EXPECT_TRUE(std::isnan(tokenizer.GetDouble())); - else - EXPECT_THAT(tokenizer.GetDouble(), testing::DoubleEq(example)); - tokenizer.Next(); - EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); - } -} - -// -// NewJSONToCBOREncoder -// -void EncodeUTF8ForTest(const std::string& key, std::vector<uint8_t>* out) { - EncodeString8( - span<uint8_t>(reinterpret_cast<const uint8_t*>(key.data()), key.size()), - out); -} - -TEST(JSONToCBOREncoderTest, SevenBitStrings) { - // When a string can be represented as 7 bit ASCII, the encoder will use the - // STRING (major Type 3) type, so the actual characters end up as bytes on the - // wire. - std::vector<uint8_t> encoded; - Status status; - std::unique_ptr<JSONParserHandler> encoder = - NewJSONToCBOREncoder(&encoded, &status); - std::vector<uint16_t> utf16 = {'f', 'o', 'o'}; - encoder->HandleString16(span<uint16_t>(utf16.data(), utf16.size())); - EXPECT_EQ(Error::OK, status.error); - // Here we assert that indeed, seven bit strings are represented as - // bytes on the wire, "foo" is just "foo". - EXPECT_THAT(encoded, - ElementsAreArray(std::array<uint8_t, 4>{ - {/*major type 3*/ 3 << 5 | /*length*/ 3, 'f', 'o', 'o'}})); -} - -TEST(JsonCborRoundtrip, EncodingDecoding) { - // Hits all the cases except binary and error in JSONParserHandler, first - // parsing a JSON message into CBOR, then parsing it back from CBOR into JSON. - std::string json = - "{" - "\"string\":\"Hello, \\ud83c\\udf0e.\"," - "\"double\":3.1415," - "\"int\":1," - "\"negative int\":-1," - "\"bool\":true," - "\"null\":null," - "\"array\":[1,2,3]" - "}"; - std::vector<uint8_t> encoded; - Status status; - std::unique_ptr<JSONParserHandler> encoder = - NewJSONToCBOREncoder(&encoded, &status); - span<uint8_t> ascii_in(reinterpret_cast<const uint8_t*>(json.data()), - json.size()); - ParseJSONChars(GetLinuxDevPlatform(), ascii_in, encoder.get()); - std::vector<uint8_t> expected = { - 0xd8, // envelope - 0x5a, // byte string with 32 bit length - 0, 0, 0, 94, // length is 94 bytes - }; - expected.push_back(0xbf); // indef length map start - EncodeUTF8ForTest("string", &expected); - // This is followed by the encoded string for "Hello, 🌎." - // So, it's the same bytes that we tested above in - // EncodeDecodeString16Test.RoundtripsHelloWorld. - expected.push_back(/*major type=*/2 << 5 | /*additional info=*/20); - for (uint8_t ch : std::array<uint8_t, 20>{ - {'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o', 0, - ',', 0, ' ', 0, 0x3c, 0xd8, 0x0e, 0xdf, '.', 0}}) - expected.push_back(ch); - EncodeUTF8ForTest("double", &expected); - EncodeDouble(3.1415, &expected); - EncodeUTF8ForTest("int", &expected); - EncodeInt32(1, &expected); - EncodeUTF8ForTest("negative int", &expected); - EncodeInt32(-1, &expected); - EncodeUTF8ForTest("bool", &expected); - expected.push_back(7 << 5 | 21); // RFC 7049 Section 2.3, Table 2: true - EncodeUTF8ForTest("null", &expected); - expected.push_back(7 << 5 | 22); // RFC 7049 Section 2.3, Table 2: null - EncodeUTF8ForTest("array", &expected); - expected.push_back(0xd8); // envelope - expected.push_back(0x5a); // byte string with 32 bit length - // the length is 5 bytes (that's up to end indef length array below). - for (uint8_t ch : std::array<uint8_t, 4>{{0, 0, 0, 5}}) - expected.push_back(ch); - expected.push_back(0x9f); // RFC 7049 Section 2.2.1, indef length array start - expected.push_back(1); // Three UNSIGNED values (easy since Major Type 0) - expected.push_back(2); - expected.push_back(3); - expected.push_back(0xff); // End indef length array - expected.push_back(0xff); // End indef length map - EXPECT_TRUE(status.ok()); - EXPECT_THAT(encoded, ElementsAreArray(expected)); - - // And now we roundtrip, decoding the message we just encoded. - std::string decoded; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &decoded, &status); - ParseCBOR(span<uint8_t>(encoded.data(), encoded.size()), json_writer.get()); - EXPECT_EQ(Error::OK, status.error); - EXPECT_EQ(json, decoded); -} - -TEST(JsonCborRoundtrip, MoreRoundtripExamples) { - std::vector<std::string> examples = { - // Tests that after closing a nested objects, additional key/value pairs - // are considered. - "{\"foo\":{\"bar\":1},\"baz\":2}", "{\"foo\":[1,2,3],\"baz\":2}"}; - for (const std::string& json : examples) { - SCOPED_TRACE(std::string("example: ") + json); - std::vector<uint8_t> encoded; - Status status; - std::unique_ptr<JSONParserHandler> encoder = - NewJSONToCBOREncoder(&encoded, &status); - span<uint8_t> ascii_in(reinterpret_cast<const uint8_t*>(json.data()), - json.size()); - ParseJSONChars(GetLinuxDevPlatform(), ascii_in, encoder.get()); - std::string decoded; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &decoded, &status); - ParseCBOR(span<uint8_t>(encoded.data(), encoded.size()), json_writer.get()); - EXPECT_EQ(Error::OK, status.error); - EXPECT_EQ(json, decoded); - } -} - -TEST(JSONToCBOREncoderTest, HelloWorldBinary_WithTripToJson) { - // The JSONParserHandler::HandleBinary is a special case: The JSON parser will - // never call this method, because JSON does not natively support the binary - // type. So, we can't fully roundtrip. However, the other direction works: - // binary will be rendered in JSON, as a base64 string. So, we make calls to - // the encoder directly here, to construct a message, and one of these calls - // is ::HandleBinary, to which we pass a "binary" string containing "Hello, - // world.". - std::vector<uint8_t> encoded; - Status status; - std::unique_ptr<JSONParserHandler> encoder = - NewJSONToCBOREncoder(&encoded, &status); - encoder->HandleObjectBegin(); - // Emit a key. - std::vector<uint16_t> key = {'f', 'o', 'o'}; - encoder->HandleString16(span<uint16_t>(key.data(), key.size())); - // Emit the binary payload, an arbitrary array of bytes that happens to - // be the ascii message "Hello, world.". - encoder->HandleBinary(std::vector<uint8_t>{'H', 'e', 'l', 'l', 'o', ',', ' ', - 'w', 'o', 'r', 'l', 'd', '.'}); - encoder->HandleObjectEnd(); - EXPECT_EQ(Error::OK, status.error); - - // Now drive the json writer via the CBOR decoder. - std::string decoded; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &decoded, &status); - ParseCBOR(span<uint8_t>(encoded.data(), encoded.size()), json_writer.get()); - EXPECT_EQ(Error::OK, status.error); - EXPECT_EQ(Status::npos(), status.pos); - // "Hello, world." in base64 is "SGVsbG8sIHdvcmxkLg==". - EXPECT_EQ("{\"foo\":\"SGVsbG8sIHdvcmxkLg==\"}", decoded); -} - -// -// ParseCBOR -// -TEST(ParseCBORTest, ParseEmptyCBORMessage) { - // An envelope starting with 0xd8, 0x5a, with the byte length - // of 2, containing a map that's empty (0xbf for map - // start, and 0xff for map end). - std::vector<uint8_t> in = {0xd8, 0x5a, 0, 0, 0, 2, 0xbf, 0xff}; - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(in.data(), in.size()), json_writer.get()); - EXPECT_EQ(Error::OK, status.error); - EXPECT_EQ("{}", out); -} - -TEST(ParseCBORTest, ParseCBORHelloWorld) { - const uint8_t kPayloadLen = 27; - std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen}; - bytes.push_back(0xbf); // start indef length map. - EncodeUTF8ForTest("msg", &bytes); // key: msg - // Now write the value, the familiar "Hello, 🌎." where the globe is expressed - // as two utf16 chars. - bytes.push_back(/*major type=*/2 << 5 | /*additional info=*/20); - for (uint8_t ch : std::array<uint8_t, 20>{ - {'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o', 0, - ',', 0, ' ', 0, 0x3c, 0xd8, 0x0e, 0xdf, '.', 0}}) - bytes.push_back(ch); - bytes.push_back(0xff); // stop byte - EXPECT_EQ(kPayloadLen, bytes.size() - 6); - - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::OK, status.error); - EXPECT_EQ("{\"msg\":\"Hello, \\ud83c\\udf0e.\"}", out); -} - -TEST(ParseCBORTest, UTF8IsSupportedInKeys) { - const uint8_t kPayloadLen = 11; - std::vector<uint8_t> bytes = {cbor::kInitialByteForEnvelope, - cbor::kInitialByteFor32BitLengthByteString, - 0, - 0, - 0, - kPayloadLen}; - bytes.push_back(cbor::kInitialByteIndefiniteLengthMap); - EncodeUTF8ForTest("🌎", &bytes); // Two UTF16 chars. - EncodeUTF8ForTest("☾", &bytes); // Can be encoded as a single UTF16 char. - bytes.push_back(cbor::kStopByte); - EXPECT_EQ(kPayloadLen, bytes.size() - 6); - - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::OK, status.error); - EXPECT_EQ("{\"\\ud83c\\udf0e\":\"\\u263e\"}", out); -} - -TEST(ParseCBORTest, NoInputError) { - std::vector<uint8_t> in = {}; - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(in.data(), in.size()), json_writer.get()); - EXPECT_EQ(Error::CBOR_NO_INPUT, status.error); - EXPECT_EQ("", out); -} - -TEST(ParseCBORTest, InvalidStartByteError) { - // Here we test that some actual json, which usually starts with {, - // is not considered CBOR. CBOR messages must start with 0x5a, the - // envelope start byte. - std::string json = "{\"msg\": \"Hello, world.\"}"; - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR( - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - json_writer.get()); - EXPECT_EQ(Error::CBOR_INVALID_START_BYTE, status.error); - EXPECT_EQ("", out); -} - -TEST(ParseCBORTest, UnexpectedEofExpectedValueError) { - constexpr uint8_t kPayloadLen = 5; - std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope - 0xbf}; // map start - EncodeUTF8ForTest("key", &bytes); // A key; so value would be next. - EXPECT_EQ(kPayloadLen, bytes.size() - 6); - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE, status.error); - EXPECT_EQ(static_cast<int64_t>(bytes.size()), status.pos); - EXPECT_EQ("", out); -} - -TEST(ParseCBORTest, UnexpectedEofInArrayError) { - constexpr uint8_t kPayloadLen = 8; - std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope - 0xbf}; // The byte for starting a map. - EncodeUTF8ForTest("array", &bytes); // A key; so value would be next. - bytes.push_back(0x9f); // byte for indefinite length array start. - EXPECT_EQ(kPayloadLen, bytes.size() - 6); - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::CBOR_UNEXPECTED_EOF_IN_ARRAY, status.error); - EXPECT_EQ(static_cast<int64_t>(bytes.size()), status.pos); - EXPECT_EQ("", out); -} - -TEST(ParseCBORTest, UnexpectedEofInMapError) { - constexpr uint8_t kPayloadLen = 1; - std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope - 0xbf}; // The byte for starting a map. - EXPECT_EQ(kPayloadLen, bytes.size() - 6); - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::CBOR_UNEXPECTED_EOF_IN_MAP, status.error); - EXPECT_EQ(7, status.pos); - EXPECT_EQ("", out); -} - -TEST(ParseCBORTest, InvalidMapKeyError) { - constexpr uint8_t kPayloadLen = 2; - std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, - 0, 0, kPayloadLen, // envelope - 0xbf, // map start - 7 << 5 | 22}; // null (not a valid map key) - EXPECT_EQ(kPayloadLen, bytes.size() - 6); - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::CBOR_INVALID_MAP_KEY, status.error); - EXPECT_EQ(7, status.pos); - EXPECT_EQ("", out); -} - -std::vector<uint8_t> MakeNestedCBOR(int depth) { - std::vector<uint8_t> bytes; - std::vector<EnvelopeEncoder> envelopes; - for (int ii = 0; ii < depth; ++ii) { - envelopes.emplace_back(); - envelopes.back().EncodeStart(&bytes); - bytes.push_back(0xbf); // indef length map start - EncodeUTF8ForTest("key", &bytes); - } - EncodeUTF8ForTest("innermost_value", &bytes); - for (int ii = 0; ii < depth; ++ii) { - bytes.push_back(0xff); // stop byte, finishes map. - envelopes.back().EncodeStop(&bytes); - envelopes.pop_back(); - } - return bytes; -} - -TEST(ParseCBORTest, StackLimitExceededError) { - { // Depth 3: no stack limit exceeded error and is easy to inspect. - std::vector<uint8_t> bytes = MakeNestedCBOR(3); - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::OK, status.error); - EXPECT_EQ(Status::npos(), status.pos); - EXPECT_EQ("{\"key\":{\"key\":{\"key\":\"innermost_value\"}}}", out); - } - { // Depth 1000: no stack limit exceeded. - std::vector<uint8_t> bytes = MakeNestedCBOR(1000); - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::OK, status.error); - EXPECT_EQ(Status::npos(), status.pos); - } - - // We just want to know the length of one opening map so we can compute - // where the error is encountered. So we look at a small example and find - // the second envelope start. - std::vector<uint8_t> small_example = MakeNestedCBOR(3); - int64_t opening_segment_size = 1; // Start after the first envelope start. - while (opening_segment_size < static_cast<int64_t>(small_example.size()) && - small_example[opening_segment_size] != 0xd8) - opening_segment_size++; - - { // Depth 1001: limit exceeded. - std::vector<uint8_t> bytes = MakeNestedCBOR(1001); - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::CBOR_STACK_LIMIT_EXCEEDED, status.error); - EXPECT_EQ(opening_segment_size * 1001, status.pos); - } - { // Depth 1200: still limit exceeded, and at the same pos as for 1001 - std::vector<uint8_t> bytes = MakeNestedCBOR(1200); - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::CBOR_STACK_LIMIT_EXCEEDED, status.error); - EXPECT_EQ(opening_segment_size * 1001, status.pos); - } -} - -TEST(ParseCBORTest, UnsupportedValueError) { - constexpr uint8_t kPayloadLen = 6; - std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope - 0xbf}; // map start - EncodeUTF8ForTest("key", &bytes); - int64_t error_pos = bytes.size(); - bytes.push_back(6 << 5 | 5); // tags aren't supported yet. - EXPECT_EQ(kPayloadLen, bytes.size() - 6); - - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::CBOR_UNSUPPORTED_VALUE, status.error); - EXPECT_EQ(error_pos, status.pos); - EXPECT_EQ("", out); -} - -TEST(ParseCBORTest, InvalidString16Error) { - constexpr uint8_t kPayloadLen = 11; - std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope - 0xbf}; // map start - EncodeUTF8ForTest("key", &bytes); - int64_t error_pos = bytes.size(); - // a BYTE_STRING of length 5 as value; since we interpret these as string16, - // it's going to be invalid as each character would need two bytes, but - // 5 isn't divisible by 2. - bytes.push_back(2 << 5 | 5); - for (int ii = 0; ii < 5; ++ii) bytes.push_back(' '); - EXPECT_EQ(kPayloadLen, bytes.size() - 6); - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::CBOR_INVALID_STRING16, status.error); - EXPECT_EQ(error_pos, status.pos); - EXPECT_EQ("", out); -} - -TEST(ParseCBORTest, InvalidString8Error) { - constexpr uint8_t kPayloadLen = 6; - std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope - 0xbf}; // map start - EncodeUTF8ForTest("key", &bytes); - int64_t error_pos = bytes.size(); - // a STRING of length 5 as value, but we're at the end of the bytes array - // so it can't be decoded successfully. - bytes.push_back(3 << 5 | 5); - EXPECT_EQ(kPayloadLen, bytes.size() - 6); - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::CBOR_INVALID_STRING8, status.error); - EXPECT_EQ(error_pos, status.pos); - EXPECT_EQ("", out); -} - -TEST(ParseCBORTest, InvalidBinaryError) { - constexpr uint8_t kPayloadLen = 9; - std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope - 0xbf}; // map start - EncodeUTF8ForTest("key", &bytes); - int64_t error_pos = bytes.size(); - bytes.push_back(6 << 5 | 22); // base64 hint for JSON; indicates binary - bytes.push_back(2 << 5 | 10); // BYTE_STRING (major type 2) of length 10 - // Just two garbage bytes, not enough for the binary. - bytes.push_back(0x31); - bytes.push_back(0x23); - EXPECT_EQ(kPayloadLen, bytes.size() - 6); - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::CBOR_INVALID_BINARY, status.error); - EXPECT_EQ(error_pos, status.pos); - EXPECT_EQ("", out); -} - -TEST(ParseCBORTest, InvalidDoubleError) { - constexpr uint8_t kPayloadLen = 8; - std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope - 0xbf}; // map start - EncodeUTF8ForTest("key", &bytes); - int64_t error_pos = bytes.size(); - bytes.push_back(7 << 5 | 27); // initial byte for double - // Just two garbage bytes, not enough to represent an actual double. - bytes.push_back(0x31); - bytes.push_back(0x23); - EXPECT_EQ(kPayloadLen, bytes.size() - 6); - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::CBOR_INVALID_DOUBLE, status.error); - EXPECT_EQ(error_pos, status.pos); - EXPECT_EQ("", out); -} - -TEST(ParseCBORTest, InvalidSignedError) { - constexpr uint8_t kPayloadLen = 14; - std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope - 0xbf}; // map start - EncodeUTF8ForTest("key", &bytes); - int64_t error_pos = bytes.size(); - // uint64_t max is a perfectly fine value to encode as CBOR unsigned, - // but we don't support this since we only cover the int32_t range. - cbor_internals::WriteTokenStart(MajorType::UNSIGNED, - std::numeric_limits<uint64_t>::max(), &bytes); - EXPECT_EQ(kPayloadLen, bytes.size() - 6); - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::CBOR_INVALID_INT32, status.error); - EXPECT_EQ(error_pos, status.pos); - EXPECT_EQ("", out); -} - -TEST(ParseCBORTest, TrailingJunk) { - constexpr uint8_t kPayloadLen = 35; - std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope - 0xbf}; // map start - EncodeUTF8ForTest("key", &bytes); - EncodeUTF8ForTest("value", &bytes); - bytes.push_back(0xff); // Up to here, it's a perfectly fine msg. - int64_t error_pos = bytes.size(); - EncodeUTF8ForTest("trailing junk", &bytes); - - cbor_internals::WriteTokenStart(MajorType::UNSIGNED, - std::numeric_limits<uint64_t>::max(), &bytes); - EXPECT_EQ(kPayloadLen, bytes.size() - 6); - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> json_writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); - EXPECT_EQ(Error::CBOR_TRAILING_JUNK, status.error); - EXPECT_EQ(error_pos, status.pos); - EXPECT_EQ("", out); -} -} // namespace inspector_protocol
diff --git a/third_party/inspector_protocol/encoding/encoding.cc b/third_party/inspector_protocol/encoding/encoding.cc new file mode 100644 index 0000000..b02a36a --- /dev/null +++ b/third_party/inspector_protocol/encoding/encoding.cc
@@ -0,0 +1,1796 @@ +// 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 "encoding.h" + +#include <cassert> +#include <cstring> +#include <limits> +#include <stack> + +namespace inspector_protocol_encoding { +namespace cbor { +namespace { +// Indicates the number of bits the "initial byte" needs to be shifted to the +// right after applying |kMajorTypeMask| to produce the major type in the +// lowermost bits. +static constexpr uint8_t kMajorTypeBitShift = 5u; +// Mask selecting the low-order 5 bits of the "initial byte", which is where +// the additional information is encoded. +static constexpr uint8_t kAdditionalInformationMask = 0x1f; +// Mask selecting the high-order 3 bits of the "initial byte", which indicates +// the major type of the encoded value. +static constexpr uint8_t kMajorTypeMask = 0xe0; +// Indicates the integer is in the following byte. +static constexpr uint8_t kAdditionalInformation1Byte = 24u; +// Indicates the integer is in the next 2 bytes. +static constexpr uint8_t kAdditionalInformation2Bytes = 25u; +// Indicates the integer is in the next 4 bytes. +static constexpr uint8_t kAdditionalInformation4Bytes = 26u; +// Indicates the integer is in the next 8 bytes. +static constexpr uint8_t kAdditionalInformation8Bytes = 27u; + +// Encodes the initial byte, consisting of the |type| in the first 3 bits +// followed by 5 bits of |additional_info|. +constexpr uint8_t EncodeInitialByte(MajorType type, uint8_t additional_info) { + return (static_cast<uint8_t>(type) << kMajorTypeBitShift) | + (additional_info & kAdditionalInformationMask); +} + +// TAG 24 indicates that what follows is a byte string which is +// encoded in CBOR format. We use this as a wrapper for +// maps and arrays, allowing us to skip them, because the +// byte string carries its size (byte length). +// https://tools.ietf.org/html/rfc7049#section-2.4.4.1 +static constexpr uint8_t kInitialByteForEnvelope = + EncodeInitialByte(MajorType::TAG, 24); +// The initial byte for a byte string with at most 2^32 bytes +// of payload. This is used for envelope encoding, even if +// the byte string is shorter. +static constexpr uint8_t kInitialByteFor32BitLengthByteString = + EncodeInitialByte(MajorType::BYTE_STRING, 26); + +// See RFC 7049 Section 2.2.1, indefinite length arrays / maps have additional +// info = 31. +static constexpr uint8_t kInitialByteIndefiniteLengthArray = + EncodeInitialByte(MajorType::ARRAY, 31); +static constexpr uint8_t kInitialByteIndefiniteLengthMap = + EncodeInitialByte(MajorType::MAP, 31); +// See RFC 7049 Section 2.3, Table 1; this is used for finishing indefinite +// length maps / arrays. +static constexpr uint8_t kStopByte = + EncodeInitialByte(MajorType::SIMPLE_VALUE, 31); + +// See RFC 7049 Section 2.3, Table 2. +static constexpr uint8_t kEncodedTrue = + EncodeInitialByte(MajorType::SIMPLE_VALUE, 21); +static constexpr uint8_t kEncodedFalse = + EncodeInitialByte(MajorType::SIMPLE_VALUE, 20); +static constexpr uint8_t kEncodedNull = + EncodeInitialByte(MajorType::SIMPLE_VALUE, 22); +static constexpr uint8_t kInitialByteForDouble = + EncodeInitialByte(MajorType::SIMPLE_VALUE, 27); + +// See RFC 7049 Table 3 and Section 2.4.4.2. This is used as a prefix for +// arbitrary binary data encoded as BYTE_STRING. +static constexpr uint8_t kExpectedConversionToBase64Tag = + EncodeInitialByte(MajorType::TAG, 22); + +// Writes the bytes for |v| to |out|, starting with the most significant byte. +// See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html +template <typename T> +void WriteBytesMostSignificantByteFirst(T v, std::vector<uint8_t>* out) { + for (int shift_bytes = sizeof(T) - 1; shift_bytes >= 0; --shift_bytes) + out->push_back(0xff & (v >> (shift_bytes * 8))); +} + +// Extracts sizeof(T) bytes from |in| to extract a value of type T +// (e.g. uint64_t, uint32_t, ...), most significant byte first. +// See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html +template <typename T> +T ReadBytesMostSignificantByteFirst(span<uint8_t> in) { + assert(static_cast<std::size_t>(in.size()) >= sizeof(T)); + T result = 0; + for (std::size_t shift_bytes = 0; shift_bytes < sizeof(T); ++shift_bytes) + result |= T(in[sizeof(T) - 1 - shift_bytes]) << (shift_bytes * 8); + return result; +} +} // namespace + +namespace internals { +// Reads the start of a token with definitive size from |bytes|. +// |type| is the major type as specified in RFC 7049 Section 2.1. +// |value| is the payload (e.g. for MajorType::UNSIGNED) or is the size +// (e.g. for BYTE_STRING). +// If successful, returns the number of bytes read. Otherwise returns -1. +int8_t ReadTokenStart(span<uint8_t> bytes, MajorType* type, uint64_t* value) { + if (bytes.empty()) + return -1; + uint8_t initial_byte = bytes[0]; + *type = MajorType((initial_byte & kMajorTypeMask) >> kMajorTypeBitShift); + + uint8_t additional_information = initial_byte & kAdditionalInformationMask; + if (additional_information < 24) { + // Values 0-23 are encoded directly into the additional info of the + // initial byte. + *value = additional_information; + return 1; + } + if (additional_information == kAdditionalInformation1Byte) { + // Values 24-255 are encoded with one initial byte, followed by the value. + if (bytes.size() < 2) + return -1; + *value = ReadBytesMostSignificantByteFirst<uint8_t>(bytes.subspan(1)); + return 2; + } + if (additional_information == kAdditionalInformation2Bytes) { + // Values 256-65535: 1 initial byte + 2 bytes payload. + if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint16_t)) + return -1; + *value = ReadBytesMostSignificantByteFirst<uint16_t>(bytes.subspan(1)); + return 3; + } + if (additional_information == kAdditionalInformation4Bytes) { + // 32 bit uint: 1 initial byte + 4 bytes payload. + if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint32_t)) + return -1; + *value = ReadBytesMostSignificantByteFirst<uint32_t>(bytes.subspan(1)); + return 5; + } + if (additional_information == kAdditionalInformation8Bytes) { + // 64 bit uint: 1 initial byte + 8 bytes payload. + if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint64_t)) + return -1; + *value = ReadBytesMostSignificantByteFirst<uint64_t>(bytes.subspan(1)); + return 9; + } + return -1; +} + +// Writes the start of a token with |type|. The |value| may indicate the size, +// or it may be the payload if the value is an unsigned integer. +void WriteTokenStart(MajorType type, + uint64_t value, + std::vector<uint8_t>* encoded) { + if (value < 24) { + // Values 0-23 are encoded directly into the additional info of the + // initial byte. + encoded->push_back(EncodeInitialByte(type, /*additional_info=*/value)); + return; + } + if (value <= std::numeric_limits<uint8_t>::max()) { + // Values 24-255 are encoded with one initial byte, followed by the value. + encoded->push_back(EncodeInitialByte(type, kAdditionalInformation1Byte)); + encoded->push_back(value); + return; + } + if (value <= std::numeric_limits<uint16_t>::max()) { + // Values 256-65535: 1 initial byte + 2 bytes payload. + encoded->push_back(EncodeInitialByte(type, kAdditionalInformation2Bytes)); + WriteBytesMostSignificantByteFirst<uint16_t>(value, encoded); + return; + } + if (value <= std::numeric_limits<uint32_t>::max()) { + // 32 bit uint: 1 initial byte + 4 bytes payload. + encoded->push_back(EncodeInitialByte(type, kAdditionalInformation4Bytes)); + WriteBytesMostSignificantByteFirst<uint32_t>(static_cast<uint32_t>(value), + encoded); + return; + } + // 64 bit uint: 1 initial byte + 8 bytes payload. + encoded->push_back(EncodeInitialByte(type, kAdditionalInformation8Bytes)); + WriteBytesMostSignificantByteFirst<uint64_t>(value, encoded); +} +} // namespace internals + +// ============================================================================= +// Detecting CBOR content +// ============================================================================= + +uint8_t InitialByteForEnvelope() { + return kInitialByteForEnvelope; +} +uint8_t InitialByteFor32BitLengthByteString() { + return kInitialByteFor32BitLengthByteString; +} +bool IsCBORMessage(span<uint8_t> msg) { + return msg.size() >= 6 && msg[0] == InitialByteForEnvelope() && + msg[1] == InitialByteFor32BitLengthByteString(); +} + +// ============================================================================= +// Encoding invidiual CBOR items +// ============================================================================= + +uint8_t EncodeTrue() { + return kEncodedTrue; +} +uint8_t EncodeFalse() { + return kEncodedFalse; +} +uint8_t EncodeNull() { + return kEncodedNull; +} + +uint8_t EncodeIndefiniteLengthArrayStart() { + return kInitialByteIndefiniteLengthArray; +} + +uint8_t EncodeIndefiniteLengthMapStart() { + return kInitialByteIndefiniteLengthMap; +} + +uint8_t EncodeStop() { + return kStopByte; +} + +void EncodeInt32(int32_t value, std::vector<uint8_t>* out) { + if (value >= 0) { + internals::WriteTokenStart(MajorType::UNSIGNED, value, out); + } else { + uint64_t representation = static_cast<uint64_t>(-(value + 1)); + internals::WriteTokenStart(MajorType::NEGATIVE, representation, out); + } +} + +void EncodeString16(span<uint16_t> in, std::vector<uint8_t>* out) { + uint64_t byte_length = static_cast<uint64_t>(in.size_bytes()); + internals::WriteTokenStart(MajorType::BYTE_STRING, byte_length, out); + // When emitting UTF16 characters, we always write the least significant byte + // first; this is because it's the native representation for X86. + // TODO(johannes): Implement a more efficient thing here later, e.g. + // casting *iff* the machine has this byte order. + // The wire format for UTF16 chars will probably remain the same + // (least significant byte first) since this way we can have + // golden files, unittests, etc. that port easily and universally. + // See also: + // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html + for (const uint16_t two_bytes : in) { + out->push_back(two_bytes); + out->push_back(two_bytes >> 8); + } +} + +void EncodeString8(span<uint8_t> in, std::vector<uint8_t>* out) { + internals::WriteTokenStart(MajorType::STRING, + static_cast<uint64_t>(in.size_bytes()), out); + out->insert(out->end(), in.begin(), in.end()); +} + +void EncodeFromLatin1(span<uint8_t> latin1, std::vector<uint8_t>* out) { + for (std::ptrdiff_t ii = 0; ii < latin1.size(); ++ii) { + if (latin1[ii] <= 127) + continue; + // If there's at least one non-ASCII char, convert to UTF8. + std::vector<uint8_t> utf8(latin1.begin(), latin1.begin() + ii); + for (; ii < latin1.size(); ++ii) { + if (latin1[ii] <= 127) { + utf8.push_back(latin1[ii]); + } else { + // 0xC0 means it's a UTF8 sequence with 2 bytes. + utf8.push_back((latin1[ii] >> 6) | 0xc0); + utf8.push_back((latin1[ii] | 0x80) & 0xbf); + } + } + EncodeString8(SpanFromVector(utf8), out); + return; + } + EncodeString8(latin1, out); +} + +void EncodeFromUTF16(span<uint16_t> utf16, std::vector<uint8_t>* out) { + // If there's at least one non-ASCII char, encode as STRING16 (UTF16). + for (uint16_t ch : utf16) { + if (ch <= 127) + continue; + EncodeString16(utf16, out); + return; + } + // It's all US-ASCII, strip out every second byte and encode as UTF8. + internals::WriteTokenStart(MajorType::STRING, + static_cast<uint64_t>(utf16.size()), out); + out->insert(out->end(), utf16.begin(), utf16.end()); +} + +void EncodeBinary(span<uint8_t> in, std::vector<uint8_t>* out) { + out->push_back(kExpectedConversionToBase64Tag); + uint64_t byte_length = static_cast<uint64_t>(in.size_bytes()); + internals::WriteTokenStart(MajorType::BYTE_STRING, byte_length, out); + out->insert(out->end(), in.begin(), in.end()); +} + +// A double is encoded with a specific initial byte +// (kInitialByteForDouble) plus the 64 bits of payload for its value. +constexpr std::ptrdiff_t kEncodedDoubleSize = 1 + sizeof(uint64_t); + +// An envelope is encoded with a specific initial byte +// (kInitialByteForEnvelope), plus the start byte for a BYTE_STRING with a 32 +// bit wide length, plus a 32 bit length for that string. +constexpr std::ptrdiff_t kEncodedEnvelopeHeaderSize = 1 + 1 + sizeof(uint32_t); + +void EncodeDouble(double value, std::vector<uint8_t>* out) { + // The additional_info=27 indicates 64 bits for the double follow. + // See RFC 7049 Section 2.3, Table 1. + out->push_back(kInitialByteForDouble); + union { + double from_double; + uint64_t to_uint64; + } reinterpret; + reinterpret.from_double = value; + WriteBytesMostSignificantByteFirst<uint64_t>(reinterpret.to_uint64, out); +} + +// ============================================================================= +// cbor::EnvelopeEncoder - for wrapping submessages +// ============================================================================= + +void EnvelopeEncoder::EncodeStart(std::vector<uint8_t>* out) { + assert(byte_size_pos_ == 0); + out->push_back(kInitialByteForEnvelope); + out->push_back(kInitialByteFor32BitLengthByteString); + byte_size_pos_ = out->size(); + out->resize(out->size() + sizeof(uint32_t)); +} + +bool EnvelopeEncoder::EncodeStop(std::vector<uint8_t>* out) { + assert(byte_size_pos_ != 0); + // The byte size is the size of the payload, that is, all the + // bytes that were written past the byte size position itself. + uint64_t byte_size = out->size() - (byte_size_pos_ + sizeof(uint32_t)); + // We store exactly 4 bytes, so at most INT32MAX, with most significant + // byte first. + if (byte_size > std::numeric_limits<uint32_t>::max()) + return false; + for (int shift_bytes = sizeof(uint32_t) - 1; shift_bytes >= 0; + --shift_bytes) { + (*out)[byte_size_pos_++] = 0xff & (byte_size >> (shift_bytes * 8)); + } + return true; +} + +// ============================================================================= +// cbor::NewCBOREncoder - for encoding from a streaming parser +// ============================================================================= + +namespace { +class CBOREncoder : public StreamingParserHandler { + public: + CBOREncoder(std::vector<uint8_t>* out, Status* status) + : out_(out), status_(status) { + *status_ = Status(); + } + + void HandleMapBegin() override { + envelopes_.emplace_back(); + envelopes_.back().EncodeStart(out_); + out_->push_back(kInitialByteIndefiniteLengthMap); + } + + void HandleMapEnd() override { + out_->push_back(kStopByte); + assert(!envelopes_.empty()); + envelopes_.back().EncodeStop(out_); + envelopes_.pop_back(); + } + + void HandleArrayBegin() override { + envelopes_.emplace_back(); + envelopes_.back().EncodeStart(out_); + out_->push_back(kInitialByteIndefiniteLengthArray); + } + + void HandleArrayEnd() override { + out_->push_back(kStopByte); + assert(!envelopes_.empty()); + envelopes_.back().EncodeStop(out_); + envelopes_.pop_back(); + } + + void HandleString8(span<uint8_t> chars) override { + EncodeString8(chars, out_); + } + + void HandleString16(span<uint16_t> chars) override { + EncodeFromUTF16(chars, out_); + } + + void HandleBinary(span<uint8_t> bytes) override { EncodeBinary(bytes, out_); } + + void HandleDouble(double value) override { EncodeDouble(value, out_); } + + void HandleInt32(int32_t value) override { EncodeInt32(value, out_); } + + void HandleBool(bool value) override { + // See RFC 7049 Section 2.3, Table 2. + out_->push_back(value ? kEncodedTrue : kEncodedFalse); + } + + void HandleNull() override { + // See RFC 7049 Section 2.3, Table 2. + out_->push_back(kEncodedNull); + } + + void HandleError(Status error) override { + assert(!error.ok()); + *status_ = error; + out_->clear(); + } + + private: + std::vector<uint8_t>* out_; + std::vector<EnvelopeEncoder> envelopes_; + Status* status_; +}; +} // namespace + +std::unique_ptr<StreamingParserHandler> NewCBOREncoder( + std::vector<uint8_t>* out, + Status* status) { + return std::unique_ptr<StreamingParserHandler>(new CBOREncoder(out, status)); +} + +// ============================================================================= +// cbor::CBORTokenizer - for parsing individual CBOR items +// ============================================================================= + +CBORTokenizer::CBORTokenizer(span<uint8_t> bytes) : bytes_(bytes) { + ReadNextToken(/*enter_envelope=*/false); +} +CBORTokenizer::~CBORTokenizer() {} + +CBORTokenTag CBORTokenizer::TokenTag() const { + return token_tag_; +} + +void CBORTokenizer::Next() { + if (token_tag_ == CBORTokenTag::ERROR_VALUE || + token_tag_ == CBORTokenTag::DONE) + return; + ReadNextToken(/*enter_envelope=*/false); +} + +void CBORTokenizer::EnterEnvelope() { + assert(token_tag_ == CBORTokenTag::ENVELOPE); + ReadNextToken(/*enter_envelope=*/true); +} + +Status CBORTokenizer::Status() const { + return status_; +} + +int32_t CBORTokenizer::GetInt32() const { + assert(token_tag_ == CBORTokenTag::INT32); + // The range checks happen in ::ReadNextToken(). + return static_cast<uint32_t>( + token_start_type_ == MajorType::UNSIGNED + ? token_start_internal_value_ + : -static_cast<int64_t>(token_start_internal_value_) - 1); +} + +double CBORTokenizer::GetDouble() const { + assert(token_tag_ == CBORTokenTag::DOUBLE); + union { + uint64_t from_uint64; + double to_double; + } reinterpret; + reinterpret.from_uint64 = ReadBytesMostSignificantByteFirst<uint64_t>( + bytes_.subspan(status_.pos + 1)); + return reinterpret.to_double; +} + +span<uint8_t> CBORTokenizer::GetString8() const { + assert(token_tag_ == CBORTokenTag::STRING8); + auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); + return bytes_.subspan(status_.pos + (token_byte_length_ - length), length); +} + +span<uint8_t> CBORTokenizer::GetString16WireRep() const { + assert(token_tag_ == CBORTokenTag::STRING16); + auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); + return bytes_.subspan(status_.pos + (token_byte_length_ - length), length); +} + +span<uint8_t> CBORTokenizer::GetBinary() const { + assert(token_tag_ == CBORTokenTag::BINARY); + auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); + return bytes_.subspan(status_.pos + (token_byte_length_ - length), length); +} + +span<uint8_t> CBORTokenizer::GetEnvelopeContents() const { + assert(token_tag_ == CBORTokenTag::ENVELOPE); + auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); + return bytes_.subspan(status_.pos + kEncodedEnvelopeHeaderSize, length); +} + +void CBORTokenizer::ReadNextToken(bool enter_envelope) { + if (enter_envelope) { + status_.pos += kEncodedEnvelopeHeaderSize; + } else { + status_.pos = + status_.pos == Status::npos() ? 0 : status_.pos + token_byte_length_; + } + status_.error = Error::OK; + if (status_.pos >= bytes_.size()) { + token_tag_ = CBORTokenTag::DONE; + return; + } + switch (bytes_[status_.pos]) { + case kStopByte: + SetToken(CBORTokenTag::STOP, 1); + return; + case kInitialByteIndefiniteLengthMap: + SetToken(CBORTokenTag::MAP_START, 1); + return; + case kInitialByteIndefiniteLengthArray: + SetToken(CBORTokenTag::ARRAY_START, 1); + return; + case kEncodedTrue: + SetToken(CBORTokenTag::TRUE_VALUE, 1); + return; + case kEncodedFalse: + SetToken(CBORTokenTag::FALSE_VALUE, 1); + return; + case kEncodedNull: + SetToken(CBORTokenTag::NULL_VALUE, 1); + return; + case kExpectedConversionToBase64Tag: { // BINARY + int8_t bytes_read = internals::ReadTokenStart( + bytes_.subspan(status_.pos + 1), &token_start_type_, + &token_start_internal_value_); + int64_t token_byte_length = 1 + bytes_read + token_start_internal_value_; + if (-1 == bytes_read || token_start_type_ != MajorType::BYTE_STRING || + status_.pos + token_byte_length > bytes_.size()) { + SetError(Error::CBOR_INVALID_BINARY); + return; + } + SetToken(CBORTokenTag::BINARY, + static_cast<std::ptrdiff_t>(token_byte_length)); + return; + } + case kInitialByteForDouble: { // DOUBLE + if (status_.pos + kEncodedDoubleSize > bytes_.size()) { + SetError(Error::CBOR_INVALID_DOUBLE); + return; + } + SetToken(CBORTokenTag::DOUBLE, kEncodedDoubleSize); + return; + } + case kInitialByteForEnvelope: { // ENVELOPE + if (status_.pos + kEncodedEnvelopeHeaderSize > bytes_.size()) { + SetError(Error::CBOR_INVALID_ENVELOPE); + return; + } + // The envelope must be a byte string with 32 bit length. + if (bytes_[status_.pos + 1] != kInitialByteFor32BitLengthByteString) { + SetError(Error::CBOR_INVALID_ENVELOPE); + return; + } + // Read the length of the byte string. + token_start_internal_value_ = ReadBytesMostSignificantByteFirst<uint32_t>( + bytes_.subspan(status_.pos + 2)); + // Make sure the payload is contained within the message. + if (token_start_internal_value_ + kEncodedEnvelopeHeaderSize + + status_.pos > + static_cast<std::size_t>(bytes_.size())) { + SetError(Error::CBOR_INVALID_ENVELOPE); + return; + } + auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); + SetToken(CBORTokenTag::ENVELOPE, kEncodedEnvelopeHeaderSize + length); + return; + } + default: { + span<uint8_t> remainder = + bytes_.subspan(status_.pos, bytes_.size() - status_.pos); + assert(!remainder.empty()); + int8_t token_start_length = internals::ReadTokenStart( + remainder, &token_start_type_, &token_start_internal_value_); + bool success = token_start_length != -1; + switch (token_start_type_) { + case MajorType::UNSIGNED: // INT32. + if (!success || std::numeric_limits<int32_t>::max() < + token_start_internal_value_) { + SetError(Error::CBOR_INVALID_INT32); + return; + } + SetToken(CBORTokenTag::INT32, token_start_length); + return; + case MajorType::NEGATIVE: // INT32. + if (!success || + std::numeric_limits<int32_t>::min() > + -static_cast<int64_t>(token_start_internal_value_) - 1) { + SetError(Error::CBOR_INVALID_INT32); + return; + } + SetToken(CBORTokenTag::INT32, token_start_length); + return; + case MajorType::STRING: { // STRING8. + if (!success || remainder.size() < static_cast<int64_t>( + token_start_internal_value_)) { + SetError(Error::CBOR_INVALID_STRING8); + return; + } + auto length = + static_cast<std::ptrdiff_t>(token_start_internal_value_); + SetToken(CBORTokenTag::STRING8, token_start_length + length); + return; + } + case MajorType::BYTE_STRING: { // STRING16. + if (!success || + remainder.size() < + static_cast<int64_t>(token_start_internal_value_) || + // Must be divisible by 2 since UTF16 is 2 bytes per character. + token_start_internal_value_ & 1) { + SetError(Error::CBOR_INVALID_STRING16); + return; + } + auto length = + static_cast<std::ptrdiff_t>(token_start_internal_value_); + SetToken(CBORTokenTag::STRING16, token_start_length + length); + return; + } + case MajorType::ARRAY: + case MajorType::MAP: + case MajorType::TAG: + case MajorType::SIMPLE_VALUE: + SetError(Error::CBOR_UNSUPPORTED_VALUE); + return; + } + } + } +} + +void CBORTokenizer::SetToken(CBORTokenTag token_tag, + std::ptrdiff_t token_byte_length) { + token_tag_ = token_tag; + token_byte_length_ = token_byte_length; +} + +void CBORTokenizer::SetError(Error error) { + token_tag_ = CBORTokenTag::ERROR_VALUE; + status_.error = error; +} + +// ============================================================================= +// cbor::ParseCBOR - for receiving streaming parser events for CBOR messages +// ============================================================================= + +namespace { +// When parsing CBOR, we limit recursion depth for objects and arrays +// to this constant. +static constexpr int kStackLimit = 1000; + +// Below are three parsing routines for CBOR, which cover enough +// to roundtrip JSON messages. +bool ParseMap(int32_t stack_depth, + CBORTokenizer* tokenizer, + StreamingParserHandler* out); +bool ParseArray(int32_t stack_depth, + CBORTokenizer* tokenizer, + StreamingParserHandler* out); +bool ParseValue(int32_t stack_depth, + CBORTokenizer* tokenizer, + StreamingParserHandler* out); + +void ParseUTF16String(CBORTokenizer* tokenizer, StreamingParserHandler* out) { + std::vector<uint16_t> value; + span<uint8_t> rep = tokenizer->GetString16WireRep(); + for (std::ptrdiff_t ii = 0; ii < rep.size(); ii += 2) + value.push_back((rep[ii + 1] << 8) | rep[ii]); + out->HandleString16(span<uint16_t>(value.data(), value.size())); + tokenizer->Next(); +} + +bool ParseUTF8String(CBORTokenizer* tokenizer, StreamingParserHandler* out) { + assert(tokenizer->TokenTag() == CBORTokenTag::STRING8); + out->HandleString8(tokenizer->GetString8()); + tokenizer->Next(); + return true; +} + +bool ParseValue(int32_t stack_depth, + CBORTokenizer* tokenizer, + StreamingParserHandler* out) { + if (stack_depth > kStackLimit) { + out->HandleError( + Status{Error::CBOR_STACK_LIMIT_EXCEEDED, tokenizer->Status().pos}); + return false; + } + // Skip past the envelope to get to what's inside. + if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE) + tokenizer->EnterEnvelope(); + switch (tokenizer->TokenTag()) { + case CBORTokenTag::ERROR_VALUE: + out->HandleError(tokenizer->Status()); + return false; + case CBORTokenTag::DONE: + out->HandleError(Status{Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE, + tokenizer->Status().pos}); + return false; + case CBORTokenTag::TRUE_VALUE: + out->HandleBool(true); + tokenizer->Next(); + return true; + case CBORTokenTag::FALSE_VALUE: + out->HandleBool(false); + tokenizer->Next(); + return true; + case CBORTokenTag::NULL_VALUE: + out->HandleNull(); + tokenizer->Next(); + return true; + case CBORTokenTag::INT32: + out->HandleInt32(tokenizer->GetInt32()); + tokenizer->Next(); + return true; + case CBORTokenTag::DOUBLE: + out->HandleDouble(tokenizer->GetDouble()); + tokenizer->Next(); + return true; + case CBORTokenTag::STRING8: + return ParseUTF8String(tokenizer, out); + case CBORTokenTag::STRING16: + ParseUTF16String(tokenizer, out); + return true; + case CBORTokenTag::BINARY: { + out->HandleBinary(tokenizer->GetBinary()); + tokenizer->Next(); + return true; + } + case CBORTokenTag::MAP_START: + return ParseMap(stack_depth + 1, tokenizer, out); + case CBORTokenTag::ARRAY_START: + return ParseArray(stack_depth + 1, tokenizer, out); + default: + out->HandleError( + Status{Error::CBOR_UNSUPPORTED_VALUE, tokenizer->Status().pos}); + return false; + } +} + +// |bytes| must start with the indefinite length array byte, so basically, +// ParseArray may only be called after an indefinite length array has been +// detected. +bool ParseArray(int32_t stack_depth, + CBORTokenizer* tokenizer, + StreamingParserHandler* out) { + assert(tokenizer->TokenTag() == CBORTokenTag::ARRAY_START); + tokenizer->Next(); + out->HandleArrayBegin(); + while (tokenizer->TokenTag() != CBORTokenTag::STOP) { + if (tokenizer->TokenTag() == CBORTokenTag::DONE) { + out->HandleError( + Status{Error::CBOR_UNEXPECTED_EOF_IN_ARRAY, tokenizer->Status().pos}); + return false; + } + if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) { + out->HandleError(tokenizer->Status()); + return false; + } + // Parse value. + if (!ParseValue(stack_depth, tokenizer, out)) + return false; + } + out->HandleArrayEnd(); + tokenizer->Next(); + return true; +} + +// |bytes| must start with the indefinite length array byte, so basically, +// ParseArray may only be called after an indefinite length array has been +// detected. +bool ParseMap(int32_t stack_depth, + CBORTokenizer* tokenizer, + StreamingParserHandler* out) { + assert(tokenizer->TokenTag() == CBORTokenTag::MAP_START); + out->HandleMapBegin(); + tokenizer->Next(); + while (tokenizer->TokenTag() != CBORTokenTag::STOP) { + if (tokenizer->TokenTag() == CBORTokenTag::DONE) { + out->HandleError( + Status{Error::CBOR_UNEXPECTED_EOF_IN_MAP, tokenizer->Status().pos}); + return false; + } + if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) { + out->HandleError(tokenizer->Status()); + return false; + } + // Parse key. + if (tokenizer->TokenTag() == CBORTokenTag::STRING8) { + if (!ParseUTF8String(tokenizer, out)) + return false; + } else if (tokenizer->TokenTag() == CBORTokenTag::STRING16) { + ParseUTF16String(tokenizer, out); + } else { + out->HandleError( + Status{Error::CBOR_INVALID_MAP_KEY, tokenizer->Status().pos}); + return false; + } + // Parse value. + if (!ParseValue(stack_depth, tokenizer, out)) + return false; + } + out->HandleMapEnd(); + tokenizer->Next(); + return true; +} +} // namespace + +void ParseCBOR(span<uint8_t> bytes, StreamingParserHandler* out) { + if (bytes.empty()) { + out->HandleError(Status{Error::CBOR_NO_INPUT, 0}); + return; + } + if (bytes[0] != kInitialByteForEnvelope) { + out->HandleError(Status{Error::CBOR_INVALID_START_BYTE, 0}); + return; + } + CBORTokenizer tokenizer(bytes); + if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) { + out->HandleError(tokenizer.Status()); + return; + } + // We checked for the envelope start byte above, so the tokenizer + // must agree here, since it's not an error. + assert(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE); + tokenizer.EnterEnvelope(); + if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) { + out->HandleError( + Status{Error::CBOR_MAP_START_EXPECTED, tokenizer.Status().pos}); + return; + } + if (!ParseMap(/*stack_depth=*/1, &tokenizer, out)) + return; + if (tokenizer.TokenTag() == CBORTokenTag::DONE) + return; + if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) { + out->HandleError(tokenizer.Status()); + return; + } + out->HandleError(Status{Error::CBOR_TRAILING_JUNK, tokenizer.Status().pos}); +} +} // namespace cbor + +namespace json { + +// ============================================================================= +// json::NewJSONEncoder - for encoding streaming parser events as JSON +// ============================================================================= + +namespace { +// Prints |value| to |out| with 4 hex digits, most significant chunk first. +void PrintHex(uint16_t value, std::string* out) { + for (int ii = 3; ii >= 0; --ii) { + int four_bits = 0xf & (value >> (4 * ii)); + out->append(1, four_bits + ((four_bits <= 9) ? '0' : ('a' - 10))); + } +} + +// In the writer below, we maintain a stack of State instances. +// It is just enough to emit the appropriate delimiters and brackets +// in JSON. +enum class Container { + // Used for the top-level, initial state. + NONE, + // Inside a JSON object. + MAP, + // Inside a JSON array. + ARRAY +}; +class State { + public: + explicit State(Container container) : container_(container) {} + void StartElement(std::string* out) { + assert(container_ != Container::NONE || size_ == 0); + if (size_ != 0) { + char delim = (!(size_ & 1) || container_ == Container::ARRAY) ? ',' : ':'; + out->append(1, delim); + } + ++size_; + } + Container container() const { return container_; } + + private: + Container container_ = Container::NONE; + int size_ = 0; +}; + +constexpr char kBase64Table[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz0123456789+/"; + +void Base64Encode(const span<uint8_t>& in, std::string* out) { + // The following three cases are based on the tables in the example + // section in https://en.wikipedia.org/wiki/Base64. We process three + // input bytes at a time, emitting 4 output bytes at a time. + std::ptrdiff_t ii = 0; + + // While possible, process three input bytes. + for (; ii + 3 <= in.size(); ii += 3) { + uint32_t twentyfour_bits = (in[ii] << 16) | (in[ii + 1] << 8) | in[ii + 2]; + out->push_back(kBase64Table[(twentyfour_bits >> 18)]); + out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]); + out->push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]); + out->push_back(kBase64Table[twentyfour_bits & 0x3f]); + } + if (ii + 2 <= in.size()) { // Process two input bytes. + uint32_t twentyfour_bits = (in[ii] << 16) | (in[ii + 1] << 8); + out->push_back(kBase64Table[(twentyfour_bits >> 18)]); + out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]); + out->push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]); + out->push_back('='); // Emit padding. + return; + } + if (ii + 1 <= in.size()) { // Process a single input byte. + uint32_t twentyfour_bits = (in[ii] << 16); + out->push_back(kBase64Table[(twentyfour_bits >> 18)]); + out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]); + out->push_back('='); // Emit padding. + out->push_back('='); // Emit padding. + } +} + +// Implements a handler for JSON parser events to emit a JSON string. +class JSONEncoder : public StreamingParserHandler { + public: + JSONEncoder(const Platform* platform, std::string* out, Status* status) + : platform_(platform), out_(out), status_(status) { + *status_ = Status(); + state_.emplace(Container::NONE); + } + + void HandleMapBegin() override { + if (!status_->ok()) + return; + assert(!state_.empty()); + state_.top().StartElement(out_); + state_.emplace(Container::MAP); + out_->append("{"); + } + + void HandleMapEnd() override { + if (!status_->ok()) + return; + assert(state_.size() >= 2 && state_.top().container() == Container::MAP); + state_.pop(); + out_->append("}"); + } + + void HandleArrayBegin() override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + state_.emplace(Container::ARRAY); + out_->append("["); + } + + void HandleArrayEnd() override { + if (!status_->ok()) + return; + assert(state_.size() >= 2 && state_.top().container() == Container::ARRAY); + state_.pop(); + out_->append("]"); + } + + void HandleString16(span<uint16_t> chars) override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + out_->append("\""); + for (const uint16_t ch : chars) { + if (ch == '"') { + out_->append("\\\""); + } else if (ch == '\\') { + out_->append("\\\\"); + } else if (ch == '\b') { + out_->append("\\b"); + } else if (ch == '\f') { + out_->append("\\f"); + } else if (ch == '\n') { + out_->append("\\n"); + } else if (ch == '\r') { + out_->append("\\r"); + } else if (ch == '\t') { + out_->append("\\t"); + } else if (ch >= 32 && ch <= 126) { + out_->append(1, ch); + } else { + out_->append("\\u"); + PrintHex(ch, out_); + } + } + out_->append("\""); + } + + void HandleString8(span<uint8_t> chars) override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + out_->append("\""); + for (std::ptrdiff_t ii = 0; ii < chars.size(); ++ii) { + uint8_t c = chars[ii]; + if (c == '"') { + out_->append("\\\""); + } else if (c == '\\') { + out_->append("\\\\"); + } else if (c == '\b') { + out_->append("\\b"); + } else if (c == '\f') { + out_->append("\\f"); + } else if (c == '\n') { + out_->append("\\n"); + } else if (c == '\r') { + out_->append("\\r"); + } else if (c == '\t') { + out_->append("\\t"); + } else if (c >= 32 && c <= 126) { + out_->append(1, c); + } else if (c < 32) { + out_->append("\\u"); + PrintHex(static_cast<uint16_t>(c), out_); + } else { + // Inspect the leading byte to figure out how long the utf8 + // byte sequence is; while doing this initialize |codepoint| + // with the first few bits. + // See table in: https://en.wikipedia.org/wiki/UTF-8 + // byte one is 110x xxxx -> 2 byte utf8 sequence + // byte one is 1110 xxxx -> 3 byte utf8 sequence + // byte one is 1111 0xxx -> 4 byte utf8 sequence + uint32_t codepoint; + int num_bytes_left; + if ((c & 0xe0) == 0xc0) { // 2 byte utf8 sequence + num_bytes_left = 1; + codepoint = c & 0x1f; + } else if ((c & 0xf0) == 0xe0) { // 3 byte utf8 sequence + num_bytes_left = 2; + codepoint = c & 0x0f; + } else if ((c & 0xf8) == 0xf0) { // 4 byte utf8 sequence + codepoint = c & 0x07; + num_bytes_left = 3; + } else { + continue; // invalid leading byte + } + + // If we have enough bytes in our input, decode the remaining ones + // belonging to this Unicode character into |codepoint|. + if (ii + num_bytes_left > chars.size()) + continue; + while (num_bytes_left > 0) { + c = chars[++ii]; + --num_bytes_left; + // Check the next byte is a continuation byte, that is 10xx xxxx. + if ((c & 0xc0) != 0x80) + continue; + codepoint = (codepoint << 6) | (c & 0x3f); + } + + // Disallow overlong encodings for ascii characters, as these + // would include " and other characters significant to JSON + // string termination / control. + if (codepoint < 0x7f) + continue; + // Invalid in UTF8, and can't be represented in UTF16 anyway. + if (codepoint > 0x10ffff) + continue; + + // So, now we transcode to UTF16, + // using the math described at https://en.wikipedia.org/wiki/UTF-16, + // for either one or two 16 bit characters. + if (codepoint < 0xffff) { + out_->append("\\u"); + PrintHex(static_cast<uint16_t>(codepoint), out_); + continue; + } + codepoint -= 0x10000; + // high surrogate + out_->append("\\u"); + PrintHex(static_cast<uint16_t>((codepoint >> 10) + 0xd800), out_); + // low surrogate + out_->append("\\u"); + PrintHex(static_cast<uint16_t>((codepoint & 0x3ff) + 0xdc00), out_); + } + } + out_->append("\""); + } + + void HandleBinary(span<uint8_t> bytes) override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + out_->append("\""); + Base64Encode(bytes, out_); + out_->append("\""); + } + + void HandleDouble(double value) override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + std::unique_ptr<char[]> str_value = platform_->DToStr(value); + + // DToStr may fail to emit a 0 before the decimal dot. E.g. this is + // the case in base::NumberToString in Chromium (which is based on + // dmg_fp). So, much like + // https://cs.chromium.org/chromium/src/base/json/json_writer.cc + // we probe for this and emit the leading 0 anyway if necessary. + const char* chars = str_value.get(); + if (chars[0] == '.') { + out_->append("0"); + } else if (chars[0] == '-' && chars[1] == '.') { + out_->append("-0"); + ++chars; + } + out_->append(chars); + } + + void HandleInt32(int32_t value) override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + out_->append(std::to_string(value)); + } + + void HandleBool(bool value) override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + out_->append(value ? "true" : "false"); + } + + void HandleNull() override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + out_->append("null"); + } + + void HandleError(Status error) override { + assert(!error.ok()); + *status_ = error; + out_->clear(); + } + + private: + const Platform* platform_; + std::string* out_; + Status* status_; + std::stack<State> state_; +}; +} // namespace + +std::unique_ptr<StreamingParserHandler> NewJSONEncoder(const Platform* platform, + std::string* out, + Status* status) { + return std::unique_ptr<StreamingParserHandler>( + new JSONEncoder(platform, out, status)); +} + +// ============================================================================= +// json::ParseJSON - for receiving streaming parser events for JSON. +// ============================================================================= + +namespace { +const int kStackLimit = 1000; + +enum Token { + ObjectBegin, + ObjectEnd, + ArrayBegin, + ArrayEnd, + StringLiteral, + Number, + BoolTrue, + BoolFalse, + NullToken, + ListSeparator, + ObjectPairSeparator, + InvalidToken, + NoInput +}; + +const char* const kNullString = "null"; +const char* const kTrueString = "true"; +const char* const kFalseString = "false"; + +template <typename Char> +class JsonParser { + public: + JsonParser(const Platform* platform, StreamingParserHandler* handler) + : platform_(platform), handler_(handler) {} + + void Parse(const Char* start, std::size_t length) { + start_pos_ = start; + const Char* end = start + length; + const Char* tokenEnd; + ParseValue(start, end, &tokenEnd, 0); + if (tokenEnd != end) { + HandleError(Error::JSON_PARSER_UNPROCESSED_INPUT_REMAINS, tokenEnd); + } + } + + private: + bool CharsToDouble(const uint16_t* chars, + std::size_t length, + double* result) { + std::string buffer; + buffer.reserve(length + 1); + for (std::size_t ii = 0; ii < length; ++ii) { + bool is_ascii = !(chars[ii] & ~0x7F); + if (!is_ascii) + return false; + buffer.push_back(static_cast<char>(chars[ii])); + } + return platform_->StrToD(buffer.c_str(), result); + } + + bool CharsToDouble(const uint8_t* chars, std::size_t length, double* result) { + std::string buffer(reinterpret_cast<const char*>(chars), length); + return platform_->StrToD(buffer.c_str(), result); + } + + static bool ParseConstToken(const Char* start, + const Char* end, + const Char** token_end, + const char* token) { + // |token| is \0 terminated, it's one of the constants at top of the file. + while (start < end && *token != '\0' && *start++ == *token++) { + } + if (*token != '\0') + return false; + *token_end = start; + return true; + } + + static bool ReadInt(const Char* start, + const Char* end, + const Char** token_end, + bool allow_leading_zeros) { + if (start == end) + return false; + bool has_leading_zero = '0' == *start; + int length = 0; + while (start < end && '0' <= *start && *start <= '9') { + ++start; + ++length; + } + if (!length) + return false; + if (!allow_leading_zeros && length > 1 && has_leading_zero) + return false; + *token_end = start; + return true; + } + + static bool ParseNumberToken(const Char* start, + const Char* end, + const Char** token_end) { + // We just grab the number here. We validate the size in DecodeNumber. + // According to RFC4627, a valid number is: [minus] int [frac] [exp] + if (start == end) + return false; + Char c = *start; + if ('-' == c) + ++start; + + if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/false)) + return false; + if (start == end) { + *token_end = start; + return true; + } + + // Optional fraction part + c = *start; + if ('.' == c) { + ++start; + if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/true)) + return false; + if (start == end) { + *token_end = start; + return true; + } + c = *start; + } + + // Optional exponent part + if ('e' == c || 'E' == c) { + ++start; + if (start == end) + return false; + c = *start; + if ('-' == c || '+' == c) { + ++start; + if (start == end) + return false; + } + if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/true)) + return false; + } + + *token_end = start; + return true; + } + + static bool ReadHexDigits(const Char* start, + const Char* end, + const Char** token_end, + int digits) { + if (end - start < digits) + return false; + for (int i = 0; i < digits; ++i) { + Char c = *start++; + if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || + ('A' <= c && c <= 'F'))) + return false; + } + *token_end = start; + return true; + } + + static bool ParseStringToken(const Char* start, + const Char* end, + const Char** token_end) { + while (start < end) { + Char c = *start++; + if ('\\' == c) { + if (start == end) + return false; + c = *start++; + // Make sure the escaped char is valid. + switch (c) { + case 'x': + if (!ReadHexDigits(start, end, &start, 2)) + return false; + break; + case 'u': + if (!ReadHexDigits(start, end, &start, 4)) + return false; + break; + case '\\': + case '/': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': + case 'v': + case '"': + break; + default: + return false; + } + } else if ('"' == c) { + *token_end = start; + return true; + } + } + return false; + } + + static bool SkipComment(const Char* start, + const Char* end, + const Char** comment_end) { + if (start == end) + return false; + + if (*start != '/' || start + 1 >= end) + return false; + ++start; + + if (*start == '/') { + // Single line comment, read to newline. + for (++start; start < end; ++start) { + if (*start == '\n' || *start == '\r') { + *comment_end = start + 1; + return true; + } + } + *comment_end = end; + // Comment reaches end-of-input, which is fine. + return true; + } + + if (*start == '*') { + Char previous = '\0'; + // Block comment, read until end marker. + for (++start; start < end; previous = *start++) { + if (previous == '*' && *start == '/') { + *comment_end = start + 1; + return true; + } + } + // Block comment must close before end-of-input. + return false; + } + + return false; + } + + static bool IsSpaceOrNewLine(Char c) { + // \v = vertial tab; \f = form feed page break. + return c == ' ' || c == '\n' || c == '\v' || c == '\f' || c == '\r' || + c == '\t'; + } + + static void SkipWhitespaceAndComments(const Char* start, + const Char* end, + const Char** whitespace_end) { + while (start < end) { + if (IsSpaceOrNewLine(*start)) { + ++start; + } else if (*start == '/') { + const Char* comment_end; + if (!SkipComment(start, end, &comment_end)) + break; + start = comment_end; + } else { + break; + } + } + *whitespace_end = start; + } + + static Token ParseToken(const Char* start, + const Char* end, + const Char** tokenStart, + const Char** token_end) { + SkipWhitespaceAndComments(start, end, tokenStart); + start = *tokenStart; + + if (start == end) + return NoInput; + + switch (*start) { + case 'n': + if (ParseConstToken(start, end, token_end, kNullString)) + return NullToken; + break; + case 't': + if (ParseConstToken(start, end, token_end, kTrueString)) + return BoolTrue; + break; + case 'f': + if (ParseConstToken(start, end, token_end, kFalseString)) + return BoolFalse; + break; + case '[': + *token_end = start + 1; + return ArrayBegin; + case ']': + *token_end = start + 1; + return ArrayEnd; + case ',': + *token_end = start + 1; + return ListSeparator; + case '{': + *token_end = start + 1; + return ObjectBegin; + case '}': + *token_end = start + 1; + return ObjectEnd; + case ':': + *token_end = start + 1; + return ObjectPairSeparator; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + if (ParseNumberToken(start, end, token_end)) + return Number; + break; + case '"': + if (ParseStringToken(start + 1, end, token_end)) + return StringLiteral; + break; + } + return InvalidToken; + } + + static int HexToInt(Char c) { + if ('0' <= c && c <= '9') + return c - '0'; + if ('A' <= c && c <= 'F') + return c - 'A' + 10; + if ('a' <= c && c <= 'f') + return c - 'a' + 10; + assert(false); // Unreachable. + return 0; + } + + static bool DecodeString(const Char* start, + const Char* end, + std::vector<uint16_t>* output) { + if (start == end) + return true; + if (start > end) + return false; + output->reserve(end - start); + while (start < end) { + uint16_t c = *start++; + // If the |Char| we're dealing with is really a byte, then + // we have utf8 here, and we need to check for multibyte characters + // and transcode them to utf16 (either one or two utf16 chars). + if (sizeof(Char) == sizeof(uint8_t) && c >= 0x7f) { + // Inspect the leading byte to figure out how long the utf8 + // byte sequence is; while doing this initialize |codepoint| + // with the first few bits. + // See table in: https://en.wikipedia.org/wiki/UTF-8 + // byte one is 110x xxxx -> 2 byte utf8 sequence + // byte one is 1110 xxxx -> 3 byte utf8 sequence + // byte one is 1111 0xxx -> 4 byte utf8 sequence + uint32_t codepoint; + int num_bytes_left; + if ((c & 0xe0) == 0xc0) { // 2 byte utf8 sequence + num_bytes_left = 1; + codepoint = c & 0x1f; + } else if ((c & 0xf0) == 0xe0) { // 3 byte utf8 sequence + num_bytes_left = 2; + codepoint = c & 0x0f; + } else if ((c & 0xf8) == 0xf0) { // 4 byte utf8 sequence + codepoint = c & 0x07; + num_bytes_left = 3; + } else { + return false; // invalid leading byte + } + + // If we have enough bytes in our inpput, decode the remaining ones + // belonging to this Unicode character into |codepoint|. + if (start + num_bytes_left > end) + return false; + while (num_bytes_left > 0) { + c = *start++; + --num_bytes_left; + // Check the next byte is a continuation byte, that is 10xx xxxx. + if ((c & 0xc0) != 0x80) + return false; + codepoint = (codepoint << 6) | (c & 0x3f); + } + + // Disallow overlong encodings for ascii characters, as these + // would include " and other characters significant to JSON + // string termination / control. + if (codepoint < 0x7f) + return false; + // Invalid in UTF8, and can't be represented in UTF16 anyway. + if (codepoint > 0x10ffff) + return false; + + // So, now we transcode to UTF16, + // using the math described at https://en.wikipedia.org/wiki/UTF-16, + // for either one or two 16 bit characters. + if (codepoint < 0xffff) { + output->push_back(codepoint); + continue; + } + codepoint -= 0x10000; + output->push_back((codepoint >> 10) + 0xd800); // high surrogate + output->push_back((codepoint & 0x3ff) + 0xdc00); // low surrogate + continue; + } + if ('\\' != c) { + output->push_back(c); + continue; + } + if (start == end) + return false; + c = *start++; + + if (c == 'x') { + // \x is not supported. + return false; + } + + switch (c) { + case '"': + case '/': + case '\\': + break; + case 'b': + c = '\b'; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'v': + c = '\v'; + break; + case 'u': + c = (HexToInt(*start) << 12) + (HexToInt(*(start + 1)) << 8) + + (HexToInt(*(start + 2)) << 4) + HexToInt(*(start + 3)); + start += 4; + break; + default: + return false; + } + output->push_back(c); + } + return true; + } + + void ParseValue(const Char* start, + const Char* end, + const Char** value_token_end, + int depth) { + if (depth > kStackLimit) { + HandleError(Error::JSON_PARSER_STACK_LIMIT_EXCEEDED, start); + return; + } + const Char* token_start; + const Char* token_end; + Token token = ParseToken(start, end, &token_start, &token_end); + switch (token) { + case NoInput: + HandleError(Error::JSON_PARSER_NO_INPUT, token_start); + return; + case InvalidToken: + HandleError(Error::JSON_PARSER_INVALID_TOKEN, token_start); + return; + case NullToken: + handler_->HandleNull(); + break; + case BoolTrue: + handler_->HandleBool(true); + break; + case BoolFalse: + handler_->HandleBool(false); + break; + case Number: { + double value; + if (!CharsToDouble(token_start, token_end - token_start, &value)) { + HandleError(Error::JSON_PARSER_INVALID_NUMBER, token_start); + return; + } + if (value >= std::numeric_limits<int32_t>::min() && + value <= std::numeric_limits<int32_t>::max() && + static_cast<int32_t>(value) == value) + handler_->HandleInt32(static_cast<int32_t>(value)); + else + handler_->HandleDouble(value); + break; + } + case StringLiteral: { + std::vector<uint16_t> value; + bool ok = DecodeString(token_start + 1, token_end - 1, &value); + if (!ok) { + HandleError(Error::JSON_PARSER_INVALID_STRING, token_start); + return; + } + handler_->HandleString16(span<uint16_t>(value.data(), value.size())); + break; + } + case ArrayBegin: { + handler_->HandleArrayBegin(); + start = token_end; + token = ParseToken(start, end, &token_start, &token_end); + while (token != ArrayEnd) { + ParseValue(start, end, &token_end, depth + 1); + if (error_) + return; + + // After a list value, we expect a comma or the end of the list. + start = token_end; + token = ParseToken(start, end, &token_start, &token_end); + if (token == ListSeparator) { + start = token_end; + token = ParseToken(start, end, &token_start, &token_end); + if (token == ArrayEnd) { + HandleError(Error::JSON_PARSER_UNEXPECTED_ARRAY_END, token_start); + return; + } + } else if (token != ArrayEnd) { + // Unexpected value after list value. Bail out. + HandleError(Error::JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED, + token_start); + return; + } + } + handler_->HandleArrayEnd(); + break; + } + case ObjectBegin: { + handler_->HandleMapBegin(); + start = token_end; + token = ParseToken(start, end, &token_start, &token_end); + while (token != ObjectEnd) { + if (token != StringLiteral) { + HandleError(Error::JSON_PARSER_STRING_LITERAL_EXPECTED, + token_start); + return; + } + std::vector<uint16_t> key; + if (!DecodeString(token_start + 1, token_end - 1, &key)) { + HandleError(Error::JSON_PARSER_INVALID_STRING, token_start); + return; + } + handler_->HandleString16(span<uint16_t>(key.data(), key.size())); + start = token_end; + + token = ParseToken(start, end, &token_start, &token_end); + if (token != ObjectPairSeparator) { + HandleError(Error::JSON_PARSER_COLON_EXPECTED, token_start); + return; + } + start = token_end; + + ParseValue(start, end, &token_end, depth + 1); + if (error_) + return; + start = token_end; + + // After a key/value pair, we expect a comma or the end of the + // object. + token = ParseToken(start, end, &token_start, &token_end); + if (token == ListSeparator) { + start = token_end; + token = ParseToken(start, end, &token_start, &token_end); + if (token == ObjectEnd) { + HandleError(Error::JSON_PARSER_UNEXPECTED_MAP_END, token_start); + return; + } + } else if (token != ObjectEnd) { + // Unexpected value after last object value. Bail out. + HandleError(Error::JSON_PARSER_COMMA_OR_MAP_END_EXPECTED, + token_start); + return; + } + } + handler_->HandleMapEnd(); + break; + } + + default: + // We got a token that's not a value. + HandleError(Error::JSON_PARSER_VALUE_EXPECTED, token_start); + return; + } + + SkipWhitespaceAndComments(token_end, end, value_token_end); + } + + void HandleError(Error error, const Char* pos) { + assert(error != Error::OK); + if (!error_) { + handler_->HandleError(Status{error, pos - start_pos_}); + error_ = true; + } + } + + const Char* start_pos_ = nullptr; + bool error_ = false; + const Platform* platform_; + StreamingParserHandler* handler_; +}; +} // namespace + +void ParseJSON(const Platform* platform, + span<uint8_t> chars, + StreamingParserHandler* handler) { + JsonParser<uint8_t> parser(platform, handler); + parser.Parse(chars.data(), chars.size()); +} + +void ParseJSON(const Platform* platform, + span<uint16_t> chars, + StreamingParserHandler* handler) { + JsonParser<uint16_t> parser(platform, handler); + parser.Parse(chars.data(), chars.size()); +} +} // namespace json +} // namespace inspector_protocol_encoding
diff --git a/third_party/inspector_protocol/lib/CBOR_h.template b/third_party/inspector_protocol/encoding/encoding.h similarity index 65% rename from third_party/inspector_protocol/lib/CBOR_h.template rename to third_party/inspector_protocol/encoding/encoding.h index 9d28adb..b958ff4 100644 --- a/third_party/inspector_protocol/lib/CBOR_h.template +++ b/third_party/inspector_protocol/encoding/encoding.h
@@ -1,75 +1,21 @@ -{# This template is generated by gen_cbor_templates.py. #} -// Generated by lib/CBOR_h.template. - // 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 {{"_".join(config.protocol.namespace)}}_CBOR_h -#define {{"_".join(config.protocol.namespace)}}_CBOR_h +#ifndef INSPECTOR_PROTOCOL_ENCODING_ENCODING_H_ +#define INSPECTOR_PROTOCOL_ENCODING_ENCODING_H_ #include <cstddef> #include <cstdint> #include <memory> +#include <string> #include <vector> -{% for namespace in config.protocol.namespace %} -namespace {{namespace}} { -{% endfor %} +namespace inspector_protocol_encoding { -// ===== encoding/status.h ===== - -// Error codes. -enum class Error { - OK = 0, - // JSON parsing errors - json_parser.{h,cc}. - JSON_PARSER_UNPROCESSED_INPUT_REMAINS = 0x01, - JSON_PARSER_STACK_LIMIT_EXCEEDED = 0x02, - JSON_PARSER_NO_INPUT = 0x03, - JSON_PARSER_INVALID_TOKEN = 0x04, - JSON_PARSER_INVALID_NUMBER = 0x05, - JSON_PARSER_INVALID_STRING = 0x06, - JSON_PARSER_UNEXPECTED_ARRAY_END = 0x07, - JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED = 0x08, - JSON_PARSER_STRING_LITERAL_EXPECTED = 0x09, - JSON_PARSER_COLON_EXPECTED = 0x0a, - JSON_PARSER_UNEXPECTED_OBJECT_END = 0x0b, - JSON_PARSER_COMMA_OR_OBJECT_END_EXPECTED = 0x0c, - JSON_PARSER_VALUE_EXPECTED = 0x0d, - - CBOR_INVALID_INT32 = 0x0e, - CBOR_INVALID_DOUBLE = 0x0f, - CBOR_INVALID_ENVELOPE = 0x10, - CBOR_INVALID_STRING8 = 0x11, - CBOR_INVALID_STRING16 = 0x12, - CBOR_INVALID_BINARY = 0x13, - CBOR_UNSUPPORTED_VALUE = 0x14, - CBOR_NO_INPUT = 0x15, - CBOR_INVALID_START_BYTE = 0x16, - CBOR_UNEXPECTED_EOF_EXPECTED_VALUE = 0x17, - CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x18, - CBOR_UNEXPECTED_EOF_IN_MAP = 0x19, - CBOR_INVALID_MAP_KEY = 0x1a, - CBOR_STACK_LIMIT_EXCEEDED = 0x1b, - CBOR_STRING8_MUST_BE_7BIT = 0x1c, - CBOR_TRAILING_JUNK = 0x1d, - CBOR_MAP_START_EXPECTED = 0x1e, -}; - -// A status value with position that can be copied. The default status -// is OK. Usually, error status values should come with a valid position. -struct Status { - static constexpr std::ptrdiff_t npos() { return -1; } - - bool ok() const { return error == Error::OK; } - - Error error = Error::OK; - std::ptrdiff_t pos = npos(); - Status(Error error, std::ptrdiff_t pos) : error(error), pos(pos) {} - Status() = default; -}; - -// ===== encoding/span.h ===== +// ============================================================================= +// span - sequence of bytes +// ============================================================================= // This template is similar to std::span, which will be included in C++20. Like // std::span it uses ptrdiff_t, which is signed (and thus a bit annoying @@ -107,19 +53,78 @@ index_type size_; }; -// ===== encoding/json_parser_handler.h ===== +template <typename T> +span<T> SpanFromVector(const std::vector<T>& v) { + return span<T>(v.data(), v.size()); +} -// Handler interface for JSON parser events. See also json_parser.h. -class JSONParserHandler { +inline span<uint8_t> SpanFromStdString(const std::string& v) { + return span<uint8_t>(reinterpret_cast<const uint8_t*>(v.data()), v.size()); +} + +// Error codes. +enum class Error { + OK = 0, + // JSON parsing errors - json_parser.{h,cc}. + JSON_PARSER_UNPROCESSED_INPUT_REMAINS = 0x01, + JSON_PARSER_STACK_LIMIT_EXCEEDED = 0x02, + JSON_PARSER_NO_INPUT = 0x03, + JSON_PARSER_INVALID_TOKEN = 0x04, + JSON_PARSER_INVALID_NUMBER = 0x05, + JSON_PARSER_INVALID_STRING = 0x06, + JSON_PARSER_UNEXPECTED_ARRAY_END = 0x07, + JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED = 0x08, + JSON_PARSER_STRING_LITERAL_EXPECTED = 0x09, + JSON_PARSER_COLON_EXPECTED = 0x0a, + JSON_PARSER_UNEXPECTED_MAP_END = 0x0b, + JSON_PARSER_COMMA_OR_MAP_END_EXPECTED = 0x0c, + JSON_PARSER_VALUE_EXPECTED = 0x0d, + + CBOR_INVALID_INT32 = 0x0e, + CBOR_INVALID_DOUBLE = 0x0f, + CBOR_INVALID_ENVELOPE = 0x10, + CBOR_INVALID_STRING8 = 0x11, + CBOR_INVALID_STRING16 = 0x12, + CBOR_INVALID_BINARY = 0x13, + CBOR_UNSUPPORTED_VALUE = 0x14, + CBOR_NO_INPUT = 0x15, + CBOR_INVALID_START_BYTE = 0x16, + CBOR_UNEXPECTED_EOF_EXPECTED_VALUE = 0x17, + CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x18, + CBOR_UNEXPECTED_EOF_IN_MAP = 0x19, + CBOR_INVALID_MAP_KEY = 0x1a, + CBOR_STACK_LIMIT_EXCEEDED = 0x1b, + CBOR_STRING8_MUST_BE_7BIT = 0x1c, + CBOR_TRAILING_JUNK = 0x1d, + CBOR_MAP_START_EXPECTED = 0x1e, +}; + +// A status value with position that can be copied. The default status +// is OK. Usually, error status values should come with a valid position. +struct Status { + static constexpr std::ptrdiff_t npos() { return -1; } + + bool ok() const { return error == Error::OK; } + + Error error = Error::OK; + std::ptrdiff_t pos = npos(); + Status(Error error, std::ptrdiff_t pos) : error(error), pos(pos) {} + Status() = default; +}; + +// Handler interface for parser events emitted by a streaming parser. +// See cbor::NewCBOREncoder, cbor::ParseCBOR, json::NewJSONEncoder, +// json::ParseJSON. +class StreamingParserHandler { public: - virtual ~JSONParserHandler() = default; - virtual void HandleObjectBegin() = 0; - virtual void HandleObjectEnd() = 0; + virtual ~StreamingParserHandler() = default; + virtual void HandleMapBegin() = 0; + virtual void HandleMapEnd() = 0; virtual void HandleArrayBegin() = 0; virtual void HandleArrayEnd() = 0; virtual void HandleString8(span<uint8_t> chars) = 0; virtual void HandleString16(span<uint16_t> chars) = 0; - virtual void HandleBinary(std::vector<uint8_t> bytes) = 0; + virtual void HandleBinary(span<uint8_t> bytes) = 0; virtual void HandleDouble(double value) = 0; virtual void HandleInt32(int32_t value) = 0; virtual void HandleBool(bool value) = 0; @@ -132,97 +137,7 @@ virtual void HandleError(Status error) = 0; }; -// ===== encoding/cbor_internals.h ===== - namespace cbor { -enum class MajorType; -} - -namespace cbor_internals { - -// Reads the start of a token with definitive size from |bytes|. -// |type| is the major type as specified in RFC 7049 Section 2.1. -// |value| is the payload (e.g. for MajorType::UNSIGNED) or is the size -// (e.g. for BYTE_STRING). -// If successful, returns the number of bytes read. Otherwise returns -1. -int8_t ReadTokenStart(span<uint8_t> bytes, cbor::MajorType* type, - uint64_t* value); - -// Writes the start of a token with |type|. The |value| may indicate the size, -// or it may be the payload if the value is an unsigned integer. -void WriteTokenStart(cbor::MajorType type, uint64_t value, - std::vector<uint8_t>* encoded); -} // namespace cbor_internals - -// ===== encoding/cbor.h ===== - - -namespace cbor { - -// The major types from RFC 7049 Section 2.1. -enum class MajorType { - UNSIGNED = 0, - NEGATIVE = 1, - BYTE_STRING = 2, - STRING = 3, - ARRAY = 4, - MAP = 5, - TAG = 6, - SIMPLE_VALUE = 7 -}; - -// Indicates the number of bits the "initial byte" needs to be shifted to the -// right after applying |kMajorTypeMask| to produce the major type in the -// lowermost bits. -static constexpr uint8_t kMajorTypeBitShift = 5u; -// Mask selecting the low-order 5 bits of the "initial byte", which is where -// the additional information is encoded. -static constexpr uint8_t kAdditionalInformationMask = 0x1f; -// Mask selecting the high-order 3 bits of the "initial byte", which indicates -// the major type of the encoded value. -static constexpr uint8_t kMajorTypeMask = 0xe0; -// Indicates the integer is in the following byte. -static constexpr uint8_t kAdditionalInformation1Byte = 24u; -// Indicates the integer is in the next 2 bytes. -static constexpr uint8_t kAdditionalInformation2Bytes = 25u; -// Indicates the integer is in the next 4 bytes. -static constexpr uint8_t kAdditionalInformation4Bytes = 26u; -// Indicates the integer is in the next 8 bytes. -static constexpr uint8_t kAdditionalInformation8Bytes = 27u; - -// Encodes the initial byte, consisting of the |type| in the first 3 bits -// followed by 5 bits of |additional_info|. -constexpr uint8_t EncodeInitialByte(MajorType type, uint8_t additional_info) { - return (static_cast<uint8_t>(type) << kMajorTypeBitShift) | - (additional_info & kAdditionalInformationMask); -} - -// TAG 24 indicates that what follows is a byte string which is -// encoded in CBOR format. We use this as a wrapper for -// maps and arrays, allowing us to skip them, because the -// byte string carries its size (byte length). -// https://tools.ietf.org/html/rfc7049#section-2.4.4.1 -static constexpr uint8_t kInitialByteForEnvelope = - EncodeInitialByte(MajorType::TAG, 24); -// The initial byte for a byte string with at most 2^32 bytes -// of payload. This is used for envelope encoding, even if -// the byte string is shorter. -static constexpr uint8_t kInitialByteFor32BitLengthByteString = - EncodeInitialByte(MajorType::BYTE_STRING, 26); - -// See RFC 7049 Section 2.2.1, indefinite length arrays / maps have additional -// info = 31. -static constexpr uint8_t kInitialByteIndefiniteLengthArray = - EncodeInitialByte(MajorType::ARRAY, 31); -static constexpr uint8_t kInitialByteIndefiniteLengthMap = - EncodeInitialByte(MajorType::MAP, 31); -// See RFC 7049 Section 2.3, Table 1; this is used for finishing indefinite -// length maps / arrays. -static constexpr uint8_t kStopByte = - EncodeInitialByte(MajorType::SIMPLE_VALUE, 31); - -} // namespace cbor - // The binary encoding for the inspector protocol follows the CBOR specification // (RFC 7049). Additional constraints: // - Only indefinite length maps and arrays are supported. @@ -239,12 +154,38 @@ // as CBOR BYTE_STRING (major type 2). For such strings, the number of // bytes encoded must be even. // - UTF8 strings (major type 3) are supported. -// - 7 bit US-ASCII strings must always be encoded as UTF8 strings, not +// - 7 bit US-ASCII strings must always be encoded as UTF8 strings, never // as UTF16 strings. // - Arbitrary byte arrays, in the inspector protocol called 'binary', // are encoded as BYTE_STRING (major type 2), prefixed with a byte // indicating base64 when rendered as JSON. +// ============================================================================= +// Detecting CBOR content +// ============================================================================= + +// The first byte for an envelope, which we use for wrapping dictionaries +// and arrays; and the byte that indicates a byte string with 32 bit length. +// These two bytes start an envelope, and thereby also any CBOR message +// produced or consumed by this protocol. See also |EnvelopeEncoder| below. +uint8_t InitialByteForEnvelope(); +uint8_t InitialByteFor32BitLengthByteString(); + +// Checks whether |msg| is a cbor message. +bool IsCBORMessage(span<uint8_t> msg); + +// ============================================================================= +// Encoding individual CBOR items +// ============================================================================= + +// Some constants for CBOR tokens that only take a single byte on the wire. +uint8_t EncodeTrue(); +uint8_t EncodeFalse(); +uint8_t EncodeNull(); +uint8_t EncodeIndefiniteLengthArrayStart(); +uint8_t EncodeIndefiniteLengthMapStart(); +uint8_t EncodeStop(); + // Encodes |value| as |UNSIGNED| (major type 0) iff >= 0, or |NEGATIVE| // (major type 1) iff < 0. void EncodeInt32(int32_t value, std::vector<uint8_t>* out); @@ -275,13 +216,9 @@ // with additional info = 27, followed by 8 bytes in big endian. void EncodeDouble(double value, std::vector<uint8_t>* out); -// Some constants for CBOR tokens that only take a single byte on the wire. -uint8_t EncodeTrue(); -uint8_t EncodeFalse(); -uint8_t EncodeNull(); -uint8_t EncodeIndefiniteLengthArrayStart(); -uint8_t EncodeIndefiniteLengthMapStart(); -uint8_t EncodeStop(); +// ============================================================================= +// cbor::EnvelopeEncoder - for wrapping submessages +// ============================================================================= // An envelope indicates the byte length of a wrapped item. // We use this for maps and array, which allows the decoder @@ -304,20 +241,23 @@ std::size_t byte_size_pos_ = 0; }; -// This can be used to convert from JSON to CBOR, by passing the -// return value to the routines in json_parser.h. The handler will encode into -// |out|, and iff an error occurs it will set |status| to an error and clear -// |out|. Otherwise, |status.ok()| will be |true|. -std::unique_ptr<JSONParserHandler> NewJSONToCBOREncoder( - std::vector<uint8_t>* out, Status* status); +// ============================================================================= +// cbor::NewCBOREncoder - for encoding from a streaming parser +// ============================================================================= -// Parses a CBOR encoded message from |bytes|, sending JSON events to -// |json_out|. If an error occurs, sends |out->HandleError|, and parsing stops. -// The client is responsible for discarding the already received information in -// that case. -void ParseCBOR(span<uint8_t> bytes, JSONParserHandler* json_out); +// This can be used to convert to CBOR, by passing the return value to a parser +// that drives it. The handler will encode into |out|, and iff an error occurs +// it will set |status| to an error and clear |out|. Otherwise, |status.ok()| +// will be |true|. +std::unique_ptr<StreamingParserHandler> NewCBOREncoder( + std::vector<uint8_t>* out, + Status* status); -// Tags for the tokens within a CBOR message that CBORStream understands. +// ============================================================================= +// cbor::CBORTokenizer - for parsing individual CBOR items +// ============================================================================= + +// Tags for the tokens within a CBOR message that CBORTokenizer understands. // Note that this is not the same terminology as the CBOR spec (RFC 7049), // but rather, our adaptation. For instance, we lump unsigned and signed // major type into INT32 here (and disallow values outside the int32_t range). @@ -357,6 +297,18 @@ DONE, }; +// The major types from RFC 7049 Section 2.1. +enum class MajorType { + UNSIGNED = 0, + NEGATIVE = 1, + BYTE_STRING = 2, + STRING = 3, + ARRAY = 4, + MAP = 5, + TAG = 6, + SIMPLE_VALUE = 7 +}; + // CBORTokenizer segments a CBOR message, presenting the tokens therein as // numbers, strings, etc. This is not a complete CBOR parser, but makes it much // easier to implement one (e.g. ParseCBOR, above). It can also be used to parse @@ -403,6 +355,9 @@ // To be called only if ::TokenTag() == CBORTokenTag::BINARY. span<uint8_t> GetBinary() const; + // To be called only if ::TokenTag() == CBORTokenTag::ENVELOPE. + span<uint8_t> GetEnvelopeContents() const; + private: void ReadNextToken(bool enter_envelope); void SetToken(CBORTokenTag token, std::ptrdiff_t token_byte_length); @@ -412,14 +367,70 @@ CBORTokenTag token_tag_; struct Status status_; std::ptrdiff_t token_byte_length_; - cbor::MajorType token_start_type_; + MajorType token_start_type_; uint64_t token_start_internal_value_; }; -void DumpCBOR(span<uint8_t> cbor); +// ============================================================================= +// cbor::ParseCBOR - for receiving streaming parser events for CBOR messages +// ============================================================================= +// Parses a CBOR encoded message from |bytes|, sending events to +// |out|. If an error occurs, sends |out->HandleError|, and parsing stops. +// The client is responsible for discarding the already received information in +// that case. +void ParseCBOR(span<uint8_t> bytes, StreamingParserHandler* out); -{% for namespace in config.protocol.namespace %} -} // namespace {{namespace}} -{% endfor %} -#endif // !defined({{"_".join(config.protocol.namespace)}}_CBOR_h) +namespace internals { // Exposed only for writing tests. +int8_t ReadTokenStart(span<uint8_t> bytes, + cbor::MajorType* type, + uint64_t* value); + +void WriteTokenStart(cbor::MajorType type, + uint64_t value, + std::vector<uint8_t>* encoded); +} // namespace internals +} // namespace cbor + +namespace json { +// Client code must provide an instance. Implementation should delegate +// to whatever is appropriate. +class Platform { + public: + virtual ~Platform() = default; + // Parses |str| into |result|. Returns false iff there are + // leftover characters or parsing errors. + virtual bool StrToD(const char* str, double* result) const = 0; + + // Prints |value| in a format suitable for JSON. + virtual std::unique_ptr<char[]> DToStr(double value) const = 0; +}; + +// ============================================================================= +// json::NewJSONEncoder - for encoding streaming parser events as JSON +// ============================================================================= + +// Returns a handler object which will write ascii characters to |out|. +// |status->ok()| will be false iff the handler routine HandleError() is called. +// In that case, we'll stop emitting output. +// Except for calling the HandleError routine at any time, the client +// code must call the Handle* methods in an order in which they'd occur +// in valid JSON; otherwise we may crash (the code uses assert). +std::unique_ptr<StreamingParserHandler> NewJSONEncoder(const Platform* platform, + std::string* out, + Status* status); + +// ============================================================================= +// json::ParseJSON - for receiving streaming parser events for JSON +// ============================================================================= + +void ParseJSON(const Platform* platform, + span<uint8_t> chars, + StreamingParserHandler* handler); +void ParseJSON(const Platform* platform, + span<uint16_t> chars, + StreamingParserHandler* handler); +} // namespace json +} // namespace inspector_protocol_encoding + +#endif // INSPECTOR_PROTOCOL_ENCODING_ENCODING_H_
diff --git a/third_party/inspector_protocol/encoding/encoding_test.cc b/third_party/inspector_protocol/encoding/encoding_test.cc new file mode 100644 index 0000000..6efe83d --- /dev/null +++ b/third_party/inspector_protocol/encoding/encoding_test.cc
@@ -0,0 +1,1595 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "encoding.h" + +#include <array> +#include <clocale> +#include <cmath> +#include <cstdlib> +#include <cstring> +#include <iomanip> +#include <iostream> +#include <sstream> +#include <string> + +#include "base/logging.h" +#include "base/strings/utf_string_conversions.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::ElementsAreArray; + +namespace inspector_protocol_encoding { + +std::string UTF16ToUTF8(span<uint16_t> in) { + std::string out; + bool success = base::UTF16ToUTF8( + reinterpret_cast<const base::char16*>(in.data()), in.size(), &out); + CHECK(success); + return out; +} + +std::vector<uint16_t> UTF8ToUTF16(span<uint8_t> in) { + base::string16 tmp; + bool success = base::UTF8ToUTF16(reinterpret_cast<const char*>(in.data()), + in.size(), &tmp); + CHECK(success); + return std::vector<uint16_t>(tmp.begin(), tmp.end()); +} + +class TestPlatform : public json::Platform { + bool StrToD(const char* str, double* result) const override { + // This is not thread-safe + // (see https://en.cppreference.com/w/cpp/locale/setlocale) + // but good enough for a unittest. + const char* saved_locale = std::setlocale(LC_NUMERIC, nullptr); + char* end; + *result = std::strtod(str, &end); + std::setlocale(LC_NUMERIC, saved_locale); + if (errno == ERANGE) { + // errno must be reset, e.g. see the example here: + // https://en.cppreference.com/w/cpp/string/byte/strtof + errno = 0; + return false; + } + return end == str + strlen(str); + } + + std::unique_ptr<char[]> DToStr(double value) const override { + std::stringstream ss; + ss.imbue(std::locale("C")); + ss << value; + std::string str = ss.str(); + std::unique_ptr<char[]> result(new char[str.size() + 1]); + memcpy(result.get(), str.c_str(), str.size() + 1); + return result; + } +}; + +json::Platform* GetTestPlatform() { + static TestPlatform* platform = new TestPlatform; + return platform; +} + +// ============================================================================= +// span - sequence of bytes +// ============================================================================= + +template <typename T> +class SpanTest : public ::testing::Test {}; + +using TestTypes = ::testing::Types<uint8_t, uint16_t>; +TYPED_TEST_SUITE(SpanTest, TestTypes); + +TYPED_TEST(SpanTest, Empty) { + span<TypeParam> empty; + EXPECT_TRUE(empty.empty()); + EXPECT_EQ(0, empty.size()); + EXPECT_EQ(0, empty.size_bytes()); + EXPECT_EQ(empty.begin(), empty.end()); +} + +TYPED_TEST(SpanTest, SingleItem) { + TypeParam single_item = 42; + span<TypeParam> singular(&single_item, 1); + EXPECT_FALSE(singular.empty()); + EXPECT_EQ(1, singular.size()); + EXPECT_EQ(sizeof(TypeParam), static_cast<size_t>(singular.size_bytes())); + EXPECT_EQ(singular.begin() + 1, singular.end()); + EXPECT_EQ(42, singular[0]); +} + +TYPED_TEST(SpanTest, FiveItems) { + std::vector<TypeParam> test_input = {31, 32, 33, 34, 35}; + span<TypeParam> five_items(test_input.data(), 5); + EXPECT_FALSE(five_items.empty()); + EXPECT_EQ(5, five_items.size()); + EXPECT_EQ(sizeof(TypeParam) * 5, + static_cast<size_t>(five_items.size_bytes())); + EXPECT_EQ(five_items.begin() + 5, five_items.end()); + EXPECT_EQ(31, five_items[0]); + EXPECT_EQ(32, five_items[1]); + EXPECT_EQ(33, five_items[2]); + EXPECT_EQ(34, five_items[3]); + EXPECT_EQ(35, five_items[4]); + span<TypeParam> three_items = five_items.subspan(2); + EXPECT_EQ(3, three_items.size()); + EXPECT_EQ(33, three_items[0]); + EXPECT_EQ(34, three_items[1]); + EXPECT_EQ(35, three_items[2]); + span<TypeParam> two_items = five_items.subspan(2, 2); + EXPECT_EQ(2, two_items.size()); + EXPECT_EQ(33, two_items[0]); + EXPECT_EQ(34, two_items[1]); +} + +namespace cbor { + +// ============================================================================= +// Detecting CBOR content +// ============================================================================= + +TEST(IsCBORMessage, SomeSmokeTests) { + std::vector<uint8_t> empty; + EXPECT_FALSE(IsCBORMessage(SpanFromVector(empty))); + std::vector<uint8_t> hello = {'H', 'e', 'l', 'o', ' ', 't', + 'h', 'e', 'r', 'e', '!'}; + EXPECT_FALSE(IsCBORMessage(SpanFromVector(hello))); + std::vector<uint8_t> example = {0xd8, 0x5a, 0, 0, 0, 0}; + EXPECT_TRUE(IsCBORMessage(SpanFromVector(example))); + std::vector<uint8_t> one = {0xd8, 0x5a, 0, 0, 0, 1, 1}; + EXPECT_TRUE(IsCBORMessage(SpanFromVector(one))); +} + +// ============================================================================= +// Encoding individual CBOR items +// cbor::CBORTokenizer - for parsing individual CBOR items +// ============================================================================= + +// +// EncodeInt32 / CBORTokenTag::INT32 +// +TEST(EncodeDecodeInt32Test, Roundtrips23) { + // This roundtrips the int32_t value 23 through the pair of EncodeInt32 / + // CBORTokenizer; this is interesting since 23 is encoded as a single byte. + std::vector<uint8_t> encoded; + EncodeInt32(23, &encoded); + // first three bits: major type = 0; remaining five bits: additional info = + // value 23. + EXPECT_THAT(encoded, ElementsAreArray(std::array<uint8_t, 1>{{23}})); + + // Reverse direction: decode with CBORTokenizer. + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag()); + EXPECT_EQ(23, tokenizer.GetInt32()); + tokenizer.Next(); + EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); +} + +TEST(EncodeDecodeInt32Test, RoundtripsUint8) { + // This roundtrips the int32_t value 42 through the pair of EncodeInt32 / + // CBORTokenizer. This is different from Roundtrip23 because 42 is encoded + // in an extra byte after the initial one. + std::vector<uint8_t> encoded; + EncodeInt32(42, &encoded); + // first three bits: major type = 0; + // remaining five bits: additional info = 24, indicating payload is uint8. + EXPECT_THAT(encoded, ElementsAreArray(std::array<uint8_t, 2>{{24, 42}})); + + // Reverse direction: decode with CBORTokenizer. + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag()); + EXPECT_EQ(42, tokenizer.GetInt32()); + tokenizer.Next(); + EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); +} + +TEST(EncodeDecodeInt32Test, RoundtripsUint16) { + // 500 is encoded as a uint16 after the initial byte. + std::vector<uint8_t> encoded; + EncodeInt32(500, &encoded); + // 1 for initial byte, 2 for uint16. + EXPECT_EQ(static_cast<std::size_t>(3), encoded.size()); + // first three bits: major type = 0; + // remaining five bits: additional info = 25, indicating payload is uint16. + EXPECT_EQ(25, encoded[0]); + EXPECT_EQ(0x01, encoded[1]); + EXPECT_EQ(0xf4, encoded[2]); + + // Reverse direction: decode with CBORTokenizer. + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag()); + EXPECT_EQ(500, tokenizer.GetInt32()); + tokenizer.Next(); + EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); +} + +TEST(EncodeDecodeInt32Test, RoundtripsInt32Max) { + // std::numeric_limits<int32_t> is encoded as a uint32 after the initial byte. + std::vector<uint8_t> encoded; + EncodeInt32(std::numeric_limits<int32_t>::max(), &encoded); + // 1 for initial byte, 4 for the uint32. + // first three bits: major type = 0; + // remaining five bits: additional info = 26, indicating payload is uint32. + EXPECT_THAT( + encoded, + ElementsAreArray(std::array<uint8_t, 5>{{26, 0x7f, 0xff, 0xff, 0xff}})); + + // Reverse direction: decode with CBORTokenizer. + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag()); + EXPECT_EQ(std::numeric_limits<int32_t>::max(), tokenizer.GetInt32()); + tokenizer.Next(); + EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); +} + +TEST(EncodeDecodeInt32Test, CantRoundtripUint32) { + // 0xdeadbeef is a value which does not fit below + // std::numerical_limits<int32_t>::max(), so we can't encode + // it with EncodeInt32. However, CBOR does support this, so we + // encode it here manually with the internal routine, just to observe + // that it's considered an invalid int32 by CBORTokenizer. + std::vector<uint8_t> encoded; + internals::WriteTokenStart(MajorType::UNSIGNED, 0xdeadbeef, &encoded); + // 1 for initial byte, 4 for the uint32. + // first three bits: major type = 0; + // remaining five bits: additional info = 26, indicating payload is uint32. + EXPECT_THAT( + encoded, + ElementsAreArray(std::array<uint8_t, 5>{{26, 0xde, 0xad, 0xbe, 0xef}})); + + // Now try to decode; we treat this as an invalid INT32. + CBORTokenizer tokenizer(SpanFromVector(encoded)); + // 0xdeadbeef is > std::numerical_limits<int32_t>::max(). + EXPECT_EQ(CBORTokenTag::ERROR_VALUE, tokenizer.TokenTag()); + EXPECT_EQ(Error::CBOR_INVALID_INT32, tokenizer.Status().error); +} + +TEST(EncodeDecodeInt32Test, DecodeErrorCases) { + struct TestCase { + std::vector<uint8_t> data; + std::string msg; + }; + std::vector<TestCase> tests{ + {TestCase{ + {24}, + "additional info = 24 would require 1 byte of payload (but it's 0)"}, + TestCase{{27, 0xaa, 0xbb, 0xcc}, + "additional info = 27 would require 8 bytes of payload (but " + "it's 3)"}, + TestCase{{29}, "additional info = 29 isn't recognized"}}}; + + for (const TestCase& test : tests) { + SCOPED_TRACE(test.msg); + CBORTokenizer tokenizer(SpanFromVector(test.data)); + EXPECT_EQ(CBORTokenTag::ERROR_VALUE, tokenizer.TokenTag()); + EXPECT_EQ(Error::CBOR_INVALID_INT32, tokenizer.Status().error); + } +} + +TEST(EncodeDecodeInt32Test, RoundtripsMinus24) { + // This roundtrips the int32_t value -24 through the pair of EncodeInt32 / + // CBORTokenizer; this is interesting since -24 is encoded as + // a single byte as NEGATIVE, and it tests the specific encoding + // (note how for unsigned the single byte covers values up to 23). + // Additional examples are covered in RoundtripsAdditionalExamples. + std::vector<uint8_t> encoded; + EncodeInt32(-24, &encoded); + // first three bits: major type = 1; remaining five bits: additional info = + // value 23. + EXPECT_THAT(encoded, ElementsAreArray(std::array<uint8_t, 1>{{1 << 5 | 23}})); + + // Reverse direction: decode with CBORTokenizer. + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag()); + EXPECT_EQ(-24, tokenizer.GetInt32()); + tokenizer.Next(); + EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); +} + +TEST(EncodeDecodeInt32Test, RoundtripsAdditionalNegativeExamples) { + std::vector<int32_t> examples = {-1, + -10, + -24, + -25, + -300, + -30000, + -300 * 1000, + -1000 * 1000, + -1000 * 1000 * 1000, + std::numeric_limits<int32_t>::min()}; + for (int32_t example : examples) { + SCOPED_TRACE(std::string("example ") + std::to_string(example)); + std::vector<uint8_t> encoded; + EncodeInt32(example, &encoded); + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::INT32, tokenizer.TokenTag()); + EXPECT_EQ(example, tokenizer.GetInt32()); + tokenizer.Next(); + EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); + } +} + +// +// EncodeString16 / CBORTokenTag::STRING16 +// +TEST(EncodeDecodeString16Test, RoundtripsEmpty) { + // This roundtrips the empty utf16 string through the pair of EncodeString16 / + // CBORTokenizer. + std::vector<uint8_t> encoded; + EncodeString16(span<uint16_t>(), &encoded); + EXPECT_EQ(static_cast<std::size_t>(1), encoded.size()); + // first three bits: major type = 2; remaining five bits: additional info = + // size 0. + EXPECT_EQ(2 << 5, encoded[0]); + + // Reverse direction: decode with CBORTokenizer. + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::STRING16, tokenizer.TokenTag()); + span<uint8_t> decoded_string16_wirerep = tokenizer.GetString16WireRep(); + EXPECT_TRUE(decoded_string16_wirerep.empty()); + tokenizer.Next(); + EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); +} + +// On the wire, we STRING16 is encoded as little endian (least +// significant byte first). The host may or may not be little endian, +// so this routine follows the advice in +// https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html. +std::vector<uint16_t> String16WireRepToHost(span<uint8_t> in) { + CHECK_EQ(in.size() & 1, 0); // must be even number of bytes. + std::vector<uint16_t> host_out; + for (std::ptrdiff_t ii = 0; ii < in.size(); ii += 2) + host_out.push_back(in[ii + 1] << 8 | in[ii]); + return host_out; +} + +TEST(EncodeDecodeString16Test, RoundtripsHelloWorld) { + // This roundtrips the hello world message which is given here in utf16 + // characters. 0xd83c, 0xdf0e: UTF16 encoding for the "Earth Globe Americas" + // character, 🌎. + std::array<uint16_t, 10> msg{ + {'H', 'e', 'l', 'l', 'o', ',', ' ', 0xd83c, 0xdf0e, '.'}}; + std::vector<uint8_t> encoded; + EncodeString16(span<uint16_t>(msg.data(), msg.size()), &encoded); + // This will be encoded as BYTE_STRING of length 20, so the 20 is encoded in + // the additional info part of the initial byte. Payload is two bytes for each + // UTF16 character. + uint8_t initial_byte = /*major type=*/2 << 5 | /*additional info=*/20; + std::array<uint8_t, 21> encoded_expected = { + {initial_byte, 'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o', 0, + ',', 0, ' ', 0, 0x3c, 0xd8, 0x0e, 0xdf, '.', 0}}; + EXPECT_THAT(encoded, ElementsAreArray(encoded_expected)); + + // Now decode to complete the roundtrip. + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::STRING16, tokenizer.TokenTag()); + std::vector<uint16_t> decoded = + String16WireRepToHost(tokenizer.GetString16WireRep()); + EXPECT_THAT(decoded, ElementsAreArray(msg)); + tokenizer.Next(); + EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); + + // For bonus points, we look at the decoded message in UTF8 as well so we can + // easily see it on the terminal screen. + std::string utf8_decoded = UTF16ToUTF8(SpanFromVector(decoded)); + EXPECT_EQ("Hello, 🌎.", utf8_decoded); +} + +TEST(EncodeDecodeString16Test, Roundtrips500) { + // We roundtrip a message that has 250 16 bit values. Each of these are just + // set to their index. 250 is interesting because the cbor spec uses a + // BYTE_STRING of length 500 for one of their examples of how to encode the + // start of it (section 2.1) so it's easy for us to look at the first three + // bytes closely. + std::vector<uint16_t> two_fifty; + for (uint16_t ii = 0; ii < 250; ++ii) + two_fifty.push_back(ii); + std::vector<uint8_t> encoded; + EncodeString16(span<uint16_t>(two_fifty.data(), two_fifty.size()), &encoded); + EXPECT_EQ(static_cast<std::size_t>(3 + 250 * 2), encoded.size()); + // Now check the first three bytes: + // Major type: 2 (BYTE_STRING) + // Additional information: 25, indicating size is represented by 2 bytes. + // Bytes 1 and 2 encode 500 (0x01f4). + EXPECT_EQ(2 << 5 | 25, encoded[0]); + EXPECT_EQ(0x01, encoded[1]); + EXPECT_EQ(0xf4, encoded[2]); + + // Now decode to complete the roundtrip. + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::STRING16, tokenizer.TokenTag()); + std::vector<uint16_t> decoded = + String16WireRepToHost(tokenizer.GetString16WireRep()); + EXPECT_THAT(decoded, ElementsAreArray(two_fifty)); + tokenizer.Next(); + EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); +} + +TEST(EncodeDecodeString16Test, ErrorCases) { + struct TestCase { + std::vector<uint8_t> data; + std::string msg; + }; + std::vector<TestCase> tests{ + {TestCase{{2 << 5 | 1, 'a'}, + "length must be divisible by 2 (but it's 1)"}, + TestCase{{2 << 5 | 29}, "additional info = 29 isn't recognized"}}}; + for (const TestCase& test : tests) { + SCOPED_TRACE(test.msg); + CBORTokenizer tokenizer(SpanFromVector(test.data)); + EXPECT_EQ(CBORTokenTag::ERROR_VALUE, tokenizer.TokenTag()); + EXPECT_EQ(Error::CBOR_INVALID_STRING16, tokenizer.Status().error); + } +} + +// +// EncodeString8 / CBORTokenTag::STRING8 +// +TEST(EncodeDecodeString8Test, RoundtripsHelloWorld) { + // This roundtrips the hello world message which is given here in utf8 + // characters. 🌎 is a four byte utf8 character. + std::string utf8_msg = "Hello, 🌎."; + std::vector<uint8_t> msg(utf8_msg.begin(), utf8_msg.end()); + std::vector<uint8_t> encoded; + EncodeString8(SpanFromStdString(utf8_msg), &encoded); + // This will be encoded as STRING of length 12, so the 12 is encoded in + // the additional info part of the initial byte. Payload is one byte per + // utf8 byte. + uint8_t initial_byte = /*major type=*/3 << 5 | /*additional info=*/12; + std::array<uint8_t, 13> encoded_expected = {{initial_byte, 'H', 'e', 'l', 'l', + 'o', ',', ' ', 0xF0, 0x9f, 0x8c, + 0x8e, '.'}}; + EXPECT_THAT(encoded, ElementsAreArray(encoded_expected)); + + // Now decode to complete the roundtrip. + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::STRING8, tokenizer.TokenTag()); + std::vector<uint8_t> decoded(tokenizer.GetString8().begin(), + tokenizer.GetString8().end()); + EXPECT_THAT(decoded, ElementsAreArray(msg)); + tokenizer.Next(); + EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); +} + +TEST(EncodeFromLatin1Test, ConvertsToUTF8IfNeeded) { + std::vector<std::pair<std::string, std::string>> examples = { + {"Hello, world.", "Hello, world."}, + {"Above: \xDC" + "ber", + "Above: Über"}, + {"\xA5 500 are about \xA3 3.50; a y with umlaut is \xFF", + "¥ 500 are about £ 3.50; a y with umlaut is ÿ"}}; + + for (const auto& example : examples) { + const std::string& latin1 = example.first; + const std::string& expected_utf8 = example.second; + std::vector<uint8_t> encoded; + EncodeFromLatin1(SpanFromStdString(latin1), &encoded); + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::STRING8, tokenizer.TokenTag()); + std::vector<uint8_t> decoded(tokenizer.GetString8().begin(), + tokenizer.GetString8().end()); + std::string decoded_str(decoded.begin(), decoded.end()); + EXPECT_THAT(decoded_str, testing::Eq(expected_utf8)); + } +} + +TEST(EncodeFromUTF16Test, ConvertsToUTF8IfEasy) { + std::vector<uint16_t> ascii = {'e', 'a', 's', 'y'}; + std::vector<uint8_t> encoded; + EncodeFromUTF16(span<uint16_t>(ascii.data(), ascii.size()), &encoded); + + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::STRING8, tokenizer.TokenTag()); + std::vector<uint8_t> decoded(tokenizer.GetString8().begin(), + tokenizer.GetString8().end()); + std::string decoded_str(decoded.begin(), decoded.end()); + EXPECT_THAT(decoded_str, testing::Eq("easy")); +} + +TEST(EncodeFromUTF16Test, EncodesAsString16IfNeeded) { + // Since this message contains non-ASCII characters, the routine is + // forced to encode as UTF16. We see this below by checking that the + // token tag is STRING16. + std::vector<uint16_t> msg = {'H', 'e', 'l', 'l', 'o', + ',', ' ', 0xd83c, 0xdf0e, '.'}; + std::vector<uint8_t> encoded; + EncodeFromUTF16(span<uint16_t>(msg.data(), msg.size()), &encoded); + + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::STRING16, tokenizer.TokenTag()); + std::vector<uint16_t> decoded = + String16WireRepToHost(tokenizer.GetString16WireRep()); + std::string utf8_decoded = UTF16ToUTF8(SpanFromVector(decoded)); + EXPECT_EQ("Hello, 🌎.", utf8_decoded); +} + +// +// EncodeBinary / CBORTokenTag::BINARY +// +TEST(EncodeDecodeBinaryTest, RoundtripsHelloWorld) { + std::vector<uint8_t> binary = {'H', 'e', 'l', 'l', 'o', ',', ' ', + 'w', 'o', 'r', 'l', 'd', '.'}; + std::vector<uint8_t> encoded; + EncodeBinary(span<uint8_t>(binary.data(), binary.size()), &encoded); + // So, on the wire we see that the binary blob travels unmodified. + EXPECT_THAT( + encoded, + ElementsAreArray(std::array<uint8_t, 15>{ + {(6 << 5 | 22), // tag 22 indicating base64 interpretation in JSON + (2 << 5 | 13), // BYTE_STRING (type 2) of length 13 + 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '.'}})); + std::vector<uint8_t> decoded; + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::BINARY, tokenizer.TokenTag()); + EXPECT_EQ(0, int(tokenizer.Status().error)); + decoded = std::vector<uint8_t>(tokenizer.GetBinary().begin(), + tokenizer.GetBinary().end()); + EXPECT_THAT(decoded, ElementsAreArray(binary)); + tokenizer.Next(); + EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); +} + +// +// EncodeDouble / CBORTokenTag::DOUBLE +// +TEST(EncodeDecodeDoubleTest, RoundtripsWikipediaExample) { + // https://en.wikipedia.org/wiki/Double-precision_floating-point_format + // provides the example of a hex representation 3FD5 5555 5555 5555, which + // approximates 1/3. + + const double kOriginalValue = 1.0 / 3; + std::vector<uint8_t> encoded; + EncodeDouble(kOriginalValue, &encoded); + // first three bits: major type = 7; remaining five bits: additional info = + // value 27. This is followed by 8 bytes of payload (which match Wikipedia). + EXPECT_THAT( + encoded, + ElementsAreArray(std::array<uint8_t, 9>{ + {7 << 5 | 27, 0x3f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55}})); + + // Reverse direction: decode and compare with original value. + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::DOUBLE, tokenizer.TokenTag()); + EXPECT_THAT(tokenizer.GetDouble(), testing::DoubleEq(kOriginalValue)); + tokenizer.Next(); + EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); +} + +TEST(EncodeDecodeDoubleTest, RoundtripsAdditionalExamples) { + std::vector<double> examples = {0.0, + 1.0, + -1.0, + 3.1415, + std::numeric_limits<double>::min(), + std::numeric_limits<double>::max(), + std::numeric_limits<double>::infinity(), + std::numeric_limits<double>::quiet_NaN()}; + for (double example : examples) { + SCOPED_TRACE(std::string("example ") + std::to_string(example)); + std::vector<uint8_t> encoded; + EncodeDouble(example, &encoded); + CBORTokenizer tokenizer(SpanFromVector(encoded)); + EXPECT_EQ(CBORTokenTag::DOUBLE, tokenizer.TokenTag()); + if (std::isnan(example)) + EXPECT_TRUE(std::isnan(tokenizer.GetDouble())); + else + EXPECT_THAT(tokenizer.GetDouble(), testing::DoubleEq(example)); + tokenizer.Next(); + EXPECT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); + } +} + +// ============================================================================= +// cbor::NewCBOREncoder - for encoding from a streaming parser +// ============================================================================= + +void EncodeUTF8ForTest(const std::string& key, std::vector<uint8_t>* out) { + EncodeString8(SpanFromStdString(key), out); +} +TEST(JSONToCBOREncoderTest, SevenBitStrings) { + // When a string can be represented as 7 bit ASCII, the encoder will use the + // STRING (major Type 3) type, so the actual characters end up as bytes on the + // wire. + std::vector<uint8_t> encoded; + Status status; + std::unique_ptr<StreamingParserHandler> encoder = + NewCBOREncoder(&encoded, &status); + std::vector<uint16_t> utf16 = {'f', 'o', 'o'}; + encoder->HandleString16(span<uint16_t>(utf16.data(), utf16.size())); + EXPECT_EQ(Error::OK, status.error); + // Here we assert that indeed, seven bit strings are represented as + // bytes on the wire, "foo" is just "foo". + EXPECT_THAT(encoded, + ElementsAreArray(std::array<uint8_t, 4>{ + {/*major type 3*/ 3 << 5 | /*length*/ 3, 'f', 'o', 'o'}})); +} + +TEST(JsonCborRoundtrip, EncodingDecoding) { + // Hits all the cases except binary and error in StreamingParserHandler, first + // parsing a JSON message into CBOR, then parsing it back from CBOR into JSON. + std::string json = + "{" + "\"string\":\"Hello, \\ud83c\\udf0e.\"," + "\"double\":3.1415," + "\"int\":1," + "\"negative int\":-1," + "\"bool\":true," + "\"null\":null," + "\"array\":[1,2,3]" + "}"; + std::vector<uint8_t> encoded; + Status status; + std::unique_ptr<StreamingParserHandler> encoder = + NewCBOREncoder(&encoded, &status); + span<uint8_t> ascii_in = SpanFromStdString(json); + json::ParseJSON(GetTestPlatform(), ascii_in, encoder.get()); + std::vector<uint8_t> expected = { + 0xd8, // envelope + 0x5a, // byte string with 32 bit length + 0, 0, 0, 94, // length is 94 bytes + }; + expected.push_back(0xbf); // indef length map start + EncodeString8(SpanFromStdString("string"), &expected); + // This is followed by the encoded string for "Hello, 🌎." + // So, it's the same bytes that we tested above in + // EncodeDecodeString16Test.RoundtripsHelloWorld. + expected.push_back(/*major type=*/2 << 5 | /*additional info=*/20); + for (uint8_t ch : std::array<uint8_t, 20>{ + {'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o', 0, + ',', 0, ' ', 0, 0x3c, 0xd8, 0x0e, 0xdf, '.', 0}}) + expected.push_back(ch); + EncodeString8(SpanFromStdString("double"), &expected); + EncodeDouble(3.1415, &expected); + EncodeString8(SpanFromStdString("int"), &expected); + EncodeInt32(1, &expected); + EncodeString8(SpanFromStdString("negative int"), &expected); + EncodeInt32(-1, &expected); + EncodeString8(SpanFromStdString("bool"), &expected); + expected.push_back(7 << 5 | 21); // RFC 7049 Section 2.3, Table 2: true + EncodeString8(SpanFromStdString("null"), &expected); + expected.push_back(7 << 5 | 22); // RFC 7049 Section 2.3, Table 2: null + EncodeString8(SpanFromStdString("array"), &expected); + expected.push_back(0xd8); // envelope + expected.push_back(0x5a); // byte string with 32 bit length + // the length is 5 bytes (that's up to end indef length array below). + for (uint8_t ch : std::array<uint8_t, 4>{{0, 0, 0, 5}}) + expected.push_back(ch); + expected.push_back(0x9f); // RFC 7049 Section 2.2.1, indef length array start + expected.push_back(1); // Three UNSIGNED values (easy since Major Type 0) + expected.push_back(2); + expected.push_back(3); + expected.push_back(0xff); // End indef length array + expected.push_back(0xff); // End indef length map + EXPECT_TRUE(status.ok()); + EXPECT_THAT(encoded, ElementsAreArray(expected)); + + // And now we roundtrip, decoding the message we just encoded. + std::string decoded; + std::unique_ptr<StreamingParserHandler> json_encoder = + NewJSONEncoder(GetTestPlatform(), &decoded, &status); + ParseCBOR(span<uint8_t>(encoded.data(), encoded.size()), json_encoder.get()); + EXPECT_EQ(Error::OK, status.error); + EXPECT_EQ(json, decoded); +} + +TEST(JsonCborRoundtrip, MoreRoundtripExamples) { + std::vector<std::string> examples = { + // Tests that after closing a nested objects, additional key/value pairs + // are considered. + "{\"foo\":{\"bar\":1},\"baz\":2}", "{\"foo\":[1,2,3],\"baz\":2}"}; + for (const std::string& json : examples) { + SCOPED_TRACE(std::string("example: ") + json); + std::vector<uint8_t> encoded; + Status status; + std::unique_ptr<StreamingParserHandler> encoder = + NewCBOREncoder(&encoded, &status); + span<uint8_t> ascii_in = SpanFromStdString(json); + ParseJSON(GetTestPlatform(), ascii_in, encoder.get()); + std::string decoded; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &decoded, &status); + ParseCBOR(span<uint8_t>(encoded.data(), encoded.size()), json_writer.get()); + EXPECT_EQ(Error::OK, status.error); + EXPECT_EQ(json, decoded); + } +} + +TEST(JSONToCBOREncoderTest, HelloWorldBinary_WithTripToJson) { + // The StreamingParserHandler::HandleBinary is a special case: The JSON parser + // will never call this method, because JSON does not natively support the + // binary type. So, we can't fully roundtrip. However, the other direction + // works: binary will be rendered in JSON, as a base64 string. So, we make + // calls to the encoder directly here, to construct a message, and one of + // these calls is ::HandleBinary, to which we pass a "binary" string + // containing "Hello, world.". + std::vector<uint8_t> encoded; + Status status; + std::unique_ptr<StreamingParserHandler> encoder = + NewCBOREncoder(&encoded, &status); + encoder->HandleMapBegin(); + // Emit a key. + std::vector<uint16_t> key = {'f', 'o', 'o'}; + encoder->HandleString16(SpanFromVector(key)); + // Emit the binary payload, an arbitrary array of bytes that happens to + // be the ascii message "Hello, world.". + encoder->HandleBinary(SpanFromVector(std::vector<uint8_t>{ + 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '.'})); + encoder->HandleMapEnd(); + EXPECT_EQ(Error::OK, status.error); + + // Now drive the json writer via the CBOR decoder. + std::string decoded; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &decoded, &status); + ParseCBOR(SpanFromVector(encoded), json_writer.get()); + EXPECT_EQ(Error::OK, status.error); + EXPECT_EQ(Status::npos(), status.pos); + // "Hello, world." in base64 is "SGVsbG8sIHdvcmxkLg==". + EXPECT_EQ("{\"foo\":\"SGVsbG8sIHdvcmxkLg==\"}", decoded); +} + +// ============================================================================= +// cbor::ParseCBOR - for receiving streaming parser events for CBOR messages +// ============================================================================= + +TEST(ParseCBORTest, ParseEmptyCBORMessage) { + // An envelope starting with 0xd8, 0x5a, with the byte length + // of 2, containing a map that's empty (0xbf for map + // start, and 0xff for map end). + std::vector<uint8_t> in = {0xd8, 0x5a, 0, 0, 0, 2, 0xbf, 0xff}; + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(in.data(), in.size()), json_writer.get()); + EXPECT_EQ(Error::OK, status.error); + EXPECT_EQ("{}", out); +} + +TEST(ParseCBORTest, ParseCBORHelloWorld) { + const uint8_t kPayloadLen = 27; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen}; + bytes.push_back(0xbf); // start indef length map. + EncodeString8(SpanFromStdString("msg"), &bytes); // key: msg + // Now write the value, the familiar "Hello, 🌎." where the globe is expressed + // as two utf16 chars. + bytes.push_back(/*major type=*/2 << 5 | /*additional info=*/20); + for (uint8_t ch : std::array<uint8_t, 20>{ + {'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o', 0, + ',', 0, ' ', 0, 0x3c, 0xd8, 0x0e, 0xdf, '.', 0}}) + bytes.push_back(ch); + bytes.push_back(0xff); // stop byte + EXPECT_EQ(kPayloadLen, bytes.size() - 6); + + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::OK, status.error); + EXPECT_EQ("{\"msg\":\"Hello, \\ud83c\\udf0e.\"}", out); +} + +TEST(ParseCBORTest, UTF8IsSupportedInKeys) { + const uint8_t kPayloadLen = 11; + std::vector<uint8_t> bytes = {cbor::InitialByteForEnvelope(), + cbor::InitialByteFor32BitLengthByteString(), + 0, + 0, + 0, + kPayloadLen}; + bytes.push_back(cbor::EncodeIndefiniteLengthMapStart()); + // Two UTF16 chars. + EncodeString8(SpanFromStdString("🌎"), &bytes); + // Can be encoded as a single UTF16 char. + EncodeString8(SpanFromStdString("☾"), &bytes); + bytes.push_back(cbor::EncodeStop()); + EXPECT_EQ(kPayloadLen, bytes.size() - 6); + + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::OK, status.error); + EXPECT_EQ("{\"\\ud83c\\udf0e\":\"\\u263e\"}", out); +} + +TEST(ParseCBORTest, NoInputError) { + std::vector<uint8_t> in = {}; + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(in.data(), in.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_NO_INPUT, status.error); + EXPECT_EQ("", out); +} + +TEST(ParseCBORTest, InvalidStartByteError) { + // Here we test that some actual json, which usually starts with {, + // is not considered CBOR. CBOR messages must start with 0x5a, the + // envelope start byte. + std::string json = "{\"msg\": \"Hello, world.\"}"; + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(SpanFromStdString(json), json_writer.get()); + EXPECT_EQ(Error::CBOR_INVALID_START_BYTE, status.error); + EXPECT_EQ("", out); +} + +TEST(ParseCBORTest, UnexpectedEofExpectedValueError) { + constexpr uint8_t kPayloadLen = 5; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start + // A key; so value would be next. + EncodeString8(SpanFromStdString("key"), &bytes); + EXPECT_EQ(kPayloadLen, bytes.size() - 6); + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE, status.error); + EXPECT_EQ(static_cast<int64_t>(bytes.size()), status.pos); + EXPECT_EQ("", out); +} + +TEST(ParseCBORTest, UnexpectedEofInArrayError) { + constexpr uint8_t kPayloadLen = 8; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // The byte for starting a map. + // A key; so value would be next. + EncodeString8(SpanFromStdString("array"), &bytes); + bytes.push_back(0x9f); // byte for indefinite length array start. + EXPECT_EQ(kPayloadLen, bytes.size() - 6); + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_UNEXPECTED_EOF_IN_ARRAY, status.error); + EXPECT_EQ(static_cast<int64_t>(bytes.size()), status.pos); + EXPECT_EQ("", out); +} + +TEST(ParseCBORTest, UnexpectedEofInMapError) { + constexpr uint8_t kPayloadLen = 1; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // The byte for starting a map. + EXPECT_EQ(kPayloadLen, bytes.size() - 6); + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_UNEXPECTED_EOF_IN_MAP, status.error); + EXPECT_EQ(7, status.pos); + EXPECT_EQ("", out); +} + +TEST(ParseCBORTest, InvalidMapKeyError) { + constexpr uint8_t kPayloadLen = 2; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, + 0, 0, kPayloadLen, // envelope + 0xbf, // map start + 7 << 5 | 22}; // null (not a valid map key) + EXPECT_EQ(kPayloadLen, bytes.size() - 6); + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_INVALID_MAP_KEY, status.error); + EXPECT_EQ(7, status.pos); + EXPECT_EQ("", out); +} + +std::vector<uint8_t> MakeNestedCBOR(int depth) { + std::vector<uint8_t> bytes; + std::vector<EnvelopeEncoder> envelopes; + for (int ii = 0; ii < depth; ++ii) { + envelopes.emplace_back(); + envelopes.back().EncodeStart(&bytes); + bytes.push_back(0xbf); // indef length map start + EncodeString8(SpanFromStdString("key"), &bytes); + } + EncodeString8(SpanFromStdString("innermost_value"), &bytes); + for (int ii = 0; ii < depth; ++ii) { + bytes.push_back(0xff); // stop byte, finishes map. + envelopes.back().EncodeStop(&bytes); + envelopes.pop_back(); + } + return bytes; +} + +TEST(ParseCBORTest, StackLimitExceededError) { + { // Depth 3: no stack limit exceeded error and is easy to inspect. + std::vector<uint8_t> bytes = MakeNestedCBOR(3); + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::OK, status.error); + EXPECT_EQ(Status::npos(), status.pos); + EXPECT_EQ("{\"key\":{\"key\":{\"key\":\"innermost_value\"}}}", out); + } + { // Depth 1000: no stack limit exceeded. + std::vector<uint8_t> bytes = MakeNestedCBOR(1000); + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::OK, status.error); + EXPECT_EQ(Status::npos(), status.pos); + } + + // We just want to know the length of one opening map so we can compute + // where the error is encountered. So we look at a small example and find + // the second envelope start. + std::vector<uint8_t> small_example = MakeNestedCBOR(3); + int64_t opening_segment_size = 1; // Start after the first envelope start. + while (opening_segment_size < static_cast<int64_t>(small_example.size()) && + small_example[opening_segment_size] != 0xd8) + opening_segment_size++; + + { // Depth 1001: limit exceeded. + std::vector<uint8_t> bytes = MakeNestedCBOR(1001); + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_STACK_LIMIT_EXCEEDED, status.error); + EXPECT_EQ(opening_segment_size * 1001, status.pos); + } + { // Depth 1200: still limit exceeded, and at the same pos as for 1001 + std::vector<uint8_t> bytes = MakeNestedCBOR(1200); + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_STACK_LIMIT_EXCEEDED, status.error); + EXPECT_EQ(opening_segment_size * 1001, status.pos); + } +} + +TEST(ParseCBORTest, UnsupportedValueError) { + constexpr uint8_t kPayloadLen = 6; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start + EncodeString8(SpanFromStdString("key"), &bytes); + int64_t error_pos = bytes.size(); + bytes.push_back(6 << 5 | 5); // tags aren't supported yet. + EXPECT_EQ(kPayloadLen, bytes.size() - 6); + + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_UNSUPPORTED_VALUE, status.error); + EXPECT_EQ(error_pos, status.pos); + EXPECT_EQ("", out); +} + +TEST(ParseCBORTest, InvalidString16Error) { + constexpr uint8_t kPayloadLen = 11; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start + EncodeString8(SpanFromStdString("key"), &bytes); + int64_t error_pos = bytes.size(); + // a BYTE_STRING of length 5 as value; since we interpret these as string16, + // it's going to be invalid as each character would need two bytes, but + // 5 isn't divisible by 2. + bytes.push_back(2 << 5 | 5); + for (int ii = 0; ii < 5; ++ii) + bytes.push_back(' '); + EXPECT_EQ(kPayloadLen, bytes.size() - 6); + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_INVALID_STRING16, status.error); + EXPECT_EQ(error_pos, status.pos); + EXPECT_EQ("", out); +} + +TEST(ParseCBORTest, InvalidString8Error) { + constexpr uint8_t kPayloadLen = 6; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start + EncodeString8(SpanFromStdString("key"), &bytes); + int64_t error_pos = bytes.size(); + // a STRING of length 5 as value, but we're at the end of the bytes array + // so it can't be decoded successfully. + bytes.push_back(3 << 5 | 5); + EXPECT_EQ(kPayloadLen, bytes.size() - 6); + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_INVALID_STRING8, status.error); + EXPECT_EQ(error_pos, status.pos); + EXPECT_EQ("", out); +} + +TEST(ParseCBORTest, InvalidBinaryError) { + constexpr uint8_t kPayloadLen = 9; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start + EncodeString8(SpanFromStdString("key"), &bytes); + int64_t error_pos = bytes.size(); + bytes.push_back(6 << 5 | 22); // base64 hint for JSON; indicates binary + bytes.push_back(2 << 5 | 10); // BYTE_STRING (major type 2) of length 10 + // Just two garbage bytes, not enough for the binary. + bytes.push_back(0x31); + bytes.push_back(0x23); + EXPECT_EQ(kPayloadLen, bytes.size() - 6); + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_INVALID_BINARY, status.error); + EXPECT_EQ(error_pos, status.pos); + EXPECT_EQ("", out); +} + +TEST(ParseCBORTest, InvalidDoubleError) { + constexpr uint8_t kPayloadLen = 8; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start + EncodeString8(SpanFromStdString("key"), &bytes); + int64_t error_pos = bytes.size(); + bytes.push_back(7 << 5 | 27); // initial byte for double + // Just two garbage bytes, not enough to represent an actual double. + bytes.push_back(0x31); + bytes.push_back(0x23); + EXPECT_EQ(kPayloadLen, bytes.size() - 6); + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_INVALID_DOUBLE, status.error); + EXPECT_EQ(error_pos, status.pos); + EXPECT_EQ("", out); +} + +TEST(ParseCBORTest, InvalidSignedError) { + constexpr uint8_t kPayloadLen = 14; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start + EncodeString8(SpanFromStdString("key"), &bytes); + int64_t error_pos = bytes.size(); + // uint64_t max is a perfectly fine value to encode as CBOR unsigned, + // but we don't support this since we only cover the int32_t range. + internals::WriteTokenStart(MajorType::UNSIGNED, + std::numeric_limits<uint64_t>::max(), &bytes); + EXPECT_EQ(kPayloadLen, bytes.size() - 6); + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_INVALID_INT32, status.error); + EXPECT_EQ(error_pos, status.pos); + EXPECT_EQ("", out); +} + +TEST(ParseCBORTest, TrailingJunk) { + constexpr uint8_t kPayloadLen = 35; + std::vector<uint8_t> bytes = {0xd8, 0x5a, 0, 0, 0, kPayloadLen, // envelope + 0xbf}; // map start + EncodeString8(SpanFromStdString("key"), &bytes); + EncodeString8(SpanFromStdString("value"), &bytes); + bytes.push_back(0xff); // Up to here, it's a perfectly fine msg. + int64_t error_pos = bytes.size(); + EncodeString8(SpanFromStdString("trailing junk"), &bytes); + + internals::WriteTokenStart(MajorType::UNSIGNED, + std::numeric_limits<uint64_t>::max(), &bytes); + EXPECT_EQ(kPayloadLen, bytes.size() - 6); + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> json_writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + ParseCBOR(span<uint8_t>(bytes.data(), bytes.size()), json_writer.get()); + EXPECT_EQ(Error::CBOR_TRAILING_JUNK, status.error); + EXPECT_EQ(error_pos, status.pos); + EXPECT_EQ("", out); +} +} // namespace cbor + +namespace json { + +// ============================================================================= +// json::NewJSONEncoder - for encoding streaming parser events as JSON +// ============================================================================= + +void WriteUTF8AsUTF16(StreamingParserHandler* writer, const std::string& utf8) { + writer->HandleString16(SpanFromVector(UTF8ToUTF16(SpanFromStdString(utf8)))); +} + +TEST(JsonStdStringWriterTest, HelloWorld) { + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + writer->HandleMapBegin(); + WriteUTF8AsUTF16(writer.get(), "msg1"); + WriteUTF8AsUTF16(writer.get(), "Hello, 🌎."); + std::string key = "msg1-as-utf8"; + std::string value = "Hello, 🌎."; + writer->HandleString8(SpanFromStdString(key)); + writer->HandleString8(SpanFromStdString(value)); + WriteUTF8AsUTF16(writer.get(), "msg2"); + WriteUTF8AsUTF16(writer.get(), "\\\b\r\n\t\f\""); + WriteUTF8AsUTF16(writer.get(), "nested"); + writer->HandleMapBegin(); + WriteUTF8AsUTF16(writer.get(), "double"); + writer->HandleDouble(3.1415); + WriteUTF8AsUTF16(writer.get(), "int"); + writer->HandleInt32(-42); + WriteUTF8AsUTF16(writer.get(), "bool"); + writer->HandleBool(false); + WriteUTF8AsUTF16(writer.get(), "null"); + writer->HandleNull(); + writer->HandleMapEnd(); + WriteUTF8AsUTF16(writer.get(), "array"); + writer->HandleArrayBegin(); + writer->HandleInt32(1); + writer->HandleInt32(2); + writer->HandleInt32(3); + writer->HandleArrayEnd(); + writer->HandleMapEnd(); + EXPECT_TRUE(status.ok()); + EXPECT_EQ( + "{\"msg1\":\"Hello, \\ud83c\\udf0e.\"," + "\"msg1-as-utf8\":\"Hello, \\ud83c\\udf0e.\"," + "\"msg2\":\"\\\\\\b\\r\\n\\t\\f\\\"\"," + "\"nested\":{\"double\":3.1415,\"int\":-42," + "\"bool\":false,\"null\":null},\"array\":[1,2,3]}", + out); +} + +TEST(JsonStdStringWriterTest, BinaryEncodedAsJsonString) { + // The encoder emits binary submitted to StreamingParserHandler::HandleBinary + // as base64. The following three examples are taken from + // https://en.wikipedia.org/wiki/Base64. + { + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + writer->HandleBinary(SpanFromVector(std::vector<uint8_t>({'M', 'a', 'n'}))); + EXPECT_TRUE(status.ok()); + EXPECT_EQ("\"TWFu\"", out); + } + { + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + writer->HandleBinary(SpanFromVector(std::vector<uint8_t>({'M', 'a'}))); + EXPECT_TRUE(status.ok()); + EXPECT_EQ("\"TWE=\"", out); + } + { + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + writer->HandleBinary(SpanFromVector(std::vector<uint8_t>({'M'}))); + EXPECT_TRUE(status.ok()); + EXPECT_EQ("\"TQ==\"", out); + } + { // "Hello, world.", verified with base64decode.org. + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + writer->HandleBinary(SpanFromVector(std::vector<uint8_t>( + {'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '.'}))); + EXPECT_TRUE(status.ok()); + EXPECT_EQ("\"SGVsbG8sIHdvcmxkLg==\"", out); + } +} + +TEST(JsonStdStringWriterTest, HandlesErrors) { + // When an error is sent via HandleError, it saves it in the provided + // status and clears the output. + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> writer = + NewJSONEncoder(GetTestPlatform(), &out, &status); + writer->HandleMapBegin(); + WriteUTF8AsUTF16(writer.get(), "msg1"); + writer->HandleError(Status{Error::JSON_PARSER_VALUE_EXPECTED, 42}); + EXPECT_EQ(Error::JSON_PARSER_VALUE_EXPECTED, status.error); + EXPECT_EQ(42, status.pos); + EXPECT_EQ("", out); +} + +// We'd use Gmock but unfortunately it only handles copyable return types. +class MockPlatform : public Platform { + public: + // Not implemented. + bool StrToD(const char* str, double* result) const override { return false; } + + // A map with pre-registered responses for DToSTr. + std::map<double, std::string> dtostr_responses; + + std::unique_ptr<char[]> DToStr(double value) const override { + auto it = dtostr_responses.find(value); + CHECK(it != dtostr_responses.end()); + const std::string& str = it->second; + std::unique_ptr<char[]> response(new char[str.size() + 1]); + memcpy(response.get(), str.c_str(), str.size() + 1); + return response; + } +}; + +TEST(JsonStdStringWriterTest, DoubleToString) { + // This "broken" platform responds without the leading 0 before the + // decimal dot, so it'd be invalid JSON. + MockPlatform platform; + platform.dtostr_responses[.1] = ".1"; + platform.dtostr_responses[-.7] = "-.7"; + + std::string out; + Status status; + std::unique_ptr<StreamingParserHandler> writer = + NewJSONEncoder(&platform, &out, &status); + writer->HandleArrayBegin(); + writer->HandleDouble(.1); + writer->HandleDouble(-.7); + writer->HandleArrayEnd(); + EXPECT_EQ("[0.1,-0.7]", out); +} + +// ============================================================================= +// json::ParseJSON - for receiving streaming parser events for JSON +// ============================================================================= + +class Log : public StreamingParserHandler { + public: + void HandleMapBegin() override { log_ << "map begin\n"; } + + void HandleMapEnd() override { log_ << "map end\n"; } + + void HandleArrayBegin() override { log_ << "array begin\n"; } + + void HandleArrayEnd() override { log_ << "array end\n"; } + + void HandleString8(span<uint8_t> chars) override { + log_ << "string8: " << std::string(chars.begin(), chars.end()) << "\n"; + } + + void HandleString16(span<uint16_t> chars) override { + log_ << "string16: " << UTF16ToUTF8(chars) << "\n"; + } + + void HandleBinary(span<uint8_t> bytes) override { + // JSON doesn't have native support for arbitrary bytes, so our parser will + // never call this. + CHECK(false); + } + + void HandleDouble(double value) override { + log_ << "double: " << value << "\n"; + } + + void HandleInt32(int32_t value) override { log_ << "int: " << value << "\n"; } + + void HandleBool(bool value) override { log_ << "bool: " << value << "\n"; } + + void HandleNull() override { log_ << "null\n"; } + + void HandleError(Status status) override { status_ = status; } + + std::string str() const { return status_.ok() ? log_.str() : ""; } + + Status status() const { return status_; } + + private: + std::ostringstream log_; + Status status_; +}; + +class JsonParserTest : public ::testing::Test { + protected: + Log log_; +}; + +TEST_F(JsonParserTest, SimpleDictionary) { + std::string json = "{\"foo\": 42}"; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_TRUE(log_.status().ok()); + EXPECT_EQ( + "map begin\n" + "string16: foo\n" + "int: 42\n" + "map end\n", + log_.str()); +} + +TEST_F(JsonParserTest, Whitespace) { + std::string json = "\n {\n\"msg\"\n: \v\"Hello, world.\"\t\r}\t"; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_TRUE(log_.status().ok()); + EXPECT_EQ( + "map begin\n" + "string16: msg\n" + "string16: Hello, world.\n" + "map end\n", + log_.str()); +} + +TEST_F(JsonParserTest, NestedDictionary) { + std::string json = "{\"foo\": {\"bar\": {\"baz\": 1}, \"bar2\": 2}}"; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_TRUE(log_.status().ok()); + EXPECT_EQ( + "map begin\n" + "string16: foo\n" + "map begin\n" + "string16: bar\n" + "map begin\n" + "string16: baz\n" + "int: 1\n" + "map end\n" + "string16: bar2\n" + "int: 2\n" + "map end\n" + "map end\n", + log_.str()); +} + +TEST_F(JsonParserTest, Doubles) { + std::string json = "{\"foo\": 3.1415, \"bar\": 31415e-4}"; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_TRUE(log_.status().ok()); + EXPECT_EQ( + "map begin\n" + "string16: foo\n" + "double: 3.1415\n" + "string16: bar\n" + "double: 3.1415\n" + "map end\n", + log_.str()); +} + +TEST_F(JsonParserTest, Unicode) { + // Globe character. 0xF0 0x9F 0x8C 0x8E in utf8, 0xD83C 0xDF0E in utf16. + std::string json = "{\"msg\": \"Hello, \\uD83C\\uDF0E.\"}"; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_TRUE(log_.status().ok()); + EXPECT_EQ( + "map begin\n" + "string16: msg\n" + "string16: Hello, 🌎.\n" + "map end\n", + log_.str()); +} + +TEST_F(JsonParserTest, Unicode_ParseUtf16) { + // Globe character. utf8: 0xF0 0x9F 0x8C 0x8E; utf16: 0xD83C 0xDF0E. + // Crescent moon character. utf8: 0xF0 0x9F 0x8C 0x99; utf16: 0xD83C 0xDF19. + + // We provide the moon with json escape, but the earth as utf16 input. + // Either way they arrive as utf8 (after decoding in log_.str()). + std::vector<uint16_t> json = + UTF8ToUTF16(SpanFromStdString("{\"space\": \"🌎 \\uD83C\\uDF19.\"}")); + ParseJSON(GetTestPlatform(), SpanFromVector(json), &log_); + EXPECT_TRUE(log_.status().ok()); + EXPECT_EQ( + "map begin\n" + "string16: space\n" + "string16: 🌎 🌙.\n" + "map end\n", + log_.str()); +} + +TEST_F(JsonParserTest, Unicode_ParseUtf8) { + // Used below: + // гласность - example for 2 byte utf8, Russian word "glasnost" + // 屋 - example for 3 byte utf8, Chinese word for "house" + // 🌎 - example for 4 byte utf8: 0xF0 0x9F 0x8C 0x8E; utf16: 0xD83C 0xDF0E. + // 🌙 - example for escapes: utf8: 0xF0 0x9F 0x8C 0x99; utf16: 0xD83C 0xDF19. + + // We provide the moon with json escape, but the earth as utf8 input. + // Either way they arrive as utf8 (after decoding in log_.str()). + std::string json = + "{" + "\"escapes\": \"\\uD83C\\uDF19\"," + "\"2 byte\":\"гласность\"," + "\"3 byte\":\"屋\"," + "\"4 byte\":\"🌎\"" + "}"; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_TRUE(log_.status().ok()); + EXPECT_EQ( + "map begin\n" + "string16: escapes\n" + "string16: 🌙\n" + "string16: 2 byte\n" + "string16: гласность\n" + "string16: 3 byte\n" + "string16: 屋\n" + "string16: 4 byte\n" + "string16: 🌎\n" + "map end\n", + log_.str()); +} + +TEST_F(JsonParserTest, UnprocessedInputRemainsError) { + // Trailing junk after the valid JSON. + std::string json = "{\"foo\": 3.1415} junk"; + int64_t junk_idx = json.find("junk"); + EXPECT_GT(junk_idx, 0); + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_EQ(Error::JSON_PARSER_UNPROCESSED_INPUT_REMAINS, log_.status().error); + EXPECT_EQ(junk_idx, log_.status().pos); + EXPECT_EQ("", log_.str()); +} + +std::string MakeNestedJson(int depth) { + std::string json; + for (int ii = 0; ii < depth; ++ii) + json += "{\"foo\":"; + json += "42"; + for (int ii = 0; ii < depth; ++ii) + json += "}"; + return json; +} + +TEST_F(JsonParserTest, StackLimitExceededError) { + // kStackLimit is 1000 (see json_parser.cc). First let's + // try with a small nested example. + std::string json_3 = MakeNestedJson(3); + ParseJSON(GetTestPlatform(), SpanFromStdString(json_3), &log_); + EXPECT_TRUE(log_.status().ok()); + EXPECT_EQ( + "map begin\n" + "string16: foo\n" + "map begin\n" + "string16: foo\n" + "map begin\n" + "string16: foo\n" + "int: 42\n" + "map end\n" + "map end\n" + "map end\n", + log_.str()); + + // Now with kStackLimit (1000). + log_ = Log(); + std::string json_limit = MakeNestedJson(1000); + ParseJSON(GetTestPlatform(), + span<uint8_t>(reinterpret_cast<const uint8_t*>(json_limit.data()), + json_limit.size()), + &log_); + EXPECT_TRUE(log_.status().ok()); + // Now with kStackLimit + 1 (1001) - it exceeds in the innermost instance. + log_ = Log(); + std::string exceeded = MakeNestedJson(1001); + ParseJSON(GetTestPlatform(), SpanFromStdString(exceeded), &log_); + EXPECT_EQ(Error::JSON_PARSER_STACK_LIMIT_EXCEEDED, log_.status().error); + EXPECT_EQ(static_cast<std::ptrdiff_t>(strlen("{\"foo\":") * 1001), + log_.status().pos); + // Now way past the limit. Still, the point of exceeding is 1001. + log_ = Log(); + std::string far_out = MakeNestedJson(10000); + ParseJSON(GetTestPlatform(), SpanFromStdString(far_out), &log_); + EXPECT_EQ(Error::JSON_PARSER_STACK_LIMIT_EXCEEDED, log_.status().error); + EXPECT_EQ(static_cast<std::ptrdiff_t>(strlen("{\"foo\":") * 1001), + log_.status().pos); +} + +TEST_F(JsonParserTest, NoInputError) { + std::string json = ""; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_EQ(Error::JSON_PARSER_NO_INPUT, log_.status().error); + EXPECT_EQ(0, log_.status().pos); + EXPECT_EQ("", log_.str()); +} + +TEST_F(JsonParserTest, InvalidTokenError) { + std::string json = "|"; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_EQ(Error::JSON_PARSER_INVALID_TOKEN, log_.status().error); + EXPECT_EQ(0, log_.status().pos); + EXPECT_EQ("", log_.str()); +} + +TEST_F(JsonParserTest, InvalidNumberError) { + // Mantissa exceeds max (the constant used here is int64_t max). + std::string json = "1E9223372036854775807"; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_EQ(Error::JSON_PARSER_INVALID_NUMBER, log_.status().error); + EXPECT_EQ(0, log_.status().pos); + EXPECT_EQ("", log_.str()); +} + +TEST_F(JsonParserTest, InvalidStringError) { + // \x22 is an unsupported escape sequence + std::string json = "\"foo\\x22\""; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_EQ(Error::JSON_PARSER_INVALID_STRING, log_.status().error); + EXPECT_EQ(0, log_.status().pos); + EXPECT_EQ("", log_.str()); +} + +TEST_F(JsonParserTest, UnexpectedArrayEndError) { + std::string json = "[1,2,]"; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_EQ(Error::JSON_PARSER_UNEXPECTED_ARRAY_END, log_.status().error); + EXPECT_EQ(5, log_.status().pos); + EXPECT_EQ("", log_.str()); +} + +TEST_F(JsonParserTest, CommaOrArrayEndExpectedError) { + std::string json = "[1,2 2"; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_EQ(Error::JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED, + log_.status().error); + EXPECT_EQ(5, log_.status().pos); + EXPECT_EQ("", log_.str()); +} + +TEST_F(JsonParserTest, StringLiteralExpectedError) { + // There's an error because the key bar, a string, is not terminated. + std::string json = "{\"foo\": 3.1415, \"bar: 31415e-4}"; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_EQ(Error::JSON_PARSER_STRING_LITERAL_EXPECTED, log_.status().error); + EXPECT_EQ(16, log_.status().pos); + EXPECT_EQ("", log_.str()); +} + +TEST_F(JsonParserTest, ColonExpectedError) { + std::string json = "{\"foo\", 42}"; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_EQ(Error::JSON_PARSER_COLON_EXPECTED, log_.status().error); + EXPECT_EQ(6, log_.status().pos); + EXPECT_EQ("", log_.str()); +} + +TEST_F(JsonParserTest, UnexpectedMapEndError) { + std::string json = "{\"foo\": 42, }"; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_EQ(Error::JSON_PARSER_UNEXPECTED_MAP_END, log_.status().error); + EXPECT_EQ(12, log_.status().pos); + EXPECT_EQ("", log_.str()); +} + +TEST_F(JsonParserTest, CommaOrMapEndExpectedError) { + // The second separator should be a comma. + std::string json = "{\"foo\": 3.1415: \"bar\": 0}"; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_EQ(Error::JSON_PARSER_COMMA_OR_MAP_END_EXPECTED, log_.status().error); + EXPECT_EQ(14, log_.status().pos); + EXPECT_EQ("", log_.str()); +} + +TEST_F(JsonParserTest, ValueExpectedError) { + std::string json = "}"; + ParseJSON(GetTestPlatform(), SpanFromStdString(json), &log_); + EXPECT_EQ(Error::JSON_PARSER_VALUE_EXPECTED, log_.status().error); + EXPECT_EQ(0, log_.status().pos); + EXPECT_EQ("", log_.str()); +} +} // namespace json +} // namespace inspector_protocol_encoding
diff --git a/third_party/inspector_protocol/encoding/json_parser.cc b/third_party/inspector_protocol/encoding/json_parser.cc deleted file mode 100644 index 27a1f23..0000000 --- a/third_party/inspector_protocol/encoding/json_parser.cc +++ /dev/null
@@ -1,588 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "json_parser.h" - -#include <cassert> -#include <limits> -#include <string> -#include "status.h" - -namespace inspector_protocol { -namespace { -const int kStackLimit = 1000; - -enum Token { - ObjectBegin, - ObjectEnd, - ArrayBegin, - ArrayEnd, - StringLiteral, - Number, - BoolTrue, - BoolFalse, - NullToken, - ListSeparator, - ObjectPairSeparator, - InvalidToken, - NoInput -}; - -const char* const kNullString = "null"; -const char* const kTrueString = "true"; -const char* const kFalseString = "false"; - -template <typename Char> -class JsonParser { - public: - JsonParser(const Platform* platform, JSONParserHandler* handler) - : platform_(platform), handler_(handler) {} - - void Parse(const Char* start, std::size_t length) { - start_pos_ = start; - const Char* end = start + length; - const Char* tokenEnd; - ParseValue(start, end, &tokenEnd, 0); - if (tokenEnd != end) { - HandleError(Error::JSON_PARSER_UNPROCESSED_INPUT_REMAINS, tokenEnd); - } - } - - private: - bool CharsToDouble(const uint16_t* chars, - std::size_t length, - double* result) { - std::string buffer; - buffer.reserve(length + 1); - for (std::size_t ii = 0; ii < length; ++ii) { - bool is_ascii = !(chars[ii] & ~0x7F); - if (!is_ascii) return false; - buffer.push_back(static_cast<char>(chars[ii])); - } - return platform_->StrToD(buffer.c_str(), result); - } - - bool CharsToDouble(const uint8_t* chars, std::size_t length, double* result) { - std::string buffer(reinterpret_cast<const char*>(chars), length); - return platform_->StrToD(buffer.c_str(), result); - } - - static bool ParseConstToken(const Char* start, const Char* end, - const Char** token_end, const char* token) { - // |token| is \0 terminated, it's one of the constants at top of the file. - while (start < end && *token != '\0' && *start++ == *token++) { - } - if (*token != '\0') return false; - *token_end = start; - return true; - } - - static bool ReadInt(const Char* start, const Char* end, - const Char** token_end, bool allow_leading_zeros) { - if (start == end) return false; - bool has_leading_zero = '0' == *start; - int length = 0; - while (start < end && '0' <= *start && *start <= '9') { - ++start; - ++length; - } - if (!length) return false; - if (!allow_leading_zeros && length > 1 && has_leading_zero) return false; - *token_end = start; - return true; - } - - static bool ParseNumberToken(const Char* start, const Char* end, - const Char** token_end) { - // We just grab the number here. We validate the size in DecodeNumber. - // According to RFC4627, a valid number is: [minus] int [frac] [exp] - if (start == end) return false; - Char c = *start; - if ('-' == c) ++start; - - if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/false)) - return false; - if (start == end) { - *token_end = start; - return true; - } - - // Optional fraction part - c = *start; - if ('.' == c) { - ++start; - if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/true)) - return false; - if (start == end) { - *token_end = start; - return true; - } - c = *start; - } - - // Optional exponent part - if ('e' == c || 'E' == c) { - ++start; - if (start == end) return false; - c = *start; - if ('-' == c || '+' == c) { - ++start; - if (start == end) return false; - } - if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/true)) - return false; - } - - *token_end = start; - return true; - } - - static bool ReadHexDigits(const Char* start, const Char* end, - const Char** token_end, int digits) { - if (end - start < digits) return false; - for (int i = 0; i < digits; ++i) { - Char c = *start++; - if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || - ('A' <= c && c <= 'F'))) - return false; - } - *token_end = start; - return true; - } - - static bool ParseStringToken(const Char* start, const Char* end, - const Char** token_end) { - while (start < end) { - Char c = *start++; - if ('\\' == c) { - if (start == end) return false; - c = *start++; - // Make sure the escaped char is valid. - switch (c) { - case 'x': - if (!ReadHexDigits(start, end, &start, 2)) return false; - break; - case 'u': - if (!ReadHexDigits(start, end, &start, 4)) return false; - break; - case '\\': - case '/': - case 'b': - case 'f': - case 'n': - case 'r': - case 't': - case 'v': - case '"': - break; - default: - return false; - } - } else if ('"' == c) { - *token_end = start; - return true; - } - } - return false; - } - - static bool SkipComment(const Char* start, const Char* end, - const Char** comment_end) { - if (start == end) return false; - - if (*start != '/' || start + 1 >= end) return false; - ++start; - - if (*start == '/') { - // Single line comment, read to newline. - for (++start; start < end; ++start) { - if (*start == '\n' || *start == '\r') { - *comment_end = start + 1; - return true; - } - } - *comment_end = end; - // Comment reaches end-of-input, which is fine. - return true; - } - - if (*start == '*') { - Char previous = '\0'; - // Block comment, read until end marker. - for (++start; start < end; previous = *start++) { - if (previous == '*' && *start == '/') { - *comment_end = start + 1; - return true; - } - } - // Block comment must close before end-of-input. - return false; - } - - return false; - } - - static bool IsSpaceOrNewLine(Char c) { - // \v = vertial tab; \f = form feed page break. - return c == ' ' || c == '\n' || c == '\v' || c == '\f' || c == '\r' || - c == '\t'; - } - - static void SkipWhitespaceAndComments(const Char* start, const Char* end, - const Char** whitespace_end) { - while (start < end) { - if (IsSpaceOrNewLine(*start)) { - ++start; - } else if (*start == '/') { - const Char* comment_end; - if (!SkipComment(start, end, &comment_end)) break; - start = comment_end; - } else { - break; - } - } - *whitespace_end = start; - } - - static Token ParseToken(const Char* start, const Char* end, - const Char** tokenStart, const Char** token_end) { - SkipWhitespaceAndComments(start, end, tokenStart); - start = *tokenStart; - - if (start == end) return NoInput; - - switch (*start) { - case 'n': - if (ParseConstToken(start, end, token_end, kNullString)) - return NullToken; - break; - case 't': - if (ParseConstToken(start, end, token_end, kTrueString)) - return BoolTrue; - break; - case 'f': - if (ParseConstToken(start, end, token_end, kFalseString)) - return BoolFalse; - break; - case '[': - *token_end = start + 1; - return ArrayBegin; - case ']': - *token_end = start + 1; - return ArrayEnd; - case ',': - *token_end = start + 1; - return ListSeparator; - case '{': - *token_end = start + 1; - return ObjectBegin; - case '}': - *token_end = start + 1; - return ObjectEnd; - case ':': - *token_end = start + 1; - return ObjectPairSeparator; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - if (ParseNumberToken(start, end, token_end)) return Number; - break; - case '"': - if (ParseStringToken(start + 1, end, token_end)) return StringLiteral; - break; - } - return InvalidToken; - } - - static int HexToInt(Char c) { - if ('0' <= c && c <= '9') return c - '0'; - if ('A' <= c && c <= 'F') return c - 'A' + 10; - if ('a' <= c && c <= 'f') return c - 'a' + 10; - assert(false); // Unreachable. - return 0; - } - - static bool DecodeString(const Char* start, const Char* end, - std::vector<uint16_t>* output) { - if (start == end) return true; - if (start > end) return false; - output->reserve(end - start); - while (start < end) { - uint16_t c = *start++; - // If the |Char| we're dealing with is really a byte, then - // we have utf8 here, and we need to check for multibyte characters - // and transcode them to utf16 (either one or two utf16 chars). - if (sizeof(Char) == sizeof(uint8_t) && c >= 0x7f) { - // Inspect the leading byte to figure out how long the utf8 - // byte sequence is; while doing this initialize |codepoint| - // with the first few bits. - // See table in: https://en.wikipedia.org/wiki/UTF-8 - // byte one is 110x xxxx -> 2 byte utf8 sequence - // byte one is 1110 xxxx -> 3 byte utf8 sequence - // byte one is 1111 0xxx -> 4 byte utf8 sequence - uint32_t codepoint; - int num_bytes_left; - if ((c & 0xe0) == 0xc0) { // 2 byte utf8 sequence - num_bytes_left = 1; - codepoint = c & 0x1f; - } else if ((c & 0xf0) == 0xe0) { // 3 byte utf8 sequence - num_bytes_left = 2; - codepoint = c & 0x0f; - } else if ((c & 0xf8) == 0xf0) { // 4 byte utf8 sequence - codepoint = c & 0x07; - num_bytes_left = 3; - } else { - return false; // invalid leading byte - } - - // If we have enough bytes in our inpput, decode the remaining ones - // belonging to this Unicode character into |codepoint|. - if (start + num_bytes_left > end) return false; - while (num_bytes_left > 0) { - c = *start++; - --num_bytes_left; - // Check the next byte is a continuation byte, that is 10xx xxxx. - if ((c & 0xc0) != 0x80) return false; - codepoint = (codepoint << 6) | (c & 0x3f); - } - - // Disallow overlong encodings for ascii characters, as these - // would include " and other characters significant to JSON - // string termination / control. - if (codepoint < 0x7f) return false; - // Invalid in UTF8, and can't be represented in UTF16 anyway. - if (codepoint > 0x10ffff) return false; - - // So, now we transcode to UTF16, - // using the math described at https://en.wikipedia.org/wiki/UTF-16, - // for either one or two 16 bit characters. - if (codepoint < 0xffff) { - output->push_back(codepoint); - continue; - } - codepoint -= 0x10000; - output->push_back((codepoint >> 10) + 0xd800); // high surrogate - output->push_back((codepoint & 0x3ff) + 0xdc00); // low surrogate - continue; - } - if ('\\' != c) { - output->push_back(c); - continue; - } - if (start == end) return false; - c = *start++; - - if (c == 'x') { - // \x is not supported. - return false; - } - - switch (c) { - case '"': - case '/': - case '\\': - break; - case 'b': - c = '\b'; - break; - case 'f': - c = '\f'; - break; - case 'n': - c = '\n'; - break; - case 'r': - c = '\r'; - break; - case 't': - c = '\t'; - break; - case 'v': - c = '\v'; - break; - case 'u': - c = (HexToInt(*start) << 12) + (HexToInt(*(start + 1)) << 8) + - (HexToInt(*(start + 2)) << 4) + HexToInt(*(start + 3)); - start += 4; - break; - default: - return false; - } - output->push_back(c); - } - return true; - } - - void ParseValue(const Char* start, const Char* end, - const Char** value_token_end, int depth) { - if (depth > kStackLimit) { - HandleError(Error::JSON_PARSER_STACK_LIMIT_EXCEEDED, start); - return; - } - const Char* token_start; - const Char* token_end; - Token token = ParseToken(start, end, &token_start, &token_end); - switch (token) { - case NoInput: - HandleError(Error::JSON_PARSER_NO_INPUT, token_start); - return; - case InvalidToken: - HandleError(Error::JSON_PARSER_INVALID_TOKEN, token_start); - return; - case NullToken: - handler_->HandleNull(); - break; - case BoolTrue: - handler_->HandleBool(true); - break; - case BoolFalse: - handler_->HandleBool(false); - break; - case Number: { - double value; - if (!CharsToDouble(token_start, token_end - token_start, &value)) { - HandleError(Error::JSON_PARSER_INVALID_NUMBER, token_start); - return; - } - if (value >= std::numeric_limits<int32_t>::min() && - value <= std::numeric_limits<int32_t>::max() && - static_cast<int32_t>(value) == value) - handler_->HandleInt32(static_cast<int32_t>(value)); - else - handler_->HandleDouble(value); - break; - } - case StringLiteral: { - std::vector<uint16_t> value; - bool ok = DecodeString(token_start + 1, token_end - 1, &value); - if (!ok) { - HandleError(Error::JSON_PARSER_INVALID_STRING, token_start); - return; - } - handler_->HandleString16(span<uint16_t>(value.data(), value.size())); - break; - } - case ArrayBegin: { - handler_->HandleArrayBegin(); - start = token_end; - token = ParseToken(start, end, &token_start, &token_end); - while (token != ArrayEnd) { - ParseValue(start, end, &token_end, depth + 1); - if (error_) return; - - // After a list value, we expect a comma or the end of the list. - start = token_end; - token = ParseToken(start, end, &token_start, &token_end); - if (token == ListSeparator) { - start = token_end; - token = ParseToken(start, end, &token_start, &token_end); - if (token == ArrayEnd) { - HandleError(Error::JSON_PARSER_UNEXPECTED_ARRAY_END, token_start); - return; - } - } else if (token != ArrayEnd) { - // Unexpected value after list value. Bail out. - HandleError(Error::JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED, - token_start); - return; - } - } - handler_->HandleArrayEnd(); - break; - } - case ObjectBegin: { - handler_->HandleObjectBegin(); - start = token_end; - token = ParseToken(start, end, &token_start, &token_end); - while (token != ObjectEnd) { - if (token != StringLiteral) { - HandleError(Error::JSON_PARSER_STRING_LITERAL_EXPECTED, - token_start); - return; - } - std::vector<uint16_t> key; - if (!DecodeString(token_start + 1, token_end - 1, &key)) { - HandleError(Error::JSON_PARSER_INVALID_STRING, token_start); - return; - } - handler_->HandleString16(span<uint16_t>(key.data(), key.size())); - start = token_end; - - token = ParseToken(start, end, &token_start, &token_end); - if (token != ObjectPairSeparator) { - HandleError(Error::JSON_PARSER_COLON_EXPECTED, token_start); - return; - } - start = token_end; - - ParseValue(start, end, &token_end, depth + 1); - if (error_) return; - start = token_end; - - // After a key/value pair, we expect a comma or the end of the - // object. - token = ParseToken(start, end, &token_start, &token_end); - if (token == ListSeparator) { - start = token_end; - token = ParseToken(start, end, &token_start, &token_end); - if (token == ObjectEnd) { - HandleError(Error::JSON_PARSER_UNEXPECTED_OBJECT_END, - token_start); - return; - } - } else if (token != ObjectEnd) { - // Unexpected value after last object value. Bail out. - HandleError(Error::JSON_PARSER_COMMA_OR_OBJECT_END_EXPECTED, - token_start); - return; - } - } - handler_->HandleObjectEnd(); - break; - } - - default: - // We got a token that's not a value. - HandleError(Error::JSON_PARSER_VALUE_EXPECTED, token_start); - return; - } - - SkipWhitespaceAndComments(token_end, end, value_token_end); - } - - void HandleError(Error error, const Char* pos) { - assert(error != Error::OK); - if (!error_) { - handler_->HandleError(Status{error, pos - start_pos_}); - error_ = true; - } - } - - const Char* start_pos_ = nullptr; - bool error_ = false; - const Platform* platform_; - JSONParserHandler* handler_; -}; -} // namespace - -void ParseJSONChars(const Platform* platform, span<uint8_t> chars, - JSONParserHandler* handler) { - JsonParser<uint8_t> parser(platform, handler); - parser.Parse(chars.data(), chars.size()); -} - -void ParseJSONChars(const Platform* platform, span<uint16_t> chars, - JSONParserHandler* handler) { - JsonParser<uint16_t> parser(platform, handler); - parser.Parse(chars.data(), chars.size()); -} -} // namespace inspector_protocol
diff --git a/third_party/inspector_protocol/encoding/json_parser.h b/third_party/inspector_protocol/encoding/json_parser.h deleted file mode 100644 index 55384be..0000000 --- a/third_party/inspector_protocol/encoding/json_parser.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef INSPECTOR_PROTOCOL_ENCODING_JSON_PARSER_H_ -#define INSPECTOR_PROTOCOL_ENCODING_JSON_PARSER_H_ - -#include <cstdint> -#include <vector> -#include "json_parser_handler.h" -#include "platform.h" -#include "span.h" - -namespace inspector_protocol { -// JSON parsing routines. -void ParseJSONChars(const Platform* platform, span<uint8_t> chars, - JSONParserHandler* handler); -void ParseJSONChars(const Platform* platform, span<uint16_t> chars, - JSONParserHandler* handler); -} // namespace inspector_protocol - -#endif // INSPECTOR_PROTOCOL_ENCODING_JSON_PARSER_H_
diff --git a/third_party/inspector_protocol/encoding/json_parser_handler.h b/third_party/inspector_protocol/encoding/json_parser_handler.h deleted file mode 100644 index d90b65f7..0000000 --- a/third_party/inspector_protocol/encoding/json_parser_handler.h +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef INSPECTOR_PROTOCOL_ENCODING_JSON_PARSER_HANDLER_H_ -#define INSPECTOR_PROTOCOL_ENCODING_JSON_PARSER_HANDLER_H_ - -#include <cstdint> -#include <vector> -#include "span.h" -#include "status.h" - -namespace inspector_protocol { -// Handler interface for JSON parser events. See also json_parser.h. -class JSONParserHandler { - public: - virtual ~JSONParserHandler() = default; - virtual void HandleObjectBegin() = 0; - virtual void HandleObjectEnd() = 0; - virtual void HandleArrayBegin() = 0; - virtual void HandleArrayEnd() = 0; - virtual void HandleString8(span<uint8_t> chars) = 0; - virtual void HandleString16(span<uint16_t> chars) = 0; - virtual void HandleBinary(std::vector<uint8_t> bytes) = 0; - virtual void HandleDouble(double value) = 0; - virtual void HandleInt32(int32_t value) = 0; - virtual void HandleBool(bool value) = 0; - virtual void HandleNull() = 0; - - // The parser may send one error even after other events have already - // been received. Client code is reponsible to then discard the - // already processed events. - // |error| must be an eror, as in, |error.is_ok()| can't be true. - virtual void HandleError(Status error) = 0; -}; -} // namespace inspector_protocol - -#endif // INSPECTOR_PROTOCOL_ENCODING_JSON_PARSER_HANDLER_H_
diff --git a/third_party/inspector_protocol/encoding/json_parser_test.cc b/third_party/inspector_protocol/encoding/json_parser_test.cc deleted file mode 100644 index 2e63129..0000000 --- a/third_party/inspector_protocol/encoding/json_parser_test.cc +++ /dev/null
@@ -1,413 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "json_parser.h" - -#include <iostream> -#include <sstream> -#include "base/strings/string16.h" -#include "base/strings/utf_string_conversions.h" -#include "gtest/gtest.h" -#include "linux_dev_platform.h" - -namespace inspector_protocol { -class Log : public JSONParserHandler { - public: - void HandleObjectBegin() override { log_ << "object begin\n"; } - - void HandleObjectEnd() override { log_ << "object end\n"; } - - void HandleArrayBegin() override { log_ << "array begin\n"; } - - void HandleArrayEnd() override { log_ << "array end\n"; } - - void HandleString8(span<uint8_t> chars) override { - base::StringPiece foo(reinterpret_cast<const char*>(chars.data()), - chars.size()); - log_ << "string8: " << foo << "\n"; - } - - void HandleString16(span<uint16_t> chars) override { - base::StringPiece16 foo(reinterpret_cast<const base::char16*>(chars.data()), - chars.size()); - log_ << "string16: " << base::UTF16ToUTF8(foo) << "\n"; - } - - void HandleBinary(std::vector<uint8_t> bytes) override { - // JSON doesn't have native support for arbitrary bytes, so our parser will - // never call this. - assert(false); - } - - void HandleDouble(double value) override { - log_ << "double: " << value << "\n"; - } - - void HandleInt32(int32_t value) override { log_ << "int: " << value << "\n"; } - - void HandleBool(bool value) override { log_ << "bool: " << value << "\n"; } - - void HandleNull() override { log_ << "null\n"; } - - void HandleError(Status status) override { status_ = status; } - - std::string str() const { return status_.ok() ? log_.str() : ""; } - - Status status() const { return status_; } - - private: - std::ostringstream log_; - Status status_; -}; - -class JsonParserTest : public ::testing::Test { - protected: - Log log_; -}; - -TEST_F(JsonParserTest, SimpleDictionary) { - std::string json = "{\"foo\": 42}"; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_TRUE(log_.status().ok()); - EXPECT_EQ( - "object begin\n" - "string16: foo\n" - "int: 42\n" - "object end\n", - log_.str()); -} - -TEST_F(JsonParserTest, Whitespace) { - std::string json = "\n {\n\"msg\"\n: \v\"Hello, world.\"\t\r}\t"; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_TRUE(log_.status().ok()); - EXPECT_EQ( - "object begin\n" - "string16: msg\n" - "string16: Hello, world.\n" - "object end\n", - log_.str()); -} - -TEST_F(JsonParserTest, NestedDictionary) { - std::string json = "{\"foo\": {\"bar\": {\"baz\": 1}, \"bar2\": 2}}"; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_TRUE(log_.status().ok()); - EXPECT_EQ( - "object begin\n" - "string16: foo\n" - "object begin\n" - "string16: bar\n" - "object begin\n" - "string16: baz\n" - "int: 1\n" - "object end\n" - "string16: bar2\n" - "int: 2\n" - "object end\n" - "object end\n", - log_.str()); -} - -TEST_F(JsonParserTest, Doubles) { - std::string json = "{\"foo\": 3.1415, \"bar\": 31415e-4}"; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_TRUE(log_.status().ok()); - EXPECT_EQ( - "object begin\n" - "string16: foo\n" - "double: 3.1415\n" - "string16: bar\n" - "double: 3.1415\n" - "object end\n", - log_.str()); -} - -TEST_F(JsonParserTest, Unicode) { - // Globe character. 0xF0 0x9F 0x8C 0x8E in utf8, 0xD83C 0xDF0E in utf16. - std::string json = "{\"msg\": \"Hello, \\uD83C\\uDF0E.\"}"; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_TRUE(log_.status().ok()); - EXPECT_EQ( - "object begin\n" - "string16: msg\n" - "string16: Hello, 🌎.\n" - "object end\n", - log_.str()); -} - -TEST_F(JsonParserTest, Unicode_ParseUtf16) { - // Globe character. utf8: 0xF0 0x9F 0x8C 0x8E; utf16: 0xD83C 0xDF0E. - // Crescent moon character. utf8: 0xF0 0x9F 0x8C 0x99; utf16: 0xD83C 0xDF19. - - // We provide the moon with json escape, but the earth as utf16 input. - // Either way they arrive as utf8 (after decoding in log_.str()). - base::string16 json = base::UTF8ToUTF16("{\"space\": \"🌎 \\uD83C\\uDF19.\"}"); - ParseJSONChars(GetLinuxDevPlatform(), - span<uint16_t>(reinterpret_cast<const uint16_t*>(json.data()), - json.size()), - &log_); - EXPECT_TRUE(log_.status().ok()); - EXPECT_EQ( - "object begin\n" - "string16: space\n" - "string16: 🌎 🌙.\n" - "object end\n", - log_.str()); -} - -TEST_F(JsonParserTest, Unicode_ParseUtf8) { - // Used below: - // гласность - example for 2 byte utf8, Russian word "glasnost" - // 屋 - example for 3 byte utf8, Chinese word for "house" - // 🌎 - example for 4 byte utf8: 0xF0 0x9F 0x8C 0x8E; utf16: 0xD83C 0xDF0E. - // 🌙 - example for escapes: utf8: 0xF0 0x9F 0x8C 0x99; utf16: 0xD83C 0xDF19. - - // We provide the moon with json escape, but the earth as utf8 input. - // Either way they arrive as utf8 (after decoding in log_.str()). - std::string json = - "{" - "\"escapes\": \"\\uD83C\\uDF19\"," - "\"2 byte\":\"гласность\"," - "\"3 byte\":\"屋\"," - "\"4 byte\":\"🌎\"" - "}"; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_TRUE(log_.status().ok()); - EXPECT_EQ( - "object begin\n" - "string16: escapes\n" - "string16: 🌙\n" - "string16: 2 byte\n" - "string16: гласность\n" - "string16: 3 byte\n" - "string16: 屋\n" - "string16: 4 byte\n" - "string16: 🌎\n" - "object end\n", - log_.str()); -} - -TEST_F(JsonParserTest, UnprocessedInputRemainsError) { - // Trailing junk after the valid JSON. - std::string json = "{\"foo\": 3.1415} junk"; - int64_t junk_idx = json.find("junk"); - EXPECT_GT(junk_idx, 0); - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_EQ(Error::JSON_PARSER_UNPROCESSED_INPUT_REMAINS, log_.status().error); - EXPECT_EQ(junk_idx, log_.status().pos); - EXPECT_EQ("", log_.str()); -} - -std::string MakeNestedJson(int depth) { - std::string json; - for (int ii = 0; ii < depth; ++ii) json += "{\"foo\":"; - json += "42"; - for (int ii = 0; ii < depth; ++ii) json += "}"; - return json; -} - -TEST_F(JsonParserTest, StackLimitExceededError) { - // kStackLimit is 1000 (see json_parser.cc). First let's - // try with a small nested example. - std::string json_3 = MakeNestedJson(3); - ParseJSONChars(GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json_3.data()), - json_3.size()), - &log_); - EXPECT_TRUE(log_.status().ok()); - EXPECT_EQ( - "object begin\n" - "string16: foo\n" - "object begin\n" - "string16: foo\n" - "object begin\n" - "string16: foo\n" - "int: 42\n" - "object end\n" - "object end\n" - "object end\n", - log_.str()); - - // Now with kStackLimit (1000). - log_ = Log(); - std::string json_limit = MakeNestedJson(1000); - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json_limit.data()), - json_limit.size()), - &log_); - EXPECT_TRUE(log_.status().ok()); - // Now with kStackLimit + 1 (1001) - it exceeds in the innermost instance. - log_ = Log(); - std::string exceeded = MakeNestedJson(1001); - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(exceeded.data()), - exceeded.size()), - &log_); - EXPECT_EQ(Error::JSON_PARSER_STACK_LIMIT_EXCEEDED, log_.status().error); - EXPECT_EQ(static_cast<std::ptrdiff_t>(strlen("{\"foo\":") * 1001), - log_.status().pos); - // Now way past the limit. Still, the point of exceeding is 1001. - log_ = Log(); - std::string far_out = MakeNestedJson(10000); - ParseJSONChars(GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(far_out.data()), - far_out.size()), - &log_); - EXPECT_EQ(Error::JSON_PARSER_STACK_LIMIT_EXCEEDED, log_.status().error); - EXPECT_EQ(static_cast<std::ptrdiff_t>(strlen("{\"foo\":") * 1001), - log_.status().pos); -} - -TEST_F(JsonParserTest, NoInputError) { - std::string json = ""; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_EQ(Error::JSON_PARSER_NO_INPUT, log_.status().error); - EXPECT_EQ(0, log_.status().pos); - EXPECT_EQ("", log_.str()); -} - -TEST_F(JsonParserTest, InvalidTokenError) { - std::string json = "|"; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_EQ(Error::JSON_PARSER_INVALID_TOKEN, log_.status().error); - EXPECT_EQ(0, log_.status().pos); - EXPECT_EQ("", log_.str()); -} - -TEST_F(JsonParserTest, InvalidNumberError) { - // Mantissa exceeds max (the constant used here is int64_t max). - std::string json = "1E9223372036854775807"; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_EQ(Error::JSON_PARSER_INVALID_NUMBER, log_.status().error); - EXPECT_EQ(0, log_.status().pos); - EXPECT_EQ("", log_.str()); -} - -TEST_F(JsonParserTest, InvalidStringError) { - // \x22 is an unsupported escape sequence - std::string json = "\"foo\\x22\""; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_EQ(Error::JSON_PARSER_INVALID_STRING, log_.status().error); - EXPECT_EQ(0, log_.status().pos); - EXPECT_EQ("", log_.str()); -} - -TEST_F(JsonParserTest, UnexpectedArrayEndError) { - std::string json = "[1,2,]"; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_EQ(Error::JSON_PARSER_UNEXPECTED_ARRAY_END, log_.status().error); - EXPECT_EQ(5, log_.status().pos); - EXPECT_EQ("", log_.str()); -} - -TEST_F(JsonParserTest, CommaOrArrayEndExpectedError) { - std::string json = "[1,2 2"; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_EQ(Error::JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED, - log_.status().error); - EXPECT_EQ(5, log_.status().pos); - EXPECT_EQ("", log_.str()); -} - -TEST_F(JsonParserTest, StringLiteralExpectedError) { - // There's an error because the key bar, a string, is not terminated. - std::string json = "{\"foo\": 3.1415, \"bar: 31415e-4}"; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_EQ(Error::JSON_PARSER_STRING_LITERAL_EXPECTED, log_.status().error); - EXPECT_EQ(16, log_.status().pos); - EXPECT_EQ("", log_.str()); -} - -TEST_F(JsonParserTest, ColonExpectedError) { - std::string json = "{\"foo\", 42}"; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_EQ(Error::JSON_PARSER_COLON_EXPECTED, log_.status().error); - EXPECT_EQ(6, log_.status().pos); - EXPECT_EQ("", log_.str()); -} - -TEST_F(JsonParserTest, UnexpectedObjectEndError) { - std::string json = "{\"foo\": 42, }"; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_EQ(Error::JSON_PARSER_UNEXPECTED_OBJECT_END, log_.status().error); - EXPECT_EQ(12, log_.status().pos); - EXPECT_EQ("", log_.str()); -} - -TEST_F(JsonParserTest, CommaOrObjectEndExpectedError) { - // The second separator should be a comma. - std::string json = "{\"foo\": 3.1415: \"bar\": 0}"; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_EQ(Error::JSON_PARSER_COMMA_OR_OBJECT_END_EXPECTED, - log_.status().error); - EXPECT_EQ(14, log_.status().pos); - EXPECT_EQ("", log_.str()); -} - -TEST_F(JsonParserTest, ValueExpectedError) { - std::string json = "}"; - ParseJSONChars( - GetLinuxDevPlatform(), - span<uint8_t>(reinterpret_cast<const uint8_t*>(json.data()), json.size()), - &log_); - EXPECT_EQ(Error::JSON_PARSER_VALUE_EXPECTED, log_.status().error); - EXPECT_EQ(0, log_.status().pos); - EXPECT_EQ("", log_.str()); -} - -} // namespace inspector_protocol
diff --git a/third_party/inspector_protocol/encoding/json_std_string_writer.cc b/third_party/inspector_protocol/encoding/json_std_string_writer.cc deleted file mode 100644 index 1c849cc..0000000 --- a/third_party/inspector_protocol/encoding/json_std_string_writer.cc +++ /dev/null
@@ -1,306 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "json_std_string_writer.h" -#include <cassert> -#include <stack> - -namespace inspector_protocol { -namespace { -// Prints |value| to |out| with 4 hex digits, most significant chunk first. -void PrintHex(uint16_t value, std::string* out) { - for (int ii = 3; ii >= 0; --ii) { - int four_bits = 0xf & (value >> (4 * ii)); - out->append(1, four_bits + ((four_bits <= 9) ? '0' : ('a' - 10))); - } -} - -// In the writer below, we maintain a stack of State instances. -// It is just enough to emit the appropriate delimiters and brackets -// in JSON. -enum class Container { - // Used for the top-level, initial state. - NONE, - // Inside a JSON object. - OBJECT, - // Inside a JSON array. - ARRAY -}; -class State { - public: - explicit State(Container container) : container_(container) {} - void StartElement(std::string* out) { - assert(container_ != Container::NONE || size_ == 0); - if (size_ != 0) { - char delim = (!(size_ & 1) || container_ == Container::ARRAY) ? ',' : ':'; - out->append(1, delim); - } - ++size_; - } - Container container() const { return container_; } - - private: - Container container_ = Container::NONE; - int size_ = 0; -}; - -constexpr char kBase64Table[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz0123456789+/"; - -void Base64Encode(const std::vector<uint8_t>& in, std::string* out) { - // The following three cases are based on the tables in the example - // section in https://en.wikipedia.org/wiki/Base64. We process three - // input bytes at a time, emitting 4 output bytes at a time. - std::size_t ii = 0; - - // While possible, process three input bytes. - for (; ii + 3 <= in.size(); ii += 3) { - uint32_t twentyfour_bits = (in[ii] << 16) | (in[ii + 1] << 8) | in[ii + 2]; - out->push_back(kBase64Table[(twentyfour_bits >> 18)]); - out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]); - out->push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]); - out->push_back(kBase64Table[twentyfour_bits & 0x3f]); - } - if (ii + 2 <= in.size()) { // Process two input bytes. - uint32_t twentyfour_bits = (in[ii] << 16) | (in[ii + 1] << 8); - out->push_back(kBase64Table[(twentyfour_bits >> 18)]); - out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]); - out->push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]); - out->push_back('='); // Emit padding. - return; - } - if (ii + 1 <= in.size()) { // Process a single input byte. - uint32_t twentyfour_bits = (in[ii] << 16); - out->push_back(kBase64Table[(twentyfour_bits >> 18)]); - out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]); - out->push_back('='); // Emit padding. - out->push_back('='); // Emit padding. - } -} - -// Implements a handler for JSON parser events to emit a JSON string. -class Writer : public JSONParserHandler { - public: - Writer(Platform* platform, std::string* out, Status* status) - : platform_(platform), out_(out), status_(status) { - *status_ = Status(); - state_.emplace(Container::NONE); - } - - void HandleObjectBegin() override { - if (!status_->ok()) return; - assert(!state_.empty()); - state_.top().StartElement(out_); - state_.emplace(Container::OBJECT); - out_->append("{"); - } - - void HandleObjectEnd() override { - if (!status_->ok()) return; - assert(state_.size() >= 2 && state_.top().container() == Container::OBJECT); - state_.pop(); - out_->append("}"); - } - - void HandleArrayBegin() override { - if (!status_->ok()) return; - state_.top().StartElement(out_); - state_.emplace(Container::ARRAY); - out_->append("["); - } - - void HandleArrayEnd() override { - if (!status_->ok()) return; - assert(state_.size() >= 2 && state_.top().container() == Container::ARRAY); - state_.pop(); - out_->append("]"); - } - - void HandleString16(span<uint16_t> chars) override { - if (!status_->ok()) return; - state_.top().StartElement(out_); - out_->append("\""); - for (const uint16_t ch : chars) { - if (ch == '"') { - out_->append("\\\""); - } else if (ch == '\\') { - out_->append("\\\\"); - } else if (ch == '\b') { - out_->append("\\b"); - } else if (ch == '\f') { - out_->append("\\f"); - } else if (ch == '\n') { - out_->append("\\n"); - } else if (ch == '\r') { - out_->append("\\r"); - } else if (ch == '\t') { - out_->append("\\t"); - } else if (ch >= 32 && ch <= 126) { - out_->append(1, ch); - } else { - out_->append("\\u"); - PrintHex(ch, out_); - } - } - out_->append("\""); - } - - void HandleString8(span<uint8_t> chars) override { - if (!status_->ok()) - return; - state_.top().StartElement(out_); - out_->append("\""); - for (std::ptrdiff_t ii = 0; ii < chars.size(); ++ii) { - uint8_t c = chars[ii]; - if (c == '"') { - out_->append("\\\""); - } else if (c == '\\') { - out_->append("\\\\"); - } else if (c == '\b') { - out_->append("\\b"); - } else if (c == '\f') { - out_->append("\\f"); - } else if (c == '\n') { - out_->append("\\n"); - } else if (c == '\r') { - out_->append("\\r"); - } else if (c == '\t') { - out_->append("\\t"); - } else if (c >= 32 && c <= 126) { - out_->append(1, c); - } else if (c < 32) { - out_->append("\\u"); - PrintHex(static_cast<uint16_t>(c), out_); - } else { - // Inspect the leading byte to figure out how long the utf8 - // byte sequence is; while doing this initialize |codepoint| - // with the first few bits. - // See table in: https://en.wikipedia.org/wiki/UTF-8 - // byte one is 110x xxxx -> 2 byte utf8 sequence - // byte one is 1110 xxxx -> 3 byte utf8 sequence - // byte one is 1111 0xxx -> 4 byte utf8 sequence - uint32_t codepoint; - int num_bytes_left; - if ((c & 0xe0) == 0xc0) { // 2 byte utf8 sequence - num_bytes_left = 1; - codepoint = c & 0x1f; - } else if ((c & 0xf0) == 0xe0) { // 3 byte utf8 sequence - num_bytes_left = 2; - codepoint = c & 0x0f; - } else if ((c & 0xf8) == 0xf0) { // 4 byte utf8 sequence - codepoint = c & 0x07; - num_bytes_left = 3; - } else { - continue; // invalid leading byte - } - - // If we have enough bytes in our input, decode the remaining ones - // belonging to this Unicode character into |codepoint|. - if (ii + num_bytes_left > chars.size()) - continue; - while (num_bytes_left > 0) { - c = chars[++ii]; - --num_bytes_left; - // Check the next byte is a continuation byte, that is 10xx xxxx. - if ((c & 0xc0) != 0x80) - continue; - codepoint = (codepoint << 6) | (c & 0x3f); - } - - // Disallow overlong encodings for ascii characters, as these - // would include " and other characters significant to JSON - // string termination / control. - if (codepoint < 0x7f) - continue; - // Invalid in UTF8, and can't be represented in UTF16 anyway. - if (codepoint > 0x10ffff) - continue; - - // So, now we transcode to UTF16, - // using the math described at https://en.wikipedia.org/wiki/UTF-16, - // for either one or two 16 bit characters. - if (codepoint < 0xffff) { - out_->append("\\u"); - PrintHex(static_cast<uint16_t>(codepoint), out_); - continue; - } - codepoint -= 0x10000; - // high surrogate - out_->append("\\u"); - PrintHex(static_cast<uint16_t>((codepoint >> 10) + 0xd800), out_); - // low surrogate - out_->append("\\u"); - PrintHex(static_cast<uint16_t>((codepoint & 0x3ff) + 0xdc00), out_); - } - } - out_->append("\""); - } - - void HandleBinary(std::vector<uint8_t> bytes) override { - if (!status_->ok()) return; - state_.top().StartElement(out_); - out_->append("\""); - Base64Encode(bytes, out_); - out_->append("\""); - } - - void HandleDouble(double value) override { - if (!status_->ok()) return; - state_.top().StartElement(out_); - std::unique_ptr<char[]> str_value = platform_->DToStr(value); - - // DToStr may fail to emit a 0 before the decimal dot. E.g. this is - // the case in base::NumberToString in Chromium (which is based on - // dmg_fp). So, much like - // https://cs.chromium.org/chromium/src/base/json/json_writer.cc - // we probe for this and emit the leading 0 anyway if necessary. - const char* chars = str_value.get(); - if (chars[0] == '.') { - out_->append("0"); - } else if (chars[0] == '-' && chars[1] == '.') { - out_->append("-0"); - ++chars; - } - out_->append(chars); - } - - void HandleInt32(int32_t value) override { - if (!status_->ok()) return; - state_.top().StartElement(out_); - out_->append(std::to_string(value)); - } - - void HandleBool(bool value) override { - if (!status_->ok()) return; - state_.top().StartElement(out_); - out_->append(value ? "true" : "false"); - } - - void HandleNull() override { - if (!status_->ok()) return; - state_.top().StartElement(out_); - out_->append("null"); - } - - void HandleError(Status error) override { - assert(!error.ok()); - *status_ = error; - out_->clear(); - } - - private: - Platform* platform_; - std::string* out_; - Status* status_; - std::stack<State> state_; -}; -} // namespace - -std::unique_ptr<JSONParserHandler> NewJSONWriter(Platform* platform, - std::string* out, - Status* status) { - return std::unique_ptr<Writer>(new Writer(platform, out, status)); -} -} // namespace inspector_protocol
diff --git a/third_party/inspector_protocol/encoding/json_std_string_writer.h b/third_party/inspector_protocol/encoding/json_std_string_writer.h deleted file mode 100644 index b2c9b634..0000000 --- a/third_party/inspector_protocol/encoding/json_std_string_writer.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef INSPECTOR_PROTOCOL_ENCODING_JSON_STD_STRING_WRITER_H_ -#define INSPECTOR_PROTOCOL_ENCODING_JSON_STD_STRING_WRITER_H_ - -#include <memory> -#include <string> -#include "json_parser_handler.h" -#include "platform.h" - -namespace inspector_protocol { -// Returns a handler object which will write ascii characters to |out|. -// |status->ok()| will be false iff the handler routine HandleError() is called. -// In that case, we'll stop emitting output. -// Except for calling the HandleError routine at any time, the client -// code must call the Handle* methods in an order in which they'd occur -// in valid JSON; otherwise we may crash (the code uses assert). -std::unique_ptr<JSONParserHandler> NewJSONWriter(Platform* platform, - std::string* out, - Status* status); -} // namespace inspector_protocol - -#endif // INSPECTOR_PROTOCOL_ENCODING_JSON_STD_STRING_WRITER_H_
diff --git a/third_party/inspector_protocol/encoding/json_std_string_writer_test.cc b/third_party/inspector_protocol/encoding/json_std_string_writer_test.cc deleted file mode 100644 index 553f8b2..0000000 --- a/third_party/inspector_protocol/encoding/json_std_string_writer_test.cc +++ /dev/null
@@ -1,162 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "json_std_string_writer.h" - -#include "base/strings/string16.h" -#include "base/strings/utf_string_conversions.h" -#include "gtest/gtest.h" -#include "linux_dev_platform.h" - -namespace inspector_protocol { -std::vector<uint16_t> UTF16String(const std::string& utf8) { - base::string16 string16 = base::UTF8ToUTF16(utf8); - return std::vector<uint16_t>(string16.data(), - string16.data() + string16.size()); -} - -void WriteUTF8AsUTF16(JSONParserHandler* writer, const std::string& utf8) { - std::vector<uint16_t> utf16 = UTF16String(utf8); - writer->HandleString16(span<uint16_t>(utf16.data(), utf16.size())); -} - -TEST(JsonStdStringWriterTest, HelloWorld) { - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - writer->HandleObjectBegin(); - WriteUTF8AsUTF16(writer.get(), "msg1"); - WriteUTF8AsUTF16(writer.get(), "Hello, 🌎."); - std::string key = "msg1-as-utf8"; - std::string value = "Hello, 🌎."; - writer->HandleString8( - span<uint8_t>(reinterpret_cast<const uint8_t*>(key.data()), key.size())); - writer->HandleString8(span<uint8_t>( - reinterpret_cast<const uint8_t*>(value.data()), value.size())); - WriteUTF8AsUTF16(writer.get(), "msg2"); - WriteUTF8AsUTF16(writer.get(), "\\\b\r\n\t\f\""); - WriteUTF8AsUTF16(writer.get(), "nested"); - writer->HandleObjectBegin(); - WriteUTF8AsUTF16(writer.get(), "double"); - writer->HandleDouble(3.1415); - WriteUTF8AsUTF16(writer.get(), "int"); - writer->HandleInt32(-42); - WriteUTF8AsUTF16(writer.get(), "bool"); - writer->HandleBool(false); - WriteUTF8AsUTF16(writer.get(), "null"); - writer->HandleNull(); - writer->HandleObjectEnd(); - WriteUTF8AsUTF16(writer.get(), "array"); - writer->HandleArrayBegin(); - writer->HandleInt32(1); - writer->HandleInt32(2); - writer->HandleInt32(3); - writer->HandleArrayEnd(); - writer->HandleObjectEnd(); - EXPECT_TRUE(status.ok()); - EXPECT_EQ( - "{\"msg1\":\"Hello, \\ud83c\\udf0e.\"," - "\"msg1-as-utf8\":\"Hello, \\ud83c\\udf0e.\"," - "\"msg2\":\"\\\\\\b\\r\\n\\t\\f\\\"\"," - "\"nested\":{\"double\":3.1415,\"int\":-42," - "\"bool\":false,\"null\":null},\"array\":[1,2,3]}", - out); -} - -TEST(JsonStdStringWriterTest, BinaryEncodedAsJsonString) { - // The encoder emits binary submitted to JSONParserHandler::HandleBinary - // as base64. The following three examples are taken from - // https://en.wikipedia.org/wiki/Base64. - { - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - writer->HandleBinary({'M', 'a', 'n'}); - EXPECT_TRUE(status.ok()); - EXPECT_EQ("\"TWFu\"", out); - } - { - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - writer->HandleBinary({'M', 'a'}); - EXPECT_TRUE(status.ok()); - EXPECT_EQ("\"TWE=\"", out); - } - { - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - writer->HandleBinary({'M'}); - EXPECT_TRUE(status.ok()); - EXPECT_EQ("\"TQ==\"", out); - } - { // "Hello, world.", verified with base64decode.org. - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - writer->HandleBinary( - {'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '.'}); - EXPECT_TRUE(status.ok()); - EXPECT_EQ("\"SGVsbG8sIHdvcmxkLg==\"", out); - } -} - -TEST(JsonStdStringWriterTest, HandlesErrors) { - // When an error is sent via HandleError, it saves it in the provided - // status and clears the output. - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> writer = - NewJSONWriter(GetLinuxDevPlatform(), &out, &status); - writer->HandleObjectBegin(); - WriteUTF8AsUTF16(writer.get(), "msg1"); - writer->HandleError(Status{Error::JSON_PARSER_VALUE_EXPECTED, 42}); - EXPECT_EQ(Error::JSON_PARSER_VALUE_EXPECTED, status.error); - EXPECT_EQ(42, status.pos); - EXPECT_EQ("", out); -} - -// We'd use Gmock but unfortunately it only handles copyable return types. -class MockPlatform : public Platform { - public: - // Not implemented. - bool StrToD(const char* str, double* result) const override { return false; } - - // A map with pre-registered responses for DToSTr. - std::map<double, std::string> dtostr_responses; - - std::unique_ptr<char[]> DToStr(double value) const override { - auto it = dtostr_responses.find(value); - assert(it != dtostr_responses.end()); - const std::string& str = it->second; - std::unique_ptr<char[]> response(new char[str.size() + 1]); - memcpy(response.get(), str.c_str(), str.size() + 1); - return response; - } -}; - -TEST(JsonStdStringWriterTest, DoubleToString) { - // This "broken" platform responds without the leading 0 before the - // decimal dot, so it'd be invalid JSON. - MockPlatform platform; - platform.dtostr_responses[.1] = ".1"; - platform.dtostr_responses[-.7] = "-.7"; - - std::string out; - Status status; - std::unique_ptr<JSONParserHandler> writer = - NewJSONWriter(&platform, &out, &status); - writer->HandleArrayBegin(); - writer->HandleDouble(.1); - writer->HandleDouble(-.7); - writer->HandleArrayEnd(); - EXPECT_EQ("[0.1,-0.7]", out); -} -} // namespace inspector_protocol
diff --git a/third_party/inspector_protocol/encoding/linux_dev_platform.cc b/third_party/inspector_protocol/encoding/linux_dev_platform.cc deleted file mode 100644 index 142ca086..0000000 --- a/third_party/inspector_protocol/encoding/linux_dev_platform.cc +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "linux_dev_platform.h" - -#include <clocale> -#include <cstdlib> -#include <cstring> -#include <iomanip> -#include <sstream> - -namespace inspector_protocol { -namespace { -class LinuxDevPlatform : public Platform { - bool StrToD(const char* str, double* result) const override { - // This is not thread-safe - // (see https://en.cppreference.com/w/cpp/locale/setlocale) - // but good enough for a unittest. - const char* saved_locale = std::setlocale(LC_NUMERIC, nullptr); - char* end; - *result = std::strtod(str, &end); - std::setlocale(LC_NUMERIC, saved_locale); - if (errno == ERANGE) { - // errno must be reset, e.g. see the example here: - // https://en.cppreference.com/w/cpp/string/byte/strtof - errno = 0; - return false; - } - return end == str + strlen(str); - } - - std::unique_ptr<char[]> DToStr(double value) const override { - std::stringstream ss; - ss.imbue(std::locale("C")); - ss << value; - std::string str = ss.str(); - std::unique_ptr<char[]> result(new char[str.size() + 1]); - memcpy(result.get(), str.c_str(), str.size() + 1); - return result; - } -}; -} // namespace - -Platform* GetLinuxDevPlatform() { - static Platform* deps = new LinuxDevPlatform; - return deps; -} -} // namespace inspector_protocol
diff --git a/third_party/inspector_protocol/encoding/linux_dev_platform.h b/third_party/inspector_protocol/encoding/linux_dev_platform.h deleted file mode 100644 index cf5dfd5b..0000000 --- a/third_party/inspector_protocol/encoding/linux_dev_platform.h +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef INSPECTOR_PROTOCOL_ENCODING_LINUX_DEV_PLATFORM_H_ -#define INSPECTOR_PROTOCOL_ENCODING_LINUX_DEV_PLATFORM_H_ - -#include "platform.h" - -namespace inspector_protocol { -// Returns an instance of the platform implementation that we're using for -// development on Linux. This is intended and appropriate for tests for this -// package, for now. -Platform* GetLinuxDevPlatform(); -} // namespace inspector_protocol - -#endif // INSPECTOR_PROTOCOL_ENCODING_LINUX_DEV_PLATFORM_H_
diff --git a/third_party/inspector_protocol/encoding/platform.h b/third_party/inspector_protocol/encoding/platform.h deleted file mode 100644 index cfd2d5d..0000000 --- a/third_party/inspector_protocol/encoding/platform.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef INSPECTOR_PROTOCOL_ENCODING_PLATFORM_H_ -#define INSPECTOR_PROTOCOL_ENCODING_PLATFORM_H_ - -#include <memory> - -namespace inspector_protocol { -// Client code must provide an instance. Implementation should delegate -// to whatever is appropriate. -class Platform { - public: - virtual ~Platform() = default; - // Parses |str| into |result|. Returns false iff there are - // leftover characters or parsing errors. - virtual bool StrToD(const char* str, double* result) const = 0; - - // Prints |value| in a format suitable for JSON. - virtual std::unique_ptr<char[]> DToStr(double value) const = 0; -}; -} // namespace inspector_protocol - -#endif // INSPECTOR_PROTOCOL_ENCODING_PLATFORM_H_
diff --git a/third_party/inspector_protocol/encoding/span.h b/third_party/inspector_protocol/encoding/span.h deleted file mode 100644 index 052062cf..0000000 --- a/third_party/inspector_protocol/encoding/span.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef INSPECTOR_PROTOCOL_ENCODING_SPAN_H_ -#define INSPECTOR_PROTOCOL_ENCODING_SPAN_H_ - -#include <cstddef> - -namespace inspector_protocol { -// This template is similar to std::span, which will be included in C++20. Like -// std::span it uses ptrdiff_t, which is signed (and thus a bit annoying -// sometimes when comparing with size_t), but other than this it's much simpler. -template <typename T> -class span { - public: - using index_type = std::ptrdiff_t; - - span() : data_(nullptr), size_(0) {} - span(const T* data, index_type size) : data_(data), size_(size) {} - - const T* data() const { return data_; } - - const T* begin() const { return data_; } - const T* end() const { return data_ + size_; } - - const T& operator[](index_type idx) const { return data_[idx]; } - - span<T> subspan(index_type offset, index_type count) const { - return span(data_ + offset, count); - } - - span<T> subspan(index_type offset) const { - return span(data_ + offset, size_ - offset); - } - - bool empty() const { return size_ == 0; } - - index_type size() const { return size_; } - index_type size_bytes() const { return size_ * sizeof(T); } - - private: - const T* data_; - index_type size_; -}; -} // namespace inspector_protocol -#endif // INSPECTOR_PROTOCOL_ENCODING_SPAN_H_
diff --git a/third_party/inspector_protocol/encoding/span_test.cc b/third_party/inspector_protocol/encoding/span_test.cc deleted file mode 100644 index 48ee76d..0000000 --- a/third_party/inspector_protocol/encoding/span_test.cc +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "span.h" - -#include "gtest/gtest.h" - -namespace inspector_protocol { -template <typename T> -class SpanTest : public ::testing::Test {}; - -using TestTypes = ::testing::Types<uint8_t, uint16_t>; -TYPED_TEST_SUITE(SpanTest, TestTypes); - -TYPED_TEST(SpanTest, Empty) { - span<TypeParam> empty; - EXPECT_TRUE(empty.empty()); - EXPECT_EQ(0, empty.size()); - EXPECT_EQ(0, empty.size_bytes()); - EXPECT_EQ(empty.begin(), empty.end()); -} - -TYPED_TEST(SpanTest, SingleItem) { - TypeParam single_item = 42; - span<TypeParam> singular(&single_item, 1); - EXPECT_FALSE(singular.empty()); - EXPECT_EQ(1, singular.size()); - EXPECT_EQ(sizeof(TypeParam), static_cast<size_t>(singular.size_bytes())); - EXPECT_EQ(singular.begin() + 1, singular.end()); - EXPECT_EQ(42, singular[0]); -} - -TYPED_TEST(SpanTest, FiveItems) { - std::vector<TypeParam> test_input = {31, 32, 33, 34, 35}; - span<TypeParam> five_items(test_input.data(), 5); - EXPECT_FALSE(five_items.empty()); - EXPECT_EQ(5, five_items.size()); - EXPECT_EQ(sizeof(TypeParam) * 5, - static_cast<size_t>(five_items.size_bytes())); - EXPECT_EQ(five_items.begin() + 5, five_items.end()); - EXPECT_EQ(31, five_items[0]); - EXPECT_EQ(32, five_items[1]); - EXPECT_EQ(33, five_items[2]); - EXPECT_EQ(34, five_items[3]); - EXPECT_EQ(35, five_items[4]); - span<TypeParam> three_items = five_items.subspan(2); - EXPECT_EQ(3, three_items.size()); - EXPECT_EQ(33, three_items[0]); - EXPECT_EQ(34, three_items[1]); - EXPECT_EQ(35, three_items[2]); - span<TypeParam> two_items = five_items.subspan(2, 2); - EXPECT_EQ(2, two_items.size()); - EXPECT_EQ(33, two_items[0]); - EXPECT_EQ(34, two_items[1]); -} -} // namespace inspector_protocol
diff --git a/third_party/inspector_protocol/encoding/status.h b/third_party/inspector_protocol/encoding/status.h deleted file mode 100644 index ea4a3da..0000000 --- a/third_party/inspector_protocol/encoding/status.h +++ /dev/null
@@ -1,61 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef INSPECTOR_PROTOCOL_ENCODING_STATUS_H_ -#define INSPECTOR_PROTOCOL_ENCODING_STATUS_H_ - -#include <cstdint> - -namespace inspector_protocol { -// Error codes. -enum class Error { - OK = 0, - // JSON parsing errors - json_parser.{h,cc}. - JSON_PARSER_UNPROCESSED_INPUT_REMAINS = 0x01, - JSON_PARSER_STACK_LIMIT_EXCEEDED = 0x02, - JSON_PARSER_NO_INPUT = 0x03, - JSON_PARSER_INVALID_TOKEN = 0x04, - JSON_PARSER_INVALID_NUMBER = 0x05, - JSON_PARSER_INVALID_STRING = 0x06, - JSON_PARSER_UNEXPECTED_ARRAY_END = 0x07, - JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED = 0x08, - JSON_PARSER_STRING_LITERAL_EXPECTED = 0x09, - JSON_PARSER_COLON_EXPECTED = 0x0a, - JSON_PARSER_UNEXPECTED_OBJECT_END = 0x0b, - JSON_PARSER_COMMA_OR_OBJECT_END_EXPECTED = 0x0c, - JSON_PARSER_VALUE_EXPECTED = 0x0d, - - CBOR_INVALID_INT32 = 0x0e, - CBOR_INVALID_DOUBLE = 0x0f, - CBOR_INVALID_ENVELOPE = 0x10, - CBOR_INVALID_STRING8 = 0x11, - CBOR_INVALID_STRING16 = 0x12, - CBOR_INVALID_BINARY = 0x13, - CBOR_UNSUPPORTED_VALUE = 0x14, - CBOR_NO_INPUT = 0x15, - CBOR_INVALID_START_BYTE = 0x16, - CBOR_UNEXPECTED_EOF_EXPECTED_VALUE = 0x17, - CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x18, - CBOR_UNEXPECTED_EOF_IN_MAP = 0x19, - CBOR_INVALID_MAP_KEY = 0x1a, - CBOR_STACK_LIMIT_EXCEEDED = 0x1b, - CBOR_STRING8_MUST_BE_7BIT = 0x1c, - CBOR_TRAILING_JUNK = 0x1d, - CBOR_MAP_START_EXPECTED = 0x1e, -}; - -// A status value with position that can be copied. The default status -// is OK. Usually, error status values should come with a valid position. -struct Status { - static constexpr std::ptrdiff_t npos() { return -1; } - - bool ok() const { return error == Error::OK; } - - Error error = Error::OK; - std::ptrdiff_t pos = npos(); - Status(Error error, std::ptrdiff_t pos) : error(error), pos(pos) {} - Status() = default; -}; -} // namespace inspector_protocol -#endif // INSPECTOR_PROTOCOL_ENCODING_STATUS_H_
diff --git a/third_party/inspector_protocol/encoding/str_util.cc b/third_party/inspector_protocol/encoding/str_util.cc deleted file mode 100644 index 1f4be7c..0000000 --- a/third_party/inspector_protocol/encoding/str_util.cc +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "str_util.h" - -#include <cstring> - -namespace inspector_protocol { -bool StrEq(span<uint8_t> left, span<uint8_t> right) { - return left.size() == right.size() && - 0 == memcmp(left.data(), right.data(), left.size()); -} - -bool StrEq(span<uint8_t> left, const char* null_terminated_right) { - return static_cast<std::size_t>(left.size()) == - strlen(null_terminated_right) && - 0 == memcmp(left.data(), null_terminated_right, left.size()); -} -} // namespace inspector_protocol
diff --git a/third_party/inspector_protocol/encoding/str_util.h b/third_party/inspector_protocol/encoding/str_util.h deleted file mode 100644 index f377541..0000000 --- a/third_party/inspector_protocol/encoding/str_util.h +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef INSPECTOR_PROTOCOL_ENCODING_STR_UTIL_H_ -#define INSPECTOR_PROTOCOL_ENCODING_STR_UTIL_H_ - -#include <cstdint> - -#include "span.h" - -namespace inspector_protocol { -// Returns true iff |left| and right have the same contents, byte for byte. -bool StrEq(span<uint8_t> left, span<uint8_t> right); -bool StrEq(span<uint8_t> left, const char* null_terminated_right); -} // namespace inspector_protocol -#endif // INSPECTOR_PROTOCOL_ENCODING_STR_UTIL_H_
diff --git a/third_party/inspector_protocol/inspector_protocol.gni b/third_party/inspector_protocol/inspector_protocol.gni index ecee942..d612fb6a 100644 --- a/third_party/inspector_protocol/inspector_protocol.gni +++ b/third_party/inspector_protocol/inspector_protocol.gni
@@ -33,10 +33,10 @@ invoker.config_file, "$inspector_protocol_dir/lib/base_string_adapter_cc.template", "$inspector_protocol_dir/lib/base_string_adapter_h.template", + "$inspector_protocol_dir/lib/encoding_h.template", + "$inspector_protocol_dir/lib/encoding_cpp.template", "$inspector_protocol_dir/lib/Allocator_h.template", "$inspector_protocol_dir/lib/Array_h.template", - "$inspector_protocol_dir/lib/CBOR_h.template", - "$inspector_protocol_dir/lib/CBOR_cpp.template", "$inspector_protocol_dir/lib/DispatcherBase_cpp.template", "$inspector_protocol_dir/lib/DispatcherBase_h.template", "$inspector_protocol_dir/lib/ErrorSupport_cpp.template",
diff --git a/third_party/inspector_protocol/inspector_protocol.gypi b/third_party/inspector_protocol/inspector_protocol.gypi index 3d0a60e..d614474 100644 --- a/third_party/inspector_protocol/inspector_protocol.gypi +++ b/third_party/inspector_protocol/inspector_protocol.gypi
@@ -5,10 +5,10 @@ { 'variables': { 'inspector_protocol_files': [ + 'lib/encoding_h.template', + 'lib/encoding_cpp.template', 'lib/Allocator_h.template', 'lib/Array_h.template', - 'lib/CBOR_h.template', - 'lib/CBOR_cpp.template', 'lib/DispatcherBase_cpp.template', 'lib/DispatcherBase_h.template', 'lib/ErrorSupport_cpp.template',
diff --git a/third_party/inspector_protocol/lib/CBOR_cpp.template b/third_party/inspector_protocol/lib/CBOR_cpp.template deleted file mode 100644 index d2375b6c..0000000 --- a/third_party/inspector_protocol/lib/CBOR_cpp.template +++ /dev/null
@@ -1,828 +0,0 @@ -{# This template is generated by gen_cbor_templates.py. #} -// Generated by lib/CBOR_cpp.template. - -// 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 <cassert> -#include <limits> - -{% for namespace in config.protocol.namespace %} -namespace {{namespace}} { -{% endfor %} - -// ===== encoding/cbor.cc ===== - -using namespace cbor; - -namespace { - -// See RFC 7049 Section 2.3, Table 2. -static constexpr uint8_t kEncodedTrue = - EncodeInitialByte(MajorType::SIMPLE_VALUE, 21); -static constexpr uint8_t kEncodedFalse = - EncodeInitialByte(MajorType::SIMPLE_VALUE, 20); -static constexpr uint8_t kEncodedNull = - EncodeInitialByte(MajorType::SIMPLE_VALUE, 22); -static constexpr uint8_t kInitialByteForDouble = - EncodeInitialByte(MajorType::SIMPLE_VALUE, 27); - -} // namespace - -uint8_t EncodeTrue() { return kEncodedTrue; } -uint8_t EncodeFalse() { return kEncodedFalse; } -uint8_t EncodeNull() { return kEncodedNull; } - -uint8_t EncodeIndefiniteLengthArrayStart() { - return kInitialByteIndefiniteLengthArray; -} - -uint8_t EncodeIndefiniteLengthMapStart() { - return kInitialByteIndefiniteLengthMap; -} - -uint8_t EncodeStop() { return kStopByte; } - -namespace { -// See RFC 7049 Table 3 and Section 2.4.4.2. This is used as a prefix for -// arbitrary binary data encoded as BYTE_STRING. -static constexpr uint8_t kExpectedConversionToBase64Tag = - EncodeInitialByte(MajorType::TAG, 22); - -// When parsing CBOR, we limit recursion depth for objects and arrays -// to this constant. -static constexpr int kStackLimit = 1000; - -// Writes the bytes for |v| to |out|, starting with the most significant byte. -// See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html -template <typename T> -void WriteBytesMostSignificantByteFirst(T v, std::vector<uint8_t>* out) { - for (int shift_bytes = sizeof(T) - 1; shift_bytes >= 0; --shift_bytes) - out->push_back(0xff & (v >> (shift_bytes * 8))); -} -} // namespace - -namespace cbor_internals { -// Writes the start of a token with |type|. The |value| may indicate the size, -// or it may be the payload if the value is an unsigned integer. -void WriteTokenStart(MajorType type, uint64_t value, - std::vector<uint8_t>* encoded) { - if (value < 24) { - // Values 0-23 are encoded directly into the additional info of the - // initial byte. - encoded->push_back(EncodeInitialByte(type, /*additional_info=*/value)); - return; - } - if (value <= std::numeric_limits<uint8_t>::max()) { - // Values 24-255 are encoded with one initial byte, followed by the value. - encoded->push_back(EncodeInitialByte(type, kAdditionalInformation1Byte)); - encoded->push_back(value); - return; - } - if (value <= std::numeric_limits<uint16_t>::max()) { - // Values 256-65535: 1 initial byte + 2 bytes payload. - encoded->push_back(EncodeInitialByte(type, kAdditionalInformation2Bytes)); - WriteBytesMostSignificantByteFirst<uint16_t>(value, encoded); - return; - } - if (value <= std::numeric_limits<uint32_t>::max()) { - // 32 bit uint: 1 initial byte + 4 bytes payload. - encoded->push_back(EncodeInitialByte(type, kAdditionalInformation4Bytes)); - WriteBytesMostSignificantByteFirst<uint32_t>(static_cast<uint32_t>(value), - encoded); - return; - } - // 64 bit uint: 1 initial byte + 8 bytes payload. - encoded->push_back(EncodeInitialByte(type, kAdditionalInformation8Bytes)); - WriteBytesMostSignificantByteFirst<uint64_t>(value, encoded); -} -} // namespace cbor_internals - -namespace { -// Extracts sizeof(T) bytes from |in| to extract a value of type T -// (e.g. uint64_t, uint32_t, ...), most significant byte first. -// See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html -template <typename T> -T ReadBytesMostSignificantByteFirst(span<uint8_t> in) { - assert(static_cast<std::size_t>(in.size()) >= sizeof(T)); - T result = 0; - for (std::size_t shift_bytes = 0; shift_bytes < sizeof(T); ++shift_bytes) - result |= T(in[sizeof(T) - 1 - shift_bytes]) << (shift_bytes * 8); - return result; -} -} // namespace - -namespace cbor_internals { -int8_t ReadTokenStart(span<uint8_t> bytes, MajorType* type, uint64_t* value) { - if (bytes.empty()) return -1; - uint8_t initial_byte = bytes[0]; - *type = MajorType((initial_byte & kMajorTypeMask) >> kMajorTypeBitShift); - - uint8_t additional_information = initial_byte & kAdditionalInformationMask; - if (additional_information < 24) { - // Values 0-23 are encoded directly into the additional info of the - // initial byte. - *value = additional_information; - return 1; - } - if (additional_information == kAdditionalInformation1Byte) { - // Values 24-255 are encoded with one initial byte, followed by the value. - if (bytes.size() < 2) return -1; - *value = ReadBytesMostSignificantByteFirst<uint8_t>(bytes.subspan(1)); - return 2; - } - if (additional_information == kAdditionalInformation2Bytes) { - // Values 256-65535: 1 initial byte + 2 bytes payload. - if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint16_t)) - return -1; - *value = ReadBytesMostSignificantByteFirst<uint16_t>(bytes.subspan(1)); - return 3; - } - if (additional_information == kAdditionalInformation4Bytes) { - // 32 bit uint: 1 initial byte + 4 bytes payload. - if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint32_t)) - return -1; - *value = ReadBytesMostSignificantByteFirst<uint32_t>(bytes.subspan(1)); - return 5; - } - if (additional_information == kAdditionalInformation8Bytes) { - // 64 bit uint: 1 initial byte + 8 bytes payload. - if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint64_t)) - return -1; - *value = ReadBytesMostSignificantByteFirst<uint64_t>(bytes.subspan(1)); - return 9; - } - return -1; -} -} // namespace cbor_internals - -using cbor_internals::WriteTokenStart; -using cbor_internals::ReadTokenStart; - -void EncodeInt32(int32_t value, std::vector<uint8_t>* out) { - if (value >= 0) { - WriteTokenStart(MajorType::UNSIGNED, value, out); - } else { - uint64_t representation = static_cast<uint64_t>(-(value + 1)); - WriteTokenStart(MajorType::NEGATIVE, representation, out); - } -} - -void EncodeString16(span<uint16_t> in, std::vector<uint8_t>* out) { - uint64_t byte_length = static_cast<uint64_t>(in.size_bytes()); - WriteTokenStart(MajorType::BYTE_STRING, byte_length, out); - // When emitting UTF16 characters, we always write the least significant byte - // first; this is because it's the native representation for X86. - // TODO(johannes): Implement a more efficient thing here later, e.g. - // casting *iff* the machine has this byte order. - // The wire format for UTF16 chars will probably remain the same - // (least significant byte first) since this way we can have - // golden files, unittests, etc. that port easily and universally. - // See also: - // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html - for (const uint16_t two_bytes : in) { - out->push_back(two_bytes); - out->push_back(two_bytes >> 8); - } -} - -void EncodeString8(span<uint8_t> in, std::vector<uint8_t>* out) { - WriteTokenStart(MajorType::STRING, static_cast<uint64_t>(in.size_bytes()), - out); - out->insert(out->end(), in.begin(), in.end()); -} - -void EncodeFromLatin1(span<uint8_t> latin1, std::vector<uint8_t>* out) { - for (std::ptrdiff_t ii = 0; ii < latin1.size(); ++ii) { - if (latin1[ii] <= 127) continue; - // If there's at least one non-ASCII char, convert to UTF8. - std::vector<uint8_t> utf8(latin1.begin(), latin1.begin() + ii); - for (; ii < latin1.size(); ++ii) { - if (latin1[ii] <= 127) { - utf8.push_back(latin1[ii]); - } else { - // 0xC0 means it's a UTF8 sequence with 2 bytes. - utf8.push_back((latin1[ii] >> 6) | 0xc0); - utf8.push_back((latin1[ii] | 0x80) & 0xbf); - } - } - EncodeString8(span<uint8_t>(utf8.data(), utf8.size()), out); - return; - } - EncodeString8(latin1, out); -} - -void EncodeFromUTF16(span<uint16_t> utf16, std::vector<uint8_t>* out) { - // If there's at least one non-ASCII char, encode as STRING16 (UTF16). - for (uint16_t ch : utf16) { - if (ch <= 127) continue; - EncodeString16(utf16, out); - return; - } - // It's all US-ASCII, strip out every second byte and encode as UTF8. - WriteTokenStart(MajorType::STRING, static_cast<uint64_t>(utf16.size()), out); - out->insert(out->end(), utf16.begin(), utf16.end()); -} - -void EncodeBinary(span<uint8_t> in, std::vector<uint8_t>* out) { - out->push_back(kExpectedConversionToBase64Tag); - uint64_t byte_length = static_cast<uint64_t>(in.size_bytes()); - WriteTokenStart(MajorType::BYTE_STRING, byte_length, out); - out->insert(out->end(), in.begin(), in.end()); -} - -// A double is encoded with a specific initial byte -// (kInitialByteForDouble) plus the 64 bits of payload for its value. -constexpr std::ptrdiff_t kEncodedDoubleSize = 1 + sizeof(uint64_t); - -// An envelope is encoded with a specific initial byte -// (kInitialByteForEnvelope), plus the start byte for a BYTE_STRING with a 32 -// bit wide length, plus a 32 bit length for that string. -constexpr std::ptrdiff_t kEncodedEnvelopeHeaderSize = 1 + 1 + sizeof(uint32_t); - -void EncodeDouble(double value, std::vector<uint8_t>* out) { - // The additional_info=27 indicates 64 bits for the double follow. - // See RFC 7049 Section 2.3, Table 1. - out->push_back(kInitialByteForDouble); - union { - double from_double; - uint64_t to_uint64; - } reinterpret; - reinterpret.from_double = value; - WriteBytesMostSignificantByteFirst<uint64_t>(reinterpret.to_uint64, out); -} - -void EnvelopeEncoder::EncodeStart(std::vector<uint8_t>* out) { - assert(byte_size_pos_ == 0); - out->push_back(kInitialByteForEnvelope); - out->push_back(kInitialByteFor32BitLengthByteString); - byte_size_pos_ = out->size(); - out->resize(out->size() + sizeof(uint32_t)); -} - -bool EnvelopeEncoder::EncodeStop(std::vector<uint8_t>* out) { - assert(byte_size_pos_ != 0); - // The byte size is the size of the payload, that is, all the - // bytes that were written past the byte size position itself. - uint64_t byte_size = out->size() - (byte_size_pos_ + sizeof(uint32_t)); - // We store exactly 4 bytes, so at most INT32MAX, with most significant - // byte first. - if (byte_size > std::numeric_limits<uint32_t>::max()) return false; - for (int shift_bytes = sizeof(uint32_t) - 1; shift_bytes >= 0; - --shift_bytes) { - (*out)[byte_size_pos_++] = 0xff & (byte_size >> (shift_bytes * 8)); - } - return true; -} - -namespace { -class JSONToCBOREncoder : public JSONParserHandler { - public: - JSONToCBOREncoder(std::vector<uint8_t>* out, Status* status) - : out_(out), status_(status) { - *status_ = Status(); - } - - void HandleObjectBegin() override { - envelopes_.emplace_back(); - envelopes_.back().EncodeStart(out_); - out_->push_back(kInitialByteIndefiniteLengthMap); - } - - void HandleObjectEnd() override { - out_->push_back(kStopByte); - assert(!envelopes_.empty()); - envelopes_.back().EncodeStop(out_); - envelopes_.pop_back(); - } - - void HandleArrayBegin() override { - envelopes_.emplace_back(); - envelopes_.back().EncodeStart(out_); - out_->push_back(kInitialByteIndefiniteLengthArray); - } - - void HandleArrayEnd() override { - out_->push_back(kStopByte); - assert(!envelopes_.empty()); - envelopes_.back().EncodeStop(out_); - envelopes_.pop_back(); - } - - void HandleString8(span<uint8_t> chars) override { - EncodeString8(chars, out_); - } - - void HandleString16(span<uint16_t> chars) override { - for (uint16_t ch : chars) { - if (ch >= 0x7f) { - // If there's at least one non-7bit character, we encode as UTF16. - EncodeString16(chars, out_); - return; - } - } - std::vector<uint8_t> sevenbit_chars(chars.begin(), chars.end()); - EncodeString8(span<uint8_t>(sevenbit_chars.data(), sevenbit_chars.size()), - out_); - } - - void HandleBinary(std::vector<uint8_t> bytes) override { - EncodeBinary(span<uint8_t>(bytes.data(), bytes.size()), out_); - } - - void HandleDouble(double value) override { EncodeDouble(value, out_); } - - void HandleInt32(int32_t value) override { EncodeInt32(value, out_); } - - void HandleBool(bool value) override { - // See RFC 7049 Section 2.3, Table 2. - out_->push_back(value ? kEncodedTrue : kEncodedFalse); - } - - void HandleNull() override { - // See RFC 7049 Section 2.3, Table 2. - out_->push_back(kEncodedNull); - } - - void HandleError(Status error) override { - assert(!error.ok()); - *status_ = error; - out_->clear(); - } - - private: - std::vector<uint8_t>* out_; - std::vector<EnvelopeEncoder> envelopes_; - Status* status_; -}; -} // namespace - -std::unique_ptr<JSONParserHandler> NewJSONToCBOREncoder( - std::vector<uint8_t>* out, Status* status) { - return std::unique_ptr<JSONParserHandler>(new JSONToCBOREncoder(out, status)); -} - -namespace { -// Below are three parsing routines for CBOR, which cover enough -// to roundtrip JSON messages. -bool ParseMap(int32_t stack_depth, CBORTokenizer* tokenizer, - JSONParserHandler* out); -bool ParseArray(int32_t stack_depth, CBORTokenizer* tokenizer, - JSONParserHandler* out); -bool ParseValue(int32_t stack_depth, CBORTokenizer* tokenizer, - JSONParserHandler* out); - -void ParseUTF16String(CBORTokenizer* tokenizer, JSONParserHandler* out) { - std::vector<uint16_t> value; - span<uint8_t> rep = tokenizer->GetString16WireRep(); - for (std::ptrdiff_t ii = 0; ii < rep.size(); ii += 2) - value.push_back((rep[ii + 1] << 8) | rep[ii]); - out->HandleString16(span<uint16_t>(value.data(), value.size())); - tokenizer->Next(); -} - -bool ParseUTF8String(CBORTokenizer* tokenizer, JSONParserHandler* out) { - assert(tokenizer->TokenTag() == CBORTokenTag::STRING8); - out->HandleString8(tokenizer->GetString8()); - tokenizer->Next(); - return true; -} - -bool ParseValue(int32_t stack_depth, CBORTokenizer* tokenizer, - JSONParserHandler* out) { - if (stack_depth > kStackLimit) { - out->HandleError( - Status{Error::CBOR_STACK_LIMIT_EXCEEDED, tokenizer->Status().pos}); - return false; - } - // Skip past the envelope to get to what's inside. - if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE) - tokenizer->EnterEnvelope(); - switch (tokenizer->TokenTag()) { - case CBORTokenTag::ERROR_VALUE: - out->HandleError(tokenizer->Status()); - return false; - case CBORTokenTag::DONE: - out->HandleError(Status{Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE, - tokenizer->Status().pos}); - return false; - case CBORTokenTag::TRUE_VALUE: - out->HandleBool(true); - tokenizer->Next(); - return true; - case CBORTokenTag::FALSE_VALUE: - out->HandleBool(false); - tokenizer->Next(); - return true; - case CBORTokenTag::NULL_VALUE: - out->HandleNull(); - tokenizer->Next(); - return true; - case CBORTokenTag::INT32: - out->HandleInt32(tokenizer->GetInt32()); - tokenizer->Next(); - return true; - case CBORTokenTag::DOUBLE: - out->HandleDouble(tokenizer->GetDouble()); - tokenizer->Next(); - return true; - case CBORTokenTag::STRING8: - return ParseUTF8String(tokenizer, out); - case CBORTokenTag::STRING16: - ParseUTF16String(tokenizer, out); - return true; - case CBORTokenTag::BINARY: { - span<uint8_t> binary = tokenizer->GetBinary(); - out->HandleBinary(std::vector<uint8_t>(binary.begin(), binary.end())); - tokenizer->Next(); - return true; - } - case CBORTokenTag::MAP_START: - return ParseMap(stack_depth + 1, tokenizer, out); - case CBORTokenTag::ARRAY_START: - return ParseArray(stack_depth + 1, tokenizer, out); - default: - out->HandleError( - Status{Error::CBOR_UNSUPPORTED_VALUE, tokenizer->Status().pos}); - return false; - } -} - -// |bytes| must start with the indefinite length array byte, so basically, -// ParseArray may only be called after an indefinite length array has been -// detected. -bool ParseArray(int32_t stack_depth, CBORTokenizer* tokenizer, - JSONParserHandler* out) { - assert(tokenizer->TokenTag() == CBORTokenTag::ARRAY_START); - tokenizer->Next(); - out->HandleArrayBegin(); - while (tokenizer->TokenTag() != CBORTokenTag::STOP) { - if (tokenizer->TokenTag() == CBORTokenTag::DONE) { - out->HandleError( - Status{Error::CBOR_UNEXPECTED_EOF_IN_ARRAY, tokenizer->Status().pos}); - return false; - } - if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) { - out->HandleError(tokenizer->Status()); - return false; - } - // Parse value. - if (!ParseValue(stack_depth, tokenizer, out)) return false; - } - out->HandleArrayEnd(); - tokenizer->Next(); - return true; -} - -// |bytes| must start with the indefinite length array byte, so basically, -// ParseArray may only be called after an indefinite length array has been -// detected. -bool ParseMap(int32_t stack_depth, CBORTokenizer* tokenizer, - JSONParserHandler* out) { - assert(tokenizer->TokenTag() == CBORTokenTag::MAP_START); - out->HandleObjectBegin(); - tokenizer->Next(); - while (tokenizer->TokenTag() != CBORTokenTag::STOP) { - if (tokenizer->TokenTag() == CBORTokenTag::DONE) { - out->HandleError( - Status{Error::CBOR_UNEXPECTED_EOF_IN_MAP, tokenizer->Status().pos}); - return false; - } - if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) { - out->HandleError(tokenizer->Status()); - return false; - } - // Parse key. - if (tokenizer->TokenTag() == CBORTokenTag::STRING8) { - if (!ParseUTF8String(tokenizer, out)) return false; - } else if (tokenizer->TokenTag() == CBORTokenTag::STRING16) { - ParseUTF16String(tokenizer, out); - } else { - out->HandleError( - Status{Error::CBOR_INVALID_MAP_KEY, tokenizer->Status().pos}); - return false; - } - // Parse value. - if (!ParseValue(stack_depth, tokenizer, out)) return false; - } - out->HandleObjectEnd(); - tokenizer->Next(); - return true; -} -} // namespace - -void ParseCBOR(span<uint8_t> bytes, JSONParserHandler* json_out) { - if (bytes.empty()) { - json_out->HandleError(Status{Error::CBOR_NO_INPUT, 0}); - return; - } - if (bytes[0] != kInitialByteForEnvelope) { - json_out->HandleError(Status{Error::CBOR_INVALID_START_BYTE, 0}); - return; - } - CBORTokenizer tokenizer(bytes); - if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) { - json_out->HandleError(tokenizer.Status()); - return; - } - // We checked for the envelope start byte above, so the tokenizer - // must agree here, since it's not an error. - assert(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE); - tokenizer.EnterEnvelope(); - if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) { - json_out->HandleError( - Status{Error::CBOR_MAP_START_EXPECTED, tokenizer.Status().pos}); - return; - } - if (!ParseMap(/*stack_depth=*/1, &tokenizer, json_out)) return; - if (tokenizer.TokenTag() == CBORTokenTag::DONE) return; - if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) { - json_out->HandleError(tokenizer.Status()); - return; - } - json_out->HandleError( - Status{Error::CBOR_TRAILING_JUNK, tokenizer.Status().pos}); -} - -CBORTokenizer::CBORTokenizer(span<uint8_t> bytes) : bytes_(bytes) { - ReadNextToken(/*enter_envelope=*/false); -} -CBORTokenizer::~CBORTokenizer() {} - -CBORTokenTag CBORTokenizer::TokenTag() const { return token_tag_; } - -void CBORTokenizer::Next() { - if (token_tag_ == CBORTokenTag::ERROR_VALUE || token_tag_ == CBORTokenTag::DONE) - return; - ReadNextToken(/*enter_envelope=*/false); -} - -void CBORTokenizer::EnterEnvelope() { - assert(token_tag_ == CBORTokenTag::ENVELOPE); - ReadNextToken(/*enter_envelope=*/true); -} - -Status CBORTokenizer::Status() const { return status_; } - -int32_t CBORTokenizer::GetInt32() const { - assert(token_tag_ == CBORTokenTag::INT32); - // The range checks happen in ::ReadNextToken(). - return static_cast<uint32_t>( - token_start_type_ == MajorType::UNSIGNED - ? token_start_internal_value_ - : -static_cast<int64_t>(token_start_internal_value_) - 1); -} - -double CBORTokenizer::GetDouble() const { - assert(token_tag_ == CBORTokenTag::DOUBLE); - union { - uint64_t from_uint64; - double to_double; - } reinterpret; - reinterpret.from_uint64 = ReadBytesMostSignificantByteFirst<uint64_t>( - bytes_.subspan(status_.pos + 1)); - return reinterpret.to_double; -} - -span<uint8_t> CBORTokenizer::GetString8() const { - assert(token_tag_ == CBORTokenTag::STRING8); - auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); - return bytes_.subspan(status_.pos + (token_byte_length_ - length), length); -} - -span<uint8_t> CBORTokenizer::GetString16WireRep() const { - assert(token_tag_ == CBORTokenTag::STRING16); - auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); - return bytes_.subspan(status_.pos + (token_byte_length_ - length), length); -} - -span<uint8_t> CBORTokenizer::GetBinary() const { - assert(token_tag_ == CBORTokenTag::BINARY); - auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); - return bytes_.subspan(status_.pos + (token_byte_length_ - length), length); -} - -void CBORTokenizer::ReadNextToken(bool enter_envelope) { - if (enter_envelope) { - status_.pos += kEncodedEnvelopeHeaderSize; - } else { - status_.pos = - status_.pos == Status::npos() ? 0 : status_.pos + token_byte_length_; - } - status_.error = Error::OK; - if (status_.pos >= bytes_.size()) { - token_tag_ = CBORTokenTag::DONE; - return; - } - switch (bytes_[status_.pos]) { - case kStopByte: - SetToken(CBORTokenTag::STOP, 1); - return; - case kInitialByteIndefiniteLengthMap: - SetToken(CBORTokenTag::MAP_START, 1); - return; - case kInitialByteIndefiniteLengthArray: - SetToken(CBORTokenTag::ARRAY_START, 1); - return; - case kEncodedTrue: - SetToken(CBORTokenTag::TRUE_VALUE, 1); - return; - case kEncodedFalse: - SetToken(CBORTokenTag::FALSE_VALUE, 1); - return; - case kEncodedNull: - SetToken(CBORTokenTag::NULL_VALUE, 1); - return; - case kExpectedConversionToBase64Tag: { // BINARY - int8_t bytes_read = - ReadTokenStart(bytes_.subspan(status_.pos + 1), &token_start_type_, - &token_start_internal_value_); - int64_t token_byte_length = 1 + bytes_read + token_start_internal_value_; - if (-1 == bytes_read || token_start_type_ != MajorType::BYTE_STRING || - status_.pos + token_byte_length > bytes_.size()) { - SetError(Error::CBOR_INVALID_BINARY); - return; - } - SetToken(CBORTokenTag::BINARY, - static_cast<std::ptrdiff_t>(token_byte_length)); - return; - } - case kInitialByteForDouble: { // DOUBLE - if (status_.pos + kEncodedDoubleSize > bytes_.size()) { - SetError(Error::CBOR_INVALID_DOUBLE); - return; - } - SetToken(CBORTokenTag::DOUBLE, kEncodedDoubleSize); - return; - } - case kInitialByteForEnvelope: { // ENVELOPE - if (status_.pos + kEncodedEnvelopeHeaderSize > bytes_.size()) { - SetError(Error::CBOR_INVALID_ENVELOPE); - return; - } - // The envelope must be a byte string with 32 bit length. - if (bytes_[status_.pos + 1] != kInitialByteFor32BitLengthByteString) { - SetError(Error::CBOR_INVALID_ENVELOPE); - return; - } - // Read the length of the byte string. - token_start_internal_value_ = ReadBytesMostSignificantByteFirst<uint32_t>( - bytes_.subspan(status_.pos + 2)); - // Make sure the payload is contained within the message. - if (token_start_internal_value_ + kEncodedEnvelopeHeaderSize + - status_.pos > - static_cast<std::size_t>(bytes_.size())) { - SetError(Error::CBOR_INVALID_ENVELOPE); - return; - } - auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); - SetToken(CBORTokenTag::ENVELOPE, - kEncodedEnvelopeHeaderSize + length); - return; - } - default: { - span<uint8_t> remainder = - bytes_.subspan(status_.pos, bytes_.size() - status_.pos); - assert(!remainder.empty()); - int8_t token_start_length = ReadTokenStart(remainder, &token_start_type_, - &token_start_internal_value_); - bool success = token_start_length != -1; - switch (token_start_type_) { - case MajorType::UNSIGNED: // INT32. - if (!success || std::numeric_limits<int32_t>::max() < - token_start_internal_value_) { - SetError(Error::CBOR_INVALID_INT32); - return; - } - SetToken(CBORTokenTag::INT32, token_start_length); - return; - case MajorType::NEGATIVE: // INT32. - if (!success || - std::numeric_limits<int32_t>::min() > - -static_cast<int64_t>(token_start_internal_value_) - 1) { - SetError(Error::CBOR_INVALID_INT32); - return; - } - SetToken(CBORTokenTag::INT32, token_start_length); - return; - case MajorType::STRING: { // STRING8. - if (!success || remainder.size() < static_cast<int64_t>( - token_start_internal_value_)) { - SetError(Error::CBOR_INVALID_STRING8); - return; - } - auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); - SetToken(CBORTokenTag::STRING8, token_start_length + length); - return; - } - case MajorType::BYTE_STRING: { // STRING16. - if (!success || - remainder.size() < - static_cast<int64_t>(token_start_internal_value_) || - // Must be divisible by 2 since UTF16 is 2 bytes per character. - token_start_internal_value_ & 1) { - SetError(Error::CBOR_INVALID_STRING16); - return; - } - auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); - SetToken(CBORTokenTag::STRING16, token_start_length + length); - return; - } - case MajorType::ARRAY: - case MajorType::MAP: - case MajorType::TAG: - case MajorType::SIMPLE_VALUE: - SetError(Error::CBOR_UNSUPPORTED_VALUE); - return; - } - } - } -} - -void CBORTokenizer::SetToken(CBORTokenTag token_tag, - std::ptrdiff_t token_byte_length) { - token_tag_ = token_tag; - token_byte_length_ = token_byte_length; -} - -void CBORTokenizer::SetError(Error error) { - token_tag_ = CBORTokenTag::ERROR_VALUE; - status_.error = error; -} - -#if 0 -void DumpCBOR(span<uint8_t> cbor) { - std::string indent; - CBORTokenizer tokenizer(cbor); - while (true) { - fprintf(stderr, "%s", indent.c_str()); - switch (tokenizer.TokenTag()) { - case CBORTokenTag::ERROR_VALUE: - fprintf(stderr, "ERROR {status.error=%d, status.pos=%ld}\n", - tokenizer.Status().error, tokenizer.Status().pos); - return; - case CBORTokenTag::DONE: - fprintf(stderr, "DONE\n"); - return; - case CBORTokenTag::TRUE_VALUE: - fprintf(stderr, "TRUE_VALUE\n"); - break; - case CBORTokenTag::FALSE_VALUE: - fprintf(stderr, "FALSE_VALUE\n"); - break; - case CBORTokenTag::NULL_VALUE: - fprintf(stderr, "NULL_VALUE\n"); - break; - case CBORTokenTag::INT32: - fprintf(stderr, "INT32 [%d]\n", tokenizer.GetInt32()); - break; - case CBORTokenTag::DOUBLE: - fprintf(stderr, "DOUBLE [%lf]\n", tokenizer.GetDouble()); - break; - case CBORTokenTag::STRING8: { - span<uint8_t> v = tokenizer.GetString8(); - std::string t(v.begin(), v.end()); - fprintf(stderr, "STRING8 [%s]\n", t.c_str()); - break; - } - case CBORTokenTag::STRING16: { - span<uint8_t> v = tokenizer.GetString16WireRep(); - std::string t(v.begin(), v.end()); - fprintf(stderr, "STRING16 [%s]\n", t.c_str()); - break; - } - case CBORTokenTag::BINARY: { - span<uint8_t> v = tokenizer.GetBinary(); - std::string t(v.begin(), v.end()); - fprintf(stderr, "BINARY [%s]\n", t.c_str()); - break; - } - case CBORTokenTag::MAP_START: - fprintf(stderr, "MAP_START\n"); - indent += " "; - break; - case CBORTokenTag::ARRAY_START: - fprintf(stderr, "ARRAY_START\n"); - indent += " "; - break; - case CBORTokenTag::STOP: - fprintf(stderr, "STOP\n"); - indent.erase(0, 2); - break; - case CBORTokenTag::ENVELOPE: - fprintf(stderr, "ENVELOPE\n"); - tokenizer.EnterEnvelope(); - continue; - } - tokenizer.Next(); - } -} -#endif - - -{% for namespace in config.protocol.namespace %} -} // namespace {{namespace}} -{% endfor %} -
diff --git a/third_party/inspector_protocol/lib/Values_cpp.template b/third_party/inspector_protocol/lib/Values_cpp.template index 20899a3..2d4463e2 100644 --- a/third_party/inspector_protocol/lib/Values_cpp.template +++ b/third_party/inspector_protocol/lib/Values_cpp.template
@@ -66,21 +66,21 @@ // Below are three parsing routines for CBOR, which cover enough // to roundtrip JSON messages. -std::unique_ptr<DictionaryValue> parseMap(int32_t stack_depth, CBORTokenizer* tokenizer); -std::unique_ptr<ListValue> parseArray(int32_t stack_depth, CBORTokenizer* tokenizer); -std::unique_ptr<Value> parseValue(int32_t stack_depth, CBORTokenizer* tokenizer); +std::unique_ptr<DictionaryValue> parseMap(int32_t stack_depth, cbor::CBORTokenizer* tokenizer); +std::unique_ptr<ListValue> parseArray(int32_t stack_depth, cbor::CBORTokenizer* tokenizer); +std::unique_ptr<Value> parseValue(int32_t stack_depth, cbor::CBORTokenizer* tokenizer); // |bytes| must start with the indefinite length array byte, so basically, // ParseArray may only be called after an indefinite length array has been // detected. -std::unique_ptr<ListValue> parseArray(int32_t stack_depth, CBORTokenizer* tokenizer) { - DCHECK(tokenizer->TokenTag() == CBORTokenTag::ARRAY_START); +std::unique_ptr<ListValue> parseArray(int32_t stack_depth, cbor::CBORTokenizer* tokenizer) { + DCHECK(tokenizer->TokenTag() == cbor::CBORTokenTag::ARRAY_START); tokenizer->Next(); auto list = ListValue::create(); - while (tokenizer->TokenTag() != CBORTokenTag::STOP) { + while (tokenizer->TokenTag() != cbor::CBORTokenTag::STOP) { // Error::CBOR_UNEXPECTED_EOF_IN_ARRAY - if (tokenizer->TokenTag() == CBORTokenTag::DONE) return nullptr; - if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) return nullptr; + if (tokenizer->TokenTag() == cbor::CBORTokenTag::DONE) return nullptr; + if (tokenizer->TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr; // Parse value. auto value = parseValue(stack_depth, tokenizer); if (!value) return nullptr; @@ -91,51 +91,51 @@ } std::unique_ptr<Value> parseValue( - int32_t stack_depth, CBORTokenizer* tokenizer) { + int32_t stack_depth, cbor::CBORTokenizer* tokenizer) { // Error::CBOR_STACK_LIMIT_EXCEEDED if (stack_depth > kStackLimitValues) return nullptr; // Skip past the envelope to get to what's inside. - if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE) + if (tokenizer->TokenTag() == cbor::CBORTokenTag::ENVELOPE) tokenizer->EnterEnvelope(); switch (tokenizer->TokenTag()) { - case CBORTokenTag::ERROR_VALUE: + case cbor::CBORTokenTag::ERROR_VALUE: return nullptr; - case CBORTokenTag::DONE: + case cbor::CBORTokenTag::DONE: // Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE return nullptr; - case CBORTokenTag::TRUE_VALUE: { + case cbor::CBORTokenTag::TRUE_VALUE: { std::unique_ptr<Value> value = FundamentalValue::create(true); tokenizer->Next(); return value; } - case CBORTokenTag::FALSE_VALUE: { + case cbor::CBORTokenTag::FALSE_VALUE: { std::unique_ptr<Value> value = FundamentalValue::create(false); tokenizer->Next(); return value; } - case CBORTokenTag::NULL_VALUE: { + case cbor::CBORTokenTag::NULL_VALUE: { std::unique_ptr<Value> value = FundamentalValue::null(); tokenizer->Next(); return value; } - case CBORTokenTag::INT32: { + case cbor::CBORTokenTag::INT32: { std::unique_ptr<Value> value = FundamentalValue::create(tokenizer->GetInt32()); tokenizer->Next(); return value; } - case CBORTokenTag::DOUBLE: { + case cbor::CBORTokenTag::DOUBLE: { std::unique_ptr<Value> value = FundamentalValue::create(tokenizer->GetDouble()); tokenizer->Next(); return value; } - case CBORTokenTag::STRING8: { + case cbor::CBORTokenTag::STRING8: { span<uint8_t> str = tokenizer->GetString8(); std::unique_ptr<Value> value = StringValue::create(StringUtil::fromUTF8(str.data(), str.size())); tokenizer->Next(); return value; } - case CBORTokenTag::STRING16: { + case cbor::CBORTokenTag::STRING16: { span<uint8_t> wire = tokenizer->GetString16WireRep(); DCHECK_EQ(wire.size() & 1, 0); std::unique_ptr<Value> value = StringValue::create(StringUtil::fromUTF16( @@ -143,14 +143,14 @@ tokenizer->Next(); return value; } - case CBORTokenTag::BINARY: { + case cbor::CBORTokenTag::BINARY: { span<uint8_t> payload = tokenizer->GetBinary(); tokenizer->Next(); return BinaryValue::create(Binary::fromSpan(payload.data(), payload.size())); } - case CBORTokenTag::MAP_START: + case cbor::CBORTokenTag::MAP_START: return parseMap(stack_depth + 1, tokenizer); - case CBORTokenTag::ARRAY_START: + case cbor::CBORTokenTag::ARRAY_START: return parseArray(stack_depth + 1, tokenizer); default: // Error::CBOR_UNSUPPORTED_VALUE @@ -162,22 +162,22 @@ // ParseArray may only be called after an indefinite length array has been // detected. std::unique_ptr<DictionaryValue> parseMap( - int32_t stack_depth, CBORTokenizer* tokenizer) { + int32_t stack_depth, cbor::CBORTokenizer* tokenizer) { auto dict = DictionaryValue::create(); tokenizer->Next(); - while (tokenizer->TokenTag() != CBORTokenTag::STOP) { - if (tokenizer->TokenTag() == CBORTokenTag::DONE) { + while (tokenizer->TokenTag() != cbor::CBORTokenTag::STOP) { + if (tokenizer->TokenTag() == cbor::CBORTokenTag::DONE) { // Error::CBOR_UNEXPECTED_EOF_IN_MAP return nullptr; } - if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) return nullptr; + if (tokenizer->TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr; // Parse key. String key; - if (tokenizer->TokenTag() == CBORTokenTag::STRING8) { + if (tokenizer->TokenTag() == cbor::CBORTokenTag::STRING8) { span<uint8_t> key_span = tokenizer->GetString8(); key = StringUtil::fromUTF8(key_span.data(), key_span.size()); tokenizer->Next(); - } else if (tokenizer->TokenTag() == CBORTokenTag::STRING16) { + } else if (tokenizer->TokenTag() == cbor::CBORTokenTag::STRING16) { return nullptr; // STRING16 not supported yet. } else { // Error::CBOR_INVALID_MAP_KEY @@ -202,22 +202,21 @@ if (bytes.empty()) return nullptr; // Error::CBOR_INVALID_START_BYTE - // TODO(johannes): EncodeInitialByteForEnvelope() method. - if (bytes[0] != 0xd8) return nullptr; + if (bytes[0] != cbor::InitialByteForEnvelope()) return nullptr; - CBORTokenizer tokenizer(bytes); - if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) return nullptr; + cbor::CBORTokenizer tokenizer(bytes); + if (tokenizer.TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr; // We checked for the envelope start byte above, so the tokenizer // must agree here, since it's not an error. - DCHECK(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE); + DCHECK(tokenizer.TokenTag() == cbor::CBORTokenTag::ENVELOPE); tokenizer.EnterEnvelope(); // Error::MAP_START_EXPECTED - if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) return nullptr; + if (tokenizer.TokenTag() != cbor::CBORTokenTag::MAP_START) return nullptr; std::unique_ptr<Value> result = parseMap(/*stack_depth=*/1, &tokenizer); if (!result) return nullptr; - if (tokenizer.TokenTag() == CBORTokenTag::DONE) return result; - if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) return nullptr; + if (tokenizer.TokenTag() == cbor::CBORTokenTag::DONE) return result; + if (tokenizer.TokenTag() == cbor::CBORTokenTag::ERROR_VALUE) return nullptr; // Error::CBOR_TRAILING_JUNK return nullptr; } @@ -255,7 +254,7 @@ void Value::writeBinary(std::vector<uint8_t>* bytes) const { DCHECK(m_type == TypeNull); - bytes->push_back(EncodeNull()); + bytes->push_back(cbor::EncodeNull()); } std::unique_ptr<Value> Value::clone() const @@ -332,13 +331,13 @@ void FundamentalValue::writeBinary(std::vector<uint8_t>* bytes) const { switch (type()) { case TypeDouble: - EncodeDouble(m_doubleValue, bytes); + cbor::EncodeDouble(m_doubleValue, bytes); return; case TypeInteger: - EncodeInt32(m_integerValue, bytes); + cbor::EncodeInt32(m_integerValue, bytes); return; case TypeBoolean: - bytes->push_back(m_boolValue ? EncodeTrue() : EncodeFalse()); + bytes->push_back(m_boolValue ? cbor::EncodeTrue() : cbor::EncodeFalse()); return; default: DCHECK(false); @@ -381,19 +380,19 @@ // transcodes to UTF8 if needed. void EncodeString(const String& s, std::vector<uint8_t>* out) { if (StringUtil::CharacterCount(s) == 0) { - EncodeString8(span<uint8_t>(nullptr, 0), out); // Empty string. + cbor::EncodeString8(span<uint8_t>(nullptr, 0), out); // Empty string. } else if (StringUtil::CharactersLatin1(s)) { - EncodeFromLatin1(span<uint8_t>(StringUtil::CharactersLatin1(s), - StringUtil::CharacterCount(s)), - out); + cbor::EncodeFromLatin1(span<uint8_t>(StringUtil::CharactersLatin1(s), + StringUtil::CharacterCount(s)), + out); } else if (StringUtil::CharactersUTF16(s)) { - EncodeFromUTF16(span<uint16_t>(StringUtil::CharactersUTF16(s), - StringUtil::CharacterCount(s)), - out); + cbor::EncodeFromUTF16(span<uint16_t>(StringUtil::CharactersUTF16(s), + StringUtil::CharacterCount(s)), + out); } else if (StringUtil::CharactersUTF8(s)) { - EncodeString8(span<uint8_t>(StringUtil::CharactersUTF8(s), - StringUtil::CharacterCount(s)), - out); + cbor::EncodeString8(span<uint8_t>(StringUtil::CharactersUTF8(s), + StringUtil::CharacterCount(s)), + out); } } } // namespace @@ -420,7 +419,8 @@ } void BinaryValue::writeBinary(std::vector<uint8_t>* bytes) const { - EncodeBinary(span<uint8_t>(m_binaryValue.data(), m_binaryValue.size()), bytes); + cbor::EncodeBinary(span<uint8_t>(m_binaryValue.data(), + m_binaryValue.size()), bytes); } std::unique_ptr<Value> BinaryValue::clone() const @@ -583,9 +583,9 @@ } void DictionaryValue::writeBinary(std::vector<uint8_t>* bytes) const { - EnvelopeEncoder encoder; + cbor::EnvelopeEncoder encoder; encoder.EncodeStart(bytes); - bytes->push_back(EncodeIndefiniteLengthMapStart()); + bytes->push_back(cbor::EncodeIndefiniteLengthMapStart()); for (size_t i = 0; i < m_order.size(); ++i) { const String& key = m_order[i]; Dictionary::const_iterator value = m_data.find(key); @@ -593,7 +593,7 @@ EncodeString(key, bytes); value->second->writeBinary(bytes); } - bytes->push_back(EncodeStop()); + bytes->push_back(cbor::EncodeStop()); encoder.EncodeStop(bytes); } @@ -632,13 +632,13 @@ } void ListValue::writeBinary(std::vector<uint8_t>* bytes) const { - EnvelopeEncoder encoder; + cbor::EnvelopeEncoder encoder; encoder.EncodeStart(bytes); - bytes->push_back(EncodeIndefiniteLengthArrayStart()); + bytes->push_back(cbor::EncodeIndefiniteLengthArrayStart()); for (size_t i = 0; i < m_data.size(); ++i) { m_data[i]->writeBinary(bytes); } - bytes->push_back(EncodeStop()); + bytes->push_back(cbor::EncodeStop()); encoder.EncodeStop(bytes); }
diff --git a/third_party/inspector_protocol/lib/base_string_adapter_cc.template b/third_party/inspector_protocol/lib/base_string_adapter_cc.template index 24855d4..94bcd88 100644 --- a/third_party/inspector_protocol/lib/base_string_adapter_cc.template +++ b/third_party/inspector_protocol/lib/base_string_adapter_cc.template
@@ -256,34 +256,34 @@ if (in.size() < 1 + 1 + 4 + 1 + 1) return false; const uint8_t* envelope = reinterpret_cast<const uint8_t*>(in.data()); - if (cbor::kInitialByteForEnvelope != envelope[0]) + if (cbor::InitialByteForEnvelope() != envelope[0]) return false; - if (cbor::kInitialByteFor32BitLengthByteString != envelope[1]) + if (cbor::InitialByteFor32BitLengthByteString() != envelope[1]) return false; - if (cbor::kInitialByteIndefiniteLengthMap != envelope[6]) + if (cbor::EncodeIndefiniteLengthMapStart() != envelope[6]) return false; uint32_t envelope_size = ReadEnvelopeSize(envelope + 2); if (envelope_size + 2 + 4 != in.size()) return false; - if (cbor::kStopByte != static_cast<uint8_t>(*in.rbegin())) + if (cbor::EncodeStop() != static_cast<uint8_t>(*in.rbegin())) return false; std::vector<uint8_t> encoded_entry; encoded_entry.reserve(1 + 4 + key.size() + 1 + 4 + value.size()); span<uint8_t> key_span( reinterpret_cast<const uint8_t*>(key.data()), key.size()); - EncodeString8(key_span, &encoded_entry); + cbor::EncodeString8(key_span, &encoded_entry); span<uint8_t> value_span( reinterpret_cast<const uint8_t*>(value.data()), value.size()); - EncodeString8(value_span, &encoded_entry); + cbor::EncodeString8(value_span, &encoded_entry); out->clear(); out->reserve(in.size() + encoded_entry.size()); out->append(in.begin(), in.end() - 1); out->append(reinterpret_cast<const char*>(encoded_entry.data()), encoded_entry.size()); - out->append(1, static_cast<char>(cbor::kStopByte)); + out->append(1, static_cast<char>(cbor::EncodeStop())); std::size_t new_size = envelope_size + out->size() - in.size(); if (new_size > static_cast<std::size_t>( std::numeric_limits<uint32_t>::max())) {
diff --git a/third_party/inspector_protocol/lib/encoding_cpp.template b/third_party/inspector_protocol/lib/encoding_cpp.template new file mode 100644 index 0000000..84251d9 --- /dev/null +++ b/third_party/inspector_protocol/lib/encoding_cpp.template
@@ -0,0 +1,1807 @@ +{# This template is generated by gen_cbor_templates.py. #} +// Generated by lib/encoding_cpp.template. + +// 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 <cassert> +#include <cstring> +#include <limits> +#include <stack> + +{% for namespace in config.protocol.namespace %} +namespace {{namespace}} { +{% endfor %} + +// ===== encoding/encoding.cc ===== + +namespace cbor { +namespace { +// Indicates the number of bits the "initial byte" needs to be shifted to the +// right after applying |kMajorTypeMask| to produce the major type in the +// lowermost bits. +static constexpr uint8_t kMajorTypeBitShift = 5u; +// Mask selecting the low-order 5 bits of the "initial byte", which is where +// the additional information is encoded. +static constexpr uint8_t kAdditionalInformationMask = 0x1f; +// Mask selecting the high-order 3 bits of the "initial byte", which indicates +// the major type of the encoded value. +static constexpr uint8_t kMajorTypeMask = 0xe0; +// Indicates the integer is in the following byte. +static constexpr uint8_t kAdditionalInformation1Byte = 24u; +// Indicates the integer is in the next 2 bytes. +static constexpr uint8_t kAdditionalInformation2Bytes = 25u; +// Indicates the integer is in the next 4 bytes. +static constexpr uint8_t kAdditionalInformation4Bytes = 26u; +// Indicates the integer is in the next 8 bytes. +static constexpr uint8_t kAdditionalInformation8Bytes = 27u; + +// Encodes the initial byte, consisting of the |type| in the first 3 bits +// followed by 5 bits of |additional_info|. +constexpr uint8_t EncodeInitialByte(MajorType type, uint8_t additional_info) { + return (static_cast<uint8_t>(type) << kMajorTypeBitShift) | + (additional_info & kAdditionalInformationMask); +} + +// TAG 24 indicates that what follows is a byte string which is +// encoded in CBOR format. We use this as a wrapper for +// maps and arrays, allowing us to skip them, because the +// byte string carries its size (byte length). +// https://tools.ietf.org/html/rfc7049#section-2.4.4.1 +static constexpr uint8_t kInitialByteForEnvelope = + EncodeInitialByte(MajorType::TAG, 24); +// The initial byte for a byte string with at most 2^32 bytes +// of payload. This is used for envelope encoding, even if +// the byte string is shorter. +static constexpr uint8_t kInitialByteFor32BitLengthByteString = + EncodeInitialByte(MajorType::BYTE_STRING, 26); + +// See RFC 7049 Section 2.2.1, indefinite length arrays / maps have additional +// info = 31. +static constexpr uint8_t kInitialByteIndefiniteLengthArray = + EncodeInitialByte(MajorType::ARRAY, 31); +static constexpr uint8_t kInitialByteIndefiniteLengthMap = + EncodeInitialByte(MajorType::MAP, 31); +// See RFC 7049 Section 2.3, Table 1; this is used for finishing indefinite +// length maps / arrays. +static constexpr uint8_t kStopByte = + EncodeInitialByte(MajorType::SIMPLE_VALUE, 31); + +// See RFC 7049 Section 2.3, Table 2. +static constexpr uint8_t kEncodedTrue = + EncodeInitialByte(MajorType::SIMPLE_VALUE, 21); +static constexpr uint8_t kEncodedFalse = + EncodeInitialByte(MajorType::SIMPLE_VALUE, 20); +static constexpr uint8_t kEncodedNull = + EncodeInitialByte(MajorType::SIMPLE_VALUE, 22); +static constexpr uint8_t kInitialByteForDouble = + EncodeInitialByte(MajorType::SIMPLE_VALUE, 27); + +// See RFC 7049 Table 3 and Section 2.4.4.2. This is used as a prefix for +// arbitrary binary data encoded as BYTE_STRING. +static constexpr uint8_t kExpectedConversionToBase64Tag = + EncodeInitialByte(MajorType::TAG, 22); + +// Writes the bytes for |v| to |out|, starting with the most significant byte. +// See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html +template <typename T> +void WriteBytesMostSignificantByteFirst(T v, std::vector<uint8_t>* out) { + for (int shift_bytes = sizeof(T) - 1; shift_bytes >= 0; --shift_bytes) + out->push_back(0xff & (v >> (shift_bytes * 8))); +} + +// Extracts sizeof(T) bytes from |in| to extract a value of type T +// (e.g. uint64_t, uint32_t, ...), most significant byte first. +// See also: https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html +template <typename T> +T ReadBytesMostSignificantByteFirst(span<uint8_t> in) { + assert(static_cast<std::size_t>(in.size()) >= sizeof(T)); + T result = 0; + for (std::size_t shift_bytes = 0; shift_bytes < sizeof(T); ++shift_bytes) + result |= T(in[sizeof(T) - 1 - shift_bytes]) << (shift_bytes * 8); + return result; +} +} // namespace + +namespace internals { +// Reads the start of a token with definitive size from |bytes|. +// |type| is the major type as specified in RFC 7049 Section 2.1. +// |value| is the payload (e.g. for MajorType::UNSIGNED) or is the size +// (e.g. for BYTE_STRING). +// If successful, returns the number of bytes read. Otherwise returns -1. +int8_t ReadTokenStart(span<uint8_t> bytes, MajorType* type, uint64_t* value) { + if (bytes.empty()) + return -1; + uint8_t initial_byte = bytes[0]; + *type = MajorType((initial_byte & kMajorTypeMask) >> kMajorTypeBitShift); + + uint8_t additional_information = initial_byte & kAdditionalInformationMask; + if (additional_information < 24) { + // Values 0-23 are encoded directly into the additional info of the + // initial byte. + *value = additional_information; + return 1; + } + if (additional_information == kAdditionalInformation1Byte) { + // Values 24-255 are encoded with one initial byte, followed by the value. + if (bytes.size() < 2) + return -1; + *value = ReadBytesMostSignificantByteFirst<uint8_t>(bytes.subspan(1)); + return 2; + } + if (additional_information == kAdditionalInformation2Bytes) { + // Values 256-65535: 1 initial byte + 2 bytes payload. + if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint16_t)) + return -1; + *value = ReadBytesMostSignificantByteFirst<uint16_t>(bytes.subspan(1)); + return 3; + } + if (additional_information == kAdditionalInformation4Bytes) { + // 32 bit uint: 1 initial byte + 4 bytes payload. + if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint32_t)) + return -1; + *value = ReadBytesMostSignificantByteFirst<uint32_t>(bytes.subspan(1)); + return 5; + } + if (additional_information == kAdditionalInformation8Bytes) { + // 64 bit uint: 1 initial byte + 8 bytes payload. + if (static_cast<std::size_t>(bytes.size()) < 1 + sizeof(uint64_t)) + return -1; + *value = ReadBytesMostSignificantByteFirst<uint64_t>(bytes.subspan(1)); + return 9; + } + return -1; +} + +// Writes the start of a token with |type|. The |value| may indicate the size, +// or it may be the payload if the value is an unsigned integer. +void WriteTokenStart(MajorType type, + uint64_t value, + std::vector<uint8_t>* encoded) { + if (value < 24) { + // Values 0-23 are encoded directly into the additional info of the + // initial byte. + encoded->push_back(EncodeInitialByte(type, /*additional_info=*/value)); + return; + } + if (value <= std::numeric_limits<uint8_t>::max()) { + // Values 24-255 are encoded with one initial byte, followed by the value. + encoded->push_back(EncodeInitialByte(type, kAdditionalInformation1Byte)); + encoded->push_back(value); + return; + } + if (value <= std::numeric_limits<uint16_t>::max()) { + // Values 256-65535: 1 initial byte + 2 bytes payload. + encoded->push_back(EncodeInitialByte(type, kAdditionalInformation2Bytes)); + WriteBytesMostSignificantByteFirst<uint16_t>(value, encoded); + return; + } + if (value <= std::numeric_limits<uint32_t>::max()) { + // 32 bit uint: 1 initial byte + 4 bytes payload. + encoded->push_back(EncodeInitialByte(type, kAdditionalInformation4Bytes)); + WriteBytesMostSignificantByteFirst<uint32_t>(static_cast<uint32_t>(value), + encoded); + return; + } + // 64 bit uint: 1 initial byte + 8 bytes payload. + encoded->push_back(EncodeInitialByte(type, kAdditionalInformation8Bytes)); + WriteBytesMostSignificantByteFirst<uint64_t>(value, encoded); +} +} // namespace internals + +// ============================================================================= +// Detecting CBOR content +// ============================================================================= + +uint8_t InitialByteForEnvelope() { + return kInitialByteForEnvelope; +} +uint8_t InitialByteFor32BitLengthByteString() { + return kInitialByteFor32BitLengthByteString; +} +bool IsCBORMessage(span<uint8_t> msg) { + return msg.size() >= 6 && msg[0] == InitialByteForEnvelope() && + msg[1] == InitialByteFor32BitLengthByteString(); +} + +// ============================================================================= +// Encoding invidiual CBOR items +// ============================================================================= + +uint8_t EncodeTrue() { + return kEncodedTrue; +} +uint8_t EncodeFalse() { + return kEncodedFalse; +} +uint8_t EncodeNull() { + return kEncodedNull; +} + +uint8_t EncodeIndefiniteLengthArrayStart() { + return kInitialByteIndefiniteLengthArray; +} + +uint8_t EncodeIndefiniteLengthMapStart() { + return kInitialByteIndefiniteLengthMap; +} + +uint8_t EncodeStop() { + return kStopByte; +} + +void EncodeInt32(int32_t value, std::vector<uint8_t>* out) { + if (value >= 0) { + internals::WriteTokenStart(MajorType::UNSIGNED, value, out); + } else { + uint64_t representation = static_cast<uint64_t>(-(value + 1)); + internals::WriteTokenStart(MajorType::NEGATIVE, representation, out); + } +} + +void EncodeString16(span<uint16_t> in, std::vector<uint8_t>* out) { + uint64_t byte_length = static_cast<uint64_t>(in.size_bytes()); + internals::WriteTokenStart(MajorType::BYTE_STRING, byte_length, out); + // When emitting UTF16 characters, we always write the least significant byte + // first; this is because it's the native representation for X86. + // TODO(johannes): Implement a more efficient thing here later, e.g. + // casting *iff* the machine has this byte order. + // The wire format for UTF16 chars will probably remain the same + // (least significant byte first) since this way we can have + // golden files, unittests, etc. that port easily and universally. + // See also: + // https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html + for (const uint16_t two_bytes : in) { + out->push_back(two_bytes); + out->push_back(two_bytes >> 8); + } +} + +void EncodeString8(span<uint8_t> in, std::vector<uint8_t>* out) { + internals::WriteTokenStart(MajorType::STRING, + static_cast<uint64_t>(in.size_bytes()), out); + out->insert(out->end(), in.begin(), in.end()); +} + +void EncodeFromLatin1(span<uint8_t> latin1, std::vector<uint8_t>* out) { + for (std::ptrdiff_t ii = 0; ii < latin1.size(); ++ii) { + if (latin1[ii] <= 127) + continue; + // If there's at least one non-ASCII char, convert to UTF8. + std::vector<uint8_t> utf8(latin1.begin(), latin1.begin() + ii); + for (; ii < latin1.size(); ++ii) { + if (latin1[ii] <= 127) { + utf8.push_back(latin1[ii]); + } else { + // 0xC0 means it's a UTF8 sequence with 2 bytes. + utf8.push_back((latin1[ii] >> 6) | 0xc0); + utf8.push_back((latin1[ii] | 0x80) & 0xbf); + } + } + EncodeString8(SpanFromVector(utf8), out); + return; + } + EncodeString8(latin1, out); +} + +void EncodeFromUTF16(span<uint16_t> utf16, std::vector<uint8_t>* out) { + // If there's at least one non-ASCII char, encode as STRING16 (UTF16). + for (uint16_t ch : utf16) { + if (ch <= 127) + continue; + EncodeString16(utf16, out); + return; + } + // It's all US-ASCII, strip out every second byte and encode as UTF8. + internals::WriteTokenStart(MajorType::STRING, + static_cast<uint64_t>(utf16.size()), out); + out->insert(out->end(), utf16.begin(), utf16.end()); +} + +void EncodeBinary(span<uint8_t> in, std::vector<uint8_t>* out) { + out->push_back(kExpectedConversionToBase64Tag); + uint64_t byte_length = static_cast<uint64_t>(in.size_bytes()); + internals::WriteTokenStart(MajorType::BYTE_STRING, byte_length, out); + out->insert(out->end(), in.begin(), in.end()); +} + +// A double is encoded with a specific initial byte +// (kInitialByteForDouble) plus the 64 bits of payload for its value. +constexpr std::ptrdiff_t kEncodedDoubleSize = 1 + sizeof(uint64_t); + +// An envelope is encoded with a specific initial byte +// (kInitialByteForEnvelope), plus the start byte for a BYTE_STRING with a 32 +// bit wide length, plus a 32 bit length for that string. +constexpr std::ptrdiff_t kEncodedEnvelopeHeaderSize = 1 + 1 + sizeof(uint32_t); + +void EncodeDouble(double value, std::vector<uint8_t>* out) { + // The additional_info=27 indicates 64 bits for the double follow. + // See RFC 7049 Section 2.3, Table 1. + out->push_back(kInitialByteForDouble); + union { + double from_double; + uint64_t to_uint64; + } reinterpret; + reinterpret.from_double = value; + WriteBytesMostSignificantByteFirst<uint64_t>(reinterpret.to_uint64, out); +} + +// ============================================================================= +// cbor::EnvelopeEncoder - for wrapping submessages +// ============================================================================= + +void EnvelopeEncoder::EncodeStart(std::vector<uint8_t>* out) { + assert(byte_size_pos_ == 0); + out->push_back(kInitialByteForEnvelope); + out->push_back(kInitialByteFor32BitLengthByteString); + byte_size_pos_ = out->size(); + out->resize(out->size() + sizeof(uint32_t)); +} + +bool EnvelopeEncoder::EncodeStop(std::vector<uint8_t>* out) { + assert(byte_size_pos_ != 0); + // The byte size is the size of the payload, that is, all the + // bytes that were written past the byte size position itself. + uint64_t byte_size = out->size() - (byte_size_pos_ + sizeof(uint32_t)); + // We store exactly 4 bytes, so at most INT32MAX, with most significant + // byte first. + if (byte_size > std::numeric_limits<uint32_t>::max()) + return false; + for (int shift_bytes = sizeof(uint32_t) - 1; shift_bytes >= 0; + --shift_bytes) { + (*out)[byte_size_pos_++] = 0xff & (byte_size >> (shift_bytes * 8)); + } + return true; +} + +// ============================================================================= +// cbor::NewCBOREncoder - for encoding from a streaming parser +// ============================================================================= + +namespace { +class CBOREncoder : public StreamingParserHandler { + public: + CBOREncoder(std::vector<uint8_t>* out, Status* status) + : out_(out), status_(status) { + *status_ = Status(); + } + + void HandleMapBegin() override { + envelopes_.emplace_back(); + envelopes_.back().EncodeStart(out_); + out_->push_back(kInitialByteIndefiniteLengthMap); + } + + void HandleMapEnd() override { + out_->push_back(kStopByte); + assert(!envelopes_.empty()); + envelopes_.back().EncodeStop(out_); + envelopes_.pop_back(); + } + + void HandleArrayBegin() override { + envelopes_.emplace_back(); + envelopes_.back().EncodeStart(out_); + out_->push_back(kInitialByteIndefiniteLengthArray); + } + + void HandleArrayEnd() override { + out_->push_back(kStopByte); + assert(!envelopes_.empty()); + envelopes_.back().EncodeStop(out_); + envelopes_.pop_back(); + } + + void HandleString8(span<uint8_t> chars) override { + EncodeString8(chars, out_); + } + + void HandleString16(span<uint16_t> chars) override { + EncodeFromUTF16(chars, out_); + } + + void HandleBinary(span<uint8_t> bytes) override { EncodeBinary(bytes, out_); } + + void HandleDouble(double value) override { EncodeDouble(value, out_); } + + void HandleInt32(int32_t value) override { EncodeInt32(value, out_); } + + void HandleBool(bool value) override { + // See RFC 7049 Section 2.3, Table 2. + out_->push_back(value ? kEncodedTrue : kEncodedFalse); + } + + void HandleNull() override { + // See RFC 7049 Section 2.3, Table 2. + out_->push_back(kEncodedNull); + } + + void HandleError(Status error) override { + assert(!error.ok()); + *status_ = error; + out_->clear(); + } + + private: + std::vector<uint8_t>* out_; + std::vector<EnvelopeEncoder> envelopes_; + Status* status_; +}; +} // namespace + +std::unique_ptr<StreamingParserHandler> NewCBOREncoder( + std::vector<uint8_t>* out, + Status* status) { + return std::unique_ptr<StreamingParserHandler>(new CBOREncoder(out, status)); +} + +// ============================================================================= +// cbor::CBORTokenizer - for parsing individual CBOR items +// ============================================================================= + +CBORTokenizer::CBORTokenizer(span<uint8_t> bytes) : bytes_(bytes) { + ReadNextToken(/*enter_envelope=*/false); +} +CBORTokenizer::~CBORTokenizer() {} + +CBORTokenTag CBORTokenizer::TokenTag() const { + return token_tag_; +} + +void CBORTokenizer::Next() { + if (token_tag_ == CBORTokenTag::ERROR_VALUE || + token_tag_ == CBORTokenTag::DONE) + return; + ReadNextToken(/*enter_envelope=*/false); +} + +void CBORTokenizer::EnterEnvelope() { + assert(token_tag_ == CBORTokenTag::ENVELOPE); + ReadNextToken(/*enter_envelope=*/true); +} + +Status CBORTokenizer::Status() const { + return status_; +} + +int32_t CBORTokenizer::GetInt32() const { + assert(token_tag_ == CBORTokenTag::INT32); + // The range checks happen in ::ReadNextToken(). + return static_cast<uint32_t>( + token_start_type_ == MajorType::UNSIGNED + ? token_start_internal_value_ + : -static_cast<int64_t>(token_start_internal_value_) - 1); +} + +double CBORTokenizer::GetDouble() const { + assert(token_tag_ == CBORTokenTag::DOUBLE); + union { + uint64_t from_uint64; + double to_double; + } reinterpret; + reinterpret.from_uint64 = ReadBytesMostSignificantByteFirst<uint64_t>( + bytes_.subspan(status_.pos + 1)); + return reinterpret.to_double; +} + +span<uint8_t> CBORTokenizer::GetString8() const { + assert(token_tag_ == CBORTokenTag::STRING8); + auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); + return bytes_.subspan(status_.pos + (token_byte_length_ - length), length); +} + +span<uint8_t> CBORTokenizer::GetString16WireRep() const { + assert(token_tag_ == CBORTokenTag::STRING16); + auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); + return bytes_.subspan(status_.pos + (token_byte_length_ - length), length); +} + +span<uint8_t> CBORTokenizer::GetBinary() const { + assert(token_tag_ == CBORTokenTag::BINARY); + auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); + return bytes_.subspan(status_.pos + (token_byte_length_ - length), length); +} + +span<uint8_t> CBORTokenizer::GetEnvelopeContents() const { + assert(token_tag_ == CBORTokenTag::ENVELOPE); + auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); + return bytes_.subspan(status_.pos + kEncodedEnvelopeHeaderSize, length); +} + +void CBORTokenizer::ReadNextToken(bool enter_envelope) { + if (enter_envelope) { + status_.pos += kEncodedEnvelopeHeaderSize; + } else { + status_.pos = + status_.pos == Status::npos() ? 0 : status_.pos + token_byte_length_; + } + status_.error = Error::OK; + if (status_.pos >= bytes_.size()) { + token_tag_ = CBORTokenTag::DONE; + return; + } + switch (bytes_[status_.pos]) { + case kStopByte: + SetToken(CBORTokenTag::STOP, 1); + return; + case kInitialByteIndefiniteLengthMap: + SetToken(CBORTokenTag::MAP_START, 1); + return; + case kInitialByteIndefiniteLengthArray: + SetToken(CBORTokenTag::ARRAY_START, 1); + return; + case kEncodedTrue: + SetToken(CBORTokenTag::TRUE_VALUE, 1); + return; + case kEncodedFalse: + SetToken(CBORTokenTag::FALSE_VALUE, 1); + return; + case kEncodedNull: + SetToken(CBORTokenTag::NULL_VALUE, 1); + return; + case kExpectedConversionToBase64Tag: { // BINARY + int8_t bytes_read = internals::ReadTokenStart( + bytes_.subspan(status_.pos + 1), &token_start_type_, + &token_start_internal_value_); + int64_t token_byte_length = 1 + bytes_read + token_start_internal_value_; + if (-1 == bytes_read || token_start_type_ != MajorType::BYTE_STRING || + status_.pos + token_byte_length > bytes_.size()) { + SetError(Error::CBOR_INVALID_BINARY); + return; + } + SetToken(CBORTokenTag::BINARY, + static_cast<std::ptrdiff_t>(token_byte_length)); + return; + } + case kInitialByteForDouble: { // DOUBLE + if (status_.pos + kEncodedDoubleSize > bytes_.size()) { + SetError(Error::CBOR_INVALID_DOUBLE); + return; + } + SetToken(CBORTokenTag::DOUBLE, kEncodedDoubleSize); + return; + } + case kInitialByteForEnvelope: { // ENVELOPE + if (status_.pos + kEncodedEnvelopeHeaderSize > bytes_.size()) { + SetError(Error::CBOR_INVALID_ENVELOPE); + return; + } + // The envelope must be a byte string with 32 bit length. + if (bytes_[status_.pos + 1] != kInitialByteFor32BitLengthByteString) { + SetError(Error::CBOR_INVALID_ENVELOPE); + return; + } + // Read the length of the byte string. + token_start_internal_value_ = ReadBytesMostSignificantByteFirst<uint32_t>( + bytes_.subspan(status_.pos + 2)); + // Make sure the payload is contained within the message. + if (token_start_internal_value_ + kEncodedEnvelopeHeaderSize + + status_.pos > + static_cast<std::size_t>(bytes_.size())) { + SetError(Error::CBOR_INVALID_ENVELOPE); + return; + } + auto length = static_cast<std::ptrdiff_t>(token_start_internal_value_); + SetToken(CBORTokenTag::ENVELOPE, kEncodedEnvelopeHeaderSize + length); + return; + } + default: { + span<uint8_t> remainder = + bytes_.subspan(status_.pos, bytes_.size() - status_.pos); + assert(!remainder.empty()); + int8_t token_start_length = internals::ReadTokenStart( + remainder, &token_start_type_, &token_start_internal_value_); + bool success = token_start_length != -1; + switch (token_start_type_) { + case MajorType::UNSIGNED: // INT32. + if (!success || std::numeric_limits<int32_t>::max() < + token_start_internal_value_) { + SetError(Error::CBOR_INVALID_INT32); + return; + } + SetToken(CBORTokenTag::INT32, token_start_length); + return; + case MajorType::NEGATIVE: // INT32. + if (!success || + std::numeric_limits<int32_t>::min() > + -static_cast<int64_t>(token_start_internal_value_) - 1) { + SetError(Error::CBOR_INVALID_INT32); + return; + } + SetToken(CBORTokenTag::INT32, token_start_length); + return; + case MajorType::STRING: { // STRING8. + if (!success || remainder.size() < static_cast<int64_t>( + token_start_internal_value_)) { + SetError(Error::CBOR_INVALID_STRING8); + return; + } + auto length = + static_cast<std::ptrdiff_t>(token_start_internal_value_); + SetToken(CBORTokenTag::STRING8, token_start_length + length); + return; + } + case MajorType::BYTE_STRING: { // STRING16. + if (!success || + remainder.size() < + static_cast<int64_t>(token_start_internal_value_) || + // Must be divisible by 2 since UTF16 is 2 bytes per character. + token_start_internal_value_ & 1) { + SetError(Error::CBOR_INVALID_STRING16); + return; + } + auto length = + static_cast<std::ptrdiff_t>(token_start_internal_value_); + SetToken(CBORTokenTag::STRING16, token_start_length + length); + return; + } + case MajorType::ARRAY: + case MajorType::MAP: + case MajorType::TAG: + case MajorType::SIMPLE_VALUE: + SetError(Error::CBOR_UNSUPPORTED_VALUE); + return; + } + } + } +} + +void CBORTokenizer::SetToken(CBORTokenTag token_tag, + std::ptrdiff_t token_byte_length) { + token_tag_ = token_tag; + token_byte_length_ = token_byte_length; +} + +void CBORTokenizer::SetError(Error error) { + token_tag_ = CBORTokenTag::ERROR_VALUE; + status_.error = error; +} + +// ============================================================================= +// cbor::ParseCBOR - for receiving streaming parser events for CBOR messages +// ============================================================================= + +namespace { +// When parsing CBOR, we limit recursion depth for objects and arrays +// to this constant. +static constexpr int kStackLimit = 1000; + +// Below are three parsing routines for CBOR, which cover enough +// to roundtrip JSON messages. +bool ParseMap(int32_t stack_depth, + CBORTokenizer* tokenizer, + StreamingParserHandler* out); +bool ParseArray(int32_t stack_depth, + CBORTokenizer* tokenizer, + StreamingParserHandler* out); +bool ParseValue(int32_t stack_depth, + CBORTokenizer* tokenizer, + StreamingParserHandler* out); + +void ParseUTF16String(CBORTokenizer* tokenizer, StreamingParserHandler* out) { + std::vector<uint16_t> value; + span<uint8_t> rep = tokenizer->GetString16WireRep(); + for (std::ptrdiff_t ii = 0; ii < rep.size(); ii += 2) + value.push_back((rep[ii + 1] << 8) | rep[ii]); + out->HandleString16(span<uint16_t>(value.data(), value.size())); + tokenizer->Next(); +} + +bool ParseUTF8String(CBORTokenizer* tokenizer, StreamingParserHandler* out) { + assert(tokenizer->TokenTag() == CBORTokenTag::STRING8); + out->HandleString8(tokenizer->GetString8()); + tokenizer->Next(); + return true; +} + +bool ParseValue(int32_t stack_depth, + CBORTokenizer* tokenizer, + StreamingParserHandler* out) { + if (stack_depth > kStackLimit) { + out->HandleError( + Status{Error::CBOR_STACK_LIMIT_EXCEEDED, tokenizer->Status().pos}); + return false; + } + // Skip past the envelope to get to what's inside. + if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE) + tokenizer->EnterEnvelope(); + switch (tokenizer->TokenTag()) { + case CBORTokenTag::ERROR_VALUE: + out->HandleError(tokenizer->Status()); + return false; + case CBORTokenTag::DONE: + out->HandleError(Status{Error::CBOR_UNEXPECTED_EOF_EXPECTED_VALUE, + tokenizer->Status().pos}); + return false; + case CBORTokenTag::TRUE_VALUE: + out->HandleBool(true); + tokenizer->Next(); + return true; + case CBORTokenTag::FALSE_VALUE: + out->HandleBool(false); + tokenizer->Next(); + return true; + case CBORTokenTag::NULL_VALUE: + out->HandleNull(); + tokenizer->Next(); + return true; + case CBORTokenTag::INT32: + out->HandleInt32(tokenizer->GetInt32()); + tokenizer->Next(); + return true; + case CBORTokenTag::DOUBLE: + out->HandleDouble(tokenizer->GetDouble()); + tokenizer->Next(); + return true; + case CBORTokenTag::STRING8: + return ParseUTF8String(tokenizer, out); + case CBORTokenTag::STRING16: + ParseUTF16String(tokenizer, out); + return true; + case CBORTokenTag::BINARY: { + out->HandleBinary(tokenizer->GetBinary()); + tokenizer->Next(); + return true; + } + case CBORTokenTag::MAP_START: + return ParseMap(stack_depth + 1, tokenizer, out); + case CBORTokenTag::ARRAY_START: + return ParseArray(stack_depth + 1, tokenizer, out); + default: + out->HandleError( + Status{Error::CBOR_UNSUPPORTED_VALUE, tokenizer->Status().pos}); + return false; + } +} + +// |bytes| must start with the indefinite length array byte, so basically, +// ParseArray may only be called after an indefinite length array has been +// detected. +bool ParseArray(int32_t stack_depth, + CBORTokenizer* tokenizer, + StreamingParserHandler* out) { + assert(tokenizer->TokenTag() == CBORTokenTag::ARRAY_START); + tokenizer->Next(); + out->HandleArrayBegin(); + while (tokenizer->TokenTag() != CBORTokenTag::STOP) { + if (tokenizer->TokenTag() == CBORTokenTag::DONE) { + out->HandleError( + Status{Error::CBOR_UNEXPECTED_EOF_IN_ARRAY, tokenizer->Status().pos}); + return false; + } + if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) { + out->HandleError(tokenizer->Status()); + return false; + } + // Parse value. + if (!ParseValue(stack_depth, tokenizer, out)) + return false; + } + out->HandleArrayEnd(); + tokenizer->Next(); + return true; +} + +// |bytes| must start with the indefinite length array byte, so basically, +// ParseArray may only be called after an indefinite length array has been +// detected. +bool ParseMap(int32_t stack_depth, + CBORTokenizer* tokenizer, + StreamingParserHandler* out) { + assert(tokenizer->TokenTag() == CBORTokenTag::MAP_START); + out->HandleMapBegin(); + tokenizer->Next(); + while (tokenizer->TokenTag() != CBORTokenTag::STOP) { + if (tokenizer->TokenTag() == CBORTokenTag::DONE) { + out->HandleError( + Status{Error::CBOR_UNEXPECTED_EOF_IN_MAP, tokenizer->Status().pos}); + return false; + } + if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) { + out->HandleError(tokenizer->Status()); + return false; + } + // Parse key. + if (tokenizer->TokenTag() == CBORTokenTag::STRING8) { + if (!ParseUTF8String(tokenizer, out)) + return false; + } else if (tokenizer->TokenTag() == CBORTokenTag::STRING16) { + ParseUTF16String(tokenizer, out); + } else { + out->HandleError( + Status{Error::CBOR_INVALID_MAP_KEY, tokenizer->Status().pos}); + return false; + } + // Parse value. + if (!ParseValue(stack_depth, tokenizer, out)) + return false; + } + out->HandleMapEnd(); + tokenizer->Next(); + return true; +} +} // namespace + +void ParseCBOR(span<uint8_t> bytes, StreamingParserHandler* out) { + if (bytes.empty()) { + out->HandleError(Status{Error::CBOR_NO_INPUT, 0}); + return; + } + if (bytes[0] != kInitialByteForEnvelope) { + out->HandleError(Status{Error::CBOR_INVALID_START_BYTE, 0}); + return; + } + CBORTokenizer tokenizer(bytes); + if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) { + out->HandleError(tokenizer.Status()); + return; + } + // We checked for the envelope start byte above, so the tokenizer + // must agree here, since it's not an error. + assert(tokenizer.TokenTag() == CBORTokenTag::ENVELOPE); + tokenizer.EnterEnvelope(); + if (tokenizer.TokenTag() != CBORTokenTag::MAP_START) { + out->HandleError( + Status{Error::CBOR_MAP_START_EXPECTED, tokenizer.Status().pos}); + return; + } + if (!ParseMap(/*stack_depth=*/1, &tokenizer, out)) + return; + if (tokenizer.TokenTag() == CBORTokenTag::DONE) + return; + if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) { + out->HandleError(tokenizer.Status()); + return; + } + out->HandleError(Status{Error::CBOR_TRAILING_JUNK, tokenizer.Status().pos}); +} +} // namespace cbor + +namespace json { + +// ============================================================================= +// json::NewJSONEncoder - for encoding streaming parser events as JSON +// ============================================================================= + +namespace { +// Prints |value| to |out| with 4 hex digits, most significant chunk first. +void PrintHex(uint16_t value, std::string* out) { + for (int ii = 3; ii >= 0; --ii) { + int four_bits = 0xf & (value >> (4 * ii)); + out->append(1, four_bits + ((four_bits <= 9) ? '0' : ('a' - 10))); + } +} + +// In the writer below, we maintain a stack of State instances. +// It is just enough to emit the appropriate delimiters and brackets +// in JSON. +enum class Container { + // Used for the top-level, initial state. + NONE, + // Inside a JSON object. + MAP, + // Inside a JSON array. + ARRAY +}; +class State { + public: + explicit State(Container container) : container_(container) {} + void StartElement(std::string* out) { + assert(container_ != Container::NONE || size_ == 0); + if (size_ != 0) { + char delim = (!(size_ & 1) || container_ == Container::ARRAY) ? ',' : ':'; + out->append(1, delim); + } + ++size_; + } + Container container() const { return container_; } + + private: + Container container_ = Container::NONE; + int size_ = 0; +}; + +constexpr char kBase64Table[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz0123456789+/"; + +void Base64Encode(const span<uint8_t>& in, std::string* out) { + // The following three cases are based on the tables in the example + // section in https://en.wikipedia.org/wiki/Base64. We process three + // input bytes at a time, emitting 4 output bytes at a time. + std::ptrdiff_t ii = 0; + + // While possible, process three input bytes. + for (; ii + 3 <= in.size(); ii += 3) { + uint32_t twentyfour_bits = (in[ii] << 16) | (in[ii + 1] << 8) | in[ii + 2]; + out->push_back(kBase64Table[(twentyfour_bits >> 18)]); + out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]); + out->push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]); + out->push_back(kBase64Table[twentyfour_bits & 0x3f]); + } + if (ii + 2 <= in.size()) { // Process two input bytes. + uint32_t twentyfour_bits = (in[ii] << 16) | (in[ii + 1] << 8); + out->push_back(kBase64Table[(twentyfour_bits >> 18)]); + out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]); + out->push_back(kBase64Table[(twentyfour_bits >> 6) & 0x3f]); + out->push_back('='); // Emit padding. + return; + } + if (ii + 1 <= in.size()) { // Process a single input byte. + uint32_t twentyfour_bits = (in[ii] << 16); + out->push_back(kBase64Table[(twentyfour_bits >> 18)]); + out->push_back(kBase64Table[(twentyfour_bits >> 12) & 0x3f]); + out->push_back('='); // Emit padding. + out->push_back('='); // Emit padding. + } +} + +// Implements a handler for JSON parser events to emit a JSON string. +class JSONEncoder : public StreamingParserHandler { + public: + JSONEncoder(const Platform* platform, std::string* out, Status* status) + : platform_(platform), out_(out), status_(status) { + *status_ = Status(); + state_.emplace(Container::NONE); + } + + void HandleMapBegin() override { + if (!status_->ok()) + return; + assert(!state_.empty()); + state_.top().StartElement(out_); + state_.emplace(Container::MAP); + out_->append("{"); + } + + void HandleMapEnd() override { + if (!status_->ok()) + return; + assert(state_.size() >= 2 && state_.top().container() == Container::MAP); + state_.pop(); + out_->append("}"); + } + + void HandleArrayBegin() override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + state_.emplace(Container::ARRAY); + out_->append("["); + } + + void HandleArrayEnd() override { + if (!status_->ok()) + return; + assert(state_.size() >= 2 && state_.top().container() == Container::ARRAY); + state_.pop(); + out_->append("]"); + } + + void HandleString16(span<uint16_t> chars) override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + out_->append("\""); + for (const uint16_t ch : chars) { + if (ch == '"') { + out_->append("\\\""); + } else if (ch == '\\') { + out_->append("\\\\"); + } else if (ch == '\b') { + out_->append("\\b"); + } else if (ch == '\f') { + out_->append("\\f"); + } else if (ch == '\n') { + out_->append("\\n"); + } else if (ch == '\r') { + out_->append("\\r"); + } else if (ch == '\t') { + out_->append("\\t"); + } else if (ch >= 32 && ch <= 126) { + out_->append(1, ch); + } else { + out_->append("\\u"); + PrintHex(ch, out_); + } + } + out_->append("\""); + } + + void HandleString8(span<uint8_t> chars) override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + out_->append("\""); + for (std::ptrdiff_t ii = 0; ii < chars.size(); ++ii) { + uint8_t c = chars[ii]; + if (c == '"') { + out_->append("\\\""); + } else if (c == '\\') { + out_->append("\\\\"); + } else if (c == '\b') { + out_->append("\\b"); + } else if (c == '\f') { + out_->append("\\f"); + } else if (c == '\n') { + out_->append("\\n"); + } else if (c == '\r') { + out_->append("\\r"); + } else if (c == '\t') { + out_->append("\\t"); + } else if (c >= 32 && c <= 126) { + out_->append(1, c); + } else if (c < 32) { + out_->append("\\u"); + PrintHex(static_cast<uint16_t>(c), out_); + } else { + // Inspect the leading byte to figure out how long the utf8 + // byte sequence is; while doing this initialize |codepoint| + // with the first few bits. + // See table in: https://en.wikipedia.org/wiki/UTF-8 + // byte one is 110x xxxx -> 2 byte utf8 sequence + // byte one is 1110 xxxx -> 3 byte utf8 sequence + // byte one is 1111 0xxx -> 4 byte utf8 sequence + uint32_t codepoint; + int num_bytes_left; + if ((c & 0xe0) == 0xc0) { // 2 byte utf8 sequence + num_bytes_left = 1; + codepoint = c & 0x1f; + } else if ((c & 0xf0) == 0xe0) { // 3 byte utf8 sequence + num_bytes_left = 2; + codepoint = c & 0x0f; + } else if ((c & 0xf8) == 0xf0) { // 4 byte utf8 sequence + codepoint = c & 0x07; + num_bytes_left = 3; + } else { + continue; // invalid leading byte + } + + // If we have enough bytes in our input, decode the remaining ones + // belonging to this Unicode character into |codepoint|. + if (ii + num_bytes_left > chars.size()) + continue; + while (num_bytes_left > 0) { + c = chars[++ii]; + --num_bytes_left; + // Check the next byte is a continuation byte, that is 10xx xxxx. + if ((c & 0xc0) != 0x80) + continue; + codepoint = (codepoint << 6) | (c & 0x3f); + } + + // Disallow overlong encodings for ascii characters, as these + // would include " and other characters significant to JSON + // string termination / control. + if (codepoint < 0x7f) + continue; + // Invalid in UTF8, and can't be represented in UTF16 anyway. + if (codepoint > 0x10ffff) + continue; + + // So, now we transcode to UTF16, + // using the math described at https://en.wikipedia.org/wiki/UTF-16, + // for either one or two 16 bit characters. + if (codepoint < 0xffff) { + out_->append("\\u"); + PrintHex(static_cast<uint16_t>(codepoint), out_); + continue; + } + codepoint -= 0x10000; + // high surrogate + out_->append("\\u"); + PrintHex(static_cast<uint16_t>((codepoint >> 10) + 0xd800), out_); + // low surrogate + out_->append("\\u"); + PrintHex(static_cast<uint16_t>((codepoint & 0x3ff) + 0xdc00), out_); + } + } + out_->append("\""); + } + + void HandleBinary(span<uint8_t> bytes) override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + out_->append("\""); + Base64Encode(bytes, out_); + out_->append("\""); + } + + void HandleDouble(double value) override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + std::unique_ptr<char[]> str_value = platform_->DToStr(value); + + // DToStr may fail to emit a 0 before the decimal dot. E.g. this is + // the case in base::NumberToString in Chromium (which is based on + // dmg_fp). So, much like + // https://cs.chromium.org/chromium/src/base/json/json_writer.cc + // we probe for this and emit the leading 0 anyway if necessary. + const char* chars = str_value.get(); + if (chars[0] == '.') { + out_->append("0"); + } else if (chars[0] == '-' && chars[1] == '.') { + out_->append("-0"); + ++chars; + } + out_->append(chars); + } + + void HandleInt32(int32_t value) override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + out_->append(std::to_string(value)); + } + + void HandleBool(bool value) override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + out_->append(value ? "true" : "false"); + } + + void HandleNull() override { + if (!status_->ok()) + return; + state_.top().StartElement(out_); + out_->append("null"); + } + + void HandleError(Status error) override { + assert(!error.ok()); + *status_ = error; + out_->clear(); + } + + private: + const Platform* platform_; + std::string* out_; + Status* status_; + std::stack<State> state_; +}; +} // namespace + +std::unique_ptr<StreamingParserHandler> NewJSONEncoder(const Platform* platform, + std::string* out, + Status* status) { + return std::unique_ptr<StreamingParserHandler>( + new JSONEncoder(platform, out, status)); +} + +// ============================================================================= +// json::ParseJSON - for receiving streaming parser events for JSON. +// ============================================================================= + +namespace { +const int kStackLimit = 1000; + +enum Token { + ObjectBegin, + ObjectEnd, + ArrayBegin, + ArrayEnd, + StringLiteral, + Number, + BoolTrue, + BoolFalse, + NullToken, + ListSeparator, + ObjectPairSeparator, + InvalidToken, + NoInput +}; + +const char* const kNullString = "null"; +const char* const kTrueString = "true"; +const char* const kFalseString = "false"; + +template <typename Char> +class JsonParser { + public: + JsonParser(const Platform* platform, StreamingParserHandler* handler) + : platform_(platform), handler_(handler) {} + + void Parse(const Char* start, std::size_t length) { + start_pos_ = start; + const Char* end = start + length; + const Char* tokenEnd; + ParseValue(start, end, &tokenEnd, 0); + if (tokenEnd != end) { + HandleError(Error::JSON_PARSER_UNPROCESSED_INPUT_REMAINS, tokenEnd); + } + } + + private: + bool CharsToDouble(const uint16_t* chars, + std::size_t length, + double* result) { + std::string buffer; + buffer.reserve(length + 1); + for (std::size_t ii = 0; ii < length; ++ii) { + bool is_ascii = !(chars[ii] & ~0x7F); + if (!is_ascii) + return false; + buffer.push_back(static_cast<char>(chars[ii])); + } + return platform_->StrToD(buffer.c_str(), result); + } + + bool CharsToDouble(const uint8_t* chars, std::size_t length, double* result) { + std::string buffer(reinterpret_cast<const char*>(chars), length); + return platform_->StrToD(buffer.c_str(), result); + } + + static bool ParseConstToken(const Char* start, + const Char* end, + const Char** token_end, + const char* token) { + // |token| is \0 terminated, it's one of the constants at top of the file. + while (start < end && *token != '\0' && *start++ == *token++) { + } + if (*token != '\0') + return false; + *token_end = start; + return true; + } + + static bool ReadInt(const Char* start, + const Char* end, + const Char** token_end, + bool allow_leading_zeros) { + if (start == end) + return false; + bool has_leading_zero = '0' == *start; + int length = 0; + while (start < end && '0' <= *start && *start <= '9') { + ++start; + ++length; + } + if (!length) + return false; + if (!allow_leading_zeros && length > 1 && has_leading_zero) + return false; + *token_end = start; + return true; + } + + static bool ParseNumberToken(const Char* start, + const Char* end, + const Char** token_end) { + // We just grab the number here. We validate the size in DecodeNumber. + // According to RFC4627, a valid number is: [minus] int [frac] [exp] + if (start == end) + return false; + Char c = *start; + if ('-' == c) + ++start; + + if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/false)) + return false; + if (start == end) { + *token_end = start; + return true; + } + + // Optional fraction part + c = *start; + if ('.' == c) { + ++start; + if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/true)) + return false; + if (start == end) { + *token_end = start; + return true; + } + c = *start; + } + + // Optional exponent part + if ('e' == c || 'E' == c) { + ++start; + if (start == end) + return false; + c = *start; + if ('-' == c || '+' == c) { + ++start; + if (start == end) + return false; + } + if (!ReadInt(start, end, &start, /*allow_leading_zeros=*/true)) + return false; + } + + *token_end = start; + return true; + } + + static bool ReadHexDigits(const Char* start, + const Char* end, + const Char** token_end, + int digits) { + if (end - start < digits) + return false; + for (int i = 0; i < digits; ++i) { + Char c = *start++; + if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || + ('A' <= c && c <= 'F'))) + return false; + } + *token_end = start; + return true; + } + + static bool ParseStringToken(const Char* start, + const Char* end, + const Char** token_end) { + while (start < end) { + Char c = *start++; + if ('\\' == c) { + if (start == end) + return false; + c = *start++; + // Make sure the escaped char is valid. + switch (c) { + case 'x': + if (!ReadHexDigits(start, end, &start, 2)) + return false; + break; + case 'u': + if (!ReadHexDigits(start, end, &start, 4)) + return false; + break; + case '\\': + case '/': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': + case 'v': + case '"': + break; + default: + return false; + } + } else if ('"' == c) { + *token_end = start; + return true; + } + } + return false; + } + + static bool SkipComment(const Char* start, + const Char* end, + const Char** comment_end) { + if (start == end) + return false; + + if (*start != '/' || start + 1 >= end) + return false; + ++start; + + if (*start == '/') { + // Single line comment, read to newline. + for (++start; start < end; ++start) { + if (*start == '\n' || *start == '\r') { + *comment_end = start + 1; + return true; + } + } + *comment_end = end; + // Comment reaches end-of-input, which is fine. + return true; + } + + if (*start == '*') { + Char previous = '\0'; + // Block comment, read until end marker. + for (++start; start < end; previous = *start++) { + if (previous == '*' && *start == '/') { + *comment_end = start + 1; + return true; + } + } + // Block comment must close before end-of-input. + return false; + } + + return false; + } + + static bool IsSpaceOrNewLine(Char c) { + // \v = vertial tab; \f = form feed page break. + return c == ' ' || c == '\n' || c == '\v' || c == '\f' || c == '\r' || + c == '\t'; + } + + static void SkipWhitespaceAndComments(const Char* start, + const Char* end, + const Char** whitespace_end) { + while (start < end) { + if (IsSpaceOrNewLine(*start)) { + ++start; + } else if (*start == '/') { + const Char* comment_end; + if (!SkipComment(start, end, &comment_end)) + break; + start = comment_end; + } else { + break; + } + } + *whitespace_end = start; + } + + static Token ParseToken(const Char* start, + const Char* end, + const Char** tokenStart, + const Char** token_end) { + SkipWhitespaceAndComments(start, end, tokenStart); + start = *tokenStart; + + if (start == end) + return NoInput; + + switch (*start) { + case 'n': + if (ParseConstToken(start, end, token_end, kNullString)) + return NullToken; + break; + case 't': + if (ParseConstToken(start, end, token_end, kTrueString)) + return BoolTrue; + break; + case 'f': + if (ParseConstToken(start, end, token_end, kFalseString)) + return BoolFalse; + break; + case '[': + *token_end = start + 1; + return ArrayBegin; + case ']': + *token_end = start + 1; + return ArrayEnd; + case ',': + *token_end = start + 1; + return ListSeparator; + case '{': + *token_end = start + 1; + return ObjectBegin; + case '}': + *token_end = start + 1; + return ObjectEnd; + case ':': + *token_end = start + 1; + return ObjectPairSeparator; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + if (ParseNumberToken(start, end, token_end)) + return Number; + break; + case '"': + if (ParseStringToken(start + 1, end, token_end)) + return StringLiteral; + break; + } + return InvalidToken; + } + + static int HexToInt(Char c) { + if ('0' <= c && c <= '9') + return c - '0'; + if ('A' <= c && c <= 'F') + return c - 'A' + 10; + if ('a' <= c && c <= 'f') + return c - 'a' + 10; + assert(false); // Unreachable. + return 0; + } + + static bool DecodeString(const Char* start, + const Char* end, + std::vector<uint16_t>* output) { + if (start == end) + return true; + if (start > end) + return false; + output->reserve(end - start); + while (start < end) { + uint16_t c = *start++; + // If the |Char| we're dealing with is really a byte, then + // we have utf8 here, and we need to check for multibyte characters + // and transcode them to utf16 (either one or two utf16 chars). + if (sizeof(Char) == sizeof(uint8_t) && c >= 0x7f) { + // Inspect the leading byte to figure out how long the utf8 + // byte sequence is; while doing this initialize |codepoint| + // with the first few bits. + // See table in: https://en.wikipedia.org/wiki/UTF-8 + // byte one is 110x xxxx -> 2 byte utf8 sequence + // byte one is 1110 xxxx -> 3 byte utf8 sequence + // byte one is 1111 0xxx -> 4 byte utf8 sequence + uint32_t codepoint; + int num_bytes_left; + if ((c & 0xe0) == 0xc0) { // 2 byte utf8 sequence + num_bytes_left = 1; + codepoint = c & 0x1f; + } else if ((c & 0xf0) == 0xe0) { // 3 byte utf8 sequence + num_bytes_left = 2; + codepoint = c & 0x0f; + } else if ((c & 0xf8) == 0xf0) { // 4 byte utf8 sequence + codepoint = c & 0x07; + num_bytes_left = 3; + } else { + return false; // invalid leading byte + } + + // If we have enough bytes in our inpput, decode the remaining ones + // belonging to this Unicode character into |codepoint|. + if (start + num_bytes_left > end) + return false; + while (num_bytes_left > 0) { + c = *start++; + --num_bytes_left; + // Check the next byte is a continuation byte, that is 10xx xxxx. + if ((c & 0xc0) != 0x80) + return false; + codepoint = (codepoint << 6) | (c & 0x3f); + } + + // Disallow overlong encodings for ascii characters, as these + // would include " and other characters significant to JSON + // string termination / control. + if (codepoint < 0x7f) + return false; + // Invalid in UTF8, and can't be represented in UTF16 anyway. + if (codepoint > 0x10ffff) + return false; + + // So, now we transcode to UTF16, + // using the math described at https://en.wikipedia.org/wiki/UTF-16, + // for either one or two 16 bit characters. + if (codepoint < 0xffff) { + output->push_back(codepoint); + continue; + } + codepoint -= 0x10000; + output->push_back((codepoint >> 10) + 0xd800); // high surrogate + output->push_back((codepoint & 0x3ff) + 0xdc00); // low surrogate + continue; + } + if ('\\' != c) { + output->push_back(c); + continue; + } + if (start == end) + return false; + c = *start++; + + if (c == 'x') { + // \x is not supported. + return false; + } + + switch (c) { + case '"': + case '/': + case '\\': + break; + case 'b': + c = '\b'; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'v': + c = '\v'; + break; + case 'u': + c = (HexToInt(*start) << 12) + (HexToInt(*(start + 1)) << 8) + + (HexToInt(*(start + 2)) << 4) + HexToInt(*(start + 3)); + start += 4; + break; + default: + return false; + } + output->push_back(c); + } + return true; + } + + void ParseValue(const Char* start, + const Char* end, + const Char** value_token_end, + int depth) { + if (depth > kStackLimit) { + HandleError(Error::JSON_PARSER_STACK_LIMIT_EXCEEDED, start); + return; + } + const Char* token_start; + const Char* token_end; + Token token = ParseToken(start, end, &token_start, &token_end); + switch (token) { + case NoInput: + HandleError(Error::JSON_PARSER_NO_INPUT, token_start); + return; + case InvalidToken: + HandleError(Error::JSON_PARSER_INVALID_TOKEN, token_start); + return; + case NullToken: + handler_->HandleNull(); + break; + case BoolTrue: + handler_->HandleBool(true); + break; + case BoolFalse: + handler_->HandleBool(false); + break; + case Number: { + double value; + if (!CharsToDouble(token_start, token_end - token_start, &value)) { + HandleError(Error::JSON_PARSER_INVALID_NUMBER, token_start); + return; + } + if (value >= std::numeric_limits<int32_t>::min() && + value <= std::numeric_limits<int32_t>::max() && + static_cast<int32_t>(value) == value) + handler_->HandleInt32(static_cast<int32_t>(value)); + else + handler_->HandleDouble(value); + break; + } + case StringLiteral: { + std::vector<uint16_t> value; + bool ok = DecodeString(token_start + 1, token_end - 1, &value); + if (!ok) { + HandleError(Error::JSON_PARSER_INVALID_STRING, token_start); + return; + } + handler_->HandleString16(span<uint16_t>(value.data(), value.size())); + break; + } + case ArrayBegin: { + handler_->HandleArrayBegin(); + start = token_end; + token = ParseToken(start, end, &token_start, &token_end); + while (token != ArrayEnd) { + ParseValue(start, end, &token_end, depth + 1); + if (error_) + return; + + // After a list value, we expect a comma or the end of the list. + start = token_end; + token = ParseToken(start, end, &token_start, &token_end); + if (token == ListSeparator) { + start = token_end; + token = ParseToken(start, end, &token_start, &token_end); + if (token == ArrayEnd) { + HandleError(Error::JSON_PARSER_UNEXPECTED_ARRAY_END, token_start); + return; + } + } else if (token != ArrayEnd) { + // Unexpected value after list value. Bail out. + HandleError(Error::JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED, + token_start); + return; + } + } + handler_->HandleArrayEnd(); + break; + } + case ObjectBegin: { + handler_->HandleMapBegin(); + start = token_end; + token = ParseToken(start, end, &token_start, &token_end); + while (token != ObjectEnd) { + if (token != StringLiteral) { + HandleError(Error::JSON_PARSER_STRING_LITERAL_EXPECTED, + token_start); + return; + } + std::vector<uint16_t> key; + if (!DecodeString(token_start + 1, token_end - 1, &key)) { + HandleError(Error::JSON_PARSER_INVALID_STRING, token_start); + return; + } + handler_->HandleString16(span<uint16_t>(key.data(), key.size())); + start = token_end; + + token = ParseToken(start, end, &token_start, &token_end); + if (token != ObjectPairSeparator) { + HandleError(Error::JSON_PARSER_COLON_EXPECTED, token_start); + return; + } + start = token_end; + + ParseValue(start, end, &token_end, depth + 1); + if (error_) + return; + start = token_end; + + // After a key/value pair, we expect a comma or the end of the + // object. + token = ParseToken(start, end, &token_start, &token_end); + if (token == ListSeparator) { + start = token_end; + token = ParseToken(start, end, &token_start, &token_end); + if (token == ObjectEnd) { + HandleError(Error::JSON_PARSER_UNEXPECTED_MAP_END, token_start); + return; + } + } else if (token != ObjectEnd) { + // Unexpected value after last object value. Bail out. + HandleError(Error::JSON_PARSER_COMMA_OR_MAP_END_EXPECTED, + token_start); + return; + } + } + handler_->HandleMapEnd(); + break; + } + + default: + // We got a token that's not a value. + HandleError(Error::JSON_PARSER_VALUE_EXPECTED, token_start); + return; + } + + SkipWhitespaceAndComments(token_end, end, value_token_end); + } + + void HandleError(Error error, const Char* pos) { + assert(error != Error::OK); + if (!error_) { + handler_->HandleError(Status{error, pos - start_pos_}); + error_ = true; + } + } + + const Char* start_pos_ = nullptr; + bool error_ = false; + const Platform* platform_; + StreamingParserHandler* handler_; +}; +} // namespace + +void ParseJSON(const Platform* platform, + span<uint8_t> chars, + StreamingParserHandler* handler) { + JsonParser<uint8_t> parser(platform, handler); + parser.Parse(chars.data(), chars.size()); +} + +void ParseJSON(const Platform* platform, + span<uint16_t> chars, + StreamingParserHandler* handler) { + JsonParser<uint16_t> parser(platform, handler); + parser.Parse(chars.data(), chars.size()); +} +} // namespace json + +{% for namespace in config.protocol.namespace %} +} // namespace {{namespace}} +{% endfor %} +
diff --git a/third_party/inspector_protocol/lib/CBOR_h.template b/third_party/inspector_protocol/lib/encoding_h.template similarity index 65% copy from third_party/inspector_protocol/lib/CBOR_h.template copy to third_party/inspector_protocol/lib/encoding_h.template index 9d28adb..aba28c8 100644 --- a/third_party/inspector_protocol/lib/CBOR_h.template +++ b/third_party/inspector_protocol/lib/encoding_h.template
@@ -1,75 +1,29 @@ {# This template is generated by gen_cbor_templates.py. #} -// Generated by lib/CBOR_h.template. +// Generated by lib/encoding_h.template. // 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 {{"_".join(config.protocol.namespace)}}_CBOR_h -#define {{"_".join(config.protocol.namespace)}}_CBOR_h +#ifndef {{"_".join(config.protocol.namespace)}}_encoding_h +#define {{"_".join(config.protocol.namespace)}}_encoding_h #include <cstddef> #include <cstdint> #include <memory> +#include <string> #include <vector> {% for namespace in config.protocol.namespace %} namespace {{namespace}} { {% endfor %} -// ===== encoding/status.h ===== +// ===== encoding/encoding.h ===== -// Error codes. -enum class Error { - OK = 0, - // JSON parsing errors - json_parser.{h,cc}. - JSON_PARSER_UNPROCESSED_INPUT_REMAINS = 0x01, - JSON_PARSER_STACK_LIMIT_EXCEEDED = 0x02, - JSON_PARSER_NO_INPUT = 0x03, - JSON_PARSER_INVALID_TOKEN = 0x04, - JSON_PARSER_INVALID_NUMBER = 0x05, - JSON_PARSER_INVALID_STRING = 0x06, - JSON_PARSER_UNEXPECTED_ARRAY_END = 0x07, - JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED = 0x08, - JSON_PARSER_STRING_LITERAL_EXPECTED = 0x09, - JSON_PARSER_COLON_EXPECTED = 0x0a, - JSON_PARSER_UNEXPECTED_OBJECT_END = 0x0b, - JSON_PARSER_COMMA_OR_OBJECT_END_EXPECTED = 0x0c, - JSON_PARSER_VALUE_EXPECTED = 0x0d, - CBOR_INVALID_INT32 = 0x0e, - CBOR_INVALID_DOUBLE = 0x0f, - CBOR_INVALID_ENVELOPE = 0x10, - CBOR_INVALID_STRING8 = 0x11, - CBOR_INVALID_STRING16 = 0x12, - CBOR_INVALID_BINARY = 0x13, - CBOR_UNSUPPORTED_VALUE = 0x14, - CBOR_NO_INPUT = 0x15, - CBOR_INVALID_START_BYTE = 0x16, - CBOR_UNEXPECTED_EOF_EXPECTED_VALUE = 0x17, - CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x18, - CBOR_UNEXPECTED_EOF_IN_MAP = 0x19, - CBOR_INVALID_MAP_KEY = 0x1a, - CBOR_STACK_LIMIT_EXCEEDED = 0x1b, - CBOR_STRING8_MUST_BE_7BIT = 0x1c, - CBOR_TRAILING_JUNK = 0x1d, - CBOR_MAP_START_EXPECTED = 0x1e, -}; - -// A status value with position that can be copied. The default status -// is OK. Usually, error status values should come with a valid position. -struct Status { - static constexpr std::ptrdiff_t npos() { return -1; } - - bool ok() const { return error == Error::OK; } - - Error error = Error::OK; - std::ptrdiff_t pos = npos(); - Status(Error error, std::ptrdiff_t pos) : error(error), pos(pos) {} - Status() = default; -}; - -// ===== encoding/span.h ===== +// ============================================================================= +// span - sequence of bytes +// ============================================================================= // This template is similar to std::span, which will be included in C++20. Like // std::span it uses ptrdiff_t, which is signed (and thus a bit annoying @@ -107,19 +61,78 @@ index_type size_; }; -// ===== encoding/json_parser_handler.h ===== +template <typename T> +span<T> SpanFromVector(const std::vector<T>& v) { + return span<T>(v.data(), v.size()); +} -// Handler interface for JSON parser events. See also json_parser.h. -class JSONParserHandler { +inline span<uint8_t> SpanFromStdString(const std::string& v) { + return span<uint8_t>(reinterpret_cast<const uint8_t*>(v.data()), v.size()); +} + +// Error codes. +enum class Error { + OK = 0, + // JSON parsing errors - json_parser.{h,cc}. + JSON_PARSER_UNPROCESSED_INPUT_REMAINS = 0x01, + JSON_PARSER_STACK_LIMIT_EXCEEDED = 0x02, + JSON_PARSER_NO_INPUT = 0x03, + JSON_PARSER_INVALID_TOKEN = 0x04, + JSON_PARSER_INVALID_NUMBER = 0x05, + JSON_PARSER_INVALID_STRING = 0x06, + JSON_PARSER_UNEXPECTED_ARRAY_END = 0x07, + JSON_PARSER_COMMA_OR_ARRAY_END_EXPECTED = 0x08, + JSON_PARSER_STRING_LITERAL_EXPECTED = 0x09, + JSON_PARSER_COLON_EXPECTED = 0x0a, + JSON_PARSER_UNEXPECTED_MAP_END = 0x0b, + JSON_PARSER_COMMA_OR_MAP_END_EXPECTED = 0x0c, + JSON_PARSER_VALUE_EXPECTED = 0x0d, + + CBOR_INVALID_INT32 = 0x0e, + CBOR_INVALID_DOUBLE = 0x0f, + CBOR_INVALID_ENVELOPE = 0x10, + CBOR_INVALID_STRING8 = 0x11, + CBOR_INVALID_STRING16 = 0x12, + CBOR_INVALID_BINARY = 0x13, + CBOR_UNSUPPORTED_VALUE = 0x14, + CBOR_NO_INPUT = 0x15, + CBOR_INVALID_START_BYTE = 0x16, + CBOR_UNEXPECTED_EOF_EXPECTED_VALUE = 0x17, + CBOR_UNEXPECTED_EOF_IN_ARRAY = 0x18, + CBOR_UNEXPECTED_EOF_IN_MAP = 0x19, + CBOR_INVALID_MAP_KEY = 0x1a, + CBOR_STACK_LIMIT_EXCEEDED = 0x1b, + CBOR_STRING8_MUST_BE_7BIT = 0x1c, + CBOR_TRAILING_JUNK = 0x1d, + CBOR_MAP_START_EXPECTED = 0x1e, +}; + +// A status value with position that can be copied. The default status +// is OK. Usually, error status values should come with a valid position. +struct Status { + static constexpr std::ptrdiff_t npos() { return -1; } + + bool ok() const { return error == Error::OK; } + + Error error = Error::OK; + std::ptrdiff_t pos = npos(); + Status(Error error, std::ptrdiff_t pos) : error(error), pos(pos) {} + Status() = default; +}; + +// Handler interface for parser events emitted by a streaming parser. +// See cbor::NewCBOREncoder, cbor::ParseCBOR, json::NewJSONEncoder, +// json::ParseJSON. +class StreamingParserHandler { public: - virtual ~JSONParserHandler() = default; - virtual void HandleObjectBegin() = 0; - virtual void HandleObjectEnd() = 0; + virtual ~StreamingParserHandler() = default; + virtual void HandleMapBegin() = 0; + virtual void HandleMapEnd() = 0; virtual void HandleArrayBegin() = 0; virtual void HandleArrayEnd() = 0; virtual void HandleString8(span<uint8_t> chars) = 0; virtual void HandleString16(span<uint16_t> chars) = 0; - virtual void HandleBinary(std::vector<uint8_t> bytes) = 0; + virtual void HandleBinary(span<uint8_t> bytes) = 0; virtual void HandleDouble(double value) = 0; virtual void HandleInt32(int32_t value) = 0; virtual void HandleBool(bool value) = 0; @@ -132,97 +145,7 @@ virtual void HandleError(Status error) = 0; }; -// ===== encoding/cbor_internals.h ===== - namespace cbor { -enum class MajorType; -} - -namespace cbor_internals { - -// Reads the start of a token with definitive size from |bytes|. -// |type| is the major type as specified in RFC 7049 Section 2.1. -// |value| is the payload (e.g. for MajorType::UNSIGNED) or is the size -// (e.g. for BYTE_STRING). -// If successful, returns the number of bytes read. Otherwise returns -1. -int8_t ReadTokenStart(span<uint8_t> bytes, cbor::MajorType* type, - uint64_t* value); - -// Writes the start of a token with |type|. The |value| may indicate the size, -// or it may be the payload if the value is an unsigned integer. -void WriteTokenStart(cbor::MajorType type, uint64_t value, - std::vector<uint8_t>* encoded); -} // namespace cbor_internals - -// ===== encoding/cbor.h ===== - - -namespace cbor { - -// The major types from RFC 7049 Section 2.1. -enum class MajorType { - UNSIGNED = 0, - NEGATIVE = 1, - BYTE_STRING = 2, - STRING = 3, - ARRAY = 4, - MAP = 5, - TAG = 6, - SIMPLE_VALUE = 7 -}; - -// Indicates the number of bits the "initial byte" needs to be shifted to the -// right after applying |kMajorTypeMask| to produce the major type in the -// lowermost bits. -static constexpr uint8_t kMajorTypeBitShift = 5u; -// Mask selecting the low-order 5 bits of the "initial byte", which is where -// the additional information is encoded. -static constexpr uint8_t kAdditionalInformationMask = 0x1f; -// Mask selecting the high-order 3 bits of the "initial byte", which indicates -// the major type of the encoded value. -static constexpr uint8_t kMajorTypeMask = 0xe0; -// Indicates the integer is in the following byte. -static constexpr uint8_t kAdditionalInformation1Byte = 24u; -// Indicates the integer is in the next 2 bytes. -static constexpr uint8_t kAdditionalInformation2Bytes = 25u; -// Indicates the integer is in the next 4 bytes. -static constexpr uint8_t kAdditionalInformation4Bytes = 26u; -// Indicates the integer is in the next 8 bytes. -static constexpr uint8_t kAdditionalInformation8Bytes = 27u; - -// Encodes the initial byte, consisting of the |type| in the first 3 bits -// followed by 5 bits of |additional_info|. -constexpr uint8_t EncodeInitialByte(MajorType type, uint8_t additional_info) { - return (static_cast<uint8_t>(type) << kMajorTypeBitShift) | - (additional_info & kAdditionalInformationMask); -} - -// TAG 24 indicates that what follows is a byte string which is -// encoded in CBOR format. We use this as a wrapper for -// maps and arrays, allowing us to skip them, because the -// byte string carries its size (byte length). -// https://tools.ietf.org/html/rfc7049#section-2.4.4.1 -static constexpr uint8_t kInitialByteForEnvelope = - EncodeInitialByte(MajorType::TAG, 24); -// The initial byte for a byte string with at most 2^32 bytes -// of payload. This is used for envelope encoding, even if -// the byte string is shorter. -static constexpr uint8_t kInitialByteFor32BitLengthByteString = - EncodeInitialByte(MajorType::BYTE_STRING, 26); - -// See RFC 7049 Section 2.2.1, indefinite length arrays / maps have additional -// info = 31. -static constexpr uint8_t kInitialByteIndefiniteLengthArray = - EncodeInitialByte(MajorType::ARRAY, 31); -static constexpr uint8_t kInitialByteIndefiniteLengthMap = - EncodeInitialByte(MajorType::MAP, 31); -// See RFC 7049 Section 2.3, Table 1; this is used for finishing indefinite -// length maps / arrays. -static constexpr uint8_t kStopByte = - EncodeInitialByte(MajorType::SIMPLE_VALUE, 31); - -} // namespace cbor - // The binary encoding for the inspector protocol follows the CBOR specification // (RFC 7049). Additional constraints: // - Only indefinite length maps and arrays are supported. @@ -239,12 +162,38 @@ // as CBOR BYTE_STRING (major type 2). For such strings, the number of // bytes encoded must be even. // - UTF8 strings (major type 3) are supported. -// - 7 bit US-ASCII strings must always be encoded as UTF8 strings, not +// - 7 bit US-ASCII strings must always be encoded as UTF8 strings, never // as UTF16 strings. // - Arbitrary byte arrays, in the inspector protocol called 'binary', // are encoded as BYTE_STRING (major type 2), prefixed with a byte // indicating base64 when rendered as JSON. +// ============================================================================= +// Detecting CBOR content +// ============================================================================= + +// The first byte for an envelope, which we use for wrapping dictionaries +// and arrays; and the byte that indicates a byte string with 32 bit length. +// These two bytes start an envelope, and thereby also any CBOR message +// produced or consumed by this protocol. See also |EnvelopeEncoder| below. +uint8_t InitialByteForEnvelope(); +uint8_t InitialByteFor32BitLengthByteString(); + +// Checks whether |msg| is a cbor message. +bool IsCBORMessage(span<uint8_t> msg); + +// ============================================================================= +// Encoding individual CBOR items +// ============================================================================= + +// Some constants for CBOR tokens that only take a single byte on the wire. +uint8_t EncodeTrue(); +uint8_t EncodeFalse(); +uint8_t EncodeNull(); +uint8_t EncodeIndefiniteLengthArrayStart(); +uint8_t EncodeIndefiniteLengthMapStart(); +uint8_t EncodeStop(); + // Encodes |value| as |UNSIGNED| (major type 0) iff >= 0, or |NEGATIVE| // (major type 1) iff < 0. void EncodeInt32(int32_t value, std::vector<uint8_t>* out); @@ -275,13 +224,9 @@ // with additional info = 27, followed by 8 bytes in big endian. void EncodeDouble(double value, std::vector<uint8_t>* out); -// Some constants for CBOR tokens that only take a single byte on the wire. -uint8_t EncodeTrue(); -uint8_t EncodeFalse(); -uint8_t EncodeNull(); -uint8_t EncodeIndefiniteLengthArrayStart(); -uint8_t EncodeIndefiniteLengthMapStart(); -uint8_t EncodeStop(); +// ============================================================================= +// cbor::EnvelopeEncoder - for wrapping submessages +// ============================================================================= // An envelope indicates the byte length of a wrapped item. // We use this for maps and array, which allows the decoder @@ -304,20 +249,23 @@ std::size_t byte_size_pos_ = 0; }; -// This can be used to convert from JSON to CBOR, by passing the -// return value to the routines in json_parser.h. The handler will encode into -// |out|, and iff an error occurs it will set |status| to an error and clear -// |out|. Otherwise, |status.ok()| will be |true|. -std::unique_ptr<JSONParserHandler> NewJSONToCBOREncoder( - std::vector<uint8_t>* out, Status* status); +// ============================================================================= +// cbor::NewCBOREncoder - for encoding from a streaming parser +// ============================================================================= -// Parses a CBOR encoded message from |bytes|, sending JSON events to -// |json_out|. If an error occurs, sends |out->HandleError|, and parsing stops. -// The client is responsible for discarding the already received information in -// that case. -void ParseCBOR(span<uint8_t> bytes, JSONParserHandler* json_out); +// This can be used to convert to CBOR, by passing the return value to a parser +// that drives it. The handler will encode into |out|, and iff an error occurs +// it will set |status| to an error and clear |out|. Otherwise, |status.ok()| +// will be |true|. +std::unique_ptr<StreamingParserHandler> NewCBOREncoder( + std::vector<uint8_t>* out, + Status* status); -// Tags for the tokens within a CBOR message that CBORStream understands. +// ============================================================================= +// cbor::CBORTokenizer - for parsing individual CBOR items +// ============================================================================= + +// Tags for the tokens within a CBOR message that CBORTokenizer understands. // Note that this is not the same terminology as the CBOR spec (RFC 7049), // but rather, our adaptation. For instance, we lump unsigned and signed // major type into INT32 here (and disallow values outside the int32_t range). @@ -357,6 +305,18 @@ DONE, }; +// The major types from RFC 7049 Section 2.1. +enum class MajorType { + UNSIGNED = 0, + NEGATIVE = 1, + BYTE_STRING = 2, + STRING = 3, + ARRAY = 4, + MAP = 5, + TAG = 6, + SIMPLE_VALUE = 7 +}; + // CBORTokenizer segments a CBOR message, presenting the tokens therein as // numbers, strings, etc. This is not a complete CBOR parser, but makes it much // easier to implement one (e.g. ParseCBOR, above). It can also be used to parse @@ -403,6 +363,9 @@ // To be called only if ::TokenTag() == CBORTokenTag::BINARY. span<uint8_t> GetBinary() const; + // To be called only if ::TokenTag() == CBORTokenTag::ENVELOPE. + span<uint8_t> GetEnvelopeContents() const; + private: void ReadNextToken(bool enter_envelope); void SetToken(CBORTokenTag token, std::ptrdiff_t token_byte_length); @@ -412,14 +375,72 @@ CBORTokenTag token_tag_; struct Status status_; std::ptrdiff_t token_byte_length_; - cbor::MajorType token_start_type_; + MajorType token_start_type_; uint64_t token_start_internal_value_; }; -void DumpCBOR(span<uint8_t> cbor); +// ============================================================================= +// cbor::ParseCBOR - for receiving streaming parser events for CBOR messages +// ============================================================================= +// Parses a CBOR encoded message from |bytes|, sending events to +// |out|. If an error occurs, sends |out->HandleError|, and parsing stops. +// The client is responsible for discarding the already received information in +// that case. +void ParseCBOR(span<uint8_t> bytes, StreamingParserHandler* out); + +namespace internals { // Exposed only for writing tests. +int8_t ReadTokenStart(span<uint8_t> bytes, + cbor::MajorType* type, + uint64_t* value); + +void WriteTokenStart(cbor::MajorType type, + uint64_t value, + std::vector<uint8_t>* encoded); +} // namespace internals +} // namespace cbor + +namespace json { +// Client code must provide an instance. Implementation should delegate +// to whatever is appropriate. +class Platform { + public: + virtual ~Platform() = default; + // Parses |str| into |result|. Returns false iff there are + // leftover characters or parsing errors. + virtual bool StrToD(const char* str, double* result) const = 0; + + // Prints |value| in a format suitable for JSON. + virtual std::unique_ptr<char[]> DToStr(double value) const = 0; +}; + +// ============================================================================= +// json::NewJSONEncoder - for encoding streaming parser events as JSON +// ============================================================================= + +// Returns a handler object which will write ascii characters to |out|. +// |status->ok()| will be false iff the handler routine HandleError() is called. +// In that case, we'll stop emitting output. +// Except for calling the HandleError routine at any time, the client +// code must call the Handle* methods in an order in which they'd occur +// in valid JSON; otherwise we may crash (the code uses assert). +std::unique_ptr<StreamingParserHandler> NewJSONEncoder(const Platform* platform, + std::string* out, + Status* status); + +// ============================================================================= +// json::ParseJSON - for receiving streaming parser events for JSON +// ============================================================================= + +void ParseJSON(const Platform* platform, + span<uint8_t> chars, + StreamingParserHandler* handler); +void ParseJSON(const Platform* platform, + span<uint16_t> chars, + StreamingParserHandler* handler); +} // namespace json {% for namespace in config.protocol.namespace %} } // namespace {{namespace}} {% endfor %} -#endif // !defined({{"_".join(config.protocol.namespace)}}_CBOR_h) +#endif // !defined({{"_".join(config.protocol.namespace)}}_encoding_h)
diff --git a/third_party/inspector_protocol/roll.py b/third_party/inspector_protocol/roll.py index 59699e6..deb1b28 100755 --- a/third_party/inspector_protocol/roll.py +++ b/third_party/inspector_protocol/roll.py
@@ -13,7 +13,6 @@ FILES_TO_SYNC = [ - 'BUILD.gn', 'README.md', 'check_protocol_compatibility.py', 'code_generator.py',
diff --git a/third_party/libjingle_xmpp/README.chromium b/third_party/libjingle_xmpp/README.chromium index 5ae9ef2..23aaef4e 100644 --- a/third_party/libjingle_xmpp/README.chromium +++ b/third_party/libjingle_xmpp/README.chromium
@@ -21,8 +21,4 @@ unused in Chromium, it's OK to delete it. Local Modifications: -* Include paths in third_party/libjingle_xmpp/xmllite, - third_party/libjingle_xmpp/xmpp, and third_party/libjingle_xmpp/task_runner - are updated to reflect the new absolute paths to their own and webrtc's - headers. -* disabled unstarted_task_test.DoNotDeleteTask2 under ASan +This code does not exist in an upstream repo anymore.
diff --git a/third_party/libjingle_xmpp/xmpp/xmppclient.cc b/third_party/libjingle_xmpp/xmpp/xmppclient.cc index 8a19078..de92055 100644 --- a/third_party/libjingle_xmpp/xmpp/xmppclient.cc +++ b/third_party/libjingle_xmpp/xmpp/xmppclient.cc
@@ -111,7 +111,7 @@ // For other servers, we leave the strings empty, which causes the jid's // domain to be used. We do the same for gmail.com and googlemail.com as the // returned CN matches the account domain in those cases. - std::string server_name = settings.server().ToString(); + std::string server_name = settings.server().host(); if (server_name == jingle_xmpp::STR_TALK_GOOGLE_COM || server_name == jingle_xmpp::STR_TALKX_L_GOOGLE_COM || server_name == jingle_xmpp::STR_XMPP_GOOGLE_COM ||
diff --git a/third_party/robolectric/BUILD.gn b/third_party/robolectric/BUILD.gn index c6ca0b5..50a63f4 100644 --- a/third_party/robolectric/BUILD.gn +++ b/third_party/robolectric/BUILD.gn
@@ -912,7 +912,7 @@ ":robolectric_utils_java", ":shadows_core_java", "//build/android:sun_tools_java", - "//third_party/android_deps:android_support_multidex_java", + "//third_party/android_deps:com_android_support_multidex_java", "//third_party/gson:gson_java", "//third_party/guava:guava_java", ]
diff --git a/third_party/sqlite/amalgamation/sqlite3.c b/third_party/sqlite/amalgamation/sqlite3.c index 911b658..1b990ba6 100644 --- a/third_party/sqlite/amalgamation/sqlite3.c +++ b/third_party/sqlite/amalgamation/sqlite3.c
@@ -57716,8 +57716,12 @@ */ pPg->flags &= ~PGHDR_NEED_SYNC; pPgOld = sqlite3PagerLookup(pPager, pgno); - assert( !pPgOld || pPgOld->nRef==1 ); + assert( !pPgOld || pPgOld->nRef==1 || CORRUPT_DB ); if( pPgOld ){ + if( pPgOld->nRef>1 ){ + sqlite3PagerUnrefNotNull(pPgOld); + return SQLITE_CORRUPT_BKPT; + } pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC); if( pPager->tempFile ){ /* Do not discard pages from an in-memory database since we might @@ -221520,7 +221524,7 @@ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ -#if __LINE__!=221523 +#if __LINE__!=221527 #undef SQLITE_SOURCE_ID #define SQLITE_SOURCE_ID "2019-02-25 16:06:06 bd49a8271d650fa89e446b42e513b595a717b9212c91dd384aab871fc1d0alt2" #endif
diff --git a/third_party/sqlite/patches/0001-Modify-default-VFS-to-support-WebDatabase.patch b/third_party/sqlite/patches/0001-Modify-default-VFS-to-support-WebDatabase.patch index 40932de..a881277c 100644 --- a/third_party/sqlite/patches/0001-Modify-default-VFS-to-support-WebDatabase.patch +++ b/third_party/sqlite/patches/0001-Modify-default-VFS-to-support-WebDatabase.patch
@@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: dumi <dumi@chromium.org> Date: Mon, 20 Jul 2009 23:40:51 +0000 -Subject: [PATCH 01/10] Modify default VFS to support WebDatabase. +Subject: [PATCH 01/11] Modify default VFS to support WebDatabase. The renderer WebDatabase implementation needs to broker certain requests to the browser. This modifies SQLite to allow monkey-patching the VFS @@ -175,5 +175,5 @@ ** CAPI3REF: String LIKE Matching * -- -2.21.0.352.gf09ad66450-goog +2.21.0.225.g810b269d1ac-goog
diff --git a/third_party/sqlite/patches/0002-Virtual-table-supporting-recovery-of-corrupted-datab.patch b/third_party/sqlite/patches/0002-Virtual-table-supporting-recovery-of-corrupted-datab.patch index e05110e..a79a522d 100644 --- a/third_party/sqlite/patches/0002-Virtual-table-supporting-recovery-of-corrupted-datab.patch +++ b/third_party/sqlite/patches/0002-Virtual-table-supporting-recovery-of-corrupted-datab.patch
@@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Scott Hess <shess@chromium.org> Date: Sat, 20 Jul 2013 11:42:21 -0700 -Subject: [PATCH 02/10] Virtual table supporting recovery of corrupted +Subject: [PATCH 02/11] Virtual table supporting recovery of corrupted databases. "recover" implements a virtual table which uses the SQLite pager layer @@ -3901,5 +3901,5 @@ + +finish_test -- -2.21.0.352.gf09ad66450-goog +2.21.0.225.g810b269d1ac-goog
diff --git a/third_party/sqlite/patches/0003-Custom-shell.c-helpers-to-load-Chromium-s-ICU-data.patch b/third_party/sqlite/patches/0003-Custom-shell.c-helpers-to-load-Chromium-s-ICU-data.patch index 2396150..b0a16fe 100644 --- a/third_party/sqlite/patches/0003-Custom-shell.c-helpers-to-load-Chromium-s-ICU-data.patch +++ b/third_party/sqlite/patches/0003-Custom-shell.c-helpers-to-load-Chromium-s-ICU-data.patch
@@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: "tc@google.com" <tc@google.com> Date: Tue, 6 Jan 2009 22:39:41 +0000 -Subject: [PATCH 03/10] Custom shell.c helpers to load Chromium's ICU data. +Subject: [PATCH 03/11] Custom shell.c helpers to load Chromium's ICU data. History uses fts3 with an icu-based segmenter. These changes allow building a sqlite3 binary for Linux or Windows which can read those files. @@ -141,5 +141,5 @@ + return 1; +} -- -2.21.0.352.gf09ad66450-goog +2.21.0.225.g810b269d1ac-goog
diff --git a/third_party/sqlite/patches/0004-fts3-Disable-fts3_tokenizer-and-fts4.patch b/third_party/sqlite/patches/0004-fts3-Disable-fts3_tokenizer-and-fts4.patch index f0c5125e..67eb49c 100644 --- a/third_party/sqlite/patches/0004-fts3-Disable-fts3_tokenizer-and-fts4.patch +++ b/third_party/sqlite/patches/0004-fts3-Disable-fts3_tokenizer-and-fts4.patch
@@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Scott Hess <shess@chromium.org> Date: Tue, 16 Dec 2014 13:02:27 -0800 -Subject: [PATCH 04/10] [fts3] Disable fts3_tokenizer and fts4. +Subject: [PATCH 04/11] [fts3] Disable fts3_tokenizer and fts4. fts3_tokenizer allows a SQLite user to specify a pointer to call as a function, which has obvious sercurity implications. Disable fts4 until @@ -56,5 +56,5 @@ } -- -2.21.0.352.gf09ad66450-goog +2.21.0.225.g810b269d1ac-goog
diff --git a/third_party/sqlite/patches/0005-fuchsia-Use-dot-file-locking-for-sqlite.patch b/third_party/sqlite/patches/0005-fuchsia-Use-dot-file-locking-for-sqlite.patch index 70172d6..8d6ff4b9 100644 --- a/third_party/sqlite/patches/0005-fuchsia-Use-dot-file-locking-for-sqlite.patch +++ b/third_party/sqlite/patches/0005-fuchsia-Use-dot-file-locking-for-sqlite.patch
@@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Scott Graham <scottmg@chromium.org> Date: Mon, 11 Sep 2017 13:37:46 -0700 -Subject: [PATCH 05/10] fuchsia: Use dot-file locking for sqlite +Subject: [PATCH 05/11] fuchsia: Use dot-file locking for sqlite --- third_party/sqlite/src/src/os_unix.c | 4 ++++ @@ -23,5 +23,5 @@ UNIXVFS("unix", posixIoFinder ), #endif -- -2.21.0.352.gf09ad66450-goog +2.21.0.225.g810b269d1ac-goog
diff --git a/third_party/sqlite/patches/0006-Fix-compilation-with-SQLITE_OMIT_WINDOWFUNC.patch b/third_party/sqlite/patches/0006-Fix-compilation-with-SQLITE_OMIT_WINDOWFUNC.patch index b1f49d81..129309c1 100644 --- a/third_party/sqlite/patches/0006-Fix-compilation-with-SQLITE_OMIT_WINDOWFUNC.patch +++ b/third_party/sqlite/patches/0006-Fix-compilation-with-SQLITE_OMIT_WINDOWFUNC.patch
@@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Victor Costan <pwnall@chromium.org> Date: Sun, 10 Feb 2019 13:12:57 -0800 -Subject: [PATCH 06/10] Fix compilation with SQLITE_OMIT_WINDOWFUNC. +Subject: [PATCH 06/11] Fix compilation with SQLITE_OMIT_WINDOWFUNC. --- third_party/sqlite/src/src/resolve.c | 2 ++ @@ -28,5 +28,5 @@ /* If this is part of a compound SELECT, check that it has the right ** number of expressions in the select list. */ -- -2.21.0.352.gf09ad66450-goog +2.21.0.225.g810b269d1ac-goog
diff --git a/third_party/sqlite/patches/0007-Fix-dbfuzz2.c-compilation-errors-on-Windows.patch b/third_party/sqlite/patches/0007-Fix-dbfuzz2.c-compilation-errors-on-Windows.patch index ad34409..7cc4db65 100644 --- a/third_party/sqlite/patches/0007-Fix-dbfuzz2.c-compilation-errors-on-Windows.patch +++ b/third_party/sqlite/patches/0007-Fix-dbfuzz2.c-compilation-errors-on-Windows.patch
@@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Victor Costan <pwnall@chromium.org> Date: Sun, 10 Feb 2019 15:18:43 -0800 -Subject: [PATCH 07/10] Fix dbfuzz2.c compilation errors on Windows. +Subject: [PATCH 07/11] Fix dbfuzz2.c compilation errors on Windows. --- third_party/sqlite/src/test/dbfuzz2.c | 4 ++++ @@ -39,5 +39,5 @@ argv[j++] = argv[i]; } -- -2.21.0.352.gf09ad66450-goog +2.21.0.225.g810b269d1ac-goog
diff --git a/third_party/sqlite/patches/0008-Fix-Heap-buffer-overflow-in-vdbeRecordCompareInt.patch b/third_party/sqlite/patches/0008-Fix-Heap-buffer-overflow-in-vdbeRecordCompareInt.patch index 456c8b1c..78c5dd9 100644 --- a/third_party/sqlite/patches/0008-Fix-Heap-buffer-overflow-in-vdbeRecordCompareInt.patch +++ b/third_party/sqlite/patches/0008-Fix-Heap-buffer-overflow-in-vdbeRecordCompareInt.patch
@@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Darwin Huang <huangdarwin@chromium.org> Date: Tue, 5 Mar 2019 13:49:51 -0800 -Subject: [PATCH 08/10] Fix Heap-buffer-overflow in vdbeRecordCompareInt +Subject: [PATCH 08/11] Fix Heap-buffer-overflow in vdbeRecordCompareInt This backports https://www.sqlite.org/src/info/c1ac00706bae45fe @@ -23,6 +23,6 @@ sqlite3_free(pCellKey); } assert( --- -2.21.0.352.gf09ad66450-goog +-- +2.21.0.225.g810b269d1ac-goog
diff --git a/third_party/sqlite/patches/0009-fix-heap-buffer-overflow-in-cellsizeptr.patch b/third_party/sqlite/patches/0009-fix-heap-buffer-overflow-in-cellsizeptr.patch index f597a3e..56044458 100644 --- a/third_party/sqlite/patches/0009-fix-heap-buffer-overflow-in-cellsizeptr.patch +++ b/third_party/sqlite/patches/0009-fix-heap-buffer-overflow-in-cellsizeptr.patch
@@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Darwin Huang <huangdarwin@chromium.org> Date: Tue, 5 Mar 2019 14:13:19 -0800 -Subject: [PATCH 09/10] fix heap-buffer-overflow in cellsizeptr +Subject: [PATCH 09/11] fix heap-buffer-overflow in cellsizeptr This backports https://www.sqlite.org/src/info/e7aca0714bc475e0 @@ -29,8 +29,8 @@ + memset(pNew+pageSize, 0, 8); + } } - + if( rc==SQLITE_OK ){ --- -2.21.0.352.gf09ad66450-goog +-- +2.21.0.225.g810b269d1ac-goog
diff --git a/third_party/sqlite/patches/0010-fix-integer-overflow-in-checkList.patch b/third_party/sqlite/patches/0010-fix-integer-overflow-in-checkList.patch index e909a7f..80c10bc 100644 --- a/third_party/sqlite/patches/0010-fix-integer-overflow-in-checkList.patch +++ b/third_party/sqlite/patches/0010-fix-integer-overflow-in-checkList.patch
@@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Darwin Huang <huangdarwin@chromium.org> Date: Tue, 5 Mar 2019 14:17:05 -0800 -Subject: [PATCH 10/10] fix integer overflow in checkList +Subject: [PATCH 10/11] fix integer overflow in checkList This backports https://www.sqlite.org/src/info/05b87e0755638d31 @@ -28,7 +28,7 @@ while( iPage!=0 && pCheck->mxErr ){ DbPage *pOvflPage; @@ -9797,7 +9797,7 @@ static int checkTreePage( - + /* Check the content overflow list */ if( info.nPayload>info.nLocal ){ - int nPage; /* Number of pages on the overflow chain */ @@ -36,6 +36,6 @@ Pgno pgnoOvfl; /* First page of the overflow chain */ assert( pc + info.nSize - 4 <= usableSize ); nPage = (info.nPayload - info.nLocal + usableSize - 5)/(usableSize - 4); --- -2.21.0.352.gf09ad66450-goog +-- +2.21.0.225.g810b269d1ac-goog
diff --git a/third_party/sqlite/patches/0011-Fix-Heap-use-after-free-in-releasePageNotNull.patch b/third_party/sqlite/patches/0011-Fix-Heap-use-after-free-in-releasePageNotNull.patch new file mode 100644 index 0000000..dca77bc --- /dev/null +++ b/third_party/sqlite/patches/0011-Fix-Heap-use-after-free-in-releasePageNotNull.patch
@@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Tue, 12 Mar 2019 17:30:33 -0700 +Subject: [PATCH 11/11] Fix Heap-use-after-free in releasePageNotNull + +This backports https://www.sqlite.org/src/info/b0d5cf40bba34e45 + +Bug: 936719 +--- + third_party/sqlite/src/src/pager.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/third_party/sqlite/src/src/pager.c b/third_party/sqlite/src/src/pager.c +index efb9155f545d..6c21cc6172b9 100644 +--- a/third_party/sqlite/src/src/pager.c ++++ b/third_party/sqlite/src/src/pager.c +@@ -7174,8 +7174,12 @@ int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ + */ + pPg->flags &= ~PGHDR_NEED_SYNC; + pPgOld = sqlite3PagerLookup(pPager, pgno); +- assert( !pPgOld || pPgOld->nRef==1 ); ++ assert( !pPgOld || pPgOld->nRef==1 || CORRUPT_DB ); + if( pPgOld ){ ++ if( pPgOld->nRef>1 ){ ++ sqlite3PagerUnrefNotNull(pPgOld); ++ return SQLITE_CORRUPT_BKPT; ++ } + pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC); + if( pPager->tempFile ){ + /* Do not discard pages from an in-memory database since we might +-- +2.21.0.225.g810b269d1ac-goog +
diff --git a/third_party/sqlite/src/src/pager.c b/third_party/sqlite/src/src/pager.c index efb9155..6c21cc6 100644 --- a/third_party/sqlite/src/src/pager.c +++ b/third_party/sqlite/src/src/pager.c
@@ -7174,8 +7174,12 @@ */ pPg->flags &= ~PGHDR_NEED_SYNC; pPgOld = sqlite3PagerLookup(pPager, pgno); - assert( !pPgOld || pPgOld->nRef==1 ); + assert( !pPgOld || pPgOld->nRef==1 || CORRUPT_DB ); if( pPgOld ){ + if( pPgOld->nRef>1 ){ + sqlite3PagerUnrefNotNull(pPgOld); + return SQLITE_CORRUPT_BKPT; + } pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC); if( pPager->tempFile ){ /* Do not discard pages from an in-memory database since we might
diff --git a/tools/android/audio_focus_grabber/BUILD.gn b/tools/android/audio_focus_grabber/BUILD.gn index a7236f4..b05e9111 100644 --- a/tools/android/audio_focus_grabber/BUILD.gn +++ b/tools/android/audio_focus_grabber/BUILD.gn
@@ -12,7 +12,7 @@ deps = [ ":audio_focus_grabber_apk_resources", "//base:base_java", - "//third_party/android_deps:android_support_compat_java", + "//third_party/android_deps:com_android_support_support_compat_java", ] java_files = [
diff --git a/tools/binary_size/libsupersize/archive.py b/tools/binary_size/libsupersize/archive.py index 892526f..ee54015 100644 --- a/tools/binary_size/libsupersize/archive.py +++ b/tools/binary_size/libsupersize/archive.py
@@ -1117,28 +1117,23 @@ return section_sizes, 0 -def _ParseDexSymbols(section_sizes, apk_path, mapping_path, size_info_prefix, - output_directory): - symbols = apkanalyzer.CreateDexSymbols( - apk_path, mapping_path, size_info_prefix, output_directory) - prev = section_sizes.setdefault(models.SECTION_DEX, 0) - section_sizes[models.SECTION_DEX] = prev + sum(s.size for s in symbols) - return symbols - - def _ParseApkOtherSymbols(section_sizes, apk_path, apk_so_path, size_info_prefix, knobs): res_source_mapper = _ResourceSourceMapper(size_info_prefix, knobs) apk_symbols = [] + dex_size = 0 zip_info_total = 0 with zipfile.ZipFile(apk_path) as z: for zip_info in z.infolist(): zip_info_total += zip_info.compress_size # Skip main shared library, pak, and dex files as they are accounted for. if (zip_info.filename == apk_so_path - or zip_info.filename.endswith('.dex') or zip_info.filename.endswith('.pak')): continue + if zip_info.filename.endswith('.dex'): + dex_size += zip_info.file_size + continue + source_path = res_source_mapper.FindSourceForPath(zip_info.filename) if source_path is None: source_path = os.path.join(models.APK_PREFIX_PATH, zip_info.filename) @@ -1153,7 +1148,8 @@ apk_symbols.append(zip_overhead_symbol) prev = section_sizes.setdefault(models.SECTION_OTHER, 0) section_sizes[models.SECTION_OTHER] = prev + sum(s.size for s in apk_symbols) - return apk_symbols + + return dex_size, apk_symbols def _CreatePakObjectMap(object_paths_by_name): @@ -1316,15 +1312,21 @@ section_sizes, metadata, apk_elf_result) pak_symbols_by_id = _FindPakSymbolsFromApk( section_sizes, apk_path, size_info_prefix, knobs) - raw_symbols.extend( - _ParseDexSymbols(section_sizes, - apk_path, - mapping_path, - size_info_prefix, - output_directory)) - raw_symbols.extend( - _ParseApkOtherSymbols(section_sizes, apk_path, apk_so_path, - size_info_prefix, knobs)) + dex_symbols = apkanalyzer.CreateDexSymbols( + apk_path, mapping_path, size_info_prefix, output_directory) + raw_symbols.extend(dex_symbols) + dex_size, other_symbols = _ParseApkOtherSymbols( + section_sizes, apk_path, apk_so_path, size_info_prefix, knobs) + raw_symbols.extend(other_symbols) + + # We can't meaningfully track section size of dex methods vs other, so just + # fake the size of dex methods as the sum of symbols, and make "dex other" + # responsible for any unattributed bytes. + dex_method_size = int(round(sum( + s.pss for s in dex_symbols + if s.section_name == models.SECTION_DEX_METHOD))) + section_sizes[models.SECTION_DEX_METHOD] = dex_method_size + section_sizes[models.SECTION_DEX] = dex_size - dex_method_size elif pak_files and pak_info_file: pak_symbols_by_id = _FindPakSymbolsFromFiles( section_sizes, pak_files, pak_info_file, output_directory)
diff --git a/tools/binary_size/libsupersize/testdata/Archive_Apk.golden b/tools/binary_size/libsupersize/testdata/Archive_Apk.golden index c992b9c7..8fd9e75 100644 --- a/tools/binary_size/libsupersize/testdata/Archive_Apk.golden +++ b/tools/binary_size/libsupersize/testdata/Archive_Apk.golden
@@ -40,12 +40,12 @@ * 6 have source paths. Accounts for 524520 bytes (100.0%). * 0 symbols have shared ownership. * 3 symbols are from generated sources. Accounts for 232 bytes (0.0%). -Section .dex: has 99.7% of 8365003 bytes accounted for from 93 symbols. 23605 bytes are unaccounted for. +Section .dex: has 100.0% of 8365003 bytes accounted for from 93 symbols. 0 bytes are unaccounted for. * Padding accounts for 0 bytes (0.0%) * 83 have source paths. Accounts for 926 bytes (0.0%). * 1 placeholders exist (symbols that start with **). Accounts for 4616803 bytes (55.2%). * 0 symbols have shared ownership. -Section .dex.method: 23605 bytes from 100 symbols. +Section .dex.method: has 100.0% of 23605 bytes accounted for from 100 symbols. 0 bytes are unaccounted for. * Padding accounts for 0 bytes (0.0%) * 90 have source paths. Accounts for 21154 bytes (89.6%). * 0 symbols have shared ownership.
diff --git a/tools/binary_size/libsupersize/testdata/Archive_MinimalApks.golden b/tools/binary_size/libsupersize/testdata/Archive_MinimalApks.golden index 102c8a8..12371d0f 100644 --- a/tools/binary_size/libsupersize/testdata/Archive_MinimalApks.golden +++ b/tools/binary_size/libsupersize/testdata/Archive_MinimalApks.golden
@@ -41,12 +41,12 @@ * 6 have source paths. Accounts for 524520 bytes (100.0%). * 0 symbols have shared ownership. * 3 symbols are from generated sources. Accounts for 232 bytes (0.0%). -Section .dex: has 99.7% of 8365003 bytes accounted for from 93 symbols. 23605 bytes are unaccounted for. +Section .dex: has 100.0% of 8365003 bytes accounted for from 93 symbols. 0 bytes are unaccounted for. * Padding accounts for 0 bytes (0.0%) * 83 have source paths. Accounts for 926 bytes (0.0%). * 1 placeholders exist (symbols that start with **). Accounts for 4616803 bytes (55.2%). * 0 symbols have shared ownership. -Section .dex.method: 23605 bytes from 100 symbols. +Section .dex.method: has 100.0% of 23605 bytes accounted for from 100 symbols. 0 bytes are unaccounted for. * Padding accounts for 0 bytes (0.0%) * 90 have source paths. Accounts for 21154 bytes (89.6%). * 0 symbols have shared ownership.
diff --git a/tools/chrome_proxy/webdriver/emulation_server.py b/tools/chrome_proxy/webdriver/emulation_server.py index 9975046..1de9846 100644 --- a/tools/chrome_proxy/webdriver/emulation_server.py +++ b/tools/chrome_proxy/webdriver/emulation_server.py
@@ -140,7 +140,7 @@ # Create a private key pair. pk = crypto.PKey() - pk.generate_key(crypto.TYPE_RSA, 1024) + pk.generate_key(crypto.TYPE_RSA, 3072) # Create a certificate and sign it. cert = crypto.X509()
diff --git a/tools/chrome_proxy/webdriver/proxy_connection.py b/tools/chrome_proxy/webdriver/proxy_connection.py index 192ad88..984bd9b 100644 --- a/tools/chrome_proxy/webdriver/proxy_connection.py +++ b/tools/chrome_proxy/webdriver/proxy_connection.py
@@ -6,6 +6,7 @@ from common import TestDriver from common import IntegrationTest from decorators import ChromeVersionBetweenInclusiveM +from decorators import ChromeVersionEqualOrAfterM from emulation_server import BlackHoleHandler from emulation_server import InvalidTLSHandler from emulation_server import TCPResetHandler @@ -13,7 +14,7 @@ class ProxyConnection(IntegrationTest): - @ChromeVersionBetweenInclusiveM(63, 72) + @ChromeVersionEqualOrAfterM(63) def testTLSInjectionAfterHandshake(self): port = common.GetOpenPort() with TestDriver() as t: @@ -25,6 +26,8 @@ '--data-reduction-proxy-http-proxies=https://127.0.0.1:%d' % port) t.AddChromeArg( '--force-fieldtrials=DataReductionProxyConfigService/Disabled') + t.AddChromeArg( + '--enable-features=NetworkService,DataReductionProxyEnabledWithNetworkService') t.UseEmulationServer(InvalidTLSHandler, port=port) t.LoadURL('http://check.googlezip.net/test.html') @@ -37,7 +40,7 @@ self.assertTrue(t.SleepUntilHistogramHasEntry('DataReductionProxy.' 'InvalidResponseHeadersReceived.NetError')) - @ChromeVersionBetweenInclusiveM(63, 72) + @ChromeVersionEqualOrAfterM(63) def testTCPReset(self): port = common.GetOpenPort() with TestDriver() as t: @@ -50,6 +53,8 @@ '--data-reduction-proxy-http-proxies=http://127.0.0.1:%d' % port) t.AddChromeArg( '--force-fieldtrials=DataReductionProxyConfigService/Disabled') + t.AddChromeArg( + '--enable-features=NetworkService,DataReductionProxyEnabledWithNetworkService') t.UseEmulationServer(TCPResetHandler, port=port) t.LoadURL('http://check.googlezip.net/test.html') @@ -62,7 +67,7 @@ self.assertTrue(t.SleepUntilHistogramHasEntry('DataReductionProxy.' 'InvalidResponseHeadersReceived.NetError')) - @ChromeVersionBetweenInclusiveM(63, 72) + @ChromeVersionEqualOrAfterM(63) def testTLSReset(self): port = common.GetOpenPort() with TestDriver() as t: @@ -75,6 +80,8 @@ '--data-reduction-proxy-http-proxies=https://127.0.0.1:%d' % port) t.AddChromeArg( '--force-fieldtrials=DataReductionProxyConfigService/Disabled') + t.AddChromeArg( + '--enable-features=NetworkService,DataReductionProxyEnabledWithNetworkService') t.UseEmulationServer(TLSResetHandler, port=port) t.LoadURL('http://check.googlezip.net/test.html')
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 3c61fcc0..6692cac 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -33038,6 +33038,7 @@ <int value="537857256" label="PipRoundedCorners:enabled"/> <int value="538468149" label="OfflinePagesCT:enabled"/> <int value="538600423" label="OmniboxDocumentProvider:enabled"/> + <int value="538685995" label="InstallableInkDrop:enabled"/> <int value="546043947" label="ImplicitRootScroller:enabled"/> <int value="546520086" label="enable-data-reduction-proxy-savings-promo"/> <int value="546710806" label="disable-easy-signin"/> @@ -33419,6 +33420,7 @@ <int value="1167613030" label="enable-permission-action-reporting"/> <int value="1169418814" label="ManualFallbacksFilling:enabled"/> <int value="1174088940" label="enable-wasm"/> + <int value="1177120582" label="InstallableInkDrop:disabled"/> <int value="1179013979" label="OmniboxUIExperimentMaxAutocompleteMatches:enabled"/> <int value="1179936481" label="enable-android-pay-integration-v1"/> @@ -44341,6 +44343,7 @@ <int value="55" label="CREDENTIAL_MANAGER_API"/> <int value="56" label="NOSTATE_PREFETCH_FINISHED"/> <int value="57" label="LOW_END_DEVICE"/> + <int value="58" label="FINAL_STATUS_BROWSER_SWITCH"/> </enum> <enum name="PrerenderHoverEvent"> @@ -44495,6 +44498,17 @@ <int value="8" label="PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP"/> </enum> +<enum name="PrerenderOrigin"> + <int value="2" label="ORIGIN_GWS_PRERENDER"/> + <int value="5" label="ORIGIN_OMNIBOX"/> + <int value="6" label="ORIGIN_NONE"/> + <int value="7" label="ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN"/> + <int value="8" label="ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN"/> + <int value="10" label="ORIGIN_EXTERNAL_REQUEST"/> + <int value="12" label="ORIGIN_LINK_REL_NEXT"/> + <int value="13" label="ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER"/> +</enum> + <enum name="PrerenderPageviewEvents"> <obsolete> deprecated Nov 16 2012 @@ -48685,6 +48699,9 @@ </enum> <enum name="ServiceWorkerContextRequestHandlerStatus"> + <obsolete> + No longer recorded since NetS13nSW shipped on Dec 2018. + </obsolete> <summary> The result of ServiceWorkerContextHandler handling a request for a service worker script. From ServiceWorkerContextHandler::CreateJobStatus.
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 8c930eb..1322d9f4 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -3920,6 +3920,16 @@ </summary> </histogram> +<histogram name="Apps.AppListSearchAbandonQueryLength" units="characters" + expires_after="2019-12-31"> + <owner>jennyz@chromium.org</owner> + <owner>jiameng@chromium.org</owner> + <summary> + The length of the query when the user abandons results of a queried search + or recommendations of zero state (zero length query) in launcher UI. + </summary> +</histogram> + <histogram name="Apps.AppListSearchBoxActivated" enum="SearchBoxActivationSource"> <owner>newcomer@chromium.org</owner> @@ -5444,6 +5454,47 @@ </summary> </histogram> +<histogram name="Ash.Overview.AnimationSmoothness.Close" units="%" + expires_after="M77"> +<!-- Name completed by histogram_suffixes + name="TabletOrClamshellMode" --> + + <owner>omrilio@chromium.org</owner> + <owner>oshima@chromium.org</owner> + <summary> + Relative smoothness of animations when closing a window, recorded when the + animation completes. 100% represents ideally smooth 60 frames per second. + </summary> +</histogram> + +<histogram name="Ash.Overview.AnimationSmoothness.Enter" units="%" + expires_after="M77"> +<!-- Name completed by histogram_suffixes + name="TabletOrClamshellMode" --> + + <owner>omrilio@chromium.org</owner> + <owner>oshima@chromium.org</owner> + <summary> + Relative smoothness of animations when entering overview mode, recorded when + the animation completes. 100% represents ideally smooth 60 frames per + second. + </summary> +</histogram> + +<histogram name="Ash.Overview.AnimationSmoothness.Exit" units="%" + expires_after="M77"> +<!-- Name completed by histogram_suffixes + name="TabletOrClamshellMode" --> + + <owner>omrilio@chromium.org</owner> + <owner>oshima@chromium.org</owner> + <summary> + Relative smoothness of animations when exiting overview mode, recorded when + the animation completes. 100% represents ideally smooth 60 frames per + second. + </summary> +</histogram> + <histogram name="Ash.PersistentWindow.NumOfWindowsRestored"> <owner>warx@chromium.org</owner> <summary> @@ -6119,25 +6170,40 @@ </summary> </histogram> -<histogram name="Ash.WindowSelector.AnimationSmoothness.Close" units="%"> +<histogram base="true" name="Ash.WindowSelector.AnimationSmoothness.Close" + units="%" expires_after="M77"> <owner>estade@chromium.org</owner> <summary> + Deprecated 03/2019 in favor of + Ash.Overview.AnimationSmoothness.Close.Clamshell and + Ash.Overview.AnimationSmoothness.Close.Tablet + Relative smoothness of animations when closing a window in overview mode. 100% represents ideally smooth 60 frames per second. </summary> </histogram> -<histogram name="Ash.WindowSelector.AnimationSmoothness.Enter" units="%"> +<histogram base="true" name="Ash.WindowSelector.AnimationSmoothness.Enter" + units="%" expires_after="M77"> <owner>estade@chromium.org</owner> <summary> + Deprecated 03/2019 in favor of + Ash.Overview.AnimationSmoothness.Enter.Clamshell and + Ash.Overview.AnimationSmoothness.Enter.Tablet + Relative smoothness of animations when entering overview mode. 100% represents ideally smooth 60 frames per second. </summary> </histogram> -<histogram name="Ash.WindowSelector.AnimationSmoothness.Exit" units="%"> +<histogram base="true" name="Ash.WindowSelector.AnimationSmoothness.Exit" + units="%" expires_after="M77"> <owner>estade@chromium.org</owner> <summary> + Deprecated 03/2019 in favor of + Ash.Overview.AnimationSmoothness.Exit.Clamshell and + Ash.Overview.AnimationSmoothness.Exit.Tablet + Relative smoothness of animations when exiting overview mode. 100% represents ideally smooth 60 frames per second. </summary> @@ -9565,6 +9631,24 @@ </details> </histogram> +<histogram name="Autofill.WalletUseDate.Address" units="ms" expires_after="M76"> + <owner>jkrcal@chromium.org</owner> + <owner>treib@chromium.org</owner> + <summary> + The time since last use date of a wallet address, as known by sync. Recorded + for each wallet address on startup. + </summary> +</histogram> + +<histogram name="Autofill.WalletUseDate.Card" units="ms" expires_after="M76"> + <owner>jkrcal@chromium.org</owner> + <owner>treib@chromium.org</owner> + <summary> + The time since last use date of a wallet card, as known by sync. Recorded + for each wallet card on startup. + </summary> +</histogram> + <histogram name="Autofill.WebView.AutofillSession" enum="AutofillSessionStates"> <owner>michaelbai@chromium.org</owner> <summary>Records the state of an autofill session.</summary> @@ -101237,6 +101321,15 @@ </summary> </histogram> +<histogram name="SBClientDownload.ZipTooBigToUnpack" enum="Boolean"> + <owner>chrome-safebrowsing-alerts@google.com</owner> + <summary> + Records whether a given ZIP download was too big to unpack, as specified by + configuration option set in SafeBrowsing download service. This metric is + logged each time the user downloads a ZIP file. + </summary> +</histogram> + <histogram name="SBClientMalware.ClassificationStart" enum="BooleanHit"> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -105762,6 +105855,9 @@ <histogram name="ServiceWorker.ContextRequestHandlerStatus" enum="ServiceWorkerContextRequestHandlerStatus"> + <obsolete> + No longer recorded since NetS13nSW shipped on Dec 2018. + </obsolete> <owner>falken@chromium.org</owner> <summary> The result of ServiceWorkerContextRequestHandler handling a request for a @@ -146385,6 +146481,9 @@ </histogram_suffixes> <histogram_suffixes name="ServiceWorker.ContextRequestType" separator="."> + <obsolete> + The affected histogram is obsolete. + </obsolete> <suffix name="InstalledWorker.ImportedScript" label="Imported script for an installed worker"/> <suffix name="InstalledWorker.MainScript" @@ -147836,6 +147935,9 @@ <suffix name="TabletMode" label="Tablet Mode Enabled"/> <affected-histogram name="Apps.AppListFolderNameLength"/> <affected-histogram name="Apps.StateTransition.AnimationSmoothness"/> + <affected-histogram name="Ash.Overview.AnimationSmoothness.Close"/> + <affected-histogram name="Ash.Overview.AnimationSmoothness.Enter"/> + <affected-histogram name="Ash.Overview.AnimationSmoothness.Exit"/> </histogram_suffixes> <histogram_suffixes name="TabNewTabOnload" separator=".">
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 89d4f0f..7235797f 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -4279,6 +4279,39 @@ </metric> </event> +<event name="NoStatePrefetch" singular="True"> + <owner>tbansal@chromium.org</owner> + <summary> + Metrics related to NoStatePrefetch that are recorded using the same UKM IDs + as PageLoad. + </summary> + <metric name="PrefetchedRecently.FinalStatus"> + <summary> + Final status of the nostate prefetch if one was recently attempted for + either the committed URL of this navigation or for any URL in the redirect + chain for the main frame resource for this navigation. page. Recorded as + enum PrerenderFinalStatus in //tools/metrics/histograms/enums.xml. + </summary> + </metric> + <metric name="PrefetchedRecently.Origin"> + <summary> + Triggering origin of the nostate prefetch if one was recently attempted + for either the committed URL of this navigation or for any URL in the + redirect chain for the main frame resource for this navigation. Recorded + as enum PrerenderOrigin in //tools/metrics/histograms/enums.xml. + </summary> + </metric> + <metric name="PrefetchedRecently.PrefetchAge"> + <summary> + Records the time (in milliseconds) from the start of the nostate prefetch + to the time of commit of this navigation. Metric is recorded down to the + nearest power of 2. Recorded only if a nostate prefetch was recently + attempted for either the committed URL of this navigation or for any URL + in the redirect chain for the main frame resource for this navigation. + </summary> + </metric> +</event> + <event name="PageLoadCapping" singular="True"> <owner>ryansturm@chromium.org</owner> <summary>
diff --git a/tools/perf/cli_tools/update_wpr/update_wpr.py b/tools/perf/cli_tools/update_wpr/update_wpr.py index b1d87d08..d7f0879 100644 --- a/tools/perf/cli_tools/update_wpr/update_wpr.py +++ b/tools/perf/cli_tools/update_wpr/update_wpr.py
@@ -401,7 +401,7 @@ if self._IsDesktop(): configs = ['linux-perf', 'win-10-perf', 'mac-10_12_laptop_low_end-perf'] else: - configs = ['Android Nexus5 Perf'] + configs = ['android-nexus5x-perf'] for config in configs: job_url = self._StartPinpointJob(config) if not job_url:
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index be1b751..17b9be0c 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -333,9 +333,9 @@ ":ui_java_resources", ":ui_utils_java", "//base:base_java", - "//third_party/android_deps:android_support_annotations_java", "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:android_support_v7_recyclerview_java", + "//third_party/android_deps:com_android_support_recyclerview_v7_java", + "//third_party/android_deps:com_android_support_support_annotations_java", ] srcjar_deps = [ ":java_enums_srcjar",
diff --git a/ui/aura/mus/client_side_window_move_handler.cc b/ui/aura/mus/client_side_window_move_handler.cc index 7c3b6738..827f401 100644 --- a/ui/aura/mus/client_side_window_move_handler.cc +++ b/ui/aura/mus/client_side_window_move_handler.cc
@@ -99,6 +99,12 @@ void ClientSideWindowMoveHandler::MaybeSetupLastTarget( ui::LocatedEvent* event) { + // Do nothing in the middle of a dragging session, otherwise some properties + // (e.g. |last_component_| or |dragging_window_|) might get wrong. See: + // https://crbug.com/940545. + if (dragging_window_) + return; + last_target_.RemoveAll(); Window* window = GetToplevelTargetForEvent(event, &last_component_); @@ -116,6 +122,11 @@ void ClientSideWindowMoveHandler::UpdateWindowResizeShadow(Window* window, int component) { + // Do nothing in the middle of a dragging session. See: + // https://crbug.com/940545. + if (dragging_window_) + return; + client_->SetWindowResizeShadow(window->GetRootWindow(), component); last_shadow_target_.RemoveAll(); last_shadow_target_.Add(window); @@ -124,6 +135,11 @@ void ClientSideWindowMoveHandler::MaybePerformWindowMove( ui::LocatedEvent* event, ws::mojom::MoveLoopSource source) { + // Do nothing in the middle of a dragging session. See: + // https://crbug.com/940545. + if (dragging_window_) + return; + Window* target = static_cast<Window*>(event->target()); if (!last_target_.Contains(target->GetToplevelWindow())) return;
diff --git a/ui/aura/mus/client_side_window_move_handler_unittest.cc b/ui/aura/mus/client_side_window_move_handler_unittest.cc index b5d1f83..d9062f20 100644 --- a/ui/aura/mus/client_side_window_move_handler_unittest.cc +++ b/ui/aura/mus/client_side_window_move_handler_unittest.cc
@@ -85,23 +85,24 @@ } ~WindowMoveObserver() override { client_->RemoveTestObserver(this); } - bool in_window_move() const { return in_window_move_; } + bool in_window_move() const { return window_move_count_ > 0; } + int window_move_count() const { return window_move_count_; } private: // WindowTreeClientTestObserver: void OnChangeStarted(uint32_t change_id, ChangeType type) override { if (type == ChangeType::MOVE_LOOP) - in_window_move_ = true; + window_move_count_++; } void OnChangeCompleted(uint32_t change_id, ChangeType type, bool success) override { if (type == ChangeType::MOVE_LOOP) - in_window_move_ = false; + window_move_count_--; } WindowTreeClient* client_; - bool in_window_move_ = false; + int window_move_count_ = 0; DISALLOW_COPY_AND_ASSIGN(WindowMoveObserver); }; @@ -154,6 +155,13 @@ event_generator_->PressTouch(); } + void ReleaseInput() { + if (IsInputMouse()) + event_generator_->ReleaseLeftButton(); + else + event_generator_->ReleaseTouch(); + } + gfx::Rect GetWindowBounds() { return test_window_->GetBoundsInScreen(); } WindowMoveTestDelegate test_delegate_; @@ -291,6 +299,38 @@ EXPECT_FALSE(observer.in_window_move()); } +TEST_P(ClientSideWindowMoveHandlerTest, + AdditionalEventsShouldntTriggerAnotherMove) { + WindowMoveObserver observer(window_tree_client_impl()); + + MoveInputTo(GetWindowBounds().origin() + gfx::Vector2d(10, 10)); + + PressInput(); + MoveInputBy(10, 10); + EXPECT_EQ(1, observer.window_move_count()); + EXPECT_EQ(HTCAPTION, window_tree()->last_move_hit_test()); + EXPECT_EQ(HTNOWHERE, window_tree()->last_window_resize_shadow()); + + // Nothing should happen for additional move events. + MoveInputBy(10, 10); + EXPECT_EQ(1, observer.window_move_count()); + EXPECT_EQ(HTCAPTION, window_tree()->last_move_hit_test()); + EXPECT_EQ(HTNOWHERE, window_tree()->last_window_resize_shadow()); + window_tree()->AckAllChanges(); + EXPECT_FALSE(observer.in_window_move()); + ReleaseInput(); + + // Restarting a move should start a new move. + MoveInputTo(GetWindowBounds().origin() + gfx::Vector2d(10, 10)); + PressInput(); + MoveInputBy(10, 10); + EXPECT_EQ(1, observer.window_move_count()); + EXPECT_EQ(HTCAPTION, window_tree()->last_move_hit_test()); + EXPECT_EQ(HTNOWHERE, window_tree()->last_window_resize_shadow()); + window_tree()->AckAllChanges(); + EXPECT_FALSE(observer.in_window_move()); +} + INSTANTIATE_TEST_SUITE_P(, ClientSideWindowMoveHandlerTest, ::testing::Values("mouse", "touch"));
diff --git a/ui/aura/mus/window_tree_client.cc b/ui/aura/mus/window_tree_client.cc index 85fa6c9..714ef6e 100644 --- a/ui/aura/mus/window_tree_client.cc +++ b/ui/aura/mus/window_tree_client.cc
@@ -1726,7 +1726,12 @@ const gfx::Point& cursor_location, int hit_test, base::OnceCallback<void(bool)> callback) { - DCHECK(on_current_move_finished_.is_null()); + if (!on_current_move_finished_.is_null()) { + // Moving multiple windows at the same time is not allowed, and it causes + // troubles. See: https://crbug.com/940545. + std::move(callback).Run(false); + return; + } on_current_move_finished_ = std::move(callback); WindowMus* window_mus = WindowMus::Get(window_tree_host->window());
diff --git a/ui/aura/mus/window_tree_client_unittest.cc b/ui/aura/mus/window_tree_client_unittest.cc index b614be2..798ae301 100644 --- a/ui/aura/mus/window_tree_client_unittest.cc +++ b/ui/aura/mus/window_tree_client_unittest.cc
@@ -2712,6 +2712,31 @@ window_tree()->last_transfer_new()); } +TEST_F(WindowTreeClientTest, SecondPerformWindowMoveIsNotAllowed) { + int call_count = 0; + bool last_result = false; + + WindowTreeHostMus* host_mus = static_cast<WindowTreeHostMus*>(host()); + host_mus->PerformWindowMove( + host_mus->window(), ws::mojom::MoveLoopSource::MOUSE, gfx::Point(), + HTCAPTION, base::BindOnce(&OnWindowMoveDone, &call_count, &last_result)); + EXPECT_EQ(0, call_count); + + int call_count_inner = 0; + bool inner_result = true; + host_mus->PerformWindowMove( + host_mus->window(), ws::mojom::MoveLoopSource::MOUSE, gfx::Point(), + HTCAPTION, + base::BindOnce(&OnWindowMoveDone, &call_count_inner, &inner_result)); + EXPECT_EQ(0, call_count); + EXPECT_EQ(1, call_count_inner); + EXPECT_FALSE(inner_result); + + window_tree()->AckAllChanges(); + EXPECT_EQ(1, call_count); + EXPECT_TRUE(last_result); +} + // Verifies occlusion state from server is applied to underlying window. TEST_F(WindowTreeClientTest, OcclusionStateFromServer) { struct {
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index 5775d95..7b59afbc 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -86,6 +86,7 @@ "animation/ink_drop_state.h", "animation/ink_drop_stub.h", "animation/ink_drop_util.h", + "animation/installable_ink_drop.h", "animation/scroll_animator.h", "animation/square_ink_drop_ripple.h", "background.h", @@ -297,6 +298,7 @@ "animation/ink_drop_state.cc", "animation/ink_drop_stub.cc", "animation/ink_drop_util.cc", + "animation/installable_ink_drop.cc", "animation/scroll_animator.cc", "animation/square_ink_drop_ripple.cc", "background.cc", @@ -992,6 +994,7 @@ "animation/ink_drop_impl_unittest.cc", "animation/ink_drop_ripple_unittest.cc", "animation/ink_drop_unittest.cc", + "animation/installable_ink_drop_unittest.cc", "animation/square_ink_drop_ripple_unittest.cc", "border_unittest.cc", "bubble/bubble_border_unittest.cc",
diff --git a/ui/views/animation/ink_drop_event_handler.cc b/ui/views/animation/ink_drop_event_handler.cc index 975728b..d9604eb 100644 --- a/ui/views/animation/ink_drop_event_handler.cc +++ b/ui/views/animation/ink_drop_event_handler.cc
@@ -16,9 +16,13 @@ : target_handler_( std::make_unique<ui::ScopedTargetHandler>(host_view, this)), host_view_(host_view), - delegate_(delegate) {} + delegate_(delegate) { + host_view_->AddObserver(this); +} -InkDropEventHandler::~InkDropEventHandler() = default; +InkDropEventHandler::~InkDropEventHandler() { + host_view_->RemoveObserver(this); +} void InkDropEventHandler::OnGestureEvent(ui::GestureEvent* event) { if (!host_view_->enabled() || !delegate_->SupportsGestureEvents()) @@ -86,4 +90,14 @@ } } +void InkDropEventHandler::OnViewFocused(View* observed_view) { + DCHECK_EQ(host_view_, observed_view); + delegate_->GetInkDrop()->SetFocused(true); +} + +void InkDropEventHandler::OnViewBlurred(View* observed_view) { + DCHECK_EQ(host_view_, observed_view); + delegate_->GetInkDrop()->SetFocused(false); +} + } // namespace views
diff --git a/ui/views/animation/ink_drop_event_handler.h b/ui/views/animation/ink_drop_event_handler.h index 2abb6365..af15f2e 100644 --- a/ui/views/animation/ink_drop_event_handler.h +++ b/ui/views/animation/ink_drop_event_handler.h
@@ -8,6 +8,7 @@ #include <memory> #include "ui/events/event_handler.h" +#include "ui/views/view_observer.h" #include "ui/views/views_export.h" namespace ui { @@ -21,7 +22,8 @@ enum class InkDropState; // This class handles ink-drop changes due to events on its host. -class VIEWS_EXPORT InkDropEventHandler : public ui::EventHandler { +class VIEWS_EXPORT InkDropEventHandler : public ui::EventHandler, + public ViewObserver { public: // Delegate class that allows InkDropEventHandler to be used with InkDrops // that are hosted in multiple ways. @@ -48,6 +50,10 @@ void OnGestureEvent(ui::GestureEvent* event) override; void OnMouseEvent(ui::MouseEvent* event) override; + // ViewObserver: + void OnViewFocused(View* observed_view) override; + void OnViewBlurred(View* observed_view) override; + // Allows |this| to handle all GestureEvents on |host_view_|. std::unique_ptr<ui::ScopedTargetHandler> target_handler_;
diff --git a/ui/views/animation/ink_drop_host_view.cc b/ui/views/animation/ink_drop_host_view.cc index 98abaa1c..967c513 100644 --- a/ui/views/animation/ink_drop_host_view.cc +++ b/ui/views/animation/ink_drop_host_view.cc
@@ -22,29 +22,6 @@ namespace views { -class InkDropHostView::InkDropViewObserver : public ViewObserver { - public: - explicit InkDropViewObserver(InkDropHostView* parent) : parent_(parent) { - parent_->AddObserver(this); - } - ~InkDropViewObserver() override { parent_->RemoveObserver(this); } - // ViewObserver: - void OnViewFocused(View* observed_view) override { - DCHECK_EQ(parent_, observed_view); - parent_->GetInkDrop()->SetFocused(true); - } - - void OnViewBlurred(View* observed_view) override { - DCHECK_EQ(parent_, observed_view); - parent_->GetInkDrop()->SetFocused(false); - } - - private: - InkDropHostView* const parent_; - - DISALLOW_COPY_AND_ASSIGN(InkDropViewObserver); -}; - InkDropHostView::InkDropHostViewEventHandlerDelegate:: InkDropHostViewEventHandlerDelegate(InkDropHostView* host_view) : host_view_(host_view) {} @@ -65,8 +42,7 @@ InkDropHostView::InkDropHostView() : ink_drop_event_handler_delegate_(this), - ink_drop_event_handler_(this, &ink_drop_event_handler_delegate_), - ink_drop_view_observer_(std::make_unique<InkDropViewObserver>(this)) {} + ink_drop_event_handler_(this, &ink_drop_event_handler_delegate_) {} InkDropHostView::~InkDropHostView() { // TODO(bruthig): Improve InkDropImpl to be safer about calling back to
diff --git a/ui/views/animation/ink_drop_host_view.h b/ui/views/animation/ink_drop_host_view.h index 6473e37..9bb24ba 100644 --- a/ui/views/animation/ink_drop_host_view.h +++ b/ui/views/animation/ink_drop_host_view.h
@@ -171,7 +171,11 @@ // Provides access to |ink_drop_|. Implements lazy initialization of // |ink_drop_| so as to avoid virtual method calls during construction since // subclasses should be able to call SetInkDropMode() during construction. - InkDrop* GetInkDrop(); + // + // WARNING: please don't override this; this is only virtual for the + // InstallableInkDrop refactor. TODO(crbug.com/931964): make non-virtual when + // this isn't necessary anymore. + virtual InkDrop* GetInkDrop(); // Returns the point of the |last_ripple_triggering_event_| if it was a // LocatedEvent, otherwise the center point of the local bounds is returned. @@ -188,7 +192,6 @@ static gfx::Size CalculateLargeInkDropSize(const gfx::Size& small_size); private: - class InkDropViewObserver; friend class test::InkDropHostViewTestApi; class InkDropHostViewEventHandlerDelegate @@ -222,9 +225,6 @@ InkDropHostViewEventHandlerDelegate ink_drop_event_handler_delegate_; InkDropEventHandler ink_drop_event_handler_; - // Used to observe changes to the host through the ViewObserver API. - const std::unique_ptr<InkDropViewObserver> ink_drop_view_observer_; - float ink_drop_visible_opacity_ = 0.175f; // TODO(pbos): Audit call sites to make sure highlight opacity is either
diff --git a/ui/views/animation/installable_ink_drop.cc b/ui/views/animation/installable_ink_drop.cc new file mode 100644 index 0000000..8e826ee4 --- /dev/null +++ b/ui/views/animation/installable_ink_drop.cc
@@ -0,0 +1,60 @@ +// 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/views/animation/installable_ink_drop.h" + +#include "base/logging.h" + +namespace views { + +const base::Feature kInstallableInkDropFeature{ + "InstallableInkDrop", base::FEATURE_DISABLED_BY_DEFAULT}; + +InstallableInkDrop::InstallableInkDrop() = default; + +InstallableInkDrop::~InstallableInkDrop() = default; + +void InstallableInkDrop::HostSizeChanged(const gfx::Size& new_size) {} + +InkDropState InstallableInkDrop::GetTargetInkDropState() const { + return current_state_; +} + +void InstallableInkDrop::AnimateToState(InkDropState ink_drop_state) { + current_state_ = ink_drop_state; +} + +void InstallableInkDrop::SetHoverHighlightFadeDurationMs(int duration_ms) { + NOTREACHED(); +} + +void InstallableInkDrop::UseDefaultHoverHighlightFadeDuration() { + NOTREACHED(); +} + +void InstallableInkDrop::SnapToActivated() { + NOTREACHED(); +} + +void InstallableInkDrop::SnapToHidden() { + NOTREACHED(); +} + +void InstallableInkDrop::SetHovered(bool is_hovered) {} + +void InstallableInkDrop::SetFocused(bool is_focused) {} + +bool InstallableInkDrop::IsHighlightFadingInOrVisible() const { + return false; +} + +void InstallableInkDrop::SetShowHighlightOnHover(bool show_highlight_on_hover) { + NOTREACHED(); +} + +void InstallableInkDrop::SetShowHighlightOnFocus(bool show_highlight_on_focus) { + NOTREACHED(); +} + +} // namespace views
diff --git a/ui/views/animation/installable_ink_drop.h b/ui/views/animation/installable_ink_drop.h new file mode 100644 index 0000000..0670195 --- /dev/null +++ b/ui/views/animation/installable_ink_drop.h
@@ -0,0 +1,47 @@ +// 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_VIEWS_ANIMATION_INSTALLABLE_INK_DROP_H_ +#define UI_VIEWS_ANIMATION_INSTALLABLE_INK_DROP_H_ + +#include "base/feature_list.h" +#include "ui/gfx/geometry/size.h" +#include "ui/views/animation/ink_drop.h" +#include "ui/views/animation/ink_drop_state.h" +#include "ui/views/views_export.h" + +namespace views { + +extern const VIEWS_EXPORT base::Feature kInstallableInkDropFeature; + +// Stub for future InkDrop implementation that will be installable on any View +// without needing InkDropHostView. This is currently non-functional and fails +// on some method calls. TODO(crbug.com/931964): implement the necessary parts +// of the API and remove the rest from the InkDrop interface. +class VIEWS_EXPORT InstallableInkDrop : public InkDrop { + public: + InstallableInkDrop(); + ~InstallableInkDrop() override; + + // InkDrop: + void HostSizeChanged(const gfx::Size& new_size) override; + InkDropState GetTargetInkDropState() const override; + void AnimateToState(InkDropState ink_drop_state) override; + void SetHoverHighlightFadeDurationMs(int duration_ms) override; + void UseDefaultHoverHighlightFadeDuration() override; + void SnapToActivated() override; + void SnapToHidden() override; + void SetHovered(bool is_hovered) override; + void SetFocused(bool is_focused) override; + bool IsHighlightFadingInOrVisible() const override; + void SetShowHighlightOnHover(bool show_highlight_on_hover) override; + void SetShowHighlightOnFocus(bool show_highlight_on_focus) override; + + private: + InkDropState current_state_ = InkDropState::HIDDEN; +}; + +} // namespace views + +#endif // UI_VIEWS_ANIMATION_INSTALLABLE_INK_DROP_H_
diff --git a/ui/views/animation/installable_ink_drop_unittest.cc b/ui/views/animation/installable_ink_drop_unittest.cc new file mode 100644 index 0000000..d75acae --- /dev/null +++ b/ui/views/animation/installable_ink_drop_unittest.cc
@@ -0,0 +1,23 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/animation/installable_ink_drop.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/views/animation/ink_drop_state.h" + +namespace views { + +TEST(InstallableInkDropTest, UpdatesState) { + InstallableInkDrop installable_ink_drop; + + // Initial state should be HIDDEN. + EXPECT_EQ(installable_ink_drop.GetTargetInkDropState(), InkDropState::HIDDEN); + + installable_ink_drop.AnimateToState(InkDropState::ACTIVATED); + EXPECT_EQ(installable_ink_drop.GetTargetInkDropState(), + InkDropState::ACTIVATED); +} + +} // namespace views
diff --git a/ui/views/controls/native/native_view_host.cc b/ui/views/controls/native/native_view_host.cc index 86c7b558..f8c2e3e 100644 --- a/ui/views/controls/native/native_view_host.cc +++ b/ui/views/controls/native/native_view_host.cc
@@ -68,6 +68,10 @@ native_wrapper_->SetHitTestTopInset(top_inset); } +int NativeViewHost::GetHitTestTopInset() const { + return native_wrapper_->GetHitTestTopInset(); +} + void NativeViewHost::SetNativeViewSize(const gfx::Size& size) { if (native_view_size_ == size) return;
diff --git a/ui/views/controls/native/native_view_host.h b/ui/views/controls/native/native_view_host.h index 5923cc46..a370cee 100644 --- a/ui/views/controls/native/native_view_host.h +++ b/ui/views/controls/native/native_view_host.h
@@ -61,6 +61,7 @@ // targeted. This will be used when another view is covering there // temporarily, like the immersive fullscreen mode of ChromeOS. void SetHitTestTopInset(int top_inset); + int GetHitTestTopInset() const; // Sets the size for the NativeView that may or may not match the size of this // View when it is being captured. If the size does not match, scaling will
diff --git a/ui/views/controls/native/native_view_host_aura.cc b/ui/views/controls/native/native_view_host_aura.cc index e603d41..293814b0 100644 --- a/ui/views/controls/native/native_view_host_aura.cc +++ b/ui/views/controls/native/native_view_host_aura.cc
@@ -186,6 +186,10 @@ new gfx::Rect(host_->ConvertRectToWidget(gfx::Rect(x, y, w, h)))); } +int NativeViewHostAura::GetHitTestTopInset() const { + return top_inset_; +} + bool NativeViewHostAura::HasInstalledClip() { return !!clip_rect_; }
diff --git a/ui/views/controls/native/native_view_host_aura.h b/ui/views/controls/native/native_view_host_aura.h index ea29802..26381af 100644 --- a/ui/views/controls/native/native_view_host_aura.h +++ b/ui/views/controls/native/native_view_host_aura.h
@@ -35,6 +35,7 @@ void RemovedFromWidget() override; bool SetCustomMask(std::unique_ptr<ui::LayerOwner> mask) override; void SetHitTestTopInset(int top_inset) override; + int GetHitTestTopInset() const override; void InstallClip(int x, int y, int w, int h) override; bool HasInstalledClip() override; void UninstallClip() override;
diff --git a/ui/views/controls/native/native_view_host_mac.h b/ui/views/controls/native/native_view_host_mac.h index cfcd98f..c9945f76 100644 --- a/ui/views/controls/native/native_view_host_mac.h +++ b/ui/views/controls/native/native_view_host_mac.h
@@ -42,6 +42,7 @@ void RemovedFromWidget() override; bool SetCustomMask(std::unique_ptr<ui::LayerOwner> mask) override; void SetHitTestTopInset(int top_inset) override; + int GetHitTestTopInset() const override; void InstallClip(int x, int y, int w, int h) override; bool HasInstalledClip() override; void UninstallClip() override;
diff --git a/ui/views/controls/native/native_view_host_mac.mm b/ui/views/controls/native/native_view_host_mac.mm index 6fda67ff..b4c366f 100644 --- a/ui/views/controls/native/native_view_host_mac.mm +++ b/ui/views/controls/native/native_view_host_mac.mm
@@ -191,6 +191,11 @@ NOTIMPLEMENTED(); } +int NativeViewHostMac::GetHitTestTopInset() const { + NOTIMPLEMENTED(); + return 0; +} + void NativeViewHostMac::InstallClip(int x, int y, int w, int h) { NOTIMPLEMENTED(); }
diff --git a/ui/views/controls/native/native_view_host_wrapper.h b/ui/views/controls/native/native_view_host_wrapper.h index d43cc71..f4208674 100644 --- a/ui/views/controls/native/native_view_host_wrapper.h +++ b/ui/views/controls/native/native_view_host_wrapper.h
@@ -49,6 +49,7 @@ // Sets the height of the top region where gfx::NativeView shouldn't be // targeted. virtual void SetHitTestTopInset(int top_inset) = 0; + virtual int GetHitTestTopInset() const = 0; // Installs a clip on the gfx::NativeView. These values are in the coordinate // space of the Widget, so if this method is called from ShowWidget
diff --git a/ui/views/mus/mus_client.cc b/ui/views/mus/mus_client.cc index ad63c545..0529adb8267 100644 --- a/ui/views/mus/mus_client.cc +++ b/ui/views/mus/mus_client.cc
@@ -116,10 +116,11 @@ } } - ViewsDelegate::GetInstance()->set_native_widget_factory( - base::Bind(&MusClient::CreateNativeWidget, base::Unretained(this))); - ViewsDelegate::GetInstance()->set_desktop_window_tree_host_factory(base::Bind( - &MusClient::CreateDesktopWindowTreeHost, base::Unretained(this))); + ViewsDelegate::GetInstance()->set_native_widget_factory(base::BindRepeating( + &MusClient::CreateNativeWidget, base::Unretained(this))); + ViewsDelegate::GetInstance()->set_desktop_window_tree_host_factory( + base::BindRepeating(&MusClient::CreateDesktopWindowTreeHost, + base::Unretained(this))); } MusClient::~MusClient() {
diff --git a/ui/views/views_delegate.h b/ui/views/views_delegate.h index 1a66e7d..41728e3 100644 --- a/ui/views/views_delegate.h +++ b/ui/views/views_delegate.h
@@ -57,11 +57,11 @@ class VIEWS_EXPORT ViewsDelegate { public: using NativeWidgetFactory = - base::Callback<NativeWidget*(const Widget::InitParams&, - internal::NativeWidgetDelegate*)>; + base::RepeatingCallback<NativeWidget*(const Widget::InitParams&, + internal::NativeWidgetDelegate*)>; #if defined(USE_AURA) using DesktopWindowTreeHostFactory = - base::Callback<std::unique_ptr<DesktopWindowTreeHost>( + base::RepeatingCallback<std::unique_ptr<DesktopWindowTreeHost>( const Widget::InitParams&, internal::NativeWidgetDelegate*, DesktopNativeWidgetAura*)>;
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js b/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js index bddc345..d050d08 100644 --- a/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js +++ b/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js
@@ -18,7 +18,8 @@ * controlledSettingRecommendedMatches: string, * controlledSettingRecommendedDiffers: string, * controlledSettingShared: (string|undefined), - * controlledSettingOwner: (string|undefined), + * controlledSettingWithOwner: string, + * controlledSettingNoOwner: string, * }} */ // eslint-disable-next-line no-var @@ -124,7 +125,9 @@ case CrPolicyIndicatorType.PRIMARY_USER: return CrPolicyStrings.controlledSettingShared.replace('$1', name); case CrPolicyIndicatorType.OWNER: - return CrPolicyStrings.controlledSettingOwner.replace('$1', name); + return name.length > 0 ? + CrPolicyStrings.controlledSettingWithOwner.replace('$1', name) : + CrPolicyStrings.controlledSettingNoOwner; case CrPolicyIndicatorType.USER_POLICY: case CrPolicyIndicatorType.DEVICE_POLICY: return CrPolicyStrings.controlledSettingPolicy;