diff --git a/DEPS b/DEPS index 23f109c..369df7b 100644 --- a/DEPS +++ b/DEPS
@@ -235,15 +235,15 @@ # 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': 'd62b7ef97056a2378d6859f90302bcbf37c6c702', + 'skia_revision': '0edd2c33d31e32aab7b29ede98005c2134d51abc', # 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': 'a6d90b3463e708e105a15b92ec324bd96840df3b', + 'v8_revision': '67b2bc000474e188455242e7a40739bea941e7a3', # 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': 'ca127443c8194b75e123779e5f0a96c9041bbbbf', + 'angle_revision': '5ad7ae4a0266752e6ebefd06a12e230dcf49d691', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -251,7 +251,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'b5c7d882305dcafc458ec7cd24c7af744a7f191f', + 'pdfium_revision': 'fc24fe55eb315ae2329ec8f2ec6cfd2aed4b9644', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -282,7 +282,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. - 'freetype_revision': '8ef8072ba151dc06214ee70985a7fb03ebc2932f', + 'freetype_revision': 'fde91ab8f19d1f789720afc67e0414a0244490d3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -310,7 +310,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': 'a5254a82d021ffe6e27080319e6329d96a2840cd', + 'devtools_frontend_revision': 'e03b7a0f6f030ddd74cee1500c60bec727699b00', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -1010,7 +1010,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '2b1165022939527fc91735ceb426f53aae89a4d0', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '4d016f6ec38ac3d77b7b90c4fdbfd86c0a11a7fc', 'condition': 'checkout_chromeos', }, @@ -1416,7 +1416,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '5f0b3b9c3082422bc98513edbfddd802c5ff0926', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'bf402916b4cc2977c63388f3a1959e38e30611b7', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1598,7 +1598,7 @@ 'src/third_party/usrsctp/usrsctplib': Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '62d7d0c928c9a040dce96aa2f16c00e7e67d59cb', - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@73210a615e951d73667a07b47559adf33e00f5c4', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@9a7c766f6d3b3aed69dade8df6bbcded52485ed4', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'e0216a5484c8345f7d792fa16fad77ac63d89a70', @@ -1634,7 +1634,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '9ec0bd5501c6a35eb365dc49be7618a763135a10', 'src/third_party/webgpu-cts/src': - Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '6e1b3a254775ffbf08fbe8e90fbc3277e780979f', + Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'fac8e0dc92ee771360ff5e57c167edbe8e615ad3', 'src/third_party/webrtc': Var('webrtc_git') + '/src.git' + '@' + '50c25ac07871bc327fb90f8d08a2dcd66eb9b661', @@ -1695,7 +1695,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@46d8d67e001b687cd1048ea9dad5cc4c2fea32a8', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@1dce7b5e5522aaa1fca767e581fb397f2ab8eec0', 'condition': 'checkout_src_internal', }, @@ -1714,7 +1714,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'BOOJZHSadjiyYxbTgM5BrURZMv0NoTd_OB5KgSv8s7gC', + 'version': 'mEWdeEJ6TG9Uo053Wm-UUqRHjG143FCjQL793DjZ6vEC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1725,7 +1725,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'yzoVZKQtJakM3rz526vxPaWC8KfMgRQFrdg8Xs8zQVIC', + 'version': 'a9IoIspNSrr3OcKG8NTMAaUP9xx58CSanK_oG02GsZsC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/browser/aw_settings.cc b/android_webview/browser/aw_settings.cc index 2b93c08..1c45e157 100644 --- a/android_webview/browser/aw_settings.cc +++ b/android_webview/browser/aw_settings.cc
@@ -405,9 +405,9 @@ web_prefs->plugins_enabled = false; + // TODO(enne): Remove this pref, and clean up Android settings. web_prefs->application_cache_enabled = - Java_AwSettings_getAppCacheEnabledLocked(env, obj) && - content::StoragePartition::IsAppCacheEnabled(); + Java_AwSettings_getAppCacheEnabledLocked(env, obj); web_prefs->local_storage_enabled = Java_AwSettings_getDomStorageEnabledLocked(env, obj);
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 45c6761..a5747df 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -2994,6 +2994,7 @@ "//testing/gtest", "//third_party/blink/public:blink_headers", "//ui/display:display_manager_test_api", + "//ui/lottie", ] deps = [ "//ash",
diff --git a/ash/app_list/BUILD.gn b/ash/app_list/BUILD.gn index 85bfb38..ad9198e 100644 --- a/ash/app_list/BUILD.gn +++ b/ash/app_list/BUILD.gn
@@ -245,6 +245,7 @@ "views/app_drag_icon_proxy_unittest.cc", "views/app_list_bubble_search_page_unittest.cc", "views/app_list_bubble_view_unittest.cc", + "views/app_list_folder_view_unittest.cc", "views/app_list_main_view_unittest.cc", "views/app_list_menu_model_adapter_unittest.cc", "views/app_list_view_unittest.cc",
diff --git a/ash/app_list/views/app_list_folder_view.cc b/ash/app_list/views/app_list_folder_view.cc index 23241336d..c23fe36 100644 --- a/ash/app_list/views/app_list_folder_view.cc +++ b/ash/app_list/views/app_list_folder_view.cc
@@ -512,6 +512,33 @@ base::OnceClosure completion_callback_; }; +// ScrollViewWithMaxHeight limits its preferred size to a maximum height that +// shows 4 apps grid rows. +class ScrollViewWithMaxHeight : public views::ScrollView { + public: + explicit ScrollViewWithMaxHeight(AppListFolderView* folder_view) + : views::ScrollView(views::ScrollView::ScrollWithLayers::kEnabled), + folder_view_(folder_view) {} + ScrollViewWithMaxHeight(const ScrollViewWithMaxHeight&) = delete; + ScrollViewWithMaxHeight& operator=(const ScrollViewWithMaxHeight&) = delete; + ~ScrollViewWithMaxHeight() override = default; + + // views::View: + gfx::Size CalculatePreferredSize() const override { + gfx::Size size = views::ScrollView::CalculatePreferredSize(); + const int tile_height = + folder_view_->items_grid_view()->GetTotalTileSize().height(); + // Show a maximum of 4 full rows, plus a little bit of the next row to make + // it obvious the view can scroll. + const int max_height = (tile_height * 4) + (tile_height / 4); + size.set_height(std::min(size.height(), max_height)); + return size; + } + + private: + AppListFolderView* const folder_view_; +}; + } // namespace AppListFolderView::AppListFolderView(AppListFolderController* folder_controller, @@ -566,7 +593,7 @@ items_grid_view_->Init(); items_grid_view->SetMaxColumnsAndRows( kMaxFolderColumns, - /*max_rows_in_first_page=*/kMaxPagedFolderRows, + /*max_rows_on_first_page=*/kMaxPagedFolderRows, /*max_rows=*/kMaxPagedFolderRows); items_grid_view->SetFixedTilePadding(kTileSpacingInFolder / 2, kTileSpacingInFolder / 2); @@ -591,9 +618,8 @@ void AppListFolderView::CreateScrollableAppsGrid() { // The top part of the folder contents is a scrollable apps grid. - scroll_view_ = - contents_container_->AddChildView(std::make_unique<views::ScrollView>( - views::ScrollView::ScrollWithLayers::kEnabled)); + scroll_view_ = contents_container_->AddChildView( + std::make_unique<ScrollViewWithMaxHeight>(this)); scroll_view_->ClipHeightTo(0, std::numeric_limits<int>::max()); scroll_view_->SetDrawOverflowIndicator(false); // Don't paint a background. The folder already has one. @@ -628,13 +654,14 @@ kTileSpacingInFolder / 2); scroll_view_->SetContents(std::move(scroll_contents)); - // The scroll view consumes all available vertical space in its parent. This - // means that when the grid has a large number of apps, the scroll view height - // is limited to the height of this folder view minus the header height. + // In the common case, the parent view is large and the folder has a small + // number of apps, so the scroll view's size will be limited by the apps grid + // view's preferred size. However, if the parent view is small, the scroll + // view will scale down, so there is enough space for the header view. scroll_view_->SetProperty( views::kFlexBehaviorKey, views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero, - views::MaximumFlexSizeRule::kScaleToMaximum)); + views::MaximumFlexSizeRule::kPreferred)); folder_header_view_ = contents_container_->AddChildView( std::make_unique<FolderHeaderView>(this));
diff --git a/ash/app_list/views/app_list_folder_view_unittest.cc b/ash/app_list/views/app_list_folder_view_unittest.cc new file mode 100644 index 0000000..00ce017 --- /dev/null +++ b/ash/app_list/views/app_list_folder_view_unittest.cc
@@ -0,0 +1,63 @@ +// Copyright 2021 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/app_list/views/app_list_folder_view.h" + +#include <utility> + +#include "ash/app_list/app_list_controller_impl.h" +#include "ash/app_list/model/app_list_test_model.h" +#include "ash/app_list/test/app_list_test_helper.h" +#include "ash/app_list/views/scrollable_apps_grid_view.h" +#include "ash/constants/ash_features.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "base/test/scoped_feature_list.h" +#include "ui/views/controls/scroll_view.h" + +namespace ash { + +class AppListFolderViewProductivityLauncherTest : public AshTestBase { + public: + AppListFolderViewProductivityLauncherTest() = default; + ~AppListFolderViewProductivityLauncherTest() override = default; + + // testing::Test: + void SetUp() override { + AshTestBase::SetUp(); + + auto model = std::make_unique<test::AppListTestModel>(); + app_list_test_model_ = model.get(); + Shell::Get()->app_list_controller()->SetAppListModelForTest( + std::move(model)); + } + + base::test::ScopedFeatureList feature_list_{features::kProductivityLauncher}; + test::AppListTestModel* app_list_test_model_ = nullptr; +}; + +TEST_F(AppListFolderViewProductivityLauncherTest, + ScrollViewSizeIsCappedForLargeFolders) { + // Create a large number of apps, more than a 4 rows. + app_list_test_model_->CreateAndPopulateFolderWithApps(30); + + // Open the app list and open the folder. + auto* helper = GetAppListTestHelper(); + helper->ShowAppList(); + auto* apps_grid_view = helper->GetScrollableAppsGridView(); + views::View* folder_item = apps_grid_view->GetItemViewAt(0); + SimulateMouseClickAt(GetEventGenerator(), folder_item); + ASSERT_TRUE(helper->IsInFolderView()); + + auto* folder_view = helper->GetBubbleFolderView(); + auto* scroll_view = folder_view->scroll_view_for_test(); + const int tile_height = + folder_view->items_grid_view()->GetTotalTileSize().height(); + + // The scroll view has space for at least 4 full rows, but not 5. + EXPECT_GE(scroll_view->height(), tile_height * 4); + EXPECT_LT(scroll_view->height(), tile_height * 5); +} + +} // namespace ash
diff --git a/ash/app_list/views/folder_header_view.cc b/ash/app_list/views/folder_header_view.cc index 6330e2b0..d0197b7 100644 --- a/ash/app_list/views/folder_header_view.cc +++ b/ash/app_list/views/folder_header_view.cc
@@ -39,9 +39,10 @@ // The max folder name length. constexpr int kMaxFolderNameChars = 28; -// The folder header dimensions: +// Folder header dimensions. The max header width is based on the width of a +// folder with 2 items. constexpr int kMinFolderHeaderWidth = 24; -constexpr int kMaxFolderHeaderWidth = 200; +constexpr int kMaxFolderHeaderWidth = 168; constexpr int kFolderHeaderHeight = 32; // The min width of folder name - ensures the folder name is easily tappable.
diff --git a/ash/app_list/views/scrollable_apps_grid_view.cc b/ash/app_list/views/scrollable_apps_grid_view.cc index 46a47e3..b85f141b 100644 --- a/ash/app_list/views/scrollable_apps_grid_view.cc +++ b/ash/app_list/views/scrollable_apps_grid_view.cc
@@ -126,8 +126,9 @@ const bool is_last_row_full = (items % cols() == 0); const int rows = is_last_row_full ? items / cols() : items / cols() + 1; gfx::Size tile_size = GetTotalTileSize(); - gfx::Size grid_size(tile_size.width() * cols(), tile_size.height() * rows); - return grid_size; + gfx::Rect grid(tile_size.width() * cols(), tile_size.height() * rows); + grid.Inset(-GetTilePadding()); + return grid.size(); } int ScrollableAppsGridView::GetPaddingBetweenPages() const {
diff --git a/ash/app_list/views/scrollable_apps_grid_view_unittest.cc b/ash/app_list/views/scrollable_apps_grid_view_unittest.cc index b01ffe346..12024b3 100644 --- a/ash/app_list/views/scrollable_apps_grid_view_unittest.cc +++ b/ash/app_list/views/scrollable_apps_grid_view_unittest.cc
@@ -23,6 +23,7 @@ #include "ash/app_list/views/apps_grid_view_test_api.h" #include "ash/app_list/views/search_box_view.h" #include "ash/constants/ash_features.h" +#include "ash/public/cpp/app_list/app_list_config.h" #include "ash/public/cpp/shelf_item_delegate.h" #include "ash/public/cpp/shelf_model.h" #include "ash/public/cpp/test/test_shelf_item_delegate.h" @@ -169,10 +170,10 @@ ShowAppList(); ScrollableAppsGridView* view = GetScrollableAppsGridView(); - const gfx::Size tile_size = view->GetTotalTileSize(); + const int tile_height = view->app_list_config()->grid_tile_height(); const gfx::Size grid_size = view->GetTileGridSize(); // The layout is one tile tall because it has only one row. - EXPECT_EQ(grid_size.height(), tile_size.height()); + EXPECT_EQ(grid_size.height(), tile_height); } TEST_F(ScrollableAppsGridViewTest, ClickOnApp) { @@ -500,6 +501,30 @@ EXPECT_LT(apps_grid_view_->height(), height_before_removing); } +TEST_F(ScrollableAppsGridViewTest, SmallFolderHasCorrectWidth) { + CreateAndPopulateFolderWithApps(2); + ShowAppList(); + + // Enter the folder view. + auto* generator = GetEventGenerator(); + SimulateMouseClickAt(generator, apps_grid_view_->GetItemViewAt(0)); + ASSERT_TRUE(GetAppListTestHelper()->IsInFolderView()); + + auto* folder_view = GetAppListTestHelper()->GetBubbleFolderView(); + auto* items_grid_view = folder_view->items_grid_view(); + const int tile_width = items_grid_view->app_list_config()->grid_tile_width(); + + // Spec calls for 8 dips of padding at edges and between tiles. + EXPECT_EQ(folder_view->width(), 8 + tile_width + 8 + tile_width + 8); + + // The leftmost item is flush to the left of the grid. + EXPECT_EQ(items_grid_view->GetItemViewAt(0)->bounds().x(), 0); + + // The rightmost item is flush to the right of the grid. + EXPECT_EQ(items_grid_view->GetItemViewAt(1)->bounds().right(), + items_grid_view->GetLocalBounds().right()); +} + TEST_F(ScrollableAppsGridViewTest, DragItemToReorderInFolderRecordsHistogram) { base::HistogramTester histogram_tester; // Create a folder with 3 apps.
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 3d1f446..04b9ba3 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -262,7 +262,7 @@ // Enables compositing-based throttling to throttle appropriate frame sinks that // do not need to be refreshed at high fps. const base::Feature kCompositingBasedThrottling{ - "CompositingBasedThrottling", base::FEATURE_DISABLED_BY_DEFAULT}; + "CompositingBasedThrottling", base::FEATURE_ENABLED_BY_DEFAULT}; // Enables contextual nudges for gesture education. const base::Feature kContextualNudges{"ContextualNudges",
diff --git a/ash/public/cpp/resources/ash_public_unscaled_resources.grd b/ash/public/cpp/resources/ash_public_unscaled_resources.grd index 1b1e3a22..dce2413 100644 --- a/ash/public/cpp/resources/ash_public_unscaled_resources.grd +++ b/ash/public/cpp/resources/ash_public_unscaled_resources.grd
@@ -17,12 +17,14 @@ <!-- CrOS internal apps images --> <include name="IDR_SHORTCUT_VIEWER_LOGO_192" file="unscaled_resources/shortcut_viewer_logo_192.png" type="BINDATA" /> <include name="IDR_SETTINGS_LOGO_192" file="unscaled_resources/settings_logo_192.png" type="BINDATA" /> - <include name="IDR_PHONE_HUB_ONBOARDING_IMAGE" file="unscaled_resources/phone_hub_onboarding_image.png" type="BINDATA" /> - <include name="IDR_PHONE_HUB_CONNECTING_IMAGE" file="unscaled_resources/phone_hub_connecting_image.png" type="BINDATA" /> - <include name="IDR_PHONE_HUB_ERROR_STATE_IMAGE" file="unscaled_resources/phone_hub_error_state_image.png" type="BINDATA" /> <include name="IDR_OS_URL_HANDLER_APP_ICONS_48_PNG" file="unscaled_resources/os_url_handler_app_icon_48.png" type="BINDATA" /> <include name="IDR_OS_URL_HANDLER_APP_ICONS_128_PNG" file="unscaled_resources/os_url_handler_app_icon_128.png" type="BINDATA" /> <include name="IDR_OS_URL_HANDLER_APP_ICONS_192_PNG" file="unscaled_resources/os_url_handler_app_icon_192.png" type="BINDATA" /> </includes> + <structures> + <structure type="lottie" name="IDR_PHONE_HUB_ONBOARDING_IMAGE" file="unscaled_resources/phone_hub_onboarding_image.json" compress="gzip" /> + <structure type="lottie" name="IDR_PHONE_HUB_CONNECTING_IMAGE" file="unscaled_resources/phone_hub_connecting_image.json" compress="gzip" /> + <structure type="lottie" name="IDR_PHONE_HUB_ERROR_STATE_IMAGE" file="unscaled_resources/phone_hub_error_state_image.json" compress="gzip" /> + </structures> </release> </grit>
diff --git a/ash/public/cpp/resources/unscaled_resources/phone_hub_connecting_image.json b/ash/public/cpp/resources/unscaled_resources/phone_hub_connecting_image.json new file mode 100644 index 0000000..74d7289 --- /dev/null +++ b/ash/public/cpp/resources/unscaled_resources/phone_hub_connecting_image.json
@@ -0,0 +1 @@ +{"v":"5.6.6","ip":0,"op":1,"fr":60,"w":256,"h":256,"layers":[{"ind":1129,"nm":"surface4614","ao":0,"ip":0,"op":60,"st":0,"ty":4,"ks":{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[133.33,133.33]},"sk":{"k":0},"sa":{"k":0}},"shapes":[{"ty":"gr","hd":false,"nm":"surface4614","it":[{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-1.05],[4.13,-0.56],[0,0],[-0.7,-0.41],[0,4.69],[0.14,0.68],[0.16,0.08],[0,0],[0.62,0.12]],"o":[[0.35,0.93],[0,4.29],[0,0],[0.52,0.62],[4.27,-1.29],[0,-0.72],[-0.16,-0.1],[0,0],[-0.57,-0.29],[0,0]],"v":[[131.04,80.09],[131.59,83.08],[124.27,91.47],[124.28,91.47],[126.12,93.02],[133.5,83.08],[133.29,80.98],[132.82,80.7],[132.82,80.7],[131.04,80.09]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[1,1,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[-3.27,-0.35],[0,0],[0.51,2.59]],"o":[[0,0],[0,0],[0.7,3.21],[0,0],[-2.56,-0.13],[0,0]],"v":[[59.58,79.42],[57.73,79.92],[57.73,79.92],[64.36,85.89],[64.86,84.02],[59.58,79.42]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[1,1,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.18,0.48],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[-0.52,0.01],[0,0],[0,0],[0,0]],"v":[[21.26,74.22],[33.82,117.03],[77.22,116.51],[77.25,118.96],[32.92,119.49],[32.92,119.49],[31.76,118.69],[31.73,118.61],[18.91,74.91]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-2.43,-4.46],[5.09,-2.76],[0.71,-0.22]],"o":[[4.69,-1.47],[2.76,5.09],[-0.65,0.36],[0,0]],"v":[[26.14,92.29],[38.48,97.28],[34.28,111.5],[32.22,112.36]],"c":false}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.97,0.51,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.25,-0.1],[-2.46,4.23],[5.14,2.59],[0,0],[1.36,0.08],[0.76,-0.12],[0,0],[0,0]],"o":[[0.23,0.12],[4.56,1.77],[2.94,-5.04],[0,0],[-1.21,-0.61],[-0.79,-0.05],[0,0],[0,0],[0,0]],"v":[[142.54,104.7],[143.27,105.03],[155.56,100.75],[151.41,86.7],[151.41,86.71],[147.5,85.67],[145.17,85.79],[142.69,85.95],[142.54,85.95]],"c":false}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-5.73],[-5.73,0],[0,5.73],[5.73,0]],"o":[[-5.73,0],[0,5.73],[5.73,0],[0,-5.73],[0,0]],"v":[[123.12,72.7],[112.73,83.08],[123.12,93.46],[133.5,83.08],[123.12,72.7]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-4.68],[4.68,0],[0,4.68],[-4.68,0]],"o":[[4.68,0],[0,4.68],[-4.68,0],[0,-4.68],[0,0]],"v":[[123.12,74.61],[131.59,83.08],[123.12,91.55],[114.64,83.08],[123.12,74.61]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.02,-0.27],[0.27,-0.04],[0,0],[0,0],[0.02,0.27],[-0.27,0.04],[0,0]],"o":[[0.27,0],[0.02,0.27],[0,0],[0,0],[-0.27,0],[-0.02,-0.27],[0,0],[0,0]],"v":[[158.7,68.54],[159.21,69.03],[158.77,69.59],[158.7,69.59],[153.78,69.59],[153.26,69.1],[153.71,68.55],[153.78,68.54]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0.35],[0.35,0],[0,-0.35],[-0.35,0]],"o":[[0.35,0],[0,-0.35],[-0.35,0],[0,0.35],[0,0]],"v":[[151.06,69.7],[151.7,69.07],[151.06,68.43],[150.43,69.07],[151.06,69.7]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[1.62,1.45],[0,0],[0,0],[0.32,0.26],[0.25,0.13],[1.72,-3.45],[-3.45,-1.72],[-0.28,-0.1],[0,0],[-0.05,0],[0,0],[-1.22,-1.83],[0,0],[0,0],[-0.48,-0.61],[-1.28,-0.61]],"o":[[-2.16,0.08],[0,0],[0,0],[-0.32,-0.27],[-0.25,-0.15],[-3.47,-1.75],[-1.75,3.47],[0.28,0.12],[0,0],[0,0],[0,0],[2.16,0.46],[0,0],[0,0],[0.36,0.69],[0.91,1.09],[0,0]],"v":[[142.53,85.92],[136.65,83.82],[134.55,81.94],[134.55,81.95],[133.59,81.16],[132.82,80.7],[123.39,83.82],[126.51,93.25],[127.32,93.6],[127.35,93.6],[128.54,93.91],[131.3,94.49],[136.57,98.06],[137.94,100.14],[137.95,100.14],[139.21,102.09],[142.53,104.68]],"c":false}}},{"ty":"fl","o":{"k":30},"c":{"k":[0.13,0.44,0.91,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0.05,-0.18],[-0.14,-0.13],[0,0],[-0.1,0.41],[0,0],[0,0],[0.13,0.13],[0.18,-0.05]],"o":[[0,0],[-0.19,0.05],[-0.05,0.19],[0,0],[0.3,0.28],[0,0],[0,0],[0.05,-0.19],[-0.14,-0.14],[0,0]],"v":[[65.68,77.76],[44.21,83.59],[43.83,83.96],[43.98,84.48],[59.78,100.14],[60.66,99.89],[66.34,78.42],[66.34,78.42],[66.2,77.9],[65.68,77.76]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[1,0.73,0,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.54,0.53],[0,0.75],[0.54,0.53],[0.76,-0.01],[0,-1.54],[-1.54,-0.03]],"o":[[0.76,0.01],[0.54,-0.53],[0,-0.76],[-0.54,-0.53],[-1.54,0.03],[0,1.54],[0,0]],"v":[[102.69,73.05],[104.71,72.24],[105.55,70.23],[104.71,68.23],[102.69,67.42],[99.92,70.23],[102.69,73.05]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.2,0.66,0.33,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.64,-4.15],[-4.14,0.64],[0,0],[0.64,4.15],[4.15,-0.64]],"o":[[0,0],[-4.16,0.64],[0.64,4.15],[0,0],[4.16,-0.64],[-0.64,-4.16],[0,0]],"v":[[79.4,68.43],[64.02,70.81],[57.64,79.48],[66.31,85.85],[81.7,83.47],[88.07,74.8],[79.4,68.43]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[3.12,-0.48],[0,0],[0.48,3.11],[-3.12,0.48],[0,0],[-0.48,-3.12]],"o":[[0.48,3.11],[0,0],[-3.1,0.48],[-0.48,-3.11],[0,0],[3.11,-0.48],[0,0]],"v":[[86.18,75.09],[81.41,81.58],[66.02,83.96],[59.53,79.19],[64.31,72.7],[79.7,70.32],[86.18,75.09]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[1,0.17,0.15,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0.95],[0,0],[-0.95,0],[0,0],[0,-0.95],[0,0],[0.94,0]],"o":[[0,0],[-0.95,0],[0,0],[0,-0.95],[0,0],[0.95,0],[0,0],[0,0.96],[0,0]],"v":[[166.79,118.11],[144.28,118.11],[142.56,116.39],[142.56,67.72],[144.28,66],[166.79,66],[168.52,67.72],[168.52,116.36],[166.79,118.11]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.82,0.89,0.99,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]}]}],"meta":{"g":"LF SVG to Lottie"}}
diff --git a/ash/public/cpp/resources/unscaled_resources/phone_hub_connecting_image.png b/ash/public/cpp/resources/unscaled_resources/phone_hub_connecting_image.png deleted file mode 100644 index de1f0f73..0000000 --- a/ash/public/cpp/resources/unscaled_resources/phone_hub_connecting_image.png +++ /dev/null Binary files differ
diff --git a/ash/public/cpp/resources/unscaled_resources/phone_hub_error_state_image.json b/ash/public/cpp/resources/unscaled_resources/phone_hub_error_state_image.json new file mode 100644 index 0000000..bbcf82c --- /dev/null +++ b/ash/public/cpp/resources/unscaled_resources/phone_hub_error_state_image.json
@@ -0,0 +1 @@ +{"v":"5.6.6","ip":0,"op":1,"fr":60,"w":256,"h":256,"layers":[{"ind":1117,"nm":"surface4584","ao":0,"ip":0,"op":60,"st":0,"ty":4,"ks":{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[133.33,133.33]},"sk":{"k":0},"sa":{"k":0}},"shapes":[{"ty":"gr","hd":false,"nm":"surface4584","it":[{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.16,-0.35],[0.35,-0.16],[0.48,-0.36],[0,0],[0.14,0.02],[0.08,0.11],[-0.02,0.14],[-0.11,0.08],[-0.59,0.34]],"o":[[0.29,-0.12],[0.12,0.29],[-0.53,0.29],[0,0],[-0.11,0.08],[-0.14,-0.02],[-0.09,-0.11],[0.02,-0.14],[0.5,-0.46],[0,0]],"v":[[139.86,31.05],[140.62,31.34],[140.34,32.1],[138.8,33.04],[138.8,33.04],[138.41,33.13],[138.07,32.92],[137.96,32.53],[138.18,32.18],[139.86,31.05]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.05,-0.31],[0.32,0.05],[0.55,-0.12],[0.05,0.33],[-0.33,0.05],[-0.64,0.01]],"o":[[0.27,-0.01],[0.01,0.27],[-0.6,0.07],[-0.33,0.05],[-0.05,-0.33],[0.66,-0.11],[0,0]],"v":[[144.75,29.73],[145.31,30.25],[144.79,30.81],[143.03,31.07],[142.35,30.64],[142.78,29.96],[144.75,29.73]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.09,-0.25],[0.25,0.09],[0.63,0.1],[0,0],[-0.05,0.32],[-0.32,-0.05],[-0.61,-0.2]],"o":[[0.25,0.09],[-0.09,0.25],[-0.55,-0.25],[0,0],[-0.32,-0.05],[0.05,-0.32],[0.66,0.27],[0,0]],"v":[[149.79,30.43],[150.11,31.12],[149.42,31.44],[147.67,30.95],[147.67,30.95],[147.18,30.28],[147.85,29.8],[149.79,30.43]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.2,-0.23],[0.24,0.2],[0.48,0.4],[-0.09,0.25],[-0.25,-0.09],[-0.41,-0.44]],"o":[[0.24,0.2],[-0.2,0.24],[-0.41,-0.44],[-0.24,-0.2],[0.09,-0.25],[0.58,0.41],[0,0]],"v":[[154.04,33.09],[154.07,33.89],[153.26,33.93],[151.88,32.79],[151.68,32.01],[152.46,31.81],[154.04,33.08]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.29,-0.12],[0.12,0.29],[0,0],[0.34,0.47],[-0.24,0.18],[-0.18,-0.24],[-0.23,-0.57]],"o":[[0.12,0.29],[-0.29,0.12],[0,0],[-0.21,-0.54],[-0.18,-0.24],[0.24,-0.18],[0.41,0.44],[0,0]],"v":[[156.98,37.26],[156.7,38.02],[155.94,37.74],[155.93,37.73],[155.1,36.21],[155.28,35.43],[156.05,35.61],[156.98,37.25]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.27,-0.01],[0.01,0.27],[0,0],[0.13,0.57],[-0.33,0.05],[-0.05,-0.33],[0,-0.64]],"o":[[0.01,0.27],[-0.27,0.01],[0,0],[0.03,-0.58],[-0.05,-0.33],[0.33,-0.05],[0.12,0.55],[0,0]],"v":[[158.02,42.25],[157.5,42.82],[156.93,42.3],[156.93,42.29],[156.78,40.55],[157.25,39.93],[157.88,40.4],[158.01,42.25]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.3,0.16],[-0.16,0.3],[-0.14,0.57],[-0.31,-0.05],[0.05,-0.31],[0.27,-0.66]],"o":[[-0.16,0.3],[-0.3,-0.16],[0.25,-0.55],[0.05,-0.31],[0.31,0.05],[-0.2,0.61],[0,0]],"v":[[157.01,47.25],[156.27,47.51],[156.01,46.77],[156.55,45.08],[157.26,44.66],[157.68,45.37],[157.01,47.25]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.18,0.24],[-0.24,0.18],[-0.34,0.43],[-0.23,-0.2],[0.2,-0.23],[0.44,-0.41]],"o":[[-0.2,0.24],[-0.24,-0.2],[0.44,-0.41],[0.2,-0.24],[0.24,0.2],[-0.4,0.47],[0,0]],"v":[[154.11,51.3],[153.36,51.29],[153.37,50.54],[154.55,49.22],[155.31,49.13],[155.41,49.89],[154.11,51.3]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.11,0.29],[-0.29,0.11],[-0.53,0.29],[-0.12,-0.29],[0.29,-0.12],[0.57,-0.23]],"o":[[-0.29,0.12],[-0.12,-0.29],[0.57,-0.23],[0.29,-0.12],[0.12,0.29],[-0.53,0.29],[0,0]],"v":[[149.76,54],[149.06,53.67],[149.39,52.97],[151,52.26],[151.72,52.48],[151.5,53.2],[149.76,54]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0.38],[-0.38,0],[-0.54,0.02],[-0.01,-0.27],[0.27,-0.01],[0.69,0.06]],"o":[[-0.31,-0.05],[0.05,-0.32],[0.59,0.04],[0.33,-0.05],[0.05,0.33],[-0.66,0.11],[0,0]],"v":[[144.71,54.7],[144.16,54.07],[144.79,53.53],[146.56,53.54],[147.18,54.01],[146.71,54.64],[144.71,54.7]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.09,0.25],[-0.25,-0.09],[-0.51,-0.19],[0.15,-0.3],[0.3,0.15],[0.55,0.25]],"o":[[-0.3,-0.16],[0.16,-0.3],[0.55,0.25],[0.25,0.09],[-0.09,0.25],[-0.57,-0.14],[0,0]],"v":[[139.83,53.34],[139.57,52.6],[140.31,52.34],[141.92,53.02],[142.24,53.72],[141.54,54.04],[139.83,53.34]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.24,0.18],[-0.18,-0.24],[-0.37,-0.38],[0.2,-0.23],[0.24,0.2],[0,0],[0.43,0.46]],"o":[[-0.18,-0.24],[0.24,-0.18],[0.35,0.48],[0.24,0.2],[-0.2,0.24],[0,0],[-0.43,-0.46],[0,0]],"v":[[135.87,50.19],[135.94,49.39],[136.73,49.46],[137.93,50.73],[137.96,51.54],[137.15,51.57],[137.15,51.57],[135.87,50.18]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.33,0.05],[-0.05,-0.33],[-0.29,-0.53],[0.29,-0.12],[0.12,0.29],[0.17,0.62]],"o":[[-0.12,-0.29],[0.33,-0.05],[0.12,0.56],[0.12,0.29],[-0.29,0.12],[-0.32,-0.7],[0,0]],"v":[[133.52,45.68],[133.95,45],[134.64,45.43],[135.29,47.09],[135,47.85],[134.24,47.57],[133.52,45.68]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.32,-0.05],[0.05,-0.32],[0,0],[0.27,-0.01],[0.01,0.27],[-0.06,0.69]],"o":[[0,0],[0.05,-0.32],[0.31,0.05],[0,0],[0.01,0.27],[-0.27,0.01],[-0.11,-0.66],[0,0]],"v":[[133.15,40.57],[133.15,40.57],[133.82,40.08],[134.3,40.75],[134.18,42.5],[133.66,43.07],[133.1,42.55],[133.15,40.57]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.3,-0.15],[0.15,-0.3],[0.25,-0.55],[0.25,0.09],[-0.09,0.25],[-0.36,0.54]],"o":[[0.16,-0.3],[0.3,0.16],[-0.29,0.49],[-0.09,0.25],[-0.25,-0.09],[0.16,-0.67],[0,0]],"v":[[134.81,35.84],[135.59,35.64],[135.79,36.43],[135,38.02],[134.31,38.34],[133.99,37.64],[134.81,35.84]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.14,-0.02],[-0.08,-0.11],[0.02,-0.14],[0.12,-0.08],[0.44,-0.41],[0.23,0.2],[-0.2,0.23],[-0.49,0.35]],"o":[[0,0],[0.11,-0.09],[0.14,0.02],[0.09,0.11],[-0.02,0.14],[-0.48,0.35],[-0.2,0.24],[-0.24,-0.2],[0.61,-0.44],[0,0]],"v":[[138.14,32.13],[138.14,32.12],[138.53,32.02],[138.87,32.24],[138.97,32.63],[138.75,32.97],[137.45,34.11],[136.64,34.14],[136.61,33.33],[138.14,32.12]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.27,0.51,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.11,0.36],[-0.35,0.54],[-0.19,0.51],[0.14,0.62],[0.52,0.46],[0.67,0.16],[0.78,-0.2],[0.45,-0.79],[0.03,-0.86],[0,0],[-0.23,0.45],[0,0],[-0.5,0.11],[-0.45,-0.23],[-0.14,-0.45],[0,0],[0.11,-0.37],[0.34,-0.43],[0.08,-0.52],[-0.17,-0.62],[0,0],[0,0]],"o":[[0,0],[-0.14,-0.45],[0.11,-0.36],[0.37,-0.64],[0.16,-0.61],[-0.21,-0.68],[-0.52,-0.46],[-0.67,-0.16],[-1.01,0.27],[-0.49,0.73],[0,0],[0.08,-0.52],[0,0],[0.3,-0.42],[0.62,-0.17],[0.45,0.23],[0,0],[0.1,0.37],[-0.11,0.36],[-0.49,0.73],[-0.12,0.46],[0,0],[0,0],[0,0]],"v":[[147.91,44.3],[147.79,43.75],[147.76,42.56],[148.39,41.27],[149.26,39.52],[149.29,37.65],[148.27,35.98],[146.52,35.12],[144.36,35.2],[142.07,36.77],[141.21,39.16],[143.27,39.43],[143.71,38],[143.7,38],[144.96,37.18],[146.5,37.26],[147.36,38.3],[147.36,38.31],[147.34,39.43],[146.66,40.67],[145.78,42.52],[145.85,44.14],[146.05,44.92],[147.92,44.3]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.2,0.33],[0.1,0.39],[0,0],[0.34,0.2],[0.39,-0.1],[0.2,-0.33],[-0.1,-0.39],[-0.34,-0.21],[-0.39,0.1]],"o":[[0.38,-0.09],[0.21,-0.34],[0,0],[-0.09,-0.38],[-0.34,-0.21],[-0.38,0.09],[-0.21,0.34],[0.1,0.39],[0.4,0.17],[0,0]],"v":[[147.98,48.98],[148.89,48.32],[149.01,47.21],[149.01,47.21],[148.35,46.3],[147.24,46.18],[146.33,46.84],[146.21,47.95],[146.87,48.86],[147.98,48.98]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[1,0.73,0,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[-0.15,-0.22],[0,0],[0,0],[0,0],[-0.3,-0.07],[0,0],[0,0],[0,0],[-0.23,0.22],[0,0],[0,0],[0,0],[0,0.38],[0,0],[0,0],[0,0],[0.3,0.15],[0,0],[0,0],[0,0],[0.3,-0.08],[0,0],[0,0],[0.07,-0.3],[0,0]],"o":[[0,0],[0,0],[-0.3,-0.07],[0,0],[0,0],[0,0],[-0.23,0.23],[0,0],[0,0],[0,0],[0,0.3],[0,0],[0,0],[0,0],[0.23,0.15],[0,0],[0,0],[0,0],[0.3,-0.07],[0,0],[0,0],[0,0],[0.15,-0.3],[0,0],[0,0],[-0.15,-0.3],[0,0],[0,0]],"v":[[121.23,42.63],[120.11,42.26],[120.04,42.26],[119.66,42.78],[120.26,43.83],[119.29,44.51],[119.14,44.51],[119.36,45.18],[120.56,45.33],[120.49,46.53],[120.49,46.61],[121.09,46.83],[121.99,46.01],[122.89,46.83],[122.89,46.91],[123.49,46.53],[123.41,45.33],[124.61,45.18],[124.69,45.18],[124.76,44.51],[123.79,43.83],[124.39,42.78],[124.39,42.71],[123.94,42.18],[122.81,42.56],[122.36,41.43],[121.69,41.43],[121.24,42.63]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[-0.15,0.08],[0,0],[0,0],[0,0],[-0.15,-0.07],[0,0],[0,0],[0,0],[-0.07,-0.15],[0,0],[0,0],[0,0],[0.15,-0.15],[0,0],[0,0],[0,0],[0.15,0],[0,0],[0,0],[0,0],[0.07,0.15],[0,0],[0,0],[-0.07,0.23],[0,0]],"o":[[0,0],[0,0],[0.07,0.15],[0,0],[0,0],[0,0],[-0.07,0.15],[0,0],[0,0],[0,0],[-0.15,0.07],[0,0],[0,0],[0,0],[-0.15,-0.07],[0,0],[0,0],[0,0],[0,-0.15],[0,0],[0,0],[0,0],[0.15,-0.15],[0,0],[0,0],[0.23,0.07],[0,0],[0,0]],"v":[[121.98,42.63],[122.21,43.23],[122.21,43.31],[122.66,43.46],[123.18,43.23],[122.88,43.75],[122.88,43.83],[123.03,44.28],[123.48,44.58],[122.88,44.65],[122.8,44.65],[122.58,45.03],[122.65,45.63],[122.2,45.25],[122.13,45.18],[121.68,45.25],[121.23,45.63],[121.38,45.03],[121.38,44.95],[121.08,44.65],[120.48,44.58],[120.93,44.28],[121,44.2],[121.07,43.75],[120.77,43.23],[121.3,43.38],[121.75,43.15],[121.97,42.63]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[1,1,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[129.71,80.66],[130.39,77.05],[131.59,80.66],[133.91,78.86],[133.31,81.48],[136.16,82.23],[132.94,82.98],[134.06,86.05],[131.59,83.95],[129.34,86.8],[129.79,83.5],[126.56,83.2],[128.81,81.93],[126.41,78.7],[129.71,80.65]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[52.76,38.88],[53.29,36.18],[54.18,38.88],[55.98,37.46],[55.54,39.48],[57.71,40.08],[55.23,40.68],[56.13,43.08],[54.26,41.43],[52.46,43.61],[52.83,41.06],[50.36,40.83],[52.08,39.86],[50.21,37.38],[52.76,38.88]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[1,1,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[127.98,107.88],[128.66,104.28],[129.79,107.88],[132.18,106.08],[131.51,108.71],[134.36,109.46],[131.21,110.21],[132.34,113.28],[129.86,111.18],[127.54,114.03],[127.98,110.73],[124.76,110.43],[127.01,109.16],[124.61,105.93],[127.98,107.88]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0.83],[0.83,0],[0,-0.83],[-0.83,0]],"o":[[0.83,0],[0,-0.83],[-0.83,0],[0,0.83],[0,0]],"v":[[60.86,60.26],[62.36,58.76],[60.86,57.26],[59.36,58.76],[60.86,60.26]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.16,0.52,0.99,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,1.24],[1.25,0],[0,-1.24],[-1.24,0]],"o":[[1.25,0],[0,-1.24],[-1.24,0],[0,1.24],[0,0]],"v":[[52.61,82.68],[54.86,80.43],[52.61,78.18],[50.36,80.43],[52.61,82.68]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.82,0.89,0.99,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,1.1],[1.1,0],[0,-1.1],[-1.1,0]],"o":[[1.1,0],[0,-1.1],[-1.1,0],[0,1.1],[0,0]],"v":[[193.15,84.34],[195.15,82.34],[193.15,80.34],[191.15,82.34],[193.15,84.34]],"c":true}}},{"ty":"st","lc":1,"lj":1,"ml":4,"o":{"k":100},"w":{"k":1},"c":{"k":[1,1,1,1]},"hd":false},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[75,75]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-0.22],[0.3,0],[0,0],[0,0.22],[-0.3,0]],"o":[[0.3,0],[0,0.23],[0,0],[-0.3,0],[0,-0.23],[0,0]],"v":[[168.49,165.78],[169.01,166.23],[168.56,166.68],[23.74,166.68],[23.21,166.23],[23.66,165.78]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.16,0.52,0.99,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.15,-7.35],[0,0],[0,0],[0,0],[-0.07,-2.55],[0,0],[0.3,0],[0,0.22],[2.1,0.3],[0,0],[0,0],[0,0],[0,0],[6.82,-0.22],[0,0.22],[-0.23,0]],"o":[[7.35,-0.23],[0,0],[0,0],[0,0],[2.55,0.3],[0,0],[0,0.3],[-0.3,0],[0,-2.1],[0,0],[0,0],[0,0],[0,0],[-0.23,-6.75],[-0.3,0],[0,-0.23],[0,0]],"v":[[67.95,127.38],[81.6,140.28],[81.6,140.43],[81.68,158.8],[94.2,160.38],[98.77,165.4],[98.77,165.55],[98.25,166],[97.73,165.55],[94.12,161.35],[93.98,161.35],[80.62,159.7],[80.55,140.57],[80.55,140.27],[67.88,128.35],[67.35,127.9],[67.95,127.38]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.16,0.52,0.99,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.07,-0.15],[0.15,-0.07],[0,0],[0,0],[0.07,0.15],[-0.15,0.07],[0,0]],"o":[[0.23,-0.07],[0.07,0.15],[0,0],[0,0],[-0.23,0.07],[-0.07,-0.15],[0,0],[0,0]],"v":[[94.5,83.05],[94.95,83.28],[94.8,83.73],[94.73,83.73],[86.93,86.21],[86.48,85.98],[86.62,85.53],[86.7,85.53]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.15,-0.15],[0.15,-0.07],[0,0],[0,0],[0.15,0.15],[-0.15,0.07],[0,0]],"o":[[0.15,-0.07],[0.07,0.15],[0,0],[0,0],[-0.15,0.07],[-0.07,-0.15],[0,0],[0,0]],"v":[[95.18,84.55],[95.7,84.63],[95.62,85.08],[95.55,85.15],[89.18,89.28],[88.65,89.2],[88.73,88.75],[88.8,88.68]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[1.35,-0.3],[0.3,-0.15]],"o":[[0,0],[0,0],[-0.3,-1.35],[-0.23,0],[0,0]],"v":[[95.33,82.15],[99.08,84.18],[99,83.88],[96.08,81.93],[95.33,82.15]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.16,0.52,0.99,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0.07,-1.05],[0,0],[1.05,0.07],[0,0],[-0.07,1.05],[0,0],[-1.05,-0.08]],"o":[[0,0],[1.05,0.07],[0,0],[-0.07,1.05],[0,0],[-1.05,-0.07],[0,0],[0.07,-0.98],[0,0]],"v":[[76.12,97.68],[96.07,99.41],[97.8,101.43],[97.73,102.11],[95.7,103.83],[75.75,102.03],[74.03,100.01],[74.1,99.33],[76.12,97.68]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0,0.45,0.94,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0.06,-0.97],[0,0]],"o":[[0,0],[0.61,-0.75],[0,0],[0,0]],"v":[[113.31,103.36],[117.85,97.79],[119.62,98.48],[119.04,108.72]],"c":false}}},{"ty":"st","lc":3,"lj":2,"ml":4,"o":{"k":100},"w":{"k":1.3},"c":{"k":[0,0.45,0.94,1]},"hd":false},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[75,75]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0.83],[0.83,0],[0,-0.83],[-0.83,0]],"o":[[0.83,0],[0,-0.83],[-0.83,0],[0,0.83],[0,0]],"v":[[126.15,32.62],[127.65,31.12],[126.15,29.62],[124.65,31.12],[126.15,32.62]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0.15,-0.3],[0,0],[-1.88,-4.2],[0,0],[2.18,-1.05],[0.3,-0.07],[2.48,-7.35],[0,0],[0,0],[0,0],[0,0],[-12.38,-3.9],[-2.4,0],[0,0],[0,0.53],[0,0],[2.55,0.07],[0,0],[0.08,1.5],[0,0],[0,0],[-0.15,1.05],[0,0],[0,0],[0.6,4.65],[0,0],[0,0],[-0.38,2.85],[1.12,3.15],[0,0],[1.5,-0.23],[0,0],[0,0],[0.82,-0.38],[0,0]],"o":[[-0.3,0.15],[0,0],[-2.02,4.12],[0,0],[1.05,2.18],[-0.23,0.07],[-8.18,2.25],[0,0],[0,0],[0,0],[0,0],[-3.9,12.38],[2.32,0.75],[0,0],[0.52,0],[0,0],[0,-2.62],[0,0],[-1.5,0],[0,0],[0,0],[0,-1.05],[0,0],[0,0],[0.9,-4.57],[0,0],[0,0],[2.32,-2.48],[0.38,-2.48],[0,0],[-0.6,-1.35],[0,0],[0,0],[-0.38,-0.82],[0,0],[0,0]],"v":[[80.1,72.38],[79.35,73.12],[75.08,81.9],[74.85,95.1],[75,95.4],[72.9,101.25],[72.15,101.55],[56.1,115.95],[54.97,119.32],[53.7,123.3],[51.75,129.38],[49.65,135.9],[64.95,165.38],[72.07,166.5],[102.15,166.5],[103.12,165.52],[103.12,164.1],[98.48,159.3],[98.33,159.3],[95.48,156.6],[95.48,156.45],[95.62,127.72],[95.93,124.57],[97.05,119.1],[97.2,118.5],[97.65,104.47],[96.97,99],[97.2,98.77],[101.32,90.82],[100.2,82.34],[100.12,82.2],[96.68,80.25],[86.78,81.67],[82.43,73.12],[80.25,72.3],[80.1,72.37]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.23,-0.3],[0,0],[0,0],[0,0],[-0.3,-1.05],[0.38,-2.32],[2.32,-2.4],[0,0],[0,0],[0.9,-4.58],[0,0],[0,0],[0.07,-0.98],[0,0],[0,0],[-2.03,-0.07],[0,0],[-0.07,-2.03],[0,0],[0,0],[2.25,0.68],[-3.75,11.85],[0,0],[0,0],[0,0],[0,0],[0,0],[-7.88,2.18],[-0.3,0.07],[1.27,2.62],[-1.8,3.9],[0,0],[0,0],[-0.15,0.07]],"o":[[0.38,-0.15],[0,0],[0,0],[0,0],[1.05,-0.15],[1.05,3],[-0.38,2.7],[0,0],[0,0],[0.6,4.57],[0,0],[0,0],[-0.23,0.98],[0,0],[0,0],[0,2.02],[0,0],[2.1,0],[0,0],[0,0],[-2.32,0],[-11.85,-3.75],[0,0],[0,0],[0,0],[0,0],[0,0],[2.32,-7.12],[0.3,-0.07],[2.7,-1.27],[-1.88,-3.9],[0,0],[0,0],[0.07,-0.15],[0,0]],"v":[[80.55,73.2],[81.53,73.43],[81.6,73.5],[86.25,82.73],[96.9,81.23],[99.3,82.73],[100.35,90.68],[96.22,98.32],[95.92,98.62],[96.67,104.62],[96.22,118.35],[96.07,118.95],[94.95,124.43],[94.57,127.36],[94.57,127.8],[94.43,156.61],[98.1,160.43],[98.25,160.43],[102.07,164.11],[102.07,165.68],[72,165.68],[65.18,164.63],[50.55,136.36],[52.95,128.78],[54.6,123.68],[55.8,120.08],[56.85,116.93],[57.07,116.33],[72.38,102.45],[73.27,102.15],[75.82,95.03],[75.75,82.65],[75.9,82.35],[80.25,73.58],[80.55,73.2]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0,0.45,0.94,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.65,1.35],[-1.05,3.68],[1.35,0.75],[0.45,-0.3],[1.05,-2.4],[-0.98,-0.75]],"o":[[1.05,0.9],[2.77,-2.32],[0.45,-1.57],[-0.45,-0.23],[-3.45,2.02],[-2.62,6.07],[0,0]],"v":[[54.37,123.97],[60,121.72],[64.64,112.72],[65.17,105.37],[63.67,105.75],[57.37,114.14],[54.37,123.97]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.9,0.94,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[6.52,-4.8],[0.3,-0.07],[0.38,1.42],[-3.82,2.18],[-0.75,1.88],[0.38,4.73],[-0.9,1.95]],"o":[[0,0],[4.43,6.82],[-2.93,2.18],[-3.75,0.82],[-0.38,-1.57],[5.1,-2.85],[1.05,-2.62],[-0.23,-3.45],[0,0]],"v":[[75.6,81.15],[79.35,86.92],[75.6,107.7],[68.85,111],[59.85,110.1],[68.25,103.5],[75.75,98.77],[73.95,89.47],[75.6,81.14]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.81,0.89,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-5.85,-10.43],[-2.25,-1.05],[1.73,5.55],[0.45,0.6],[2.18,0.6]],"o":[[-0.6,1.27],[3.52,6.3],[3.52,-7.2],[-0.9,-2.85],[-3.98,-5.62],[0,0]],"v":[[51.45,132.07],[52.12,154.57],[63.38,164.7],[66.07,145.57],[63.38,140.18],[51.45,132.07]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-15.7],[15.7,0],[1.5,0.2],[-0.1,0.3],[-1.5,0],[0,15.1],[15.2,0],[0.9,-14.2],[0,0],[-14.8,0]],"o":[[15.7,0],[0,15.7],[-1.5,0],[0.1,-0.3],[1.4,0.2],[15.2,0],[0,-15.1],[-14.6,0],[0,0],[1.3,-14.3],[0,0]],"v":[[119.18,79.84],[147.68,108.24],[119.18,136.64],[114.68,136.34],[114.88,135.34],[119.18,135.64],[146.68,108.24],[119.18,80.84],[91.78,106.34],[90.88,105.44],[119.18,79.84]],"c":true}}},{"ty":"st","lc":1,"lj":1,"ml":4,"o":{"k":100},"w":{"k":1.2},"c":{"k":[1,1,1,1]},"hd":false},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[75,75]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-0.23],[-2.7,-3.15],[0.22,-0.15],[0.15,0.15],[0,4.43],[-0.23,0]],"o":[[0.23,0],[0,4.2],[0.15,0.15],[-0.23,0.15],[-2.77,-3.3],[0,-0.15],[0,0]],"v":[[71.55,80.63],[71.92,81.01],[76.12,92.41],[76.05,92.93],[75.52,92.86],[71.17,81],[71.55,80.63]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-0.23],[0.23,0],[2.47,-1.2],[0.15,0.15],[-0.15,0.15],[-2.92,0]],"o":[[0.23,0],[0,0.23],[-2.85,0],[-0.15,0.07],[-0.07,-0.15],[2.62,-1.27],[0,0]],"v":[[89.55,62.71],[89.92,63.08],[89.55,63.46],[81.52,65.33],[81,65.18],[81.15,64.66],[89.55,62.71]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0,0.45,0.94,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-0.23],[6.82,-2.85],[2.48,0],[0,0.23],[-0.23,0],[-2.18,0.9],[0,7.2],[-0.23,0]],"o":[[0.23,0],[0,7.5],[-2.25,0.9],[-0.23,0],[0,-0.23],[2.4,0],[6.52,-2.7],[0,-0.15],[0,0]],"v":[[107.62,80.63],[108,81.01],[96.68,97.96],[89.55,99.38],[89.18,99.01],[89.55,98.63],[96.38,97.28],[107.25,81.01],[107.62,80.63]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-0.23],[0.23,0],[2.47,-1.2],[0.15,0.15],[-0.15,0.15],[-2.92,0]],"o":[[0.23,0],[0,0.23],[-2.85,0],[-0.15,0.07],[-0.07,-0.15],[2.62,-1.27],[0,0]],"v":[[89.55,62.71],[89.93,63.08],[89.55,63.46],[81.53,65.33],[81,65.18],[81.15,64.66],[89.55,62.71]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.82,0.89,0.99,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-12],[-12,0],[0,12],[12,0]],"o":[[-12,0],[0,12],[12,0],[0,-12],[0,0]],"v":[[89.4,59.49],[67.65,81.17],[89.4,102.84],[111.15,81.17],[89.4,59.49]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-11.18],[11.18,0],[0,11.18],[-11.18,0]],"o":[[11.18,0],[0,11.18],[-11.18,0],[0,-11.18],[0,0]],"v":[[89.4,60.99],[109.65,81.17],[89.4,101.34],[69.15,81.17],[89.4,60.99]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,11.35],[11.39,0],[0,-11.35],[-11.39,0]],"o":[[11.39,0],[0,-11.35],[-11.39,0],[0,11.35],[0,0]],"v":[[89.4,101.72],[110.02,81.17],[89.4,60.62],[68.77,81.17],[89.4,101.72]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.91,0.94,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[10.65,-7.8],[0,0],[0.45,-0.45],[0,0],[0.9,-0.97],[0,0],[0,0],[0.38,-4.57],[0,0],[0.07,-1.2],[0,0],[0,-0.07],[0,0],[0.23,-1.42],[0,0],[0,0],[1.5,-2.48],[0,0],[0,0],[10.65,7.65],[0,0],[-0.07,0.3],[0,0],[0,0],[0.6,4.58],[0,0],[0,9.23],[11.62,0],[0.9,-10.72],[5.93,-2.25],[0,0],[0,0],[0,0],[-1.2,9.52],[-9.52,0.82],[-2.55,-0.82],[0,0],[0,0],[-1.72,-1.12],[-1.88,-0.75],[0,0],[-1.28,-0.45],[-4.57,1.95],[0,0],[0,0],[-0.23,0.15],[0,0],[-1.72,0.53],[-3.15,-0.45],[-2.33,-1.35],[-3.38,0.9],[0,0],[-6.23,-11.85]],"o":[[6.15,11.7],[0,0],[-0.45,0.45],[0,0],[-0.98,0.9],[0,0],[0,0],[-3.07,3.38],[0,0],[0,0.23],[0,0],[-0.07,1.27],[0,0],[0.07,1.43],[0,0],[0,0],[-0.52,2.7],[0,0],[0,0],[-7.27,10.65],[0,0],[0.07,-0.3],[0,0],[0,0],[0.9,-4.5],[0,0],[8.25,-2.85],[0,-11.55],[-11.02,0],[-4.35,-4.27],[0,0],[0,0],[0,0],[-7.5,-6.23],[1.2,-9.52],[5.4,-0.45],[0,0],[0,0],[2.02,0.75],[1.88,0.52],[0,0],[1.2,0.52],[4.57,1.57],[0,0],[0,0],[1.05,-0.45],[0,0],[1.57,-0.9],[2.93,-0.82],[2.77,0.45],[2.77,-1.88],[0,0],[12.98,-3.68],[0,0]],"v":[[163.72,39.9],[155.92,73.8],[143.25,83.02],[141.89,84.3],[141.45,84.75],[138.67,87.45],[138.15,87.97],[137.92,88.27],[132.45,100.2],[132.45,100.64],[132.3,103.27],[132.3,103.64],[132.15,106.27],[132.15,106.79],[131.92,111.07],[131.85,111.59],[131.77,112.04],[128.7,119.84],[128.4,120.21],[128.17,120.52],[95.47,126.14],[95.25,125.91],[95.39,125.09],[96.52,119.61],[96.67,119.01],[97.12,105.29],[96.67,101.61],[110.84,81.81],[89.84,60.88],[68.92,80.08],[52.04,76.56],[51.74,76.63],[51.29,76.86],[41.99,68.68],[32.09,43.41],[50.54,25.71],[62.47,26.23],[62.7,26.31],[63.14,26.46],[68.84,29.23],[74.47,31.33],[75.07,31.56],[78.75,32.98],[92.55,32.76],[95.1,31.71],[95.47,31.56],[97.72,30.58],[97.8,30.58],[102.75,28.48],[111.97,27.88],[119.7,30.58],[128.85,26.38],[130.8,25.86],[163.72,39.88]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.82,0.89,0.99,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.45,-0.6],[4.57,-6.75],[0,0],[0,0],[-5.55,-3.9],[0,0],[-1.43,-0.38],[0,0],[-1.27,-0.15],[0,0],[0,0],[-2.62,-0.82],[-1.35,-0.22],[0.23,0],[0,0],[1.43,0.15],[0,0],[0,0],[0,0],[2.1,1.2],[0.45,0.38],[-5.25,7.57],[0,0],[0,0],[3.68,5.18],[0.38,0.38],[3.08,-3],[0,0],[0,0],[0.82,0.82],[-0.75,0.9],[0,0],[0,0],[-4.95,-4.8]],"o":[[0.52,0.52],[4.73,6.68],[0,0],[0,0],[-3.98,5.55],[0,0],[0.9,0.52],[0,0],[0.98,0.23],[0,0],[0,0],[2.02,1.57],[1.27,0.45],[-0.23,0.07],[0,0],[-1.57,0],[0,0],[0,0],[0,0],[-3.75,-0.45],[-0.52,-0.3],[-7.5,-5.32],[0,0],[0,0],[3.68,-5.18],[-0.3,-0.38],[-3.07,-3],[0,0],[0,0],[-0.9,0.9],[-0.82,-0.82],[0,0],[0,0],[4.73,-4.95],[0,0]],"v":[[45.82,113.55],[47.32,115.28],[47.55,137.55],[47.32,137.85],[45.22,140.85],[48.15,158.03],[49.27,158.7],[52.88,160.05],[53.4,160.2],[56.77,160.73],[58.12,160.88],[58.27,160.88],[65.25,164.55],[69.23,165.45],[68.48,165.6],[63,165.6],[58.57,165.38],[57.75,165.3],[57.38,165.3],[55.88,165.15],[47.1,162.68],[45.6,161.7],[41.48,138.45],[41.62,138.22],[43.73,135.22],[43.73,117.9],[42.75,116.77],[31.65,116.77],[31.5,116.92],[29.55,118.95],[26.4,119.02],[26.25,115.95],[26.33,115.87],[28.28,113.85],[45.83,113.55]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.16,0.52,0.99,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]}]}],"meta":{"g":"LF SVG to Lottie"}}
diff --git a/ash/public/cpp/resources/unscaled_resources/phone_hub_error_state_image.png b/ash/public/cpp/resources/unscaled_resources/phone_hub_error_state_image.png deleted file mode 100644 index 6ba6c2e0a..0000000 --- a/ash/public/cpp/resources/unscaled_resources/phone_hub_error_state_image.png +++ /dev/null Binary files differ
diff --git a/ash/public/cpp/resources/unscaled_resources/phone_hub_onboarding_image.json b/ash/public/cpp/resources/unscaled_resources/phone_hub_onboarding_image.json new file mode 100644 index 0000000..e5194d79 --- /dev/null +++ b/ash/public/cpp/resources/unscaled_resources/phone_hub_onboarding_image.json
@@ -0,0 +1 @@ +{"v":"5.6.6","ip":0,"op":1,"fr":60,"w":256,"h":256,"layers":[{"ind":6436,"nm":"surface28788","ao":0,"ip":0,"op":60,"st":0,"ty":4,"ks":{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[133.33,133.33]},"sk":{"k":0},"sa":{"k":0}},"shapes":[{"ty":"gr","hd":false,"nm":"surface28788","it":[{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[1.05,0],[0.22,0.15],[-1.05,0.23],[0,0]],"o":[[0,0],[0,1.05],[-0.38,0],[0.52,-0.98],[0,0],[0,0]],"v":[[93.38,80.14],[93.38,80.44],[91.5,82.31],[90.6,82.09],[93.08,80.29],[93.23,80.29]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.81,0.89,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,1.04],[1.04,0],[0,-1.04],[-1.04,0]],"o":[[1.04,0],[0,-1.04],[-1.04,0],[0,1.04],[0,0]],"v":[[91.5,82.31],[93.38,80.43],[91.5,78.56],[89.62,80.43],[91.5,82.31]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.97,0.51,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-0.08],[0.82,0.22],[-0.07,0.82],[-0.15,0],[0,0]],"o":[[0.07,0],[-0.3,0.75],[-0.82,-0.15],[0,-0.07],[0,0],[0,0]],"v":[[94.2,89.81],[94.35,90.04],[92.4,91.09],[91.05,89.29],[91.28,89.14],[94.2,89.81]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.07,-0.68],[0,0],[0,0],[0.23,-1.57],[0,0],[0,0],[0,0],[0.07,-0.53],[0,0],[0,0],[0.22,0],[0,0],[0,0],[0,0.22],[0,0],[0,0],[-0.6,0.15],[0,0],[0,0],[-1.5,0.3],[0,0],[0,0],[-0.6,-0.08],[0,0],[0,0]],"o":[[0.68,0.15],[0,0],[0,0],[1.27,0.82],[0,0],[0,0],[0,0],[0.52,0.3],[0,0],[0,0],[-0.07,0.23],[0,0],[0,0],[-0.23,-0.07],[0,0],[0,0],[0.15,-0.6],[0,0],[0,0],[0.38,-1.65],[0,0],[0,0],[0.15,-0.6],[0,0],[0,0],[0,0]],"v":[[94.88,79.16],[95.93,80.59],[95.93,80.66],[96.08,80.81],[97.73,84.63],[97.73,84.93],[97.43,86.43],[97.5,86.43],[98.25,87.86],[98.25,88.16],[98.18,88.61],[97.65,88.98],[97.58,88.98],[88.58,87.26],[88.2,86.73],[88.2,86.66],[88.28,86.21],[89.48,85.01],[89.7,85.01],[90,83.51],[93,80.36],[93.3,80.36],[93.3,80.21],[94.66,79.32],[94.8,79.32],[94.88,79.17]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.98,0.74,0.02,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[-6.9,-0.52],[0,0],[0,0],[0,0],[0,0],[0.15,-0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[7.43,0.15],[0,0],[0,0],[0,0],[0,0],[-0.07,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[112.05,162.34],[105.68,151.61],[106.57,151.61],[128.02,152.74],[129.38,152.89],[130.88,153.04],[129.52,153.86],[129,154.16],[128.7,154.31],[128.1,154.61],[127.5,154.98],[125.47,156.11],[123.97,156.86],[122.77,157.46],[121.5,158.06],[120.45,158.59],[117.45,156.79],[118.05,159.86],[112.05,162.34]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.23,0.07],[0,0],[0,0],[0,0],[0,0],[5.77,0.23],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.3,-0.15],[0,0],[0,0],[0,0],[0,0],[-5.48,-0.45],[0,0],[0,0],[0,0]],"v":[[107.4,152.59],[112.43,161.07],[116.78,159.12],[115.88,154.69],[120.38,157.39],[121.5,156.87],[123.3,155.97],[124.95,155.07],[125.7,154.7],[126.45,154.32],[127.12,153.95],[127.65,153.64],[126.45,153.57],[109.57,152.59],[108,152.52],[107.4,152.59]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[5.47,-0.9],[3.45,2.4],[0,0],[0,0],[0,0],[-0.82,0.23],[0,0],[-0.23,0.08],[0,0],[-0.3,0],[0,0],[-0.22,0],[0,0],[-0.15,0],[0,0],[-0.3,0.07],[0,0],[-0.3,0.07],[0,0],[-0.38,0.07],[0,0],[0,0],[0,0],[0,0],[-0.23,0.07],[0,0],[0,0],[0,0]],"o":[[0,0],[-4.12,3.38],[-5.32,0.9],[0,0],[0,0],[0,0],[0.75,-0.23],[0,0],[0.23,-0.07],[0,0],[0.3,-0.07],[0,0],[0.3,-0.07],[0,0],[0.15,0],[0,0],[0.3,-0.07],[0,0],[0.3,-0.07],[0,0],[0.38,-0.07],[0,0],[0,0],[0,0],[0,0],[0.23,0],[0,0],[0,0],[0,0],[0,0]],"v":[[78.68,151.84],[77.48,152.82],[63.08,159.19],[49.95,156.94],[49.73,156.79],[48.98,156.27],[49.88,155.97],[52.27,155.22],[53.02,154.99],[53.77,154.77],[54.52,154.62],[55.35,154.47],[56.17,154.32],[57,154.17],[58.79,153.88],[59.24,153.8],[60.22,153.65],[61.2,153.5],[62.17,153.36],[63.15,153.21],[64.2,153.06],[65.25,152.91],[66.3,152.76],[67.43,152.61],[69.68,152.46],[72.07,152.32],[72.68,152.24],[73.88,152.17],[76.42,152.02],[78.67,151.87]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0.23,-0.07],[0,0],[0.23,-0.07],[0,0],[0,0],[0,0],[0,0],[0.15,0],[0,0],[0.45,-0.08],[0,0],[0.3,-0.07],[0,0],[0.68,-0.15],[0,0],[0.52,-0.15],[0,0],[0,0],[0,0],[0,0],[-4.28,0.6],[0,0],[-3.52,2.48],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[-0.23,0],[0,0],[-0.23,0],[0,0],[0,0],[0,0],[0,0],[-0.15,0],[0,0],[-0.52,0.07],[0,0],[-0.3,0.07],[0,0],[-0.75,0.15],[0,0],[-0.52,0.15],[0,0],[0,0],[0,0],[0,0],[2.93,1.73],[0,0],[4.5,-0.75],[0,0],[0,0]],"v":[[75.3,153.19],[75.6,152.96],[74.62,153.04],[73.35,153.11],[70.95,153.26],[70.35,153.34],[69.15,153.48],[68.55,153.56],[67.43,153.63],[66.38,153.78],[65.25,153.93],[63.15,154.23],[62.62,154.3],[61.65,154.45],[60.22,154.68],[59.25,154.82],[58.35,154.97],[57.45,155.12],[55.35,155.57],[54.52,155.72],[52.95,156.09],[52.2,156.32],[51.52,156.55],[51.15,156.62],[51.3,156.7],[62.1,158.42],[62.85,158.27],[74.85,153.47],[75.3,153.17]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-1.65,-4.8],[-1.43,-6.9],[0,0],[0,0],[0,0],[2.18,1.2],[1.88,4.95],[-3.97,6.38],[-0.9,0.98],[0,0],[0,0]],"o":[[0,0],[2.25,3.9],[2.4,6.98],[0,0],[0,0],[0,0],[-2.85,0.07],[-3.23,-1.8],[-2.48,-6.38],[0.6,-0.98],[0,0],[0,0],[0,0]],"v":[[30,103.77],[30.3,104.37],[36.07,117.42],[41.7,138.19],[41.93,139.39],[42,139.99],[41.4,139.99],[33.82,138.27],[24.97,127.09],[26.92,107.59],[29.17,104.66],[29.47,104.29],[30,103.77]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0.45,-0.82],[-2.32,-6.08],[-3,-1.65],[-2.18,-0.07],[0,0],[0,0],[2.03,6.07],[0,0],[1.88,3.53]],"o":[[0,0],[-0.68,0.75],[-3.82,6.15],[1.88,4.8],[1.73,0.98],[0,0],[0,0],[-1.2,-6],[0,0],[-1.43,-4.12],[0,0]],"v":[[29.77,105.34],[29.62,105.57],[27.82,107.96],[25.95,126.57],[34.35,137.21],[40.27,138.79],[40.8,138.79],[40.65,138.19],[35.85,120.04],[35.1,117.64],[30.15,106.16]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[1,1,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[3.6,-1.65],[0,0],[0,0],[0,0],[0,0],[0,0],[-7.28,-0.67]],"o":[[0,0],[-2.02,1.2],[0,0],[0,0],[0,0],[0,0],[0,0],[7.88,0.15],[0,0]],"v":[[129.3,153.41],[129.23,153.49],[120.83,157.84],[120.38,157.99],[116.63,155.74],[117.38,159.49],[112.28,161.74],[106.58,152.14],[129.3,153.41]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[3.38,2.4],[-12.15,0.68],[5.4,-0.9]],"o":[[-5.32,0.9],[6,-2.02],[-4.05,3.3],[0,0]],"v":[[63,158.74],[50.02,156.41],[77.17,152.44],[63,158.74]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.43,-7.27],[2.18,1.2],[-8.62,13.8],[-1.05,1.05],[-1.57,-4.73]],"o":[[2.48,7.35],[-2.77,0.07],[-5.48,-3],[0.68,-1.12],[2.18,3.9],[0,0]],"v":[[35.62,117.49],[41.48,139.39],[34.12,137.74],[27.38,107.74],[29.93,104.51],[35.62,117.49]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.68,0.8,0.98,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.2,-2.78],[-0.68,-13.8],[-27,0.15],[-18.75,-4.12],[0,-2.18],[2.1,0],[0,0],[0.15,17.25],[0,0],[-3.97,0],[-1.34,-1.89],[-0.23,-0.71]],"o":[[1.2,3.38],[4.8,14.18],[6,-4.8],[25.27,-0.15],[2.18,0.45],[0,2.1],[0,0],[-17.25,-0.07],[0,0],[0,-3.98],[2.4,-0.06],[0.41,0.59],[0,0]],"v":[[31.35,107.22],[35.62,116.45],[43.88,159.2],[93.38,151.7],[159.45,157.62],[163.12,161.45],[159.38,165.2],[49.57,164.89],[18.15,133.62],[18,109.55],[24.39,101.44],[30,103.77],[31.35,107.22]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.68,0.8,0.98,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.1,0.03],[0,0],[-0.1,0.03],[0,0],[0,0],[0,0],[-0.04,0.07],[0,0],[-0.04,0.07],[0,0],[-0.04,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.04,0.07],[-0.19,-0.27],[0.27,-0.19],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.04,-0.07],[0,0],[0.14,-0.09],[0,0],[0.1,-0.03],[0,0],[0.07,-0.13],[0,0],[0.1,-0.03],[0,0],[0.1,-0.03],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.11,-0.2],[0,0],[0,0],[0.84,-0.9],[0,0],[0.04,-0.07],[0.12,0.24],[-0.17,0.16],[-1.21,1.73],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.04,-0.07],[0,0],[0.04,-0.07],[0,0],[0,0],[0,0],[0.04,-0.07],[0,0],[0.04,-0.07],[0,0],[0.04,-0.07],[0,0],[0,0],[0,0],[0.04,-0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.04,-0.07],[0.18,-0.16],[0.16,0.18],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.04,0.07],[0,0],[-0.14,0.09],[0,0],[-0.04,0.07],[0,0],[-0.07,0.13],[0,0],[-0.04,0.07],[0,0],[-0.04,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.11,0.2],[0,0],[0,0],[-0.77,0.96],[0,0],[-0.04,0.07],[-0.21,0.23],[-0.12,-0.24],[1.19,-1.23],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[114.27,81.59],[114.92,80.58],[116.36,78.29],[116.79,77.67],[117.4,76.72],[117.79,76.17],[118.19,75.61],[119.25,74.15],[119.44,73.65],[119.76,73.23],[119.94,73.07],[120.58,72.23],[120.75,72.07],[121.04,71.71],[121.67,71.03],[121.96,70.67],[122.13,70.51],[122.48,70.19],[122.66,70.03],[123.35,69.39],[123.53,69.23],[123.88,68.91],[125.12,67.89],[125.33,67.84],[125.47,67.74],[125.78,67.49],[126.16,67.27],[127.39,66.58],[128.36,66.09],[130.49,64.87],[131.14,64.46],[131.76,64.11],[132.52,63.68],[132.83,63.42],[133.94,62.66],[134.36,62.37],[134.5,62.28],[135.2,62.41],[135.07,63.11],[134.79,63.3],[134.55,63.42],[133.44,64.19],[132.92,64.5],[132.16,64.94],[131.27,65.47],[128.89,66.81],[128.1,67.32],[126.87,68],[126.49,68.22],[125.97,68.54],[125.7,68.73],[125.48,68.95],[124.93,69.34],[124.62,69.59],[124.44,69.75],[123.75,70.39],[123.57,70.55],[122.88,71.19],[122.53,71.51],[122.18,71.83],[122,71.99],[121.72,72.35],[121.43,72.71],[121.15,73.06],[120.97,73.22],[120.69,73.58],[120.51,73.74],[119.55,75],[119.2,75.49],[119.04,75.92],[118.5,76.74],[118.11,77.29],[117.54,78.18],[116.93,79.12],[115.77,81.05],[115.3,81.74],[115.12,82.07],[114.26,83.31],[114.08,83.64],[113.71,84.29],[113.32,84.85],[112.93,85.4],[112.57,85.89],[112.58,85.89],[110.18,88.67],[109.79,89.06],[109.62,89.22],[108.95,89.19],[108.97,88.52],[112.55,84.24],[112.94,83.68],[113.33,83.13],[113.66,82.54],[114.09,81.92],[114.27,81.59]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.91,0.94,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-6.04,1.62],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-2.17,2.83],[-0.3,1.46],[-0.23,-0.04],[0.04,-0.23],[1.14,-1.6],[4.41,-1.15],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.17,0.01],[0,0],[0,0],[0.07,0.04],[0,0],[0.1,-0.03],[0,0],[0.04,-0.07],[0,0],[0.04,-0.07],[0,0],[1.34,-5.52],[0.23,0.04],[-0.04,0.23]],"o":[[1.39,-5.91],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[4.21,-1.1],[1.07,-1.46],[0.04,-0.23],[0.23,0.04],[-0.37,1.6],[-2.31,3.09],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.27,0.02],[0,0],[0,0],[-0.1,0.03],[0,0],[-0.1,0.03],[0,0],[-0.1,0.03],[0,0],[-0.1,0.03],[0,0],[-5.7,1.47],[-0.08,0.3],[-0.23,-0.04],[0,0]],"v":[[109.47,85.62],[121.67,73.34],[122.48,73.11],[123.97,72.91],[124.38,72.79],[125.05,72.65],[125.79,72.55],[126.33,72.5],[127.51,72.39],[129.8,72.11],[130.92,71.96],[131.66,71.86],[132.13,71.77],[133.62,71.57],[134.19,71.46],[134.7,71.32],[135.07,71.27],[144.86,65.37],[147.02,61],[147.58,60.62],[147.96,61.18],[145.68,65.91],[135.34,72.19],[134.8,72.23],[134.05,72.33],[133.71,72.48],[132.97,72.59],[132.56,72.7],[131.92,72.78],[130.44,72.98],[129.26,73.1],[127.3,73.38],[126.72,73.49],[126.08,73.57],[125.44,73.64],[124.87,73.75],[124.6,73.77],[124.12,73.86],[123.86,73.88],[123.38,73.96],[123.18,74.02],[122.61,74.13],[122.4,74.19],[121.93,74.27],[110.39,85.8],[109.84,86.18],[109.46,85.62]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.27,0.51,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.02,-0.08],[-0.12,-0.21],[0,0],[0,0],[-0.2,-0.12],[0,0],[-0.02,0.07],[0.38,0]],"o":[[0,0],[0.01,0.09],[0.06,0.24],[0,0],[0,0],[0.16,0.17],[0,0],[0.02,-0.07],[0.08,-0.37],[0,0]],"v":[[128.48,51.21],[127.24,51.23],[127.27,51.49],[127.55,52.16],[128.29,52.16],[127.97,52.74],[128.52,53.16],[129.03,52.25],[129.08,52.03],[128.48,51.21]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[1,1,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.37,0.32],[0,0],[0.32,1.37],[1.37,-0.32],[0,0],[0.2,-0.96],[-0.08,-0.32]],"o":[[0.32,1.37],[0,0],[1.37,-0.32],[-0.32,-1.37],[0,0],[-1.03,0.16],[-0.08,0.37],[0,0]],"v":[[127.27,51.49],[130.31,53.44],[136.11,52.14],[138.05,49.11],[135.02,47.16],[129.21,48.53],[127.27,50.42],[127.27,51.5]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.27,-0.52],[0,0],[-0.25,0.48],[0,0],[0.53,0.04]],"o":[[0,0],[-0.54,0.04],[0,0],[0.29,0.45],[0,0],[0.33,-0.47],[0,0]],"v":[[128.6,51.01],[124.69,51.02],[124.07,52.12],[125.94,55.58],[127.18,55.54],[129.13,52.12],[128.6,51.01]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.97,0.51,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0.23,-0.38],[0,0],[-0.23,-0.38],[0,0],[-0.45,0],[0,0],[-0.23,0.38],[0,0],[0.23,0.38],[0,0],[0.38,0]],"o":[[0,0],[-0.45,0],[0,0],[-0.23,0.38],[0,0],[0.23,0.38],[0,0],[0.45,0],[0,0],[0.23,-0.38],[0,0],[-0.23,-0.38],[0,0]],"v":[[171.23,39.04],[167.1,39.04],[166.05,39.64],[163.95,43.09],[163.95,44.29],[166.05,47.74],[167.1,48.34],[171.23,48.34],[172.28,47.74],[174.38,44.29],[174.38,43.09],[172.28,39.64],[171.23,39.04]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.08,-0.07],[0,0],[0,0],[0,0],[0.08,0],[0,0],[0.08,0.07],[0,0],[0,0],[0,0],[-0.08,0]],"o":[[0,0],[0.07,0],[0,0],[0,0],[0,0],[-0.07,0.07],[0,0],[-0.07,0],[0,0],[0,0],[0,0],[0.07,-0.07],[0,0]],"v":[[167.03,40.02],[171.15,40.02],[171.38,40.16],[173.48,43.61],[173.48,43.84],[171.38,47.29],[171.15,47.44],[167.03,47.44],[166.8,47.29],[164.7,43.84],[164.7,43.61],[166.8,40.16],[167.03,40.02]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.27,0.51,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0.39,-1.71],[0,0],[-1.64,-0.4],[0,0],[0,0],[-0.14,0.7],[0,0],[0,0],[-0.4,1.64],[0,0],[0,0],[0.41,0.73],[0.8,0.2]],"o":[[0,0],[-1.64,-0.4],[0,0],[-0.4,1.64],[0,0],[0,0],[0.37,0.56],[0,0],[0,0],[1.64,0.4],[0,0],[0,0],[0.26,-0.79],[-0.4,-0.72],[0,0]],"v":[[113.02,64.14],[96.12,60.02],[92.4,62.36],[90.41,70.77],[92.68,74.49],[101.4,76.59],[105.39,83.21],[106.72,82.97],[107.88,78.22],[109.44,78.63],[113.16,76.36],[115.16,67.96],[115.15,67.96],[114.92,65.58],[113.02,64.14]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.2,0.66,0.33,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0.05,-0.3],[0,0],[-0.29,0.1],[0,0],[0.24,0.2]],"o":[[0,0],[-0.24,-0.2],[0,0],[-0.05,0.3],[0,0],[0.3,-0.03],[0,0]],"v":[[154.1,49.43],[149.45,45.32],[148.86,45.53],[147.67,51.66],[148.16,52.07],[154,50.05],[154.1,49.44]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[1,1,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-4.35,1.06],[0,0],[-1.07,-4.42],[4.35,-1.06],[0,0],[1.07,4.42]],"o":[[-1.06,-4.43],[0,0],[4.42,-1.07],[1.07,4.43],[0,0],[-4.35,1.06],[0,0]],"v":[[142.36,51.21],[148.34,41.28],[148.49,41.27],[158.36,47.33],[152.38,57.27],[152.23,57.28],[142.36,51.21]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.92,0.26,0.21,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.15,0.15],[0,0],[0.07,0.15],[0,0],[0.15,0],[0,0],[0.15,-0.15],[0,0],[0,-0.15],[0,0],[-0.15,0]],"o":[[0.15,0],[0,0],[0.07,-0.15],[0,0],[-0.07,-0.15],[0,0],[-0.15,0],[0,0],[-0.07,0.15],[0,0],[0.07,0.15],[0,0]],"v":[[120.15,61.99],[120.6,61.84],[122.55,59.52],[122.62,59.07],[121.64,56.14],[121.27,55.84],[118.34,55.24],[117.89,55.39],[115.95,57.71],[115.87,58.16],[116.85,61.09],[117.22,61.39]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.98,0.74,0.02,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,-0.45],[0.45,0],[0,0],[0,0.45],[-0.45,0]],"o":[[0,0],[0.45,0],[0,0.45],[0,0],[-0.45,0],[0,-0.45],[0,0]],"v":[[76.12,115.24],[110.62,115.24],[111.38,115.99],[110.62,116.74],[76.12,116.74],[75.38,115.99],[76.12,115.24]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,-0.82],[0.07,-0.15],[0,0],[0.68,0],[0,0],[0,0.82],[-0.07,0.15],[0,0],[-0.68,0]],"o":[[0,0],[0.82,0],[0,0.15],[0,0],[-0.15,0.68],[0,0],[-0.82,0],[0,-0.15],[0,0],[0.15,-0.68],[0,0]],"v":[[87,92.74],[116.55,92.74],[118.05,94.24],[117.98,94.62],[112.43,115.62],[111,116.74],[81.45,116.74],[79.95,115.24],[80.02,114.87],[85.57,93.87],[87,92.74]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.35,-1.2],[-0.23,-0.3],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.35,0],[0.68,0.52],[0,0],[0,0],[0.07,0.15],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.07,0],[0.3,0.82],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.15,0.15],[0.9,-0.82],[0,0],[0,0]],"o":[[1.27,-1.35],[0.23,0.23],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.52,1.35],[-0.38,0],[0,0],[0,0],[-0.07,-0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.07,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.23,0.15],[0.45,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.15,-0.23],[-0.9,-0.82],[0,0],[0,0],[0,0]],"v":[[75,107.66],[79.73,107.43],[80.4,108.26],[81.23,109.76],[81.68,110.58],[82.05,111.26],[82.28,111.63],[82.35,111.86],[82.43,112.01],[81.3,114.63],[79.73,113.81],[79.5,113.58],[79.12,113.28],[78.82,112.98],[78.22,112.38],[77.92,112],[77.17,111.25],[76.8,110.8],[76.57,110.58],[77.32,109.98],[77.77,110.5],[78.52,111.4],[78.89,111.77],[79.04,111.85],[79.95,112.75],[80.09,112.82],[80.32,113.05],[80.55,113.2],[80.77,113.42],[81.14,113.57],[81.37,112.3],[81.37,112.22],[81.3,112.07],[81.15,111.77],[80.85,111.1],[80.47,110.35],[79.57,108.77],[79.12,108.17],[75.9,108.17],[75.82,108.25],[75,107.64]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-0.98],[1.2,-0.6],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.67,-0.68],[1.5,0.3],[-0.07,0.3],[-0.3,-0.07],[-2.55,2.32],[-0.98,0.6],[-0.15,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0.3],[0.6,0],[1.73,-0.68],[0.08,0.3],[-0.3,0.08],[-0.98,0]],"o":[[1.12,0],[0,0.82],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.9,0.52],[-2.7,2.55],[-0.3,-0.07],[0.07,-0.3],[1.12,0.23],[0.75,-0.75],[0.07,-0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.75,-0.38],[0,-0.38],[-0.82,0],[-0.23,0.07],[-0.07,-0.23],[1.65,-0.75],[0,0]],"v":[[78.6,114.71],[80.4,116.21],[78.6,118.23],[77.78,118.61],[76.43,119.21],[75.53,119.59],[74.85,119.89],[73.95,120.34],[73.5,120.64],[71.1,122.44],[64.8,125.81],[64.43,125.21],[65.03,124.84],[70.5,121.69],[73.13,119.74],[73.43,119.59],[73.8,119.44],[74.18,119.21],[74.63,118.99],[75.3,118.69],[76.43,118.16],[77.25,117.79],[78.3,117.34],[78.45,117.27],[79.5,116.21],[78.68,115.69],[74.93,116.67],[74.33,116.37],[74.63,115.77],[78.61,114.71]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.97,-1.12],[-0.08,-0.45],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.2,0.23],[0.45,0.97],[0,0],[0,0],[-0.3,-0.07],[0.15,0.82],[0,0],[0,0],[0,0],[0,0],[0,0],[0.15,0.23],[0.75,-0.6],[0,0],[0,0]],"o":[[1.12,-1.05],[0.3,0.3],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.23,1.43],[-0.68,-0.15],[0,0],[0,0],[0.38,0.82],[0.3,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.07,-0.3],[-0.6,-0.68],[0,0],[0,0],[0,0]],"v":[[72.83,108.04],[76.73,108.26],[77.33,109.39],[77.63,110.51],[78,111.86],[78.15,112.54],[78.23,112.99],[78.3,113.21],[78.3,113.36],[76.88,115.69],[75.15,114.04],[75.07,113.89],[75.97,113.52],[77.02,114.79],[77.32,113.59],[77.25,113.36],[77.1,112.84],[76.88,112.02],[76.65,111.12],[76.35,109.62],[75.97,108.87],[73.57,108.72],[73.5,108.79],[72.82,108.04]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.2,-0.98],[-0.22,-0.45],[0,0],[0,0],[0,0],[0,0],[0,0],[1.28,0],[0.6,0.9],[0,0],[0,0],[-0.38,0],[0.23,0.82],[0,0],[0,0],[0,0],[0,0],[0.07,0.08],[0.22,0.15],[0.68,-0.75],[0,0],[0,0]],"o":[[0.98,-1.2],[0.38,0.3],[0,0],[0,0],[0,0],[0,0],[0,0],[0.45,1.35],[-0.75,0],[0,0],[0,0],[0.52,0.75],[0.3,0],[0,0],[0,0],[0,0],[0,0],[-0.07,-0.07],[-0.15,-0.23],[-0.75,-0.6],[0,0],[0,0],[0,0]],"v":[[69.38,108.86],[73.27,108.41],[74.1,109.46],[75,111.48],[75.6,112.76],[75.82,113.36],[75.97,113.73],[76.05,113.81],[75,116.43],[72.97,115.08],[72.82,114.93],[73.65,114.41],[75,115.46],[75.15,114.19],[75.07,113.96],[74.85,113.51],[74.4,112.54],[73.27,110.06],[73.12,109.83],[72.6,109.16],[70.12,109.38],[70.12,109.46],[69.38,108.86]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.43,-2.7],[-0.3,-0.75],[0,0],[0,0],[0,0],[1.57,0.45],[0.98,1.43],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.07,-0.38],[0,0],[2.25,-0.53],[0.08,0.3],[-0.3,0.08],[-0.38,1.05],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.22,-0.45],[0,0],[-0.07,-0.08],[0,0],[0,0],[-0.38,-0.15],[0.22,0.68],[0,0],[0,0],[0.07,0.3],[0.3,0.68],[1.27,-0.3],[1.27,-2.03],[0,0],[0,0],[0.15,-0.3],[0,0],[0,0],[0,0],[0,0],[0,0],[0.07,-0.07],[0.3,0.15],[-0.15,0.3],[0,0],[0,0],[0,0],[0,0],[-1.65,0.38]],"o":[[1.8,-0.38],[0.38,0.68],[0,0],[0,0],[0,0],[0.52,1.57],[-0.68,-0.23],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.07,0.52],[0,0],[-0.52,1.43],[-0.3,0.07],[-0.07,-0.3],[1.95,-0.45],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,-0.52],[0,0],[0.07,0.07],[0,0],[0,0],[0.68,0.9],[0.9,0.23],[0,0],[0,0],[-0.07,-0.3],[-0.3,-0.75],[-1.2,-2.4],[-0.98,0.23],[0,0],[0,0],[-0.15,0.23],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.07,0.07],[-0.15,0.23],[-0.3,-0.15],[0,0],[0,0],[0,0],[0,0],[1.95,-3.75],[0,0]],"v":[[67.95,108.41],[72.75,112.31],[73.73,114.48],[73.88,114.93],[74.1,115.54],[74.25,115.91],[72.07,117.86],[69.6,115.38],[69.45,115.16],[69.38,115.91],[69.3,116.58],[69.15,117.79],[69,118.83],[69,119.06],[68.86,119.96],[68.55,121.31],[68.48,121.46],[64.36,124.38],[63.75,124.01],[64.13,123.41],[67.58,121.16],[67.65,121.01],[67.73,120.78],[67.73,120.63],[67.88,120.26],[67.88,120.11],[68.02,119.36],[68.25,118.01],[68.39,116.96],[68.62,115.16],[68.77,113.81],[68.77,113.43],[69.66,113.21],[70.12,114.11],[70.27,114.33],[70.72,115.08],[70.95,115.38],[72.52,116.96],[73.5,116.36],[73.42,116.05],[73.12,115.68],[72.82,114.86],[71.92,112.75],[68.17,109.38],[64.8,112.68],[64.5,113.13],[64.2,113.65],[63.75,114.48],[63.45,115.08],[63.22,115.45],[62.92,116.13],[62.32,117.4],[61.71,118.6],[61.57,118.9],[60.89,119.13],[60.66,118.45],[61.56,116.65],[62.16,115.45],[62.46,114.85],[62.61,114.55],[67.94,108.4]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.15,-0.23],[-0.15,-0.45],[0.98,0],[2.17,2.55],[0,0],[0,-0.38],[0.82,0.15],[0.3,0.68],[0,0],[0.9,0],[0,0],[0,0],[0,-1.27],[3.9,-3.6],[1.35,0.22],[0,0],[0,0],[-0.38,0.75],[-1.58,0.3],[-0.6,-0.38],[0,0],[-0.98,-0.75],[-0.07,-0.15],[0,0],[-0.75,-0.38],[-1.2,-1.05]],"o":[[0.23,0.23],[1.12,2.02],[0.38,0.9],[-0.68,0],[0,0],[0.52,1.88],[0.15,0.98],[-0.45,-0.07],[0,0],[0.3,0.9],[0,0],[0,0],[3.45,-1.27],[0,1.95],[-2.55,2.4],[0,0],[0,0],[0.9,-1.8],[1.88,-3.6],[0.6,-0.15],[0,0],[0.82,-0.98],[0.07,0.07],[0,0],[0.68,-0.6],[0.98,-1.27],[0,0]],"v":[[79.43,107.81],[79.95,108.48],[81.9,112.16],[81.22,114.11],[76.95,110.29],[76.88,110.06],[77.7,113.43],[76.8,115.23],[75.6,114.11],[75.6,114.04],[75,115.98],[74.77,115.98],[74.62,116.21],[79.88,116.21],[70.73,122.06],[64.88,125.36],[63.38,122.36],[61.12,118.69],[63,114.79],[68.1,108.94],[69.9,109.39],[69.83,109.24],[73.05,108.86],[73.36,109.16],[73.05,108.49],[75.45,108.11],[79.43,107.81]],"c":true}}},{"ty":"fl","o":{"k":30},"c":{"k":[0.13,0.44,0.91,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[3.15,-0.6],[3.52,2.93],[0,0],[0,0],[-2.85,0.52],[-1.05,3.6],[0,0]],"o":[[0,0],[-1.12,4.12],[-3.07,0.6],[0,0],[0,0],[3.45,3],[2.7,-0.52],[0,0],[0,0]],"v":[[53.9,95.62],[54.88,95.84],[48.5,102.97],[38.6,99.37],[38.3,99.14],[38.9,98.39],[48.28,102.07],[53.83,95.92],[53.9,95.62]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.15,-0.22],[-0.3,0],[-0.07,0.22],[0,0],[-0.22,-0.07],[0.07,-0.22],[0.68,-0.08],[0.45,0.45],[-0.22,0.23]],"o":[[0.23,-0.15],[0.23,0.23],[0.23,-0.07],[0,0],[0.07,-0.3],[0.3,0.07],[-0.07,0.68],[-0.52,0.07],[-0.15,-0.23],[0,0]],"v":[[48.07,88.24],[48.75,88.32],[49.57,88.69],[50.1,88.24],[50.1,88.17],[50.62,87.79],[51,88.32],[49.64,89.67],[48,88.99],[48.07,88.24]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.07,-0.23],[0.23,-0.07],[2.47,-3.9],[-2.32,-6.08],[-3,-1.65],[-9.45,4.95],[0,0],[-0.15,0.08],[0,0],[-0.15,0.08],[0,0],[0,0],[0,0],[-0.3,0.15],[0,0],[-0.15,0.15],[0,0],[0,0],[0,0],[0.15,0.15],[0,0],[0,0],[-0.22,0.23],[-0.15,-0.22],[0,0],[0,0],[0,0],[-0.07,-0.23],[0,0],[0,0],[0.22,-0.15],[0,0],[0,0],[0,0],[0,0],[0.15,-0.15],[0,0],[0,0],[0.38,-0.23],[0,0],[0.07,-0.08],[0,0],[0,0],[5.7,3.15],[1.95,5.02],[-3.97,6.38],[-6.53,3.08]],"o":[[0.3,-0.15],[0.07,0.23],[-6.38,3.07],[-3.82,6.07],[1.88,4.8],[5.25,2.85],[0,0],[0.15,-0.07],[0,0],[0.15,-0.07],[0,0],[0,0],[0,0],[0.3,-0.15],[0,0],[0.15,-0.07],[0,0],[0,0],[0,0],[-0.15,0.07],[0,0],[0,0],[-0.15,-0.23],[0.23,-0.15],[0,0],[0,0],[0,0],[0.23,-0.07],[0,0],[0,0],[0.15,0.23],[0,0],[0,0],[0,0],[0,0],[-0.15,0.07],[0,0],[0,0],[-0.38,0.23],[0,0],[-0.15,0.07],[0,0],[0,0],[-10.12,5.4],[-3.38,-1.88],[-2.48,-6.38],[2.62,-4.12],[0,0]],"v":[[40.62,96.74],[41.3,96.97],[41.07,97.64],[27.8,108],[25.93,126.6],[34.32,137.25],[56.38,134.17],[57.12,133.8],[57.5,133.57],[58.25,133.12],[58.62,132.89],[59.38,132.45],[61.02,131.55],[61.85,131.02],[62.67,130.5],[64.32,129.45],[64.77,129.15],[65.67,128.55],[60.12,118.05],[45.12,122.1],[44.59,121.95],[44.52,121.88],[42.27,118.88],[42.34,118.13],[43.02,118.2],[43.09,118.28],[45.12,120.98],[60.12,116.93],[60.64,117.15],[60.71,117.23],[66.71,128.48],[66.57,129.15],[66.19,129.45],[65.29,130.05],[64.47,130.66],[63.64,131.18],[63.2,131.48],[62.45,132],[61.62,132.53],[60.42,133.28],[59.6,133.73],[59.22,133.95],[58.4,134.4],[57.65,134.85],[33.95,138.3],[24.95,126.98],[26.9,107.48],[40.62,96.75]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-4.65,-2.17],[-1.73,-4.12],[0.3,-0.07],[0.07,0.3],[4.5,2.1],[3.98,-0.38],[0.08,0.3],[-0.3,0.07]],"o":[[4.2,-0.38],[4.65,2.25],[0.07,0.3],[-0.3,0.07],[-1.65,-3.9],[-4.5,-2.18],[-0.3,0],[0.07,-0.38],[0,0]],"v":[[50.75,95.54],[63.95,98.32],[73.55,107.92],[73.25,108.59],[72.57,108.29],[63.43,99.29],[50.75,96.67],[50.15,96.22],[50.75,95.54]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.07,-0.23],[0,0],[0,0],[0.3,0],[0.07,0.23],[0,0],[0,0],[-0.3,0.07]],"o":[[0.23,0],[0,0],[0,0],[0,0.3],[-0.23,0],[0,0],[0,0],[-0.07,-0.23],[0,0]],"v":[[61.85,107.62],[62.38,107.99],[62.38,108.07],[63.12,115.57],[62.68,116.09],[62.15,115.71],[62.15,115.64],[61.4,108.14],[61.85,107.62]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[1.2,1.12],[1.12,-1.2],[-1.2,-1.12],[-1.12,1.2]],"o":[[1.12,-1.2],[-1.2,-1.12],[-1.12,1.2],[1.2,1.12],[0,0]],"v":[[44.18,80.82],[41.85,74.52],[37.58,74.66],[37.73,78.94],[44.18,80.81]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,1.04],[1.04,0],[0,-1.04],[-1.04,0]],"o":[[1.04,0],[0,-1.04],[-1.04,0],[0,1.04],[0,0]],"v":[[42,90.49],[43.88,88.62],[42,86.74],[40.12,88.62],[42,90.49]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[2.1,-0.9],[0.45,-3.07]],"o":[[0,0],[-2.4,-1.88],[-2.1,0.9],[0,0]],"v":[[41.62,86.74],[52.12,82.24],[45.38,80.74],[41.62,86.74]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-3.6],[-3.6,0],[0,3.6],[3.6,0]],"o":[[-3.6,0],[0,3.6],[3.6,0],[0,-3.6],[0,0]],"v":[[47.62,79.46],[41.1,85.99],[47.62,92.51],[54.15,85.99],[47.62,79.46]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-3],[3,0],[0,3],[-3,0]],"o":[[3,0],[0,3],[-3,0],[0,-3],[0,0]],"v":[[47.62,80.52],[53.1,85.99],[47.62,91.47],[42.15,85.99],[47.62,80.52]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.8,0.3],[0,0],[2.7,0],[2,2],[0,0],[0,0],[-3,0]],"o":[[1,0],[0,0],[-1.3,2.7],[-2.7,0],[0,0],[0,0],[1.4,2.4],[0,0]],"v":[[63.5,122.66],[66.2,122.16],[67.5,128.66],[61.5,132.66],[54.5,129.66],[56.5,118.66],[56.6,118.66],[63.5,122.66]],"c":true}}},{"ty":"st","lc":1,"lj":1,"ml":4,"o":{"k":100},"w":{"k":1.4},"c":{"k":[0.26,0.52,0.96,1]},"hd":false},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[75,75]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-3.3],[2.33,-0.82],[0,0],[2.02,0],[1.5,1.5],[0,0],[0,0],[0,1.12],[-3.3,0]],"o":[[3.3,0],[0,2.62],[0,0],[-0.98,2.02],[-2.02,0],[0,0],[0,0],[-0.52,-0.9],[0,-3.3],[0,0]],"v":[[47.62,79.99],[53.62,85.99],[49.65,91.62],[50.62,96.49],[46.12,99.49],[40.88,97.24],[42.38,88.99],[42.45,88.99],[41.62,85.99],[47.62,79.99]],"c":true}}},{"ty":"fl","o":{"k":30},"c":{"k":[0.13,0.44,0.91,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,1.05],[1.05,0],[0,-1.05],[-1.05,0]],"o":[[1.05,0],[0,-1.05],[-1.05,0],[0,1.05],[0,0]],"v":[[54,87.49],[55.88,85.62],[54,83.74],[54,85.69],[54,87.49]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.3,-0.08],[0,0],[-0.08,0.23],[0,0],[0,0],[0.23,0.07],[0,0],[0,0],[0,0.15],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0.07],[0,0],[0.23,0.45],[0.6,-0.23],[0.53,-0.6],[0,0],[0,0],[0,0],[0.07,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.2,0.53],[0,-0.38]],"o":[[0,0],[0,0.3],[0,0],[0.3,0],[0,0],[0,0],[0,-0.23],[0,0],[0,0],[0.15,-0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.15,-0.23],[0,0],[0,-0.82],[-0.3,-0.6],[-0.45,0.15],[0,0],[0,0],[0,0],[-0.07,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.27,0.9],[-0.38,-0.23],[0,0]],"v":[[135.75,144.11],[134.4,154.69],[134.85,155.29],[146.7,156.79],[147.3,156.41],[148.66,151.02],[148.66,150.94],[148.36,150.42],[146.03,149.22],[149.03,148.09],[149.33,147.72],[149.63,146.52],[149.86,145.32],[150.09,144.2],[150.23,143.45],[150.53,142.09],[150.68,141.12],[150.9,139.31],[151.12,137.74],[151.12,137.52],[151.2,137.07],[151.2,135.19],[151.35,134.89],[151.35,134.52],[150.97,132.57],[149.55,132.04],[148.12,133.17],[147.67,133.62],[147.44,133.92],[146.84,134.52],[146.69,134.67],[146.24,135.2],[146.02,135.72],[145.49,136.39],[144.74,137.37],[143.24,139.39],[142.49,140.37],[141.97,141.05],[141.52,141.65],[141.22,142.02],[140.92,142.48],[140.25,143.14],[140.25,143.22],[136.5,143.74],[135.75,144.12]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.35,0.9],[0,0],[0,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.23,0.15],[0,0],[0,0],[0,0],[-0.08,-0.38],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.38,-0.15],[0,0],[0,0],[0,0],[0,0]],"o":[[1.43,0.38],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,-0.07],[0.38,-0.45],[0,0],[0,0],[0,0],[0.07,0.23],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.38,0.23],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[136.73,144.94],[140.86,144.11],[141.15,143.96],[141.23,143.89],[141.75,143.37],[142.2,142.77],[142.5,142.39],[142.95,141.87],[143.55,141.04],[144.45,139.84],[145.73,138.04],[146.25,137.29],[146.77,136.62],[147.38,135.87],[147.6,135.42],[147.9,135.12],[148.58,134.21],[148.81,133.99],[148.88,133.91],[149.86,133.09],[150.01,133.02],[150.08,133.02],[150.08,133.16],[150.31,133.99],[150.31,136.76],[150.09,138.11],[150.09,138.34],[149.94,139.38],[149.86,139.83],[149.79,140.43],[149.64,141.33],[149.49,142.31],[149.27,143.29],[149.12,144.04],[148.89,145.16],[148.74,145.91],[148.44,147.18],[144.62,148.68],[144.54,148.68],[144.54,149.58],[147.62,151.08],[146.42,155.66],[135.54,154.3],[136.74,144.93]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0.83,1.65],[2.18,-1.5],[1.42,0.68],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[1.88,-8.18],[-1.12,-2.48],[-1.43,1.05],[0,0],[0,0]],"v":[[134.93,154.77],[146.78,156.27],[148.13,150.87],[144.68,149.14],[148.73,147.57],[150.38,132.79],[140.4,143.59],[136.13,144.12],[134.93,154.77]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.15,-0.23],[0,0],[-0.23,0.07],[0,0],[0,0],[0.07,0.22],[0,0],[0,0],[-0.22,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.08,0.07],[0,0],[-0.08,0.07],[0,0],[0,0],[0,0],[0,0],[-0.22,0.45],[0.52,0.38],[0.75,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0.3,1.27],[0.3,-0.15]],"o":[[0,0],[-0.23,0.15],[0,0],[0.15,0.23],[0,0],[0,0],[0.15,-0.15],[0,0],[0,0],[0.15,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.07,-0.07],[0,0],[0.07,-0.07],[0,0],[0,0],[0.15,0],[0,0],[0.68,-0.52],[0.3,-0.6],[-0.38,-0.23],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.5,-0.45],[0,-0.6],[0,0]],"v":[[115.05,145.54],[105.82,151.02],[105.68,151.69],[111.82,161.96],[112.5,162.19],[117.6,159.94],[117.68,159.87],[117.9,159.34],[117.38,156.79],[120.08,158.44],[120.6,158.44],[121.73,157.92],[123.83,156.87],[124.5,156.57],[126.61,155.52],[128.18,154.62],[129.52,153.71],[129.75,153.57],[130.12,153.34],[130.35,153.19],[131.1,152.74],[131.7,152.29],[131.93,152.21],[132.23,151.98],[133.5,150.48],[133.05,148.98],[131.33,148.54],[127.2,148.54],[125.93,148.61],[123.38,148.68],[122.18,148.76],[118.43,148.76],[115.73,146.13],[115.05,145.53]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.58,-0.52],[0,0],[0,0],[0,0],[0,0],[-0.22,-0.15],[0,0],[0,0],[0,0],[0.22,-0.23],[0,0],[0,0],[0,0],[0,0],[0.07,-0.07],[0,0],[0,0],[0.08,-0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.07,-0.45],[0,0],[0,0],[0,0],[0,0]],"o":[[0.52,1.35],[0,0],[0,0],[0,0],[0,0],[0.6,0.07],[0,0],[0,0],[0,0],[-0.15,0.23],[0,0],[0,0],[0,0],[0,0],[-0.07,0],[0,0],[0,0],[-0.07,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.38,-0.15],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[114.98,146.81],[118.2,149.59],[122.18,149.59],[123.68,149.51],[125.93,149.44],[131.11,149.44],[132.38,149.74],[132.53,149.96],[132.6,149.96],[132.53,150.04],[132,150.71],[131.86,150.94],[131.33,151.47],[130.73,151.92],[130.35,152.07],[130.2,152.22],[129.08,152.9],[128.63,153.12],[128.4,153.27],[127.95,153.5],[127.5,153.8],[126.46,154.4],[125.63,154.85],[123.98,155.68],[123.31,155.98],[122.33,156.5],[121.66,156.8],[120.46,157.4],[116.93,155.3],[116.86,155.3],[116.11,155.9],[116.79,159.2],[112.43,161.08],[106.88,151.63],[114.98,146.83]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[-0.82,1.58],[2.55,0.75],[0.38,1.5],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[7.65,-3.52],[1.2,-2.48],[-1.73,-0.52],[0,0],[0,0]],"v":[[106.12,151.46],[112.27,161.74],[117.38,159.49],[116.62,155.74],[120.38,157.99],[133.05,150.26],[118.35,148.99],[115.28,145.99],[106.13,151.46]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-5.25,-6.97],[0,0],[-0.6,-0.9],[0,0],[-0.15,-0.23],[0,0],[-0.08,-0.07],[-2.85,-1.88],[-0.3,-0.45],[1.5,-1.05],[0,0],[0,0],[1.35,1.57],[0,0],[0,0],[0,0],[11.77,-2.1],[0,0],[2.03,15.3],[-0.3,0.08],[-0.08,-0.3],[-11.7,1.95],[-5.4,13.88],[-0.22,-0.22],[0,0],[0,0],[-1.35,0.75],[0,0],[0,0],[0.68,1.12],[0.3,0.15],[1.27,2.1],[0,0],[0.08,0.15],[0,0],[0.38,0.6],[0,0],[6.67,0.53],[6.75,-3.75],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.15,0.3],[-0.3,0.15],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-6.15,-0.45]],"o":[[6.6,0.52],[0,0],[0.6,0.75],[0,0],[0.15,0.23],[0,0],[0.07,0.15],[1.2,1.95],[0.45,0.3],[0.98,1.57],[0,0],[0,0],[-1.8,1.12],[0,0],[0,0],[0,0],[-5.55,13.5],[0,0],[-12.3,1.95],[-0.07,-0.3],[0.3,-0.07],[1.95,14.7],[11.77,-1.95],[0.15,-0.38],[0,0],[0,0],[0.98,1.2],[0,0],[0,0],[1.2,-0.75],[-0.23,-0.3],[-3,-1.88],[0,0],[-0.07,-0.15],[0,0],[-0.38,-0.6],[0,0],[-5.4,-7.65],[-5.77,-0.45],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.23,0.15],[-0.15,-0.3],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[6.9,-3.9],[0,0]],"v":[[91.95,115.47],[109.12,126.42],[109.57,127.09],[111.3,129.57],[111.75,130.32],[112.2,131.07],[112.65,131.89],[112.88,132.27],[118.88,137.97],[120,139.09],[119.02,143.82],[118.88,143.89],[106.65,151.47],[101.17,150.64],[101.02,150.5],[89.4,135.8],[89.4,135.87],[63.45,159.27],[63.07,159.34],[41.47,139.32],[41.92,138.72],[42.52,139.17],[62.92,158.22],[88.72,134.52],[89.55,134.29],[89.62,134.37],[101.77,149.74],[105.82,150.57],[105.97,150.49],[118.27,142.92],[119.09,139.54],[118.34,138.79],[111.97,132.79],[111.52,131.97],[111.29,131.59],[110.84,130.84],[109.64,129.04],[109.2,128.37],[91.8,116.52],[74.25,121.39],[73.5,121.84],[72.37,122.44],[70.27,123.71],[68.32,124.84],[67.34,125.36],[66.45,125.89],[65.84,126.19],[65.09,125.96],[65.32,125.21],[66.45,124.54],[67.34,124.01],[71.54,121.54],[72.52,121.01],[73.12,120.71],[73.72,120.48],[91.95,115.46]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[-2.85,-1.8],[-0.15,-0.38],[1.2,-0.75],[0,0],[1.05,1.27],[0,0],[0.23,-0.15],[0,-0.07],[7.72,-3.68],[0,0],[0,0],[0,0],[-0.15,0.07],[0,0],[0,0],[-0.07,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-11.92,-0.9],[-0.3,2.25],[0,0],[0,0],[2.1,0.38],[0,0],[0,0]],"o":[[0,0],[0,0],[1.27,1.95],[0.3,0.23],[0.75,1.2],[0,0],[-1.43,0.9],[0,0],[-0.15,-0.23],[-0.07,0],[-4.12,10.5],[0,0],[0,0],[0,0],[0.15,0],[0,0],[0,0],[0.15,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[11.7,-0.15],[2.25,0.15],[0,0],[0,0],[0.15,-2.18],[0,0],[0,0],[0,0]],"v":[[112.79,132.36],[111.74,132.29],[112.27,133.11],[118.41,138.73],[119.16,139.56],[118.34,143.01],[106.11,150.58],[101.84,149.83],[89.61,134.46],[88.94,134.38],[88.79,134.53],[71.02,155.76],[67.87,157.26],[71.62,156.66],[73.12,156.51],[73.49,156.43],[74.24,156.36],[75.07,156.29],[75.44,156.21],[76.27,156.14],[78.96,155.91],[81.89,155.69],[82.87,155.54],[83.92,155.47],[85.49,155.39],[87.14,155.32],[88.27,155.25],[95.54,155.25],[130.94,156.45],[135.51,152.7],[136.94,141],[136.94,140.85],[133.49,136.35],[112.94,132.37],[112.79,132.37]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0.15,-1.65],[0,0],[0,0],[1.8,0.15],[11.7,-0.08],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.15,-0.07],[0,0],[0.3,0],[0,0],[0.15,-0.07],[0,0],[0,0],[0,0],[-3.75,9],[0,0],[0,0],[-1.8,1.12],[0,0],[1.05,1.65],[0.38,0.3],[1.2,1.43]],"o":[[0,0],[0,0],[1.65,0.3],[0,0],[0,0],[-0.23,1.73],[-11.77,-0.98],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.15,0],[0,0],[-0.3,0],[0,0],[-0.15,0],[0,0],[0,0],[0,0],[6.45,-3.9],[0,0],[0,0],[1.35,1.65],[0,0],[1.65,-0.98],[-0.3,-0.45],[-2.18,-1.2],[0,0]],"v":[[113.99,133.79],[113.77,133.56],[133.27,137.23],[135.89,140.68],[135.89,140.83],[134.46,152.53],[130.94,155.38],[95.62,154.11],[92.84,154.11],[90.82,154.18],[88.87,154.26],[87,154.33],[83.4,154.55],[81.15,154.7],[80.1,154.78],[78.97,154.78],[78.45,154.85],[77.47,154.93],[76.5,155],[75.52,155.07],[75.07,155.15],[74.17,155.22],[73.95,155.22],[74.09,155.15],[89.39,135.8],[89.47,135.57],[101.09,150.27],[106.64,151.25],[118.95,143.67],[120.07,138.87],[119.02,137.75],[114,133.77]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[215.44,69.79],[214.25,80.99]],"c":false}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[212.94,93.53],[210.99,111.94]],"c":false}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[170.6,38.4],[184.52,39.86]],"c":false}}},{"ty":"st","lc":2,"lj":2,"ml":4,"o":{"k":100},"w":{"k":1.3},"c":{"k":[0.26,0.52,0.96,1]},"hd":false},{"ty":"fl","o":{"k":100},"c":{"k":[0,0,0,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[75,75]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.04,-1.28],[0.18,-1.64],[0,0],[1.29,-1.04],[1.64,0.18],[0,0],[0.39,2.76],[-0.3,0.04],[-2.46,-0.26],[0,0],[-0.3,2.83],[0,0],[0.88,1.09],[1.39,0.14],[0,0],[0.3,-2.84],[0,0],[0.3,-0.04],[0,0],[0,0],[-1.29,1.04],[-1.64,-0.18],[0,0]],"o":[[1.64,0.17],[1.04,1.29],[0,0],[-0.17,1.64],[-1.28,1.04],[0,0],[-2.91,-0.3],[0.3,-0.04],[0.35,2.38],[0,0],[2.91,0.3],[0,0],[0.15,-1.39],[-0.88,-1.08],[0,0],[-2.91,-0.3],[0,0],[-0.3,-0.03],[0,0],[0,0],[0.17,-1.64],[1.29,-1.04],[0,0],[0,0]],"v":[[156.92,28.54],[161.11,30.8],[162.46,35.38],[149.39,159.64],[147.12,163.84],[142.55,165.18],[91.31,159.8],[85.77,154.39],[86.76,154.34],[91.41,158.83],[142.66,164.21],[148.43,159.54],[161.49,35.28],[160.36,31.41],[156.82,29.51],[105.57,24.12],[99.8,28.79],[90.7,115.39],[89.72,115.44],[98.84,28.69],[98.83,28.69],[101.1,24.5],[105.68,23.15],[156.92,28.54]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.26,0.52,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0.3,-2.87],[0,0],[2.85,0.3],[0,0],[0,0],[-10.98,-0.86],[-0.29,2.03],[0,0],[0,0],[1.93,0.36],[0,0],[0,0],[0.14,0.09],[8.57,0.6],[0,0],[0,0],[-2.85,-0.3]],"o":[[2.85,0.3],[0,0],[-0.3,2.87],[0,0],[0,0],[11.01,-0.07],[2.03,0.14],[0,0],[0,0],[0.12,-1.89],[0,0],[0,0],[-0.07,-0.08],[-6.06,-10.1],[0,0],[0,0],[0.3,-2.87],[0,0]],"v":[[154.72,33.58],[159.34,39.34],[147.19,154.94],[141.47,159.61],[98.53,155.09],[98.53,155.09],[131.52,156.27],[135.58,152.96],[136.98,141.12],[136.99,140.96],[133.93,136.98],[113.27,133.12],[113.12,133.11],[112.85,132.78],[92.17,116.1],[92.25,116.11],[100.89,33.19],[106.61,28.52]],"c":true}}},{"ty":"fl","o":{"k":30},"c":{"k":[0.13,0.44,0.91,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.07,0.67],[0.6,0.07],[0.06,-0.59],[-0.6,-0.07]],"o":[[0.67,0.07],[0.07,-0.67],[-0.6,-0.06],[-0.06,0.6],[0,0]],"v":[[124.36,29.71],[125.6,28.71],[124.6,27.48],[123.36,28.48],[124.36,29.71]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]}]}],"meta":{"g":"LF SVG to Lottie"}}
diff --git a/ash/public/cpp/resources/unscaled_resources/phone_hub_onboarding_image.png b/ash/public/cpp/resources/unscaled_resources/phone_hub_onboarding_image.png deleted file mode 100644 index 2fcbee5..0000000 --- a/ash/public/cpp/resources/unscaled_resources/phone_hub_onboarding_image.png +++ /dev/null Binary files differ
diff --git a/ash/system/phonehub/bluetooth_disabled_view.cc b/ash/system/phonehub/bluetooth_disabled_view.cc index ccadc2bf..1aa2635 100644 --- a/ash/system/phonehub/bluetooth_disabled_view.cc +++ b/ash/system/phonehub/bluetooth_disabled_view.cc
@@ -37,7 +37,6 @@ auto* content_view = AddChildView( std::make_unique<PhoneHubInterstitialView>(/*show_progress=*/false)); - // TODO(crbug.com/1127996): Replace PNG file with vector icon. gfx::ImageSkia* image = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( IDR_PHONE_HUB_ERROR_STATE_IMAGE);
diff --git a/ash/system/phonehub/onboarding_view.cc b/ash/system/phonehub/onboarding_view.cc index f0b73ed..7e47831 100644 --- a/ash/system/phonehub/onboarding_view.cc +++ b/ash/system/phonehub/onboarding_view.cc
@@ -68,7 +68,6 @@ private: void InitLayout() { - // TODO(crbug.com/1127996): Replace PNG file with vector icon. gfx::ImageSkia* image = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( IDR_PHONE_HUB_ONBOARDING_IMAGE);
diff --git a/ash/system/phonehub/phone_connecting_view.cc b/ash/system/phonehub/phone_connecting_view.cc index 246bef0..822fcc0a 100644 --- a/ash/system/phonehub/phone_connecting_view.cc +++ b/ash/system/phonehub/phone_connecting_view.cc
@@ -29,7 +29,6 @@ content_view_ = AddChildView( std::make_unique<PhoneHubInterstitialView>(/*show_progress=*/true)); - // TODO(crbug.com/1127996): Replace PNG file with vector icon. gfx::ImageSkia* image = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( IDR_PHONE_HUB_CONNECTING_IMAGE);
diff --git a/ash/system/phonehub/phone_disconnected_view.cc b/ash/system/phonehub/phone_disconnected_view.cc index b3dab41..bfe5096 100644 --- a/ash/system/phonehub/phone_disconnected_view.cc +++ b/ash/system/phonehub/phone_disconnected_view.cc
@@ -36,7 +36,6 @@ content_view_ = AddChildView(std::make_unique<PhoneHubInterstitialView>( /*show_progress=*/false)); - // TODO(crbug.com/1127996): Replace PNG file with vector icon. gfx::ImageSkia* image = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( IDR_PHONE_HUB_ERROR_STATE_IMAGE);
diff --git a/ash/system/phonehub/tether_connection_pending_view.cc b/ash/system/phonehub/tether_connection_pending_view.cc index 58365a11e..3ee16a0 100644 --- a/ash/system/phonehub/tether_connection_pending_view.cc +++ b/ash/system/phonehub/tether_connection_pending_view.cc
@@ -29,7 +29,6 @@ content_view_ = AddChildView( std::make_unique<PhoneHubInterstitialView>(/*show_progress=*/true)); - // TODO(crbug.com/1127996): Replace PNG file with vector icon. gfx::ImageSkia* image = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( IDR_PHONE_HUB_CONNECTING_IMAGE);
diff --git a/ash/test/ash_test_suite.cc b/ash/test/ash_test_suite.cc index 93ed86a..ea9d126d 100644 --- a/ash/test/ash_test_suite.cc +++ b/ash/test/ash_test_suite.cc
@@ -16,6 +16,7 @@ #include "ui/display/display_switches.h" #include "ui/gl/gl_switches.h" #include "ui/gl/test/gl_surface_test_support.h" +#include "ui/lottie/resource.h" namespace ash { @@ -40,6 +41,9 @@ // it'll pass regardless of the system language. base::i18n::SetICUDefaultLocale("en_US"); + ui::ResourceBundle::SetParseLottieAsStillImage( + &lottie::ParseLottieAsStillImage); + // Load ash test resources and en-US strings; not 'common' (Chrome) resources. base::FilePath path; base::PathService::Get(base::DIR_MODULE, &path);
diff --git a/ash/webui/BUILD.gn b/ash/webui/BUILD.gn index 48c6752..3af3926 100644 --- a/ash/webui/BUILD.gn +++ b/ash/webui/BUILD.gn
@@ -58,6 +58,7 @@ "//ash/webui/diagnostics_ui:closure_compile", "//ash/webui/file_manager/resources:closure_compile", "//ash/webui/file_manager/untrusted_resources:closure_compile", + "//ash/webui/firmware_update_ui:closure_compile", "//ash/webui/help_app_ui:closure_compile", "//ash/webui/media_app_ui:closure_compile", "//ash/webui/os_feedback_ui:closure_compile",
diff --git a/ash/webui/DEPS b/ash/webui/DEPS index 0a47bac..92944149 100644 --- a/ash/webui/DEPS +++ b/ash/webui/DEPS
@@ -6,4 +6,5 @@ "+content/public/common", "+content/public/test", "+mojo/core/embedder", + "+ui/webui", ]
diff --git a/ash/webui/firmware_update_ui/BUILD.gn b/ash/webui/firmware_update_ui/BUILD.gn new file mode 100644 index 0000000..331c2d7 --- /dev/null +++ b/ash/webui/firmware_update_ui/BUILD.gn
@@ -0,0 +1,26 @@ +# Copyright 2021 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. + +assert(is_chromeos, "Firmware Update App is Chrome OS only") + +static_library("firmware_update_ui") { + sources = [ + "firmware_update_app_ui.cc", + "firmware_update_app_ui.h", + "url_constants.cc", + "url_constants.h", + ] + + deps = [ + "//ash/webui/resources:firmware_update_app_resources", + "//content/public/browser", + "//ui/resources:webui_generated_resources_grd_grit", + "//ui/resources:webui_resources_grd_grit", + "//ui/webui", + ] +} + +group("closure_compile") { + deps = [ "resources:closure_compile" ] +}
diff --git a/ash/webui/firmware_update_ui/DEPS b/ash/webui/firmware_update_ui/DEPS new file mode 100644 index 0000000..0db0cc9 --- /dev/null +++ b/ash/webui/firmware_update_ui/DEPS
@@ -0,0 +1,5 @@ +include_rules = [ + "+ash/grit/ash_firmware_update_app_resources.h", + "+ash/grit/ash_firmware_update_app_resources_map.h", + "+ui/resources", +]
diff --git a/ash/webui/firmware_update_ui/OWNERS b/ash/webui/firmware_update_ui/OWNERS new file mode 100644 index 0000000..168fc77 --- /dev/null +++ b/ash/webui/firmware_update_ui/OWNERS
@@ -0,0 +1,3 @@ +# Primary OWNERS +jimmyxgong@chromium.org +zentaro@chromium.org \ No newline at end of file
diff --git a/ash/webui/firmware_update_ui/firmware_update_app_ui.cc b/ash/webui/firmware_update_ui/firmware_update_app_ui.cc new file mode 100644 index 0000000..4e7f470 --- /dev/null +++ b/ash/webui/firmware_update_ui/firmware_update_app_ui.cc
@@ -0,0 +1,55 @@ +// Copyright 2021 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/webui/firmware_update_ui/firmware_update_app_ui.h" + +#include "ash/grit/ash_firmware_update_app_resources.h" +#include "ash/grit/ash_firmware_update_app_resources_map.h" +#include "ash/webui/firmware_update_ui/url_constants.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_ui.h" +#include "content/public/browser/web_ui_data_source.h" +#include "services/network/public/mojom/content_security_policy.mojom.h" +#include "ui/resources/grit/webui_generated_resources.h" +#include "ui/resources/grit/webui_resources.h" +#include "ui/webui/mojo_web_ui_controller.h" + +namespace ash { + +namespace { + +void SetUpWebUIDataSource(content::WebUIDataSource* source, + base::span<const webui::ResourcePath> resources, + int default_resource) { + source->AddResourcePaths(resources); + source->SetDefaultResource(default_resource); + source->AddResourcePath("test_loader.html", IDR_WEBUI_HTML_TEST_LOADER_HTML); + source->AddResourcePath("test_loader.js", IDR_WEBUI_JS_TEST_LOADER_JS); + source->AddResourcePath("test_loader_util.js", + IDR_WEBUI_JS_TEST_LOADER_UTIL_JS); +} + +} // namespace + +FirmwareUpdateAppUI::FirmwareUpdateAppUI(content::WebUI* web_ui) + : ui::MojoWebUIController(web_ui) { + auto source = base::WrapUnique( + content::WebUIDataSource::Create(kChromeUIFirmwareUpdateAppHost)); + source->OverrideContentSecurityPolicy( + network::mojom::CSPDirectiveName::ScriptSrc, + "script-src chrome://resources chrome://test 'self';"); + source->DisableTrustedTypesCSP(); + + const auto resources = base::make_span(kAshFirmwareUpdateAppResources, + kAshFirmwareUpdateAppResourcesSize); + SetUpWebUIDataSource(source.get(), resources, + IDR_ASH_FIRMWARE_UPDATE_APP_INDEX_HTML); + + auto* browser_context = web_ui->GetWebContents()->GetBrowserContext(); + content::WebUIDataSource::Add(browser_context, source.release()); +} + +FirmwareUpdateAppUI::~FirmwareUpdateAppUI() = default; + +} // namespace ash \ No newline at end of file
diff --git a/ash/webui/firmware_update_ui/firmware_update_app_ui.h b/ash/webui/firmware_update_ui/firmware_update_app_ui.h new file mode 100644 index 0000000..509d527 --- /dev/null +++ b/ash/webui/firmware_update_ui/firmware_update_app_ui.h
@@ -0,0 +1,26 @@ +// Copyright 2021 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_WEBUI_FIRMWARE_UPDATE_UI_FIRMWARE_UPDATE_APP_UI_H_ +#define ASH_WEBUI_FIRMWARE_UPDATE_UI_FIRMWARE_UPDATE_APP_UI_H_ + +#include "ui/webui/mojo_web_ui_controller.h" + +namespace content { +class WebUI; +} // namespace content + +namespace ash { + +class FirmwareUpdateAppUI : public ui::MojoWebUIController { + public: + explicit FirmwareUpdateAppUI(content::WebUI* web_ui); + FirmwareUpdateAppUI(const FirmwareUpdateAppUI&) = delete; + FirmwareUpdateAppUI& operator=(const FirmwareUpdateAppUI&) = delete; + ~FirmwareUpdateAppUI() override; +}; + +} // namespace ash + +#endif // ASH_WEBUI_FIRMWARE_UPDATE_UI_FIRMWARE_UPDATE_APP_UI_H_ \ No newline at end of file
diff --git a/ash/webui/firmware_update_ui/resources/BUILD.gn b/ash/webui/firmware_update_ui/resources/BUILD.gn new file mode 100644 index 0000000..b5e51d8 --- /dev/null +++ b/ash/webui/firmware_update_ui/resources/BUILD.gn
@@ -0,0 +1,47 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") +import("//tools/grit/grit_rule.gni") +import("//tools/grit/preprocess_if_expr.gni") +import("//tools/polymer/html_to_js.gni") +import("//ui/webui/resources/tools/generate_grd.gni") + +preprocessed_dir = "preprocessed" +preprocessed_gen_manifest = "preprocessed_gen_manifest.json" + +polymer_element_files = [ "firmware_update_app.js" ] + +generate_grd("build_grd") { + input_files = [ "index.html" ] + input_files_base_dir = rebase_path(".", "//") + deps = [ ":preprocess_generated" ] + manifest_files = [ "$target_gen_dir/$preprocessed_gen_manifest" ] + grd_prefix = "ash_firmware_update_app" + out_grd = "$target_gen_dir/${grd_prefix}_resources.grd" +} + +js_type_check("closure_compile") { + is_polymer3 = true + closure_flags = default_closure_args + deps = [ ":firmware_update_app" ] +} + +js_library("firmware_update_app") { + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + +preprocess_if_expr("preprocess_generated") { + deps = [ ":web_components" ] + in_folder = target_gen_dir + out_folder = "$target_gen_dir/$preprocessed_dir" + out_manifest = "$target_gen_dir/$preprocessed_gen_manifest" + in_files = polymer_element_files +} + +html_to_js("web_components") { + js_files = polymer_element_files +}
diff --git a/ash/webui/firmware_update_ui/resources/firmware_update_app.html b/ash/webui/firmware_update_ui/resources/firmware_update_app.html new file mode 100644 index 0000000..743263b --- /dev/null +++ b/ash/webui/firmware_update_ui/resources/firmware_update_app.html
@@ -0,0 +1 @@ +<div id="header"></div>
diff --git a/ash/webui/firmware_update_ui/resources/firmware_update_app.js b/ash/webui/firmware_update_ui/resources/firmware_update_app.js new file mode 100644 index 0000000..0a43756 --- /dev/null +++ b/ash/webui/firmware_update_ui/resources/firmware_update_app.js
@@ -0,0 +1,28 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +/** + * @fileoverview + * 'firmware-update-app' is the main landing page for the firmware + * update app. + */ +export class FirmwareUpdateAppElement extends PolymerElement { + static get is() { + return 'firmware-update-app'; + } + + static get template() { + return html`{__html_template__}`; + } + + ready() { + super.ready(); + // TODO(michaelcheco): Remove this once the app has more capabilities. + this.$.header.textContent = 'Firmware Update'; + } +} + +customElements.define(FirmwareUpdateAppElement.is, FirmwareUpdateAppElement); \ No newline at end of file
diff --git a/ash/webui/firmware_update_ui/resources/index.html b/ash/webui/firmware_update_ui/resources/index.html new file mode 100644 index 0000000..4b8c66d --- /dev/null +++ b/ash/webui/firmware_update_ui/resources/index.html
@@ -0,0 +1,19 @@ +<!-- Copyright 2021 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. --> +<!DOCTYPE html> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> +<head> + <title></title> + <meta charset="utf-8"> +</head> +<body> + <firmware-update-app></firmware-update-app> + + <script type="module" src="firmware_update_app.js"> + </script> + <!-- Below mojo script required to run browser tests --> + <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"> + </script> +</body> +</html>
diff --git a/ash/webui/firmware_update_ui/url_constants.cc b/ash/webui/firmware_update_ui/url_constants.cc new file mode 100644 index 0000000..3a98680 --- /dev/null +++ b/ash/webui/firmware_update_ui/url_constants.cc
@@ -0,0 +1,11 @@ +// Copyright 2021 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/webui/firmware_update_ui/url_constants.h" + +namespace ash { + +const char kChromeUIFirmwareUpdateAppHost[] = "firmware-update"; + +} // namespace ash \ No newline at end of file
diff --git a/ash/webui/firmware_update_ui/url_constants.h b/ash/webui/firmware_update_ui/url_constants.h new file mode 100644 index 0000000..e12678e --- /dev/null +++ b/ash/webui/firmware_update_ui/url_constants.h
@@ -0,0 +1,14 @@ +// Copyright 2021 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_WEBUI_FIRMWARE_UPDATE_UI_URL_CONSTANTS_H_ +#define ASH_WEBUI_FIRMWARE_UPDATE_UI_URL_CONSTANTS_H_ + +namespace ash { + +extern const char kChromeUIFirmwareUpdateAppHost[]; + +} // namespace ash + +#endif // ASH_WEBUI_FIRMWARE_UPDATE_UI_URL_CONSTANTS_H_ \ No newline at end of file
diff --git a/ash/webui/media_app_ui/BUILD.gn b/ash/webui/media_app_ui/BUILD.gn index ef6b5d4..3c046b3e 100644 --- a/ash/webui/media_app_ui/BUILD.gn +++ b/ash/webui/media_app_ui/BUILD.gn
@@ -32,8 +32,10 @@ "//chromeos/components/web_applications", "//chromeos/strings", "//content/public/browser", + "//content/public/common", "//mojo/public/cpp/bindings", "//mojo/public/cpp/platform", + "//third_party/blink/public/common", "//ui/file_manager:resources", "//ui/webui", ]
diff --git a/ash/webui/media_app_ui/DEPS b/ash/webui/media_app_ui/DEPS index 74438497..9a6bb8d 100644 --- a/ash/webui/media_app_ui/DEPS +++ b/ash/webui/media_app_ui/DEPS
@@ -4,4 +4,8 @@ "+chromeos/grit/chromeos_media_app_bundle_resources.h", "+chromeos/grit/chromeos_media_app_bundle_resources_map.h", "+components/content_settings/core/common", + + # Allow only public Blink interfaces, similar to chrome/browser/DEPS. + "+third_party/blink/public/common", + "+third_party/blink/public/mojom", ]
diff --git a/ash/webui/media_app_ui/media_app_guest_ui.cc b/ash/webui/media_app_ui/media_app_guest_ui.cc index 191bc85..fd37b79 100644 --- a/ash/webui/media_app_ui/media_app_guest_ui.cc +++ b/ash/webui/media_app_ui/media_app_guest_ui.cc
@@ -9,10 +9,13 @@ #include "chromeos/components/web_applications/webui_test_prod_util.h" #include "chromeos/grit/chromeos_media_app_bundle_resources.h" #include "chromeos/grit/chromeos_media_app_bundle_resources_map.h" +#include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" #include "services/network/public/mojom/content_security_policy.mojom.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" +#include "third_party/blink/public/mojom/autoplay/autoplay.mojom.h" #include "ui/file_manager/grit/file_manager_resources.h" namespace ash { @@ -98,7 +101,8 @@ MediaAppGuestUI::MediaAppGuestUI(content::WebUI* web_ui, MediaAppGuestUIDelegate* delegate) - : ui::UntrustedWebUIController(web_ui) { + : UntrustedWebUIController(web_ui), + WebContentsObserver(web_ui->GetWebContents()) { content::WebUIDataSource* untrusted_source = CreateMediaAppUntrustedDataSource(delegate); @@ -108,4 +112,18 @@ MediaAppGuestUI::~MediaAppGuestUI() = default; +void MediaAppGuestUI::ReadyToCommitNavigation( + content::NavigationHandle* handle) { + // Force-enable autoplay support. + const std::string allowed_resource = "app.html"; + if (handle->GetURL() != GURL(kChromeUIMediaAppGuestURL + allowed_resource)) + return; + + mojo::AssociatedRemote<blink::mojom::AutoplayConfigurationClient> client; + handle->GetRenderFrameHost()->GetRemoteAssociatedInterfaces()->GetInterface( + &client); + client->AddAutoplayFlags(url::Origin::Create(handle->GetURL()), + blink::mojom::kAutoplayFlagForceAllow); +} + } // namespace ash
diff --git a/ash/webui/media_app_ui/media_app_guest_ui.h b/ash/webui/media_app_ui/media_app_guest_ui.h index dba3d07..e06b842f 100644 --- a/ash/webui/media_app_ui/media_app_guest_ui.h +++ b/ash/webui/media_app_ui/media_app_guest_ui.h
@@ -5,6 +5,7 @@ #ifndef ASH_WEBUI_MEDIA_APP_UI_MEDIA_APP_GUEST_UI_H_ #define ASH_WEBUI_MEDIA_APP_UI_MEDIA_APP_GUEST_UI_H_ +#include "content/public/browser/web_contents_observer.h" #include "ui/webui/untrusted_web_ui_controller.h" namespace content { @@ -22,12 +23,16 @@ }; // The webui for chrome-untrusted://media-app. -class MediaAppGuestUI : public ui::UntrustedWebUIController { +class MediaAppGuestUI : public ui::UntrustedWebUIController, + public content::WebContentsObserver { public: MediaAppGuestUI(content::WebUI* web_ui, MediaAppGuestUIDelegate* delegate); MediaAppGuestUI(const MediaAppGuestUI&) = delete; MediaAppGuestUI& operator=(const MediaAppGuestUI&) = delete; ~MediaAppGuestUI() override; + + // content::WebContentsObserver: + void ReadyToCommitNavigation(content::NavigationHandle* handle) override; }; } // namespace ash
diff --git a/ash/webui/media_app_ui/resources/mock/js/app_main.js b/ash/webui/media_app_ui/resources/mock/js/app_main.js index 9c9c814..0418f3ba 100644 --- a/ash/webui/media_app_ui/resources/mock/js/app_main.js +++ b/ash/webui/media_app_ui/resources/mock/js/app_main.js
@@ -44,13 +44,24 @@ const createAudioChild = async (blobSrc, fileName) => { const container = /** @type {HTMLDivElement} */ (document.createElement('div')); - const audio = /** @type {HTMLAudioElement} */ - (container.appendChild(document.createElement('audio'))); - audio.src = blobSrc; + const title = /** @type {HTMLDivElement} */ (container.appendChild(document.createElement('div'))); title.className = 'title'; title.innerText = fileName; + + const audio = /** @type {HTMLAudioElement} */ + (container.appendChild(document.createElement('audio'))); + audio.src = blobSrc; + // Audio will autoplay in this manner. Do the same in the mock to test + // integration points. + audio.play() + .then(() => { + console.log('Audio playing..'); + }) + .catch(e => { + console.error(String(e)); + }); return container; };
diff --git a/ash/webui/resources/BUILD.gn b/ash/webui/resources/BUILD.gn index 9dc76453..2b54342 100644 --- a/ash/webui/resources/BUILD.gn +++ b/ash/webui/resources/BUILD.gn
@@ -66,6 +66,13 @@ deps = [ "//ash/webui/personalization_app/resources:build_grd" ] } +ash_generated_grit("firmware_update_app_resources") { + firmware_update_app_gen_dir = + "$root_gen_dir/ash/webui/firmware_update_ui/resources" + source = "$firmware_update_app_gen_dir/ash_firmware_update_app_resources.grd" + deps = [ "//ash/webui/firmware_update_ui/resources:build_grd" ] +} + if (!is_official_build) { # Resources used by chrome://demo-mode-app ash_generated_grit("demo_mode_app_resources") {
diff --git a/ash/wm/desks/templates/desks_templates_unittest.cc b/ash/wm/desks/templates/desks_templates_unittest.cc index 293fbe5..ada8aad 100644 --- a/ash/wm/desks/templates/desks_templates_unittest.cc +++ b/ash/wm/desks/templates/desks_templates_unittest.cc
@@ -9,7 +9,6 @@ #include "ash/public/cpp/desk_template.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" -#include "ash/test_shell_delegate.h" #include "ash/wm/desks/desks_bar_view.h" #include "ash/wm/desks/expanded_desks_bar_button.h" #include "ash/wm/desks/templates/desks_templates_delete_button.h" @@ -23,13 +22,10 @@ #include "ash/wm/overview/overview_session.h" #include "ash/wm/overview/overview_test_base.h" #include "ash/wm/overview/overview_test_util.h" -#include "base/files/scoped_temp_dir.h" #include "base/guid.h" #include "base/strings/utf_string_conversions.h" #include "base/test/bind.h" -#include "base/test/scoped_feature_list.h" #include "base/time/time.h" -#include "components/desks_storage/core/local_desk_data_manager.h" #include "components/prefs/pref_service.h" #include "ui/aura/window.h" #include "ui/compositor/layer.h" @@ -38,22 +34,6 @@ namespace ash { -class CustomTestShellDelegate : public TestShellDelegate { - public: - explicit CustomTestShellDelegate(desks_storage::DeskModel* desk_model) - : desk_model_(desk_model) {} - CustomTestShellDelegate(const CustomTestShellDelegate&) = delete; - CustomTestShellDelegate& operator=(const CustomTestShellDelegate&) = delete; - ~CustomTestShellDelegate() override = default; - - // TestShellDelegate: - desks_storage::DeskModel* GetDeskModel() override { return desk_model_; } - - private: - // The desk model for the desks templates feature. - desks_storage::DeskModel* const desk_model_; -}; - // Wrapper for DesksTemplatesPresenter that exposes internal state to test // functions. class DesksTemplatesPresenterTestApi { @@ -134,10 +114,6 @@ DesksTemplatesTest& operator=(const DesksTemplatesTest&) = delete; ~DesksTemplatesTest() override = default; - desks_storage::LocalDeskDataManager* desk_model() { - return desk_model_.get(); - } - // Adds an entry to the desks model directly without capturing a desk. Allows // for testing the names and times of the UI directly. void AddEntry(const base::GUID& uuid, @@ -254,31 +230,6 @@ return overview_session->grid_list(); } - - // OverviewTestBase: - void SetUp() override { - scoped_feature_list_.InitAndEnableFeature(features::kDesksTemplates); - - EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); - desk_model_ = std::make_unique<desks_storage::LocalDeskDataManager>( - temp_dir_.GetPath()); - // Ensure the model is ready for tests. - desk_model_->EnsureCacheIsLoaded(); - - // This will call `AshTestBase::SetUp()`. - SetUpInternal(std::make_unique<CustomTestShellDelegate>(desk_model_.get())); - Shell::Get()->session_controller()->GetPrimaryUserPrefService()->SetBoolean( - prefs::kDeskTemplatesEnabled, true); - } - - private: - base::test::ScopedFeatureList scoped_feature_list_; - - // The desks model for tests. - std::unique_ptr<desks_storage::LocalDeskDataManager> desk_model_; - - // Temporary directory for the local desk model to store data. - base::ScopedTempDir temp_dir_; }; // Tests the helpers `AddEntry()` and `DeleteEntry()`, which will be used in
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc index ac90134..fee0fe7 100644 --- a/ash/wm/overview/overview_session.cc +++ b/ash/wm/overview/overview_session.cc
@@ -991,7 +991,7 @@ } // If a desk templates dialog is visible it should receive the key events. - if (desks_templates_util::AreDesksTemplatesEnabled() && + if (desks_templates_dialog_controller_ && desks_templates_dialog_controller_->dialog_widget()) { return; }
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc index 9fe60d1a39..5575448 100644 --- a/ash/wm/overview/overview_session_unittest.cc +++ b/ash/wm/overview/overview_session_unittest.cc
@@ -3265,7 +3265,7 @@ OverviewItem* item0 = GetOverviewItemForWindow(windows[0].get()); const gfx::RectF before_shift_bounds = item0->target_bounds(); - GenerateScrollSequence(gfx::Point(100, 50), gfx::Point(0, 50)); + GenerateScrollSequence(gfx::Point(100, 60), gfx::Point(0, 50)); EXPECT_EQ(before_shift_bounds, item0->target_bounds()); } @@ -3279,7 +3279,7 @@ OverviewItem* item0 = GetOverviewItemForWindow(windows[0].get()); const gfx::RectF before_shift_bounds = item0->target_bounds(); - GenerateScrollSequence(gfx::Point(100, 50), gfx::Point(0, 50)); + GenerateScrollSequence(gfx::Point(100, 60), gfx::Point(0, 50)); EXPECT_LT(item0->target_bounds(), before_shift_bounds); }
diff --git a/ash/wm/overview/overview_test_base.cc b/ash/wm/overview/overview_test_base.cc index 82c8b55..78b93b1 100644 --- a/ash/wm/overview/overview_test_base.cc +++ b/ash/wm/overview/overview_test_base.cc
@@ -4,7 +4,10 @@ #include "ash/wm/overview/overview_test_base.h" +#include "ash/constants/ash_features.h" +#include "ash/constants/ash_pref_names.h" #include "ash/public/cpp/presentation_time_recorder.h" +#include "ash/session/session_controller_impl.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" #include "ash/test_shell_delegate.h" @@ -24,6 +27,26 @@ namespace ash { +namespace { + +class CustomTestShellDelegate : public TestShellDelegate { + public: + explicit CustomTestShellDelegate(desks_storage::DeskModel* desk_model) + : desk_model_(desk_model) {} + CustomTestShellDelegate(const CustomTestShellDelegate&) = delete; + CustomTestShellDelegate& operator=(const CustomTestShellDelegate&) = delete; + ~CustomTestShellDelegate() override = default; + + // TestShellDelegate: + desks_storage::DeskModel* GetDeskModel() override { return desk_model_; } + + private: + // The desk model for the desks templates feature. + desks_storage::DeskModel* const desk_model_; +}; + +} // namespace + OverviewTestBase::~OverviewTestBase() = default; void OverviewTestBase::EnterTabletMode() { @@ -169,19 +192,18 @@ } void OverviewTestBase::SetUp() { - SetUpInternal(nullptr); -} + EXPECT_TRUE(desk_model_temp_dir_.CreateUniqueTempDir()); + desk_model_ = std::make_unique<desks_storage::LocalDeskDataManager>( + desk_model_temp_dir_.GetPath()); + desk_model_->EnsureCacheIsLoaded(); -void OverviewTestBase::TearDown() { - OverviewWallpaperController::SetDisableChangeWallpaperForTest(false); - PresentationTimeRecorder::SetReportPresentationTimeImmediatelyForTest(false); - trace_names_.clear(); - AshTestBase::TearDown(); -} + scoped_feature_list_.InitAndEnableFeature(features::kDesksTemplates); -void OverviewTestBase::SetUpInternal( - std::unique_ptr<TestShellDelegate> delegate) { - AshTestBase::SetUp(std::move(delegate)); + AshTestBase::SetUp( + std::make_unique<CustomTestShellDelegate>(desk_model_.get())); + + Shell::Get()->session_controller()->GetPrimaryUserPrefService()->SetBoolean( + prefs::kDeskTemplatesEnabled, true); aura::Env::GetInstance()->set_throttle_input_on_resize_for_testing(false); shelf_view_test_api_ = std::make_unique<ShelfViewTestAPI>( @@ -193,6 +215,14 @@ PresentationTimeRecorder::SetReportPresentationTimeImmediatelyForTest(true); } +void OverviewTestBase::TearDown() { + OverviewWallpaperController::SetDisableChangeWallpaperForTest(false); + PresentationTimeRecorder::SetReportPresentationTimeImmediatelyForTest(false); + trace_names_.clear(); + scoped_feature_list_.Reset(); + AshTestBase::TearDown(); +} + void OverviewTestBase::CheckForDuplicateTraceName(const char* trace) { DCHECK(!base::Contains(trace_names_, trace)) << trace; trace_names_.push_back(trace);
diff --git a/ash/wm/overview/overview_test_base.h b/ash/wm/overview/overview_test_base.h index 7a6dcb3..49db0cc8 100644 --- a/ash/wm/overview/overview_test_base.h +++ b/ash/wm/overview/overview_test_base.h
@@ -11,6 +11,9 @@ #include "ash/shelf/shelf_view_test_api.h" #include "ash/test/ash_test_base.h" +#include "base/files/scoped_temp_dir.h" +#include "base/test/scoped_feature_list.h" +#include "components/desks_storage/core/local_desk_data_manager.h" namespace views { class ImageButton; @@ -25,7 +28,6 @@ class OverviewSession; class ScopedOverviewTransformWindow; class SplitViewController; -class TestShellDelegate; class WindowPreviewView; // The base test fixture for testing Overview Mode. @@ -88,18 +90,19 @@ gfx::Rect GetGridBounds(); void SetGridBounds(OverviewGrid* grid, const gfx::Rect& bounds); + desks_storage::DeskModel* desk_model() { return desk_model_.get(); } + // AshTestBase: void SetUp() override; void TearDown() override; protected: - // Sets up the test suite with a custom `delegate`. If nullptr is used, a - // TestShellDelegate will be used by default. - void SetUpInternal(std::unique_ptr<TestShellDelegate> delegate); - void CheckForDuplicateTraceName(const char* trace); private: + std::unique_ptr<desks_storage::LocalDeskDataManager> desk_model_; + base::ScopedTempDir desk_model_temp_dir_; + base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<ShelfViewTestAPI> shelf_view_test_api_; std::vector<std::string> trace_names_; };
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.cc b/ash/wm/tablet_mode/tablet_mode_controller.cc index d1b2231a..f0e9e64 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller.cc
@@ -977,11 +977,15 @@ return elapsed_time >= kUnstableLidAngleDuration; } -bool TabletModeController::CanEnterTabletMode() { - // If we have ever seen accelerometer data, then HandleHingeRotation may - // trigger tablet mode at some point in the future. - // All TabletMode-enabled devices can enter tablet mode. - return have_seen_accelerometer_data_ || InTabletMode(); +bool TabletModeController::CanEnterTabletMode() const { + // If ChromeOS EC lid angle driver is supported, EC can handle lid angle + // calculation, and trigger tablet mode at some point. + // Otherwise, lid angle calculation is done on Chrome side for convertible + // device. If we have ever seen accelerometer data, then HandleHingeRotation + // may trigger tablet mode at some point in the future. + return IsBoardTypeMarkedAsTabletCapable() && + (is_ec_lid_angle_driver_supported_.value_or(false) || + have_seen_accelerometer_data_); } void TabletModeController::RecordTabletModeUsageInterval( @@ -1281,13 +1285,8 @@ if (is_in_tablet_physical_state_) return true; - const bool can_enter_tablet_mode = - IsBoardTypeMarkedAsTabletCapable() && HasActiveInternalDisplay() && - (is_ec_lid_angle_driver_supported_.value_or(false) || - have_seen_accelerometer_data_); - - return !has_internal_pointing_device_ && can_enter_tablet_mode && - chromeos::IsRunningAsSystemCompositor(); + return !has_internal_pointing_device_ && CanEnterTabletMode() && + HasActiveInternalDisplay() && chromeos::IsRunningAsSystemCompositor(); } bool TabletModeController::SetIsInTabletPhysicalState(bool new_state) {
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.h b/ash/wm/tablet_mode/tablet_mode_controller.h index 7075a93..06a9b0c1 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.h +++ b/ash/wm/tablet_mode/tablet_mode_controller.h
@@ -270,7 +270,7 @@ // True if it is possible to enter tablet mode in the current // configuration. If this returns false, it should never be the case that // tablet mode becomes enabled. - bool CanEnterTabletMode(); + bool CanEnterTabletMode() const; // Record UMA stats tracking TabletMode usage. If |type| is // TABLET_MODE_INTERVAL_INACTIVE, then record that TabletMode has been
diff --git a/base/test/trace_test_utils.cc b/base/test/trace_test_utils.cc index f0e6f09..4c90106f 100644 --- a/base/test/trace_test_utils.cc +++ b/base/test/trace_test_utils.cc
@@ -93,6 +93,7 @@ // Wait for any posted destruction tasks to execute. task_environment_->RunUntilIdle(); } + perfetto::Tracing::ResetForTesting(); } // static
diff --git a/base/trace_event/builtin_categories.h b/base/trace_event/builtin_categories.h index 1ef984a..ea0dff3 100644 --- a/base/trace_event/builtin_categories.h +++ b/base/trace_event/builtin_categories.h
@@ -10,6 +10,7 @@ #include "base/macros.h" #include "base/trace_event/common/trace_event_common.h" #include "base/tracing_buildflags.h" +#include "build/build_config.h" // List of builtin category names. If you want to use a new category name in // your code and you get a static assert, this is the right place to register @@ -294,6 +295,7 @@ X("browser,startup") \ X("category1,category2") \ X("cc,benchmark") \ + X("cc,benchmark,input") \ X("cc,benchmark," TRACE_DISABLED_BY_DEFAULT("devtools.timeline.frame")) \ X("cc,input") \ X("cc,raf_investigation") \
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc index 9a7d481..7e25650 100644 --- a/base/trace_event/trace_log.cc +++ b/base/trace_event/trace_log.cc
@@ -1172,7 +1172,20 @@ metadata_events_.clear(); perfetto::TrackEvent::Flush(); - tracing_session_->StopBlocking(); + // If the current thread has an active task runner, allow nested tasks to run + // while stopping the session. This is needed by some tests, e.g., to allow + // data sources to properly flush themselves. + if (ThreadTaskRunnerHandle::IsSet()) { + RunLoop stop_loop(RunLoop::Type::kNestableTasksAllowed); + auto quit_closure = stop_loop.QuitClosure(); + tracing_session_->SetOnStopCallback( + [&quit_closure] { quit_closure.Run(); }); + tracing_session_->Stop(); + AutoUnlock unlock(lock_); + stop_loop.Run(); + } else { + tracing_session_->StopBlocking(); + } #else // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) if (!(enabled_modes_ & modes_to_disable)) return; @@ -2217,10 +2230,12 @@ process_name_ = process_name; } #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) - auto track = perfetto::ProcessTrack::Current(); - auto desc = track.Serialize(); - desc.mutable_process()->set_process_name(process_name); - perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc)); + if (perfetto::Tracing::IsInitialized()) { + auto track = perfetto::ProcessTrack::Current(); + auto desc = track.Serialize(); + desc.mutable_process()->set_process_name(process_name); + perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc)); + } #endif }
diff --git a/build/android/gyp/create_unwind_table_tests.py b/build/android/gyp/create_unwind_table_tests.py index 6d8bdef..72ca167 100755 --- a/build/android/gyp/create_unwind_table_tests.py +++ b/build/android/gyp/create_unwind_table_tests.py
@@ -15,9 +15,8 @@ from create_unwind_table import ( AddressCfi, AddressUnwind, FilterToNonTombstoneCfi, FunctionCfi, FunctionUnwind, EncodeAddressUnwind, EncodeAsCUbytes, - EncodeStackPointerUpdate, EncodePop, GenerateUnwinds, NullParser, - PushOrSubSpParser, ReadFunctionCfi, StoreSpParser, Uleb128Encode, - UnwindType, VPushParser) + EncodeStackPointerUpdate, EncodePop, NullParser, PushOrSubSpParser, + ReadFunctionCfi, StoreSpParser, Uleb128Encode, UnwindType, VPushParser) class _TestReadFunctionCfi(unittest.TestCase):
diff --git a/build/android/test_runner.py b/build/android/test_runner.py index 1e312ba0..c9cbf40 100755 --- a/build/android/test_runner.py +++ b/build/android/test_runner.py
@@ -827,6 +827,42 @@ raise Exception('Unknown test type.') +def _SinkTestResult(test_result, test_file_name, result_sink_client): + """Upload test result to result_sink. + + Args: + test_result: A BaseTestResult object + test_file_name: A string representing the file location of the test + result_sink_client: A ResultSinkClient object + + Returns: + N/A + """ + # Some tests put in non utf-8 char as part of the test + # which breaks uploads, so need to decode and re-encode. + log_decoded = test_result.GetLog() + if isinstance(log_decoded, bytes): + log_decoded = log_decoded.decode('utf-8', 'replace') + html_artifact = '' + https_artifacts = [] + for link_name, link_url in sorted(test_result.GetLinks().items()): + if link_url.startswith('https:'): + https_artifacts.append('<li><a href=%s>%s</a></li>' % + (link_url, link_name)) + else: + logging.info('Skipping non-https link %r (%s) for test %s.', link_name, + link_url, test_result.GetName()) + if https_artifacts: + html_artifact += '<ul>%s</ul>' % '/n'.join(https_artifacts) + result_sink_client.Post(test_result.GetName(), + test_result.GetType(), + test_result.GetDuration(), + log_decoded.encode('utf-8'), + test_file_name, + failure_reason=test_result.GetFailureReason(), + html_artifact=html_artifact) + + _SUPPORTED_IN_PLATFORM_MODE = [ # TODO(jbudorick): Add support for more test types. 'gtest', @@ -936,17 +972,7 @@ match = re.search(r'^(.+\..+)#', r.GetName()) test_file_name = test_class_to_file_name_dict.get( match.group(1)) if match else None - # Some tests put in non utf-8 char as part of the test - # which breaks uploads, so need to decode and re-encode. - log_decoded = r.GetLog() - if isinstance(log_decoded, bytes): - log_decoded = log_decoded.decode('utf-8', 'replace') - result_sink_client.Post(r.GetName(), - r.GetType(), - r.GetDuration(), - log_decoded.encode('utf-8'), - test_file_name, - failure_reason=r.GetFailureReason()) + _SinkTestResult(r, test_file_name, result_sink_client) @contextlib.contextmanager def upload_logcats_file():
diff --git a/build/config/fuchsia/generate_runner_scripts.gni b/build/config/fuchsia/generate_runner_scripts.gni index a2be8d80..50a9c581e 100644 --- a/build/config/fuchsia/generate_runner_scripts.gni +++ b/build/config/fuchsia/generate_runner_scripts.gni
@@ -90,11 +90,10 @@ deps = [ invoker.package ] - data_deps = [ - "//build/config/fuchsia:deployment_resources", - "//testing:test_scripts_shared", - "//testing/buildbot/filters:fuchsia_filters", - ] + if (!defined(data_deps)) { + data_deps = [] + } + data_deps += [ "//build/config/fuchsia:deployment_resources" ] _combined_package_list = [ invoker.package ] if (defined(invoker.package_deps)) {
diff --git a/build/config/rust.gni b/build/config/rust.gni index 3e26675..7488352 100644 --- a/build/config/rust.gni +++ b/build/config/rust.gni
@@ -47,19 +47,20 @@ # b/193072381, but then again, we don't expect a build speedup before much # more work is done. use_goma_rust = false -} -# Rust code may end up being linked into a final executable by: -# * rustc (which calls lld) -# * our pre-existing C++ linker invocations -# At the moment, this first pipeline is incompatible with the ldflags we use -# for thin LTO, due to some problem in escaping gn rules. There's a further -# problem with -lunwind on Android. -# However, Rust code is still useful if it's contributing to our existing -# C++ linker invocations, so this doesn't disable Rust entirely. It does -# disable Rust unit test executables, so we do need to fix this. -# https://crbug.com/1229423 -rustc_can_link = !use_thin_lto && !is_android + # Rust code may end up being linked into a final executable by: + # * rustc (which calls lld) + # * our pre-existing C++ linker invocations + # At the moment, this first pipeline is incompatible with the ldflags we use + # for thin LTO, due to some problem in escaping gn rules. There's a further + # problem with -lunwind on Android. + # However, Rust code is still useful if it's contributing to our existing + # C++ linker invocations, so this doesn't disable Rust entirely. It does + # disable Rust unit test executables, so we do need to fix this. + # https://crbug.com/1229423 + # NB this may be overridden by individual toolchains + rustc_can_link = !use_thin_lto && !is_android +} # Has a Rust toolchain available in the build by default. toolchain_has_official_rust =
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index b4701e5..93aca50 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -6.20211020.0.1 +6.20211020.2.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 7bc8367..93aca50 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -6.20211020.1.1 +6.20211020.2.1
diff --git a/build/toolchain/apple/toolchain.gni b/build/toolchain/apple/toolchain.gni index 0d23e9ee..aa3d3ec8 100644 --- a/build/toolchain/apple/toolchain.gni +++ b/build/toolchain/apple/toolchain.gni
@@ -69,6 +69,9 @@ # ensure that it's always the same, regardless of the values that may be # set on those toolchains. host_toolchain = host_toolchain + + # Respect the global setting for whether rustc can make binaries. + rustc_can_link = rustc_can_link } # When the invoker has explicitly overridden use_goma or cc_wrapper in the @@ -250,7 +253,7 @@ outputs = [ rust_outfile ] } - if (rustc_can_link) { + if (toolchain_args.rustc_can_link) { tool("rust_bin") { rust_outfile = "{{root_out_dir}}/{{crate_name}}" depfile = "{{output}}.d"
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni index 2add3c6..f1f44c9 100644 --- a/build/toolchain/gcc_toolchain.gni +++ b/build/toolchain/gcc_toolchain.gni
@@ -144,6 +144,11 @@ if (!defined(invoker_toolchain_args.v8_current_cpu)) { v8_current_cpu = invoker_toolchain_args.current_cpu } + + # Whether rustc can successfully link binaries. (If not, rust code + # can still be linked by our C++ toolchain). See + # //build/config/rust.gni + rustc_can_link = !use_thin_lto && current_os != "android" } # When the invoker has explicitly overridden use_remoteexec, use_goma or @@ -690,7 +695,7 @@ outputs = [ rust_outfile ] } - if (rustc_can_link) { + if (toolchain_args.rustc_can_link) { tool("rust_bin") { rust_outfile = "{{root_out_dir}}/{{crate_name}}" depfile = "{{output}}.d"
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn index 28923e66..ace071a 100644 --- a/build/toolchain/win/BUILD.gn +++ b/build/toolchain/win/BUILD.gn
@@ -85,6 +85,9 @@ # This value needs to be passed through unchanged. host_toolchain = host_toolchain + + # Respect the global setting for whether rustc can make binaries. + rustc_can_link = rustc_can_link } # Make these apply to all tools below. @@ -317,7 +320,7 @@ outputs = [ rust_outfile ] } - if (rustc_can_link) { + if (toolchain_args.rustc_can_link) { tool("rust_bin") { rust_outfile = "{{root_out_dir}}/{{crate_name}}.exe" depfile = "{{crate_name}}.d"
diff --git a/cc/metrics/frame_sequence_tracker.cc b/cc/metrics/frame_sequence_tracker.cc index 65f52e8..720cd53 100644 --- a/cc/metrics/frame_sequence_tracker.cc +++ b/cc/metrics/frame_sequence_tracker.cc
@@ -99,9 +99,10 @@ } FrameSequenceTracker::~FrameSequenceTracker() { - TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0( + TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP2( "cc,benchmark", "TrackerValidation", TRACE_ID_LOCAL(this), - base::TimeTicks::Now()); + base::TimeTicks::Now(), "aborted_main", aborted_main_frame_, + "no_damage_main", no_damage_draw_main_frames_); CleanUp(); } @@ -186,9 +187,8 @@ } #endif - DCHECK_EQ(awaiting_main_response_sequence_, 0u) << TRACKER_DCHECK_MSG; last_processed_main_sequence_latency_ = 0; - awaiting_main_response_sequence_ = args.frame_id.sequence_number; + pending_main_sequences_.push_back(args.frame_id.sequence_number); UpdateTrackedFrameData(&begin_main_frame_data_, args.frame_id.source_id, args.frame_id.sequence_number, @@ -232,16 +232,11 @@ if (first_received_main_sequence_ && args.frame_id.sequence_number >= first_received_main_sequence_) { - if (awaiting_main_response_sequence_) { - DCHECK_EQ(awaiting_main_response_sequence_, args.frame_id.sequence_number) - << TRACKER_DCHECK_MSG; - } DCHECK_EQ(last_processed_main_sequence_latency_, 0u) << TRACKER_DCHECK_MSG; last_processed_main_sequence_ = args.frame_id.sequence_number; last_processed_main_sequence_latency_ = std::max(last_started_impl_sequence_, last_processed_impl_sequence_) - args.frame_id.sequence_number; - awaiting_main_response_sequence_ = 0; } } @@ -337,6 +332,16 @@ if (ShouldIgnoreBeginFrameSource(args.frame_id.source_id)) return; + // We only update the `pending_main_sequences` when the frame has successfully + // submitted, or when we determine that it has no damage. See + // ReportMainFrameCausedNoDamage. We do not do this in + // NotifyMainFrameProcessed, as that can occur during Commit, and we may yet + // determine at Draw that there was no damage. + while (!pending_main_sequences_.empty() && + pending_main_sequences_.front() <= + main_args.frame_id.sequence_number) { + pending_main_sequences_.pop_front(); + } TRACKER_TRACE_STREAM << "e(" << args.frame_id.sequence_number % kDebugStrMod << "," << main_args.frame_id.sequence_number % kDebugStrMod @@ -568,7 +573,8 @@ } void FrameSequenceTracker::ReportMainFrameCausedNoDamage( - const viz::BeginFrameArgs& args) { + const viz::BeginFrameArgs& args, + bool aborted) { if (termination_status_ != TerminationStatus::kActive) return; @@ -589,17 +595,28 @@ if (last_no_main_damage_sequence_ == args.frame_id.sequence_number) return; - // It is possible for |awaiting_main_response_sequence_| to be zero here if a - // commit had already happened before (e.g. B(x)E(x)N(x)). So check that case - // here. - if (awaiting_main_response_sequence_) { - DCHECK_EQ(awaiting_main_response_sequence_, args.frame_id.sequence_number) - << TRACKER_DCHECK_MSG; - } else { - DCHECK_EQ(last_processed_main_sequence_, args.frame_id.sequence_number) - << TRACKER_DCHECK_MSG; + auto initial_pending_size = pending_main_sequences_.size(); + while (!pending_main_sequences_.empty() && + pending_main_sequences_.front() <= args.frame_id.sequence_number) { + pending_main_sequences_.pop_front(); } - awaiting_main_response_sequence_ = 0; + // If we didn't remove any `pending_main_sequences`, then we have previously + // submitted a CompositorFrame with damage for `args.frame_id.sequence_number` + // and the sequence is being re-used on a subsequent Impl frame. Which just + // happens to have no damage. + // + // This can occur when there is a Compositor Animation that is offscreen, and + // when we are awaiting the next BeginMainFrame to be Committed and Activated. + // + // We do not change the `main_throughput` expectations when the sequence is + // re-used. + if (pending_main_sequences_.size() == initial_pending_size) + return; + + if (aborted) + ++aborted_main_frame_; + else + ++no_damage_draw_main_frames_; DCHECK_GT(main_throughput().frames_expected, 0u) << TRACKER_DCHECK_MSG; DCHECK_GT(main_throughput().frames_expected, @@ -618,7 +635,7 @@ // Could be 0 if there were a pause frame production. if (begin_main_frame_data_.previous_sequence != 0) { - DCHECK_EQ(begin_main_frame_data_.previous_sequence, + DCHECK_GE(begin_main_frame_data_.previous_sequence, args.frame_id.sequence_number) << TRACKER_DCHECK_MSG; }
diff --git a/cc/metrics/frame_sequence_tracker.h b/cc/metrics/frame_sequence_tracker.h index fd620120..c2f28dd 100644 --- a/cc/metrics/frame_sequence_tracker.h +++ b/cc/metrics/frame_sequence_tracker.h
@@ -5,6 +5,7 @@ #ifndef CC_METRICS_FRAME_SEQUENCE_TRACKER_H_ #define CC_METRICS_FRAME_SEQUENCE_TRACKER_H_ +#include <deque> #include <memory> #include <sstream> @@ -85,7 +86,8 @@ // Notifies the tracker that a |BeginFrameArgs| either was not dispatched to // the main-thread (because it did not ask for it), or that a |BeginFrameArgs| // that was dispatched to the main-thread did not cause any updates/damage. - void ReportMainFrameCausedNoDamage(const viz::BeginFrameArgs& args); + void ReportMainFrameCausedNoDamage(const viz::BeginFrameArgs& args, + bool aborted); // Notifies that frame production has currently paused. This is typically used // for interactive frame-sequences, e.g. during touch-scroll. @@ -193,8 +195,14 @@ // This is used to decide when to terminate this FrameSequenceTracker object. uint32_t last_submitted_frame_ = 0; - // Keeps track of the begin-main-frame that needs to be processed next. - uint64_t awaiting_main_response_sequence_ = 0; + // Keeps track of the begin-main-frames that need to be processed. There can + // be multiple in-flight, as BeginMainFrame to ReadyToCommit can be longer + // than one `viz::BeginFrameArgs.interval`. When this occurs the Compositor + // can send the `n+1` sequence_number, only for the Commit for `n` to arrive + // and lead to frame production. + std::deque<uint64_t> pending_main_sequences_; + uint64_t aborted_main_frame_ = 0; + uint64_t no_damage_draw_main_frames_ = 0; // Keeps track of the last sequence-number that produced a frame from the // main-thread.
diff --git a/cc/metrics/frame_sequence_tracker_collection.cc b/cc/metrics/frame_sequence_tracker_collection.cc index b6394a6..e1d59ec 100644 --- a/cc/metrics/frame_sequence_tracker_collection.cc +++ b/cc/metrics/frame_sequence_tracker_collection.cc
@@ -232,11 +232,12 @@ } void FrameSequenceTrackerCollection::NotifyMainFrameCausedNoDamage( - const viz::BeginFrameArgs& args) { + const viz::BeginFrameArgs& args, + bool aborted) { for (auto& tracker : frame_trackers_) - tracker.second->ReportMainFrameCausedNoDamage(args); + tracker.second->ReportMainFrameCausedNoDamage(args, aborted); for (auto& tracker : custom_frame_trackers_) - tracker.second->ReportMainFrameCausedNoDamage(args); + tracker.second->ReportMainFrameCausedNoDamage(args, aborted); } void FrameSequenceTrackerCollection::NotifyPauseFrameProduction() {
diff --git a/cc/metrics/frame_sequence_tracker_collection.h b/cc/metrics/frame_sequence_tracker_collection.h index e3dc01d..3b2c6a2a 100644 --- a/cc/metrics/frame_sequence_tracker_collection.h +++ b/cc/metrics/frame_sequence_tracker_collection.h
@@ -84,7 +84,8 @@ void NotifyBeginMainFrame(const viz::BeginFrameArgs& args); void NotifyMainFrameProcessed(const viz::BeginFrameArgs& args); void NotifyImplFrameCausedNoDamage(const viz::BeginFrameAck& ack); - void NotifyMainFrameCausedNoDamage(const viz::BeginFrameArgs& args); + void NotifyMainFrameCausedNoDamage(const viz::BeginFrameArgs& args, + bool aborted); void NotifyPauseFrameProduction(); void NotifySubmitFrame(uint32_t frame_token, bool has_missing_content,
diff --git a/cc/metrics/frame_sequence_tracker_unittest.cc b/cc/metrics/frame_sequence_tracker_unittest.cc index 4def808..2753480 100644 --- a/cc/metrics/frame_sequence_tracker_unittest.cc +++ b/cc/metrics/frame_sequence_tracker_unittest.cc
@@ -84,7 +84,7 @@ if (damage_type & kImplDamage) { if (!(damage_type & kMainDamage)) { - collection_.NotifyMainFrameCausedNoDamage(args); + collection_.NotifyMainFrameCausedNoDamage(args, false); } else { collection_.NotifyMainFrameProcessed(args); } @@ -96,7 +96,7 @@ } else { collection_.NotifyImplFrameCausedNoDamage( viz::BeginFrameAck(args, false)); - collection_.NotifyMainFrameCausedNoDamage(args); + collection_.NotifyMainFrameCausedNoDamage(args, true); collection_.NotifyFrameEnd(args, args); } return 0; @@ -234,7 +234,7 @@ case 'N': collection_.NotifyMainFrameCausedNoDamage( - CreateBeginFrameArgs(source_id, sequence)); + CreateBeginFrameArgs(source_id, sequence), true); break; default: @@ -331,7 +331,7 @@ auto args_2 = CreateBeginFrameArgs(source_2, ++sequence_2); collection_.NotifyBeginImplFrame(args_2); collection_.NotifyBeginMainFrame(args_2); - collection_.NotifyMainFrameCausedNoDamage(args_2); + collection_.NotifyMainFrameCausedNoDamage(args_2, true); // Since the main-frame did not have any new damage from the latest // BeginFrameArgs, the submit-frame will carry the previous BeginFrameArgs // (from source_1); @@ -807,6 +807,18 @@ EXPECT_EQ(MainThroughput().frames_produced, 0u); } +// This tests when a BeginMainFrame leads to No Damage, after the next Main +// Frame has started. This should not crash. +TEST_F(FrameSequenceTrackerTest, DelayedMainFrameNoDamageAfterNextMainFrame) { + const char sequence[] = + "b(1)B(0,1)n(1)e(1,0)E(1)b(2)B(0,2)N(0,1)n(2)N(0,2)e(2,0)"; + GenerateSequence(sequence); + EXPECT_EQ(ImplThroughput().frames_expected, 0u); + EXPECT_EQ(MainThroughput().frames_expected, 0u); + EXPECT_EQ(ImplThroughput().frames_produced, 0u); + EXPECT_EQ(MainThroughput().frames_produced, 0u); +} + TEST_F(FrameSequenceTrackerTest, StateResetDuringSequence) { const char sequence[] = "b(1)B(0,1)n(1)N(1,1)Re(1,0)b(2)n(2)e(2,0)"; GenerateSequence(sequence);
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index f898c7d..949857f 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -539,7 +539,7 @@ bool scroll_and_viewport_changes_synced) { if (reason == CommitEarlyOutReason::ABORTED_NOT_VISIBLE || reason == CommitEarlyOutReason::FINISHED_NO_UPDATES) { - frame_trackers_.NotifyMainFrameCausedNoDamage(args); + frame_trackers_.NotifyMainFrameCausedNoDamage(args, true); } else { frame_trackers_.NotifyMainFrameProcessed(args); } @@ -2366,6 +2366,8 @@ DCHECK(!resourceless_software_draw_); frame_trackers_.NotifyImplFrameCausedNoDamage(frame->begin_frame_ack); + frame_trackers_.NotifyMainFrameCausedNoDamage( + frame->origin_begin_main_frame_args, false); TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoDamage", TRACE_EVENT_SCOPE_THREAD); active_tree()->BreakSwapPromises(SwapPromise::SWAP_FAILS); active_tree()->ResetAllChangeTracking();
diff --git a/chrome/android/java/res/layout/share_sheet_content.xml b/chrome/android/java/res/layout/share_sheet_content.xml index 0b6b829..00d1eeb 100644 --- a/chrome/android/java/res/layout/share_sheet_content.xml +++ b/chrome/android/java/res/layout/share_sheet_content.xml
@@ -12,6 +12,7 @@ android:orientation="vertical"> <LinearLayout xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/share_sheet_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="@dimen/min_touch_target_size"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java index 84e9a6bd..29cbf62 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
@@ -382,6 +382,8 @@ * @param shouldCascadeTabs Whether the {@link CascadingStripStacker} should be used. */ void setShouldCascadeTabs(boolean shouldCascadeTabs) { + if (mModel == null) return; + if (shouldCascadeTabs != mShouldCascadeTabs) { mShouldCascadeTabs = shouldCascadeTabs; setTabStacker(shouldCascadeTabs ? mCascadingStripStacker : mScrollingStripStacker); @@ -429,6 +431,7 @@ if (mModel == model) return; mModel = model; mTabCreator = tabCreator; + setShouldCascadeTabs(mShouldCascadeTabs); computeAndUpdateTabOrders(false); }
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 5fcf632..c36bd88e 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -5790,12 +5790,6 @@ <message name="IDS_SETTINGS_ACCOUNT_MANAGER_ACCOUNT_REMOVED_MESSAGE" desc="Notification message after account removal."> <ph name="EMAIL">$1<ex>abcd@google.com</ex></ph> was removed from this device </message> - <message name="IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_PASSWORD_LABEL" desc="An input box label that tells the user to enter their password in that input box."> - Password - </message> - <message name="IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_INVALID_PASSWORD" desc="Text on a password field that tells the user the password is incorrect."> - Invalid password - </message> <!-- ADB sideloading policy-change notifications --> <message name="IDS_ADB_SIDELOADING_POLICY_CHANGE_SIDELOADING_DISALLOWED_NOTIFICATION_TITLE" desc="Title for the notification informing the user that ADB sideloading has been disabled.">
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index e195038..37b442a2 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -3763,9 +3763,6 @@ <message name="IDS_SETTINGS_PEOPLE_CONFIGURE_PIN_CONFIRM_PIN_TITLE" desc="Message shown below the title that tells the user to confirm their initial PIN entry."> Confirm your PIN </message> - <message name="IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_TITLE" desc="Title of the password prompt dialog popup."> - Confirm your password - </message> <!-- Setup fingerprint dialog (OS settings) --> <message name="IDS_SETTINGS_ADD_FINGERPRINT_DIALOG_TITLE" desc="Title of the add fingerprint dialog popup.">
diff --git a/chrome/app/shared_settings_strings.grdp b/chrome/app/shared_settings_strings.grdp index f22c14a..2f74e34 100644 --- a/chrome/app/shared_settings_strings.grdp +++ b/chrome/app/shared_settings_strings.grdp
@@ -389,4 +389,17 @@ Theme </message> </if> + + <!-- Password Prompt Dialog --> + <if expr="chromeos or lacros"> + <message name="IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_TITLE" desc="Title of the password prompt dialog popup."> + Confirm your password + </message> + <message name="IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_PASSWORD_LABEL" desc="An input box label that tells the user to enter their password in that input box."> + Password + </message> + <message name="IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_INVALID_PASSWORD" desc="Text on a password field that tells the user the password is incorrect."> + Invalid password + </message> + </if> </grit-part>
diff --git a/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_INVALID_PASSWORD.png.sha1 b/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_INVALID_PASSWORD.png.sha1 new file mode 100644 index 0000000..2399ce5a --- /dev/null +++ b/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_INVALID_PASSWORD.png.sha1
@@ -0,0 +1 @@ +19e882461d0272385ff0d68eba46ec17f43056c2 \ No newline at end of file
diff --git a/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_PASSWORD_LABEL.png.sha1 b/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_PASSWORD_LABEL.png.sha1 new file mode 100644 index 0000000..cc59571 --- /dev/null +++ b/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_PASSWORD_LABEL.png.sha1
@@ -0,0 +1 @@ +4e1ab0fae9e3d7bbff05c2034310ed3f27383f0e \ No newline at end of file
diff --git a/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_TITLE.png.sha1 b/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_TITLE.png.sha1 new file mode 100644 index 0000000..cc59571 --- /dev/null +++ b/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_PEOPLE_PASSWORD_PROMPT_TITLE.png.sha1
@@ -0,0 +1 @@ +4e1ab0fae9e3d7bbff05c2034310ed3f27383f0e \ No newline at end of file
diff --git a/chrome/app/theme/crostini/logo_crostini_terminal.png b/chrome/app/theme/crostini/logo_crostini_terminal.png deleted file mode 100644 index 12d1f854..0000000 --- a/chrome/app/theme/crostini/logo_crostini_terminal.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/mac/theme_default_active_background.png b/chrome/app/theme/default_200_percent/mac/theme_default_active_background.png deleted file mode 100644 index 9d618fd..0000000 --- a/chrome/app/theme/default_200_percent/mac/theme_default_active_background.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/OWNERS b/chrome/browser/OWNERS index fa503396..649face 100644 --- a/chrome/browser/OWNERS +++ b/chrome/browser/OWNERS
@@ -90,3 +90,6 @@ # Web Platform security metrics tests: per-file chrome_web_platform_security_metrics_browsertest.cc=file://content/OWNERS + +# Color pipeline +per-file chrome_color_mixers.*=file://ui/color/OWNERS \ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 2b45b50..c4c5fc7 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -230,9 +230,11 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "ash/constants/ash_features.h" #include "ash/constants/ash_switches.h" +#include "chrome/browser/ash/crosapi/browser_manager.h" #include "chrome/browser/ash/crosapi/browser_util.h" #include "chrome/browser/ash/crostini/crostini_util.h" #include "chrome/browser/nearby_sharing/common/nearby_share_features.h" +#include "chrome/common/webui_url_constants.h" #include "chromeos/services/assistant/public/cpp/features.h" #include "components/app_restore/features.h" #include "components/arc/arc_features.h" @@ -243,6 +245,11 @@ #include "ui/events/ozone/features.h" #endif // BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/browser/lacros/lacros_url_handling.h" +#include "chrome/common/webui_url_constants.h" +#endif + #if defined(OS_MAC) #include "chrome/browser/ui/browser_dialogs.h" #endif // OS_MAC @@ -3666,7 +3673,7 @@ flag_descriptions::kEnableNavigationPredictorDescription, kOsCrOS | kOsLinux, FEATURE_VALUE_TYPE(blink::features::kNavigationPredictor)}, -#endif // BUILDFLAG(IS_CHROMEOS_ASH) || OS_LINUX +#endif // BUILDFLAG(IS_CHROMEOS) || OS_LINUX {"enable-preconnect-to-search", flag_descriptions::kEnablePreconnectToSearchName, flag_descriptions::kEnablePreconnectToSearchDescription, kOsAll, @@ -7556,6 +7563,10 @@ flag_descriptions::kShareUsageRankingFixedMoreName, flag_descriptions::kShareUsageRankingFixedMoreDescription, kOsAndroid, FEATURE_VALUE_TYPE(features::kShareUsageRankingFixedMore)}, + {"swap-android-share-hub-rows", + flag_descriptions::kSwapAndroidShareHubRowsName, + flag_descriptions::kSwapAndroidShareHubRowsDescription, kOsAndroid, + FEATURE_VALUE_TYPE(share::kSwapAndroidShareHubRows)}, #endif #if !defined(OS_ANDROID) @@ -7971,6 +7982,18 @@ FlagsStateSingleton::GetFlagsState()->ResetAllFlags(flags_storage); } +#if defined(OS_CHROMEOS) +void CrosUrlFlagsRedirect() { +#if BUILDFLAG(IS_CHROMEOS_LACROS) + lacros_url_handling::NavigateInAsh(GURL(chrome::kChromeUIFlagsURL)); +#else + // Note: This will only be called by the UI when Lacros is available. + DCHECK(crosapi::BrowserManager::Get()); + crosapi::BrowserManager::Get()->OpenUrl(GURL(chrome::kChromeUIFlagsURL)); +#endif +} +#endif + void RecordUMAStatistics(flags_ui::FlagsStorage* flags_storage, const std::string& histogram_name) { std::set<std::string> switches;
diff --git a/chrome/browser/about_flags.h b/chrome/browser/about_flags.h index 54ce3d7..0b51be0 100644 --- a/chrome/browser/about_flags.h +++ b/chrome/browser/about_flags.h
@@ -97,6 +97,11 @@ // Reset all flags to the default state by clearing all flags. void ResetAllFlags(flags_ui::FlagsStorage* flags_storage); +#if defined(OS_CHROMEOS) +// Show flags of the other browser (Lacros/Ash). +void CrosUrlFlagsRedirect(); +#endif + // Sends UMA stats about experimental flag usage. This should be called once per // startup. void RecordUMAStatistics(flags_ui::FlagsStorage* flags_storage,
diff --git a/chrome/browser/ash/cert_provisioning/cert_provisioning_invalidator.h b/chrome/browser/ash/cert_provisioning/cert_provisioning_invalidator.h index 47b0dbb7..fede9fe 100644 --- a/chrome/browser/ash/cert_provisioning/cert_provisioning_invalidator.h +++ b/chrome/browser/ash/cert_provisioning/cert_provisioning_invalidator.h
@@ -75,6 +75,10 @@ // false otherwise. bool Register(); + // Sequence checker to ensure that calls from invalidation service are + // consecutive. + SEQUENCE_CHECKER(sequence_checker_); + struct State { bool is_registered; bool is_invalidation_service_enabled; @@ -90,22 +94,21 @@ // An invalidation service providing the handler with incoming invalidations. invalidation::InvalidationService* const invalidation_service_; - base::ScopedObservation< - invalidation::InvalidationService, - invalidation::InvalidationHandler, - &invalidation::InvalidationService::RegisterInvalidationHandler, - &invalidation::InvalidationService::UnregisterInvalidationHandler> - invalidation_service_observation_{this}; - // A topic representing certificate invalidations. const invalidation::Topic topic_; // A callback to be called on incoming invalidation event. const OnInvalidationCallback on_invalidation_callback_; - // Sequence checker to ensure that calls from invalidation service are - // consecutive. - SEQUENCE_CHECKER(sequence_checker_); + // Automatically unregisters `this` as an observer on destruction. Should be + // destroyed first so the other fields are still valid and can be used during + // the unregistration. + base::ScopedObservation< + invalidation::InvalidationService, + invalidation::InvalidationHandler, + &invalidation::InvalidationService::RegisterInvalidationHandler, + &invalidation::InvalidationService::UnregisterInvalidationHandler> + invalidation_service_observation_{this}; }; } // namespace internal
diff --git a/chrome/browser/ash/login/saml/security_token_saml_browsertest.cc b/chrome/browser/ash/login/saml/security_token_saml_browsertest.cc index 656c7fc..a99e2d6 100644 --- a/chrome/browser/ash/login/saml/security_token_saml_browsertest.cc +++ b/chrome/browser/ash/login/saml/security_token_saml_browsertest.cc
@@ -244,13 +244,8 @@ base::WeakPtrFactory<SecurityTokenSamlTest> weak_factory_{this}; }; -#define NEVER_ENABLED_Basic DISABLED_Basic - // Tests the successful login scenario with the correct PIN. -// TODO(crbug.com/1033936): Fix the flakiness and enable it. -IN_PROC_BROWSER_TEST_F(SecurityTokenSamlTest, NEVER_ENABLED_Basic) { - test::OobeJS().ExpectHiddenPath({"gaia-signin", "pinDialog"}); - +IN_PROC_BROWSER_TEST_F(SecurityTokenSamlTest, Basic) { StartSignIn(); WaitForPinDialog(); test::OobeJS().ExpectVisiblePath({"gaia-signin", "pinDialog"});
diff --git a/chrome/browser/ash/login/users/supervised_user_manager_impl.h b/chrome/browser/ash/login/users/supervised_user_manager_impl.h index e16078f..b5481fd 100644 --- a/chrome/browser/ash/login/users/supervised_user_manager_impl.h +++ b/chrome/browser/ash/login/users/supervised_user_manager_impl.h
@@ -14,7 +14,6 @@ namespace ash { class ChromeUserManagerImpl; class CrosSettings; -class SupervisedUserTestBase; // TODO(crbug.com/1155729): Check this entire class is not used anymore for // deprecated supervised users and remove it with all dependencies. @@ -41,7 +40,6 @@ private: friend class ChromeUserManagerImpl; friend class UserManager; - friend class SupervisedUserTestBase; explicit SupervisedUserManagerImpl(ChromeUserManagerImpl* owner);
diff --git a/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc index 3fc7ae5..c0deef1 100644 --- a/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc
@@ -81,6 +81,12 @@ void MediaAppLaunchWithFile(bool audio_enabled); void MediaAppWithLaunchSystemWebAppAsync(bool audio_enabled); void MediaAppEligibleOpenTask(bool audio_enabled); + + // Helper to initiate a test by launching a single file. + content::WebContents* LaunchWithOneTestFile(const char* file); + + private: + std::unique_ptr<file_manager::test::FolderInMyFiles> launch_folder_; }; class MediaAppIntegrationWithFilesAppTest : public MediaAppIntegrationTest { @@ -172,7 +178,7 @@ content::EvalJsResult WaitForAudioTrackTitle(content::WebContents* web_ui) { constexpr char kScript[] = R"( (async function waitForAudioTrackTitle() { - return (await waitForNode('div.title')).innerText; + return (await waitForNode('div.title:not(:empty)')).innerText; })(); )"; @@ -213,6 +219,17 @@ EXPECT_TRUE(base::TouchFile(path, time, time)); } +content::WebContents* MediaAppIntegrationTest::LaunchWithOneTestFile( + const char* file) { + WaitForTestSystemAppInstall(); + launch_folder_ = + std::make_unique<file_manager::test::FolderInMyFiles>(profile()); + launch_folder_->Add({TestFile(file)}); + EXPECT_EQ(launch_folder_->Open(TestFile(file)), + platform_util::OPEN_SUCCEEDED); + return PrepareActiveBrowserForTest(); +} + } // namespace // Test that the Media App installs and launches correctly. Runs some spot @@ -847,6 +864,30 @@ histograms.ExpectTotalCount("Apps.DefaultAppLaunch.FromFileManager", 2); } +// Ensures audio files opened in the media app successfully autoplay. +IN_PROC_BROWSER_TEST_P(MediaAppIntegrationAudioEnabledTest, Autoplay) { + content::WebContents* web_ui = LaunchWithOneTestFile(kFileAudioOgg); + + EXPECT_EQ(kFileAudioOgg, WaitForAudioTrackTitle(web_ui)); + + constexpr char kWaitForPlayedLength[] = R"( + (async function waitForPlayedLength() { + const audioElement = await waitForNode('audio'); + if (audioElement.played.length > 0) { + return audioElement.played.length; + } + // Wait for a timeupdate. If autoplay malfunctions, this will timeout. + await new Promise(resolve => { + audioElement.addEventListener('timeupdate', resolve, {once: true}); + }); + return audioElement.played.length; + })(); + )"; + + EXPECT_LE( + 1, MediaAppUiBrowserTest::EvalJsInAppFrame(web_ui, kWaitForPlayedLength)); +} + // Test that the MediaApp can navigate other files in the directory of a file // that was opened, even if those files have changed since launch. IN_PROC_BROWSER_TEST_P(MediaAppIntegrationWithFilesAppAllProfilesTest,
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc index 0497a349..fca85a0 100644 --- a/chrome/browser/autofill/autofill_interactive_uitest.cc +++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -328,6 +328,9 @@ cert_verifier_.SetUpCommandLine(command_line); // Needed to allow input before commit on various builders. command_line->AppendSwitch(blink::switches::kAllowPreCommitInput); + // TODO(crbug.com/1258185): Migrate to a better mechanism for testing around + // language detection. + command_line->AppendSwitch(switches::kOverrideLanguageDetection); } void SetUpInProcessBrowserTestFixture() override { @@ -2017,11 +2020,11 @@ static const char kForm[] = "<form action=\"https://www.example.com/\" method=\"POST\">" - "<label for=\"fn\">なまえ</label>" + "<label for=\"fn\">Nom</label>" " <input type=\"text\" id=\"fn\"" " onfocus=\"domAutomationController.send(true)\"" "><br>" - "<label for=\"ln\">みょうじ</label>" + "<label for=\"ln\">Nom de famille</label>" " <input type=\"text\" id=\"ln\"><br>" "<label for=\"a1\">Address line 1:</label>" " <input type=\"text\" id=\"a1\"><br>" @@ -2046,16 +2049,24 @@ "<label for=\"ph\">Phone number:</label>" " <input type=\"text\" id=\"ph\"><br>" "</form>" - // Add additional Japanese characters to ensure the translate bar + // Add additional French characters to ensure the translate bar // will appear. - "我々は重要な、興味深いものになるが、時折状況が発生するため苦労や痛みは" - "彼にいくつかの素晴らしいを調達することができます。それから、いくつかの" - "利"; + // + // TODO(crbug.com/1258185): The current translate testing overrides the + // result to be Adopted Language: 'fr' (the language the Chrome's + // translate feature believes the page language to be in). The behavior + // required here is to only force a translation which should not rely on + // language detection. The override simply just seeds the translate code + // so that a translate event occurs in a more testable way. + "Nous serons importants et intéressants, mais les épreuves et les peines" + "peuvent lui en procurer de grandes en raison de situations " + "occasionnelles." + "Puis quelques avantages"; NavigateToContentAndWaitForLanguageDetection(kForm); - ASSERT_EQ("ja", GetLanguageState().current_language()); + ASSERT_EQ("fr", GetLanguageState().current_language()); ASSERT_NO_FATAL_FAILURE(Translate(true)); - ASSERT_EQ("ja", GetLanguageState().source_language()); + ASSERT_EQ("fr", GetLanguageState().source_language()); ASSERT_EQ("en", GetLanguageState().current_language()); TryBasicFormFill(); }
diff --git a/chrome/browser/background_sync/background_sync_delegate_impl.cc b/chrome/browser/background_sync/background_sync_delegate_impl.cc index f112486..bbb830f 100644 --- a/chrome/browser/background_sync/background_sync_delegate_impl.cc +++ b/chrome/browser/background_sync/background_sync_delegate_impl.cc
@@ -14,6 +14,7 @@ #include "content/public/browser/background_sync_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" +#include "content/public/browser/web_contents.h" #include "url/origin.h" #if defined(OS_ANDROID) @@ -159,8 +160,8 @@ suspended_periodic_sync_origins_.erase(iter); - auto* storage_partition = - profile_->GetStoragePartitionForUrl(url, /* can_create= */ false); + // Engagement is always accumulated in the main frame. + auto* storage_partition = web_contents->GetMainFrame()->GetStoragePartition(); if (!storage_partition) return;
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index e2df666..91420d11 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -354,6 +354,7 @@ <include name="IDR_ADD_SUPERVISION_MOJOM_LITE_JS" file="${root_gen_dir}\chrome\browser\ui\webui\chromeos\add_supervision\add_supervision.mojom-lite.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_PARENT_ACCESS_HTML" file="resources\chromeos\parent_access\parent_access.html" type="chrome_html" /> <include name="IDR_PARENT_ACCESS_UI_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\parent_access\parent_access_ui.js" use_base_dir="false" type="BINDATA" /> + <include name="IDR_PARENT_ACCESS_CONTROLLER_JS" file="resources\chromeos\parent_access\parent_access_controller.js" type="BINDATA" /> <include name="IDR_PARENT_ACCESS_UI_MOJOM_LITE_JS" file="${root_gen_dir}\chrome\browser\ui\webui\chromeos\parent_access\parent_access_ui.mojom-lite.js" use_base_dir="false" type="BINDATA" /> </if> <if expr="chromeos">
diff --git a/chrome/browser/chrome_color_mixers.cc b/chrome/browser/chrome_color_mixers.cc index 374fa511..1511fcd 100644 --- a/chrome/browser/chrome_color_mixers.cc +++ b/chrome/browser/chrome_color_mixers.cc
@@ -10,10 +10,8 @@ void AddChromeColorMixers(ui::ColorProvider* provider, const ui::ColorProviderManager::Key& key) { - AddChromeColorMixer(provider); - AddOmniboxColorMixer( - provider, - key.contrast_mode == ui::ColorProviderManager::ContrastMode::kHigh); + AddChromeColorMixer(provider, key); + AddOmniboxColorMixer(provider, key); if (key.custom_theme) { key.custom_theme->AddColorMixers(provider, key);
diff --git a/chrome/browser/client_hints/DEPS b/chrome/browser/client_hints/DEPS index fbc751b2..9323f7d 100644 --- a/chrome/browser/client_hints/DEPS +++ b/chrome/browser/client_hints/DEPS
@@ -4,4 +4,5 @@ # header-only types, and some selected common code. "-third_party/blink", "+third_party/blink/public/common", + "+components/client_hints/common/switches.h", ]
diff --git a/chrome/browser/client_hints/client_hints_browsertest.cc b/chrome/browser/client_hints/client_hints_browsertest.cc index 6d9daaae..356aa0f 100644 --- a/chrome/browser/client_hints/client_hints_browsertest.cc +++ b/chrome/browser/client_hints/client_hints_browsertest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <cctype> +#include <cstddef> #include <memory> #include "base/base_switches.h" @@ -17,15 +18,19 @@ #include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/content_settings/cookie_settings_factory.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/devtools/protocol/devtools_protocol_test_support.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/test/base/chrome_test_utils.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/client_hints/common/switches.h" #include "components/content_settings/browser/page_specific_content_settings.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/browser/host_content_settings_map.h" @@ -168,6 +173,13 @@ return true; } +void OnUnblockOnProfileCreation(base::RunLoop* run_loop, + Profile* profile, + Profile::CreateStatus status) { + if (status == Profile::CREATE_STATUS_INITIALIZED) + run_loop->Quit(); +} + } // namespace class ClientHintsBrowserTest : public InProcessBrowserTest, @@ -293,6 +305,10 @@ accept_ch_empty_ = https_server_.GetURL("/accept_ch_empty.html"); http_equiv_accept_ch_merge_ = https_server_.GetURL("/http_equiv_accept_ch_merge.html"); + + without_accept_ch_without_lifetime_cross_origin_ = + https_cross_origin_server_.GetURL( + "/without_accept_ch_without_lifetime.html"); } ClientHintsBrowserTest(const ClientHintsBrowserTest&) = delete; @@ -368,6 +384,8 @@ } void TestProfilesIndependent(Browser* browser_a, Browser* browser_b); + void TestSwitchWithNewProfile(const std::string& switch_value, + size_t origins_stored); const GURL& accept_ch_with_lifetime_http_local_url() const { return accept_ch_with_lifetime_http_local_url_; @@ -476,6 +494,10 @@ return http_equiv_accept_ch_merge_; } + const GURL& without_accept_ch_without_lifetime_cross_origin() { + return without_accept_ch_without_lifetime_cross_origin_; + } + GURL GetHttp2Url(const std::string& relative_url) const { return http2_server_.GetURL(relative_url); } @@ -530,6 +552,21 @@ bool intercept_to_http_equiv_iframe_ = false; mutable base::Lock count_headers_lock_; + Profile* GenerateNewProfile() { + ProfileManager* profile_manager = g_browser_process->profile_manager(); + base::FilePath current_profile_path = browser()->profile()->GetPath(); + + // Create an additional profile. + base::FilePath new_path = + profile_manager->GenerateNextProfileDirectoryPath(); + base::RunLoop run_loop; + profile_manager->CreateProfileAsync( + new_path, base::BindRepeating(&OnUnblockOnProfileCreation, &run_loop)); + run_loop.Run(); + + return profile_manager->GetProfile(new_path); + } + private: // Intercepts only the main frame requests that contain // "redirect" in the resource path. The intercepted requests @@ -849,6 +886,7 @@ GURL redirect_url_; GURL accept_ch_empty_; GURL http_equiv_accept_ch_merge_; + GURL without_accept_ch_without_lifetime_cross_origin_; std::string main_frame_ua_observed_; std::string main_frame_ua_full_version_observed_; @@ -3576,3 +3614,116 @@ NavigateAndCheckHeaders(top_level_with_iframe_redirect_url(), /*ch_ua_reduced_expected=*/true); } + +// CrOS multi-profiles implementation is too different for these tests. +#if !BUILDFLAG(IS_CHROMEOS_ASH) + +void ClientHintsBrowserTest::TestSwitchWithNewProfile( + const std::string& switch_value, + size_t origins_stored) { + base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( + client_hints::switches::kInitializeClientHintsStorage, switch_value); + + Profile* profile = GenerateNewProfile(); + Browser* browser = CreateBrowser(profile); + + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser, without_accept_ch_without_lifetime_url())); + + ContentSettingsForOneType host_settings; + + // Clients hints preferences for one origin should be persisted. + HostContentSettingsMapFactory::GetForProfile(profile)->GetSettingsForOneType( + ContentSettingsType::CLIENT_HINTS, &host_settings); + EXPECT_EQ(origins_stored, host_settings.size()); +} + +IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest, SwitchAppliesStorage) { + TestSwitchWithNewProfile( + "{\"https://a.test\":\"Sec-CH-UA-Full-Version\", " + "\"https://b.test\":\"Sec-CH-UA-Full-Version\"}", + 2); +} + +IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest, SwitchNotJson) { + TestSwitchWithNewProfile("foo", 0); +} + +IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest, SwitchOriginNotSecure) { + TestSwitchWithNewProfile("{\"http://a.test\":\"Sec-CH-UA-Full-Version\"}", 0); +} + +IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest, SwitchAcceptCHInvalid) { + TestSwitchWithNewProfile("{\"https://a.test\":\"Not Valid\"}", 0); +} + +IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest, SwitchAppliesStorageOneOrigin) { + TestSwitchWithNewProfile( + "{\"https://a.test\":\"Sec-CH-UA-Full-Version\", " + "\"https://b.test\":\"Not Valid\"}", + 1); +} +#endif // !BUILDFLAG(IS_CHROMEOS_ASH) + +class ClientHintsCommandLineSwitchBrowserTest : public ClientHintsBrowserTest { + public: + ClientHintsCommandLineSwitchBrowserTest() = default; + + void SetUpCommandLine(base::CommandLine* cmd) override { + ClientHintsBrowserTest::SetUpCommandLine(cmd); + std::string server_origin = + url::Origin::Create(accept_ch_with_lifetime_url()).Serialize(); + + std::vector<std::string> accept_ch_tokens; + for (const auto& pair : network::GetClientHintToNameMap()) + accept_ch_tokens.push_back(pair.second); + + cmd->AppendSwitchASCII( + client_hints::switches::kInitializeClientHintsStorage, + base::StringPrintf("{\"%s\":\"%s\"}", server_origin.c_str(), + base::JoinString(accept_ch_tokens, ",").c_str())); + } +}; + +IN_PROC_BROWSER_TEST_F(ClientHintsCommandLineSwitchBrowserTest, + NavigationToDifferentOrigins) { + SetClientHintExpectationsOnMainFrame(true); + SetClientHintExpectationsOnSubresources(true); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), without_accept_ch_without_lifetime_url())); + + SetClientHintExpectationsOnMainFrame(false); + SetClientHintExpectationsOnSubresources(false); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), without_accept_ch_without_lifetime_cross_origin())); +} + +IN_PROC_BROWSER_TEST_F(ClientHintsCommandLineSwitchBrowserTest, + ClearHintsWithAcceptCH) { + SetClientHintExpectationsOnMainFrame(true); + SetClientHintExpectationsOnSubresources(true); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), without_accept_ch_without_lifetime_url())); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), accept_ch_empty())); + + SetClientHintExpectationsOnMainFrame(false); + SetClientHintExpectationsOnSubresources(false); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), without_accept_ch_without_lifetime_url())); +} + +IN_PROC_BROWSER_TEST_F(ClientHintsCommandLineSwitchBrowserTest, + StorageNotPresentInOffTheRecordProfile) { + SetClientHintExpectationsOnMainFrame(true); + SetClientHintExpectationsOnSubresources(true); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), without_accept_ch_without_lifetime_url())); + + // OTR profile should get neither. + Browser* otr_browser = CreateIncognitoBrowser(browser()->profile()); + SetClientHintExpectationsOnMainFrame(false); + SetClientHintExpectationsOnSubresources(false); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + otr_browser, without_accept_ch_without_lifetime_url())); +}
diff --git a/chrome/browser/commerce/merchant_viewer/merchant_viewer_data_manager_unittest.cc b/chrome/browser/commerce/merchant_viewer/merchant_viewer_data_manager_unittest.cc index 91cbc25..902a714 100644 --- a/chrome/browser/commerce/merchant_viewer/merchant_viewer_data_manager_unittest.cc +++ b/chrome/browser/commerce/merchant_viewer/merchant_viewer_data_manager_unittest.cc
@@ -10,7 +10,6 @@ #include "base/test/metrics/histogram_tester.h" #include "chrome/browser/commerce/commerce_feature_list.h" #include "chrome/browser/commerce/merchant_viewer/merchant_viewer_data_manager_factory.h" -#include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/persisted_state_db/profile_proto_db.h" #include "chrome/browser/persisted_state_db/profile_proto_db_factory.h" #include "chrome/test/base/testing_profile.h" @@ -45,7 +44,6 @@ testing::Test::SetUp(); service_ = MerchantViewerDataManagerFactory::GetForProfile(&profile_); - DCHECK(profile_.CreateHistoryService()); } void TearDown() override {
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/toolbar.xml b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/toolbar.xml index a0391050..3bbade4 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/toolbar.xml +++ b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/toolbar.xml
@@ -13,16 +13,21 @@ android:orientation="vertical" android:importantForAccessibility="yes"> - <LinearLayout - android:id="@+id/lightweight_reactions_toolbar_reaction_picker" - android:gravity="center" - android:orientation="horizontal" - android:layout_above="@id/lightweight_reactions_toolbar_controls" - android:paddingHorizontal="@dimen/toolbar_button_margin" + <HorizontalScrollView + android:layout_width="match_parent" android:layout_height="@dimen/toolbar_row_height" - android:layout_width="match_parent"> - <!-- Empty for now --> - </LinearLayout> + android:layout_above="@id/lightweight_reactions_toolbar_controls" + android:scrollbars="none"> + <LinearLayout + android:id="@+id/lightweight_reactions_toolbar_reaction_picker" + android:gravity="center" + android:orientation="horizontal" + android:layout_marginTop="@dimen/toolbar_reactions_margin" + android:layout_height="match_parent" + android:layout_width="wrap_content"> + <!-- ImageViews are added at runtime. --> + </LinearLayout> + </HorizontalScrollView> <LinearLayout android:id="@+id/lightweight_reactions_toolbar_controls"
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/res/values/dimens.xml b/chrome/browser/content_creation/reactions/internal/android/java/res/values/dimens.xml index 667239d4..11ff42b8 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/res/values/dimens.xml +++ b/chrome/browser/content_creation/reactions/internal/android/java/res/values/dimens.xml
@@ -16,4 +16,5 @@ <dimen name="toolbar_button_size">40dp</dimen> <dimen name="toolbar_button_margin">16dp</dimen> <dimen name="toolbar_button_padding">8dp</dimen> + <dimen name="toolbar_reactions_margin">10dp</dimen> </resources> \ No newline at end of file
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsCoordinatorImpl.java b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsCoordinatorImpl.java index 2b389f8..7892b3e 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsCoordinatorImpl.java +++ b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsCoordinatorImpl.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.content_creation.reactions; import android.app.Activity; +import android.graphics.Bitmap; import android.view.View; import androidx.fragment.app.FragmentActivity; @@ -36,8 +37,12 @@ private final SceneCoordinator mSceneCoordinator; private List<ReactionMetadata> mAvailableReactions; + private Bitmap[] mThumbnails; private ToolbarCoordinator mToolbarCoordinator; + private boolean mDialogViewCreated; + private boolean mAssetsFetched; + /** * Constructs a new LightweightReactionsCoordinatorImpl which initializes and displays the * Lightweight Reactions scene. @@ -53,6 +58,8 @@ ChromeOptionShareCallback chromeOptionShareCallback, BottomSheetController sheetController, ReactionService reactionService) { super(activity, tab, shareUrl, chromeOptionShareCallback, sheetController); + mDialogViewCreated = false; + mAssetsFetched = false; mReactionService = reactionService; mDialog = new LightweightReactionsDialog(); mSceneCoordinator = new SceneCoordinator(activity); @@ -63,20 +70,49 @@ mMediator = new LightweightReactionsMediator(imageFetcher); mReactionService.getReactions((reactions) -> { mAvailableReactions = reactions; - mMediator.fetchAssetsAndGetThumbnails(reactions, (thumbnails) -> { - assert thumbnails != null; - assert thumbnails.length > 0; - assert thumbnails.length == mAvailableReactions.size(); - }); + mMediator.fetchAssetsAndGetThumbnails(reactions, this::onAssetsFetched); }); } /** - * Initializes the toolbar after the root dialog view is ready. + * Creates the toolbar coordinator after the root dialog view is ready, then attempts to finish + * the initialization of the feature. * @param view The root {@link View} of the dialog. */ private void onViewCreated(View view) { + mDialogViewCreated = true; mToolbarCoordinator = new ToolbarCoordinator(view, this, mSceneCoordinator); + maybeFinishInitialization(); + } + + /** + * Stores the thumbnails of the reactions, then attempts to finish the initialization of the + * feature. + * @param thumbnails The list of thumbnails. The order must be the same as + * {@code mAvailableReactions}. + */ + private void onAssetsFetched(Bitmap[] thumbnails) { + assert thumbnails != null; + assert thumbnails.length == mAvailableReactions.size(); + + mAssetsFetched = true; + mThumbnails = thumbnails; + maybeFinishInitialization(); + } + + /** + * Performs the remaining initialization for the feature, namely creating the toolbar carousel + * for the reactions, hooking up the remaining event handlers, and dismissing the loading view. + * + * <p><b>Note:</b> The dialog view must be ready and the assets must have been fetched. If + * either is missing, this is a no-op. + */ + private void maybeFinishInitialization() { + if (!mDialogViewCreated || !mAssetsFetched) { + // Wait until both operations have completed. + return; + } + mToolbarCoordinator.initReactions(mThumbnails); } // LightweightReactionsCoordinator implementation.
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarCoordinator.java b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarCoordinator.java index 4df517f..a0d7c4f6 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarCoordinator.java +++ b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarCoordinator.java
@@ -4,28 +4,54 @@ package org.chromium.chrome.browser.content_creation.reactions.toolbar; +import android.graphics.Bitmap; import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.RelativeLayout; import org.chromium.chrome.browser.content_creation.reactions.internal.R; +import org.chromium.ui.base.ViewUtils; /** * Coordinator for the Lightweight Reactions toolbar. */ public class ToolbarCoordinator { + private static final int THUMBNAIL_SIZE_DP = 56; + private final ToolbarControlsDelegate mControlsDelegate; private final ToolbarReactionsDelegate mReactionsDelegate; + private final RelativeLayout mRootLayout; public ToolbarCoordinator(View parentView, ToolbarControlsDelegate controlsDelegate, ToolbarReactionsDelegate reactionsDelegate) { mControlsDelegate = controlsDelegate; mReactionsDelegate = reactionsDelegate; - RelativeLayout toolbarLayout = parentView.findViewById(R.id.lightweight_reactions_toolbar); + mRootLayout = parentView.findViewById(R.id.lightweight_reactions_toolbar); - View closeButton = toolbarLayout.findViewById(R.id.close_button); + View closeButton = mRootLayout.findViewById(R.id.close_button); closeButton.setOnClickListener(v -> mControlsDelegate.cancelButtonTapped()); - View doneButton = toolbarLayout.findViewById(R.id.done_button); + View doneButton = mRootLayout.findViewById(R.id.done_button); doneButton.setOnClickListener(v -> mControlsDelegate.doneButtonTapped()); } + + /** + * Populates the reaction picker carousel with the given thumbnails. + */ + public void initReactions(Bitmap[] thumbnails) { + LinearLayout lr = + mRootLayout.findViewById(R.id.lightweight_reactions_toolbar_reaction_picker); + for (int i = 0; i < thumbnails.length; ++i) { + ImageView iv = new ImageView(mRootLayout.getContext()); + iv.setImageBitmap(thumbnails[i]); + int thumbnailSizePx = ViewUtils.dpToPx(mRootLayout.getContext(), THUMBNAIL_SIZE_DP); + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( + thumbnailSizePx, LinearLayout.LayoutParams.MATCH_PARENT); + iv.setLayoutParams(params); + iv.setAdjustViewBounds(true); + iv.setScaleType(ImageView.ScaleType.CENTER_CROP); + lr.addView(iv); + } + } }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index c6163a42..3db5bcf5 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -5119,6 +5119,11 @@ "expiry_milestone": 97 }, { + "name": "swap-android-share-hub-rows", + "owners": [ "ellyjones", "chrome-sharing-eng@google.com" ], + "expiry_milestone": 100 + }, + { "name": "sync-autofill-wallet-offer-data", "owners": ["siyua", "treib"], "expiry_milestone": 100
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 0b7ce501..5653b3c4 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3467,6 +3467,10 @@ "When enabled with #share-usage-ranking, forces the 'More' option to " "occupy the right-most slot on the screen instead of moving depending on " "the length of the target list."; +const char kSwapAndroidShareHubRowsName[] = "Swap Android share hub rows."; +const char kSwapAndroidShareHubRowsDescription[] = + "Swap the order of the first-party and third-party rows in the Android " + "share hub."; const char kRequestDesktopSiteForTabletsName[] = "Request desktop site for tablets on Android";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 8f6b0d6..47f03b3 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1984,6 +1984,8 @@ extern const char kShareUsageRankingDescription[]; extern const char kShareUsageRankingFixedMoreName[]; extern const char kShareUsageRankingFixedMoreDescription[]; +extern const char kSwapAndroidShareHubRowsName[]; +extern const char kSwapAndroidShareHubRowsDescription[]; extern const char kSingleTouchSelectName[]; extern const char kSingleTouchSelectDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 0f5927b..27e81bf8 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -349,6 +349,7 @@ &send_tab_to_self::kSendTabToSelfV2, &send_tab_to_self::kSendTabToSelfManageDevicesLink, &send_tab_to_self::kSendTabToSelfWhenSignedIn, + &share::kSwapAndroidShareHubRows, &share::kUpcomingSharingFeatures, &signin::kMobileIdentityConsistencyPromos, &switches::kForceStartupSigninPromo,
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 473af55..5c55817 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -496,6 +496,7 @@ "SplitCacheByNetworkIsolationKey"; public static final String START_SURFACE_ANDROID = "StartSurfaceAndroid"; public static final String STORE_HOURS = "StoreHoursAndroid"; + public static final String SWAP_ANDROID_SHARE_HUB_ROWS = "SwapAndroidShareHubRows"; public static final String SWAP_PIXEL_FORMAT_TO_FIX_CONVERT_FROM_TRANSLUCENT = "SwapPixelFormatToFixConvertFromTranslucent"; public static final String SYNC_REUPLOAD_BOOKMARKS = "SyncReuploadBookmarks";
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc index 8831a65..e839fb51 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle.cc
@@ -15,6 +15,7 @@ #include "base/callback.h" #include "base/feature_list.h" #include "base/metrics/histogram_macros.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/lookalikes/lookalike_url_blocking_page.h" #include "chrome/browser/lookalikes/lookalike_url_controller_client.h" @@ -343,11 +344,26 @@ first_is_lookalike); } - RecordUMAFromMatchType(first_is_lookalike ? first_match_type - : last_match_type); + LookalikeUrlMatchType match_type = + first_is_lookalike ? first_match_type : last_match_type; + if (match_type == LookalikeUrlMatchType::kCharacterSwapSiteEngagement || + match_type == LookalikeUrlMatchType::kCharacterSwapTop500) { + GURL lookalike_url = first_is_lookalike ? first_url : last_url; + + navigation_handle()->GetWebContents()->GetMainFrame()->AddMessageToConsole( + blink::mojom::ConsoleMessageLevel::kWarning, + base::StringPrintf( + "Chrome has determined that %s could be fake or fraudulent.\n\n" + "Future Chrome versions will show a warning on this domain name. " + "If you believe this is shown in error please visit " + "https://g.co/chrome/lookalike-warnings", + lookalike_url.host().c_str())); + } + + RecordUMAFromMatchType(match_type); // Interstitial normally records UKM, but still record when it's not shown. RecordUkmForLookalikeUrlBlockingPage( - source_id, first_is_lookalike ? first_match_type : last_match_type, + source_id, match_type, LookalikeUrlBlockingPageUserAction::kInterstitialNotShown, first_is_lookalike); return NavigationThrottle::PROCEED;
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc index 197fc6c8..72194d4 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc
@@ -818,7 +818,14 @@ // Advance clock to force a fetch of new engaged sites list. test_clock()->Advance(base::Hours(1)); + content::WebContents* tab = + browser()->tab_strip_model()->GetActiveWebContents(); + content::WebContentsConsoleObserver console_observer(tab); + console_observer.SetPattern("Chrome has determined that*character-wsap.com*"); + TestInterstitialNotShown(browser(), kNavigatedUrl); + console_observer.Wait(); + histograms.ExpectTotalCount(lookalikes::kHistogramName, 1); histograms.ExpectBucketCount( lookalikes::kHistogramName,
diff --git a/chrome/browser/nacl_host/test/nacl_gdb_browsertest.cc b/chrome/browser/nacl_host/test/nacl_gdb_browsertest.cc index fd0c505..fed874a 100644 --- a/chrome/browser/nacl_host/test/nacl_gdb_browsertest.cc +++ b/chrome/browser/nacl_host/test/nacl_gdb_browsertest.cc
@@ -53,9 +53,8 @@ // to either add suspended process support to base::LaunchProcess or use // Win API. #if defined(OS_WIN) - if (base::win::OSInfo::GetInstance()->wow64_status() == - base::win::OSInfo::WOW64_DISABLED) { - return; + if (base::win::OSInfo::GetInstance()->IsWowDisabled()) { + return; } #endif base::ScopedAllowBlockingForTesting allow_blocking;
diff --git a/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc b/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc index 1e8d6d2..ccb14f96 100644 --- a/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc +++ b/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc
@@ -301,14 +301,6 @@ // Navigate away so UKM get recorded. ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_with_hints())); - - auto entries = ukm_recorder.GetEntriesByName( - ukm::builders::OptimizationGuide::kEntryName); - for (const auto* entry : entries) { - EXPECT_FALSE(ukm_recorder.EntryHasMetric( - entry, - ukm::builders::OptimizationGuide::kRegisteredOptimizationTypesName)); - } } IN_PROC_BROWSER_TEST_F(OptimizationGuideKeyedServiceBrowserTest,
diff --git a/chrome/browser/password_manager/android/password_store_android_backend.cc b/chrome/browser/password_manager/android/password_store_android_backend.cc index c11d3a6..d77ba8f 100644 --- a/chrome/browser/password_manager/android/password_store_android_backend.cc +++ b/chrome/browser/password_manager/android/password_store_android_backend.cc
@@ -182,6 +182,11 @@ base::Unretained(this))); } +void PasswordStoreAndroidBackend::GetSyncStatus( + base::OnceCallback<void(bool)> callback) { + NOTREACHED(); +} + void PasswordStoreAndroidBackend::OnCompleteWithLogins( JobId job_id, std::vector<PasswordForm> passwords) {
diff --git a/chrome/browser/password_manager/android/password_store_android_backend.h b/chrome/browser/password_manager/android/password_store_android_backend.h index 8131c1d..0d077eb 100644 --- a/chrome/browser/password_manager/android/password_store_android_backend.h +++ b/chrome/browser/password_manager/android/password_store_android_backend.h
@@ -153,6 +153,7 @@ FieldInfoStore* GetFieldInfoStore() override; std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> CreateSyncControllerDelegate() override; + void GetSyncStatus(base::OnceCallback<void(bool)> callback) override; // Implements PasswordStoreAndroidBackendBridge::Consumer interface. void OnCompleteWithLogins(PasswordStoreAndroidBackendBridge::JobId job_id,
diff --git a/chrome/browser/password_manager/password_store_android_backend_factory.cc b/chrome/browser/password_manager/password_store_android_backend_factory.cc index 027903700..c3db354 100644 --- a/chrome/browser/password_manager/password_store_android_backend_factory.cc +++ b/chrome/browser/password_manager/password_store_android_backend_factory.cc
@@ -23,15 +23,11 @@ return std::make_unique<PasswordStoreAndroidBackend>( PasswordStoreAndroidBackendBridge::Create()); } - if (base::FeatureList::IsEnabled( - password_manager::features::kUnifiedPasswordManagerShadowAndroid)) { - return std::make_unique<PasswordStoreBackendMigrationDecorator>( - std::make_unique<PasswordStoreImpl>(std::move(login_db)), - std::make_unique<PasswordStoreAndroidBackend>( - PasswordStoreAndroidBackendBridge::Create()), - prefs); - } - return std::make_unique<PasswordStoreImpl>(std::move(login_db)); + return std::make_unique<PasswordStoreBackendMigrationDecorator>( + std::make_unique<PasswordStoreImpl>(std::move(login_db)), + std::make_unique<PasswordStoreAndroidBackend>( + PasswordStoreAndroidBackendBridge::Create()), + prefs); } } // namespace password_manager
diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h index 1a387d2..62b73ea 100644 --- a/chrome/browser/profiles/profile_impl.h +++ b/chrome/browser/profiles/profile_impl.h
@@ -39,7 +39,6 @@ namespace chromeos { class LocaleChangeGuard; class Preferences; -class SupervisedUserTestBase; } // namespace chromeos #endif @@ -172,7 +171,6 @@ private: #if BUILDFLAG(IS_CHROMEOS_ASH) friend class ash::KioskTest; - friend class chromeos::SupervisedUserTestBase; #endif friend class Profile; FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest,
diff --git a/chrome/browser/resources/about_sys/about_sys.css b/chrome/browser/resources/about_sys/about_sys.css index 4d8b347..77f991cc 100644 --- a/chrome/browser/resources/about_sys/about_sys.css +++ b/chrome/browser/resources/about_sys/about_sys.css
@@ -2,10 +2,6 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ -#anchor { - display: none; -} - body { font-size: 84%; margin: 0; @@ -147,6 +143,18 @@ background-repeat: no-repeat; } +a.anchor { + text-decoration: none; +} + +a.anchor::before { + content: '🔗'; +} + +a.anchor:hover { + text-decoration: underline; +} + .stat-value { text-overflow: ellipsis; white-space: pre-wrap;
diff --git a/chrome/browser/resources/about_sys/about_sys.js b/chrome/browser/resources/about_sys/about_sys.js index c76da239..9b697be 100644 --- a/chrome/browser/resources/about_sys/about_sys.js +++ b/chrome/browser/resources/about_sys/about_sys.js
@@ -128,7 +128,7 @@ // Add an anchor link that links to the log entry. const anchor = document.createElement('a'); anchor.href = `#${log.statName}`; - anchor.text = '🔗'; + anchor.className = 'anchor'; nameDiv.appendChild(anchor); const a = document.createElement('a');
diff --git a/chrome/browser/resources/browser_switch/internals/browser_switch_internals.html b/chrome/browser/resources/browser_switch/internals/browser_switch_internals.html index 26745078..0a822d1 100644 --- a/chrome/browser/resources/browser_switch/internals/browser_switch_internals.html +++ b/chrome/browser/resources/browser_switch/internals/browser_switch_internals.html
@@ -1,16 +1,17 @@ <!DOCTYPE html> <html lang="en"> + <head> <meta charset="utf-8"> - <title>Legacy Browser Support Internals</title> + <title>Legacy Browser Support (LBS) - Internals</title> <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <style> ul { list-style-type: none; - padding: 0; margin: 0; + padding: 0; } table { @@ -47,8 +48,14 @@ #xml-not-fetched-yet, #xml-last-fetch { - display: none; + display: none; } + + .policy-prop { + background-color: rgba(175, 184, 193, 0.2); + color: rgb(36, 41, 47); + } + .tooltip { border-bottom: 1px dotted #666; display: inline-block; @@ -58,11 +65,11 @@ .tooltip .right { background-color: #EEE; border-radius: 8px; - box-shadow: 0 1px 8px rgba(0,0,0,0.5); + box-shadow: 0 1px 8px rgba(0, 0, 0, 0.5); box-sizing: border-box; color: #444; - font-weight: normal; font-size: 0.8rem; + font-weight: normal; left: 100%; margin-inline-start: 20px; min-width: 200px; @@ -71,7 +78,6 @@ top: 50%; transform: translate(0, -50%); visibility: hidden; - } .tooltip:hover .right { @@ -79,80 +85,145 @@ } </style> </head> + <body> - <h1>Legacy Browser Support Internals</h1> + <h1>Legacy Browser Support (LBS) - Internals</h1> + + <p> + Legacy Browser Support (LBS) allows specific URLs patterns to be opened in + an alternative browser that supports legacy features required to properly + run those sites. + </p> <!-- TODO(crbug/959379): Hide all this and show a message if BrowserSwitcherEnabled is false. --> - <h2>URL Checker</h2> + <hr> + </hr> - <label> - Enter a URL to see what LBS would do with it. - <input type="text" id="url-checker-input" - placeholder="http://example.com/"> - </label> + <section id="url-checker-section"> + <h2>URL Checker</h2> - <ul> - <li id="output"></li> - <li id="reason"></li> - </ul> + <label> + Enter a URL to see what LBS would do with it. + <input type="text" id="url-checker-input" placeholder="http://example.com/"> + </label> - <h2 class="tooltip"> - Sitelist - <span class="right"> - The list of websites that redirect to alternative browser. - </span> - </h2> - <table id="sitelist"></table> + <ul> + <li id="output"></li> + <li id="reason"></li> + </ul> + </section> - <h2 class="tooltip"> - Greylist - <span class="right"> - The list of websites that can open in either browser. - </span> - </h2> - <table id="greylist"></table> + <hr> + </hr> - <h2 class="tooltip"> - XML sitelists - <span class="right"> - XML files that are being used to set the policies. - </span> - </h2> + <section id="xml-configuration-source"> + <h2 class="tooltip"> + XML configuration source + <span class="right"> + XML files that are being used to set the policies. + </span> + </h2> - <table id="xml-sitelists"></table> + <table id="xml-sitelists"></table> - <div id="xml-description-wrapper"> - <p id="xml-not-fetched-yet"> - XML sitelists have not been fetched yet. - </p> + <div id="xml-description-wrapper"> + <p id="xml-not-fetched-yet"> + XML sitelists have not been fetched yet. + </p> - <p id="xml-last-fetch"> - XML sitelists were last downloaded at - <span id="last-fetch-placeholder"></span>. - </p> + <p id="xml-last-fetch"> + XML sitelists were last downloaded at + <span id="last-fetch-placeholder"></span>. + </p> - <p id="xml-next-fetch"> - Next download is at - <span id="next-fetch-placeholder"></span>. - </p> + <p id="xml-next-fetch"> + Next download is at + <span id="next-fetch-placeholder"></span>. + </p> + + <p> + <button id="refresh-xml-button">Download now</button> + </p> + </div> + </section> + + <hr> + </hr> + + <section id="sitelist-section"> + <h2 class="tooltip"> + Force open in + <span class="right"> + The list of websites that redirect to alternative browser. + </span> + </h2> + <h4> + This list is affected by + <a href="https://chromeenterprise.google/policies/#BrowserSwitcherUrlList"><span + class="policy-prop">{BrowserSwitcherUrlList}</span></a>, + <a + href="https://chromeenterprise.google/policies/#BrowserSwitcherExternalSitelistUrl"><span + class="policy-prop">{BrowserSwitcherExternalSitelistUrl}</span></a>, + and + <a + href="https://chromeenterprise.google/policies/#BrowserSwitcherUseIeSitelist"><span + class="policy-prop">{BrowserSwitcherUseIeSitelist}</span></a> + </h4> <p> - <button id="refresh-xml-button">Download now</button> + URLs matching these rules will be forced to open in a specific browser. </p> - </div> + <table id="sitelist"></table> + </section> - <template id="header-row-template"> + <hr> + </hr> + + <section id="greylist-section"> + <h2 class="tooltip"> + Ignore + <span class="right"> + The list of websites that can open in either browser. + </span> + </h2> + <h4> + This list is affected by + <a + href="https://chromeenterprise.google/policies/#BrowserSwitcherExternalGreylistUrl"><span + class="policy-prop">{BrowserSwitcherUrlGreylist}</span></a>, and + <a + href="https://chromeenterprise.google/policies/#BrowserSwitcherUrlGreylist"><span + class="policy-prop">{BrowserSwitcherUrlGreylist}</span></a> + </h4> + + <p> + <!-- TODO change This browser for real browser name --> + URLs matching these rules won't trigger a browser switch and can be + open in either this browser or the alternate browser. + </p> + <table id="greylist"></table> + </section> + + <template id="header-row-template-sitelist"> <tr> <th>Rule</th> <th>Source</th> <th>Type</th> - <th>Inverted?</th> + <th>Opens in</th> </tr> </template> - <template id="rule-row-template"> + <template id="header-row-template-greylist"> + <tr> + <th>Rule</th> + <th>Source</th> + <th>Type</th> + </tr> + </template> + + <template id="rule-row-template-sitelist"> <tr> <td></td> <td></td> @@ -161,6 +232,14 @@ </tr> </template> + <template id="rule-row-template-greylist"> + <tr> + <td></td> + <td></td> + <td></td> + </tr> + </template> + <template id="xml-header-row-template"> <tr> <th>Source policy</th> @@ -177,4 +256,5 @@ <script type="module" src="/internals/browser_switch_internals.js"></script> </body> + </html>
diff --git a/chrome/browser/resources/browser_switch/internals/browser_switch_internals.ts b/chrome/browser/resources/browser_switch/internals/browser_switch_internals.ts index 8d6ed74..31fc1781 100644 --- a/chrome/browser/resources/browser_switch/internals/browser_switch_internals.ts +++ b/chrome/browser/resources/browser_switch/internals/browser_switch_internals.ts
@@ -3,8 +3,8 @@ // found in the LICENSE file. import '../strings.m.js'; -import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {addWebUIListener, sendWithPromise} from 'chrome://resources/js/cr.m.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {$} from 'chrome://resources/js/util.m.js'; type Decision = { @@ -24,6 +24,8 @@ external?: RuleSet; }; +type ListName = 'sitelist'|'greylist'; + /** * Returned by getRulesetSources(). */ @@ -79,16 +81,23 @@ * Creates and returns a <tr> element for the given rule. */ function createRowForRule( - rule: string, rulesetName: string): HTMLTableRowElement { + rule: string, rulesetName: string, + listType: ListName): HTMLTableRowElement { + const templateName = `rule-row-template-${listType}`; const row = document.importNode( - ($('rule-row-template') as HTMLTemplateElement).content, - true) as unknown as HTMLTableRowElement; + ($(templateName) as HTMLTemplateElement).content, true) as + unknown as HTMLTableRowElement; const cells = row.querySelectorAll('td'); cells[0].innerText = rule; cells[0].className = 'url'; cells[1].innerText = rulesetName; cells[2].innerText = getRuleType(rule); - cells[3].innerText = /^!/.test(rule) ? 'yes' : 'no'; + if (listType === 'sitelist') { + // TODO(crbug.com/1258133): Make it show the name of the browser instead of + // 'this browser' + cells[3].innerText = /^!/.test(rule) ? 'This browser' : getAltBrowserName(); + } + return row; } @@ -96,15 +105,19 @@ * Updates the content of all tables after receiving data from the backend. */ function updateTables(rulesets: RuleSetList) { - const headerTemplate = $('header-row-template') as HTMLTemplateElement; - clearTable($('sitelist') as HTMLTableElement, headerTemplate); - clearTable($('greylist') as HTMLTableElement, headerTemplate); + const siteListHeaderTemplate = + $('header-row-template-sitelist') as HTMLTemplateElement; + const greyListHeaderTemplate = + $('header-row-template-greylist') as HTMLTemplateElement; + clearTable($('sitelist') as HTMLTableElement, siteListHeaderTemplate); + clearTable($('greylist') as HTMLTableElement, greyListHeaderTemplate); for (const [rulesetName, ruleset] of Object.entries(rulesets)) { for (const [listName, rules] of Object.entries(ruleset as RuleSet)) { const table = $(listName); for (const rule of rules) { - table.appendChild(createRowForRule(rule, rulesetName)); + table.appendChild( + createRowForRule(rule, rulesetName, listName as ListName)); } } } @@ -126,12 +139,13 @@ switch (decision.action) { case 'stay': - // TODO(crbug.com/1258133): Make it show the name of the browser. - opensIn = 'Opens in: This browser\n'; - break; + // TODO(crbug.com/1258133): Make it show the name of the browser instead + // of 'this browser' + opensIn = 'Opens in: This browser\n'; + break; case 'go': - opensIn = `Opens in: ${altBrowserName}\n`; - break; + opensIn = `Opens in: ${altBrowserName}\n`; + break; } let reason = ''; @@ -146,21 +160,23 @@ switch (decision.reason) { case 'globally_disabled': - reason += 'Reason: The BrowserSwitcherEnabled policy is false.\n'; - break; + reason += 'Reason: The BrowserSwitcherEnabled policy is false.\n'; + break; case 'protocol': - reason += 'Reason: LBS only supports http://, https://, and file:// URLs.\n'; - break; + reason += + 'Reason: LBS only supports http://, https://, and file:// URLs.\n'; + break; case 'sitelist': - reason += 'the sitelist.\n'; - break; + reason += 'the "Force open in" list.\n'; + break; case 'greylist': - reason += 'the greylist.\n'; - break; - case 'default' : - // TODO(crbug.com/1258133): Make it show the name of the browser. - reason += 'Reason: LBS stays in Google Chrome by default.\n'; - break; + reason += 'the "Ignore" list.\n'; + break; + case 'default': + // TODO(crbug.com/1258133): Make it show the name of the browser instead + // of 'this browser' + reason += 'Reason: LBS stays in this browser by default.\n'; + break; } return [opensIn, reason];
diff --git a/chrome/browser/resources/chrome-logo-faded.png b/chrome/browser/resources/chrome-logo-faded.png deleted file mode 100644 index cc35d42..0000000 --- a/chrome/browser/resources/chrome-logo-faded.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/images/options.png b/chrome/browser/resources/chromeos/accessibility/chromevox/images/options.png deleted file mode 100644 index 029b2dd..0000000 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/images/options.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/detected_sd.png b/chrome/browser/resources/chromeos/detected_sd.png deleted file mode 100644 index fe3cf300c..0000000 --- a/chrome/browser/resources/chromeos/detected_sd.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/detected_usb.png b/chrome/browser/resources/chromeos/detected_usb.png deleted file mode 100644 index a38152a..0000000 --- a/chrome/browser/resources/chromeos/detected_usb.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/images/new_charger_au.png b/chrome/browser/resources/chromeos/images/new_charger_au.png deleted file mode 100644 index 8f152d3d..0000000 --- a/chrome/browser/resources/chromeos/images/new_charger_au.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/images/new_charger_uk.png b/chrome/browser/resources/chromeos/images/new_charger_uk.png deleted file mode 100644 index fe84eff..0000000 --- a/chrome/browser/resources/chromeos/images/new_charger_uk.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/images/new_charger_us.png b/chrome/browser/resources/chromeos/images/new_charger_us.png deleted file mode 100644 index 093bb1a..0000000 --- a/chrome/browser/resources/chromeos/images/new_charger_us.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/images/original_charger_au.png b/chrome/browser/resources/chromeos/images/original_charger_au.png deleted file mode 100644 index 24b54e53..0000000 --- a/chrome/browser/resources/chromeos/images/original_charger_au.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/images/original_charger_uk.png b/chrome/browser/resources/chromeos/images/original_charger_uk.png deleted file mode 100644 index e270822..0000000 --- a/chrome/browser/resources/chromeos/images/original_charger_uk.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/images/original_charger_us.png b/chrome/browser/resources/chromeos/images/original_charger_us.png deleted file mode 100644 index bf20388..0000000 --- a/chrome/browser/resources/chromeos/images/original_charger_us.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/images/safe-charger-checkmark.png b/chrome/browser/resources/chromeos/images/safe-charger-checkmark.png deleted file mode 100644 index 474e625..0000000 --- a/chrome/browser/resources/chromeos/images/safe-charger-checkmark.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/insert.png b/chrome/browser/resources/chromeos/insert.png deleted file mode 100644 index 829a595e..0000000 --- a/chrome/browser/resources/chromeos/insert.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/login/screens/common/fingerprint_setup.js b/chrome/browser/resources/chromeos/login/screens/common/fingerprint_setup.js index 5c19f4d5..d11f6cd0 100644 --- a/chrome/browser/resources/chromeos/login/screens/common/fingerprint_setup.js +++ b/chrome/browser/resources/chromeos/login/screens/common/fingerprint_setup.js
@@ -44,6 +44,14 @@ [OobeI18nBehavior, MultiStepBehavior, LoginScreenBehavior], Polymer.Element); +/** + * @typedef {{ + * setupFingerprint: OobeAdaptiveDialogElement, + * arc: CrFingerprintProgressArcElement, + * }} + */ +FingerprintSetupBase.$; + class FingerprintSetup extends FingerprintSetupBase { static get is() { return 'fingerprint-setup-element'; @@ -197,15 +205,13 @@ /** * Enable/disable lottie animation. * @param {boolean} playing True if animation should be playing. - * @suppress {missingProperties} */ setAnimationState_(playing) { if (this.shouldUseLottieAnimation_) { const lottieElement = /** @type{CrLottieElement} */ ( this.$.setupFingerprint.querySelector('#scannerLocationLottie')); lottieElement.setPlay(playing); - /** @type {!CrFingerprintProgressArcElement} */ (this.$.arc) - .setPlay(playing); + this.$.arc.setPlay(playing); } } @@ -261,13 +267,12 @@ onProgressChanged_(newValue, oldValue) { // Start a new enrollment, so reset all enrollment related states. if (newValue === 0) { - /** @type {!CrFingerprintProgressArcElement} */ (this.$.arc).reset(); + this.$.arc.reset(); this.scanResult_ = FingerprintResultType.SUCCESS; return; } - /** @type {!CrFingerprintProgressArcElement} */ (this.$.arc) - .setProgress(oldValue, newValue, newValue === 100); + this.$.arc.setProgress(oldValue, newValue, newValue === 100); } }
diff --git a/chrome/browser/resources/chromeos/parent_access/BUILD.gn b/chrome/browser/resources/chromeos/parent_access/BUILD.gn index ad3f8ae3..f326d21 100644 --- a/chrome/browser/resources/chromeos/parent_access/BUILD.gn +++ b/chrome/browser/resources/chromeos/parent_access/BUILD.gn
@@ -7,11 +7,22 @@ js_type_check("closure_compile") { is_polymer3 = true - deps = [ ":parent_access_ui" ] + deps = [ + ":parent_access_controller", + ":parent_access_ui", + ] +} + +js_library("parent_access_controller") { + deps = [ + "//ui/webui/resources/js:post_message_api_server.m", + "//ui/webui/resources/js:promise_resolver.m", + ] } js_library("parent_access_ui") { deps = [ + ":parent_access_controller", "//chrome/browser/ui/webui/chromeos/parent_access:mojo_bindings_js_library_for_compile", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/js:load_time_data.m",
diff --git a/chrome/browser/resources/chromeos/parent_access/parent_access_controller.js b/chrome/browser/resources/chromeos/parent_access/parent_access_controller.js new file mode 100644 index 0000000..3d8bb47 --- /dev/null +++ b/chrome/browser/resources/chromeos/parent_access/parent_access_controller.js
@@ -0,0 +1,69 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {PostMessageAPIServer} from 'chrome://resources/js/post_message_api_server.m.js'; +import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; + +/** + * Class that implements the Chrome side of the ParentAccess PostMessageAPI. + */ +export class ParentAccessController extends PostMessageAPIServer { + /* + * @param {!Element} webviewElement The <webview> element to listen to as a + * client. + * @param {string} targetURL The target URL to use for outgoing messages. + * This should be the same as the URL loaded in the webview. + * @param {string} originURLPrefix The URL prefix to use to filter incoming + * messages via the postMessage API. + * @param {!function(string)} onParentAccessResultFn Function to call when + * parent access is granted. + * @param {!function(string)} onInitializationErrorFn Function to call there + * was an error initializing the controller. + */ + constructor(webviewElement, targetURL, originURLPrefix) { + super(webviewElement, targetURL, originURLPrefix); + + /** @private {!PromiseResolver} */ + this.parentAccessResultResolver_ = new PromiseResolver(); + /** @private {!PromiseResolver} */ + this.initializationErrorResolver_ = new PromiseResolver(); + + this.registerMethod('onParentAccessResult', (param) => { + this.parentAccessResult_(param[0]); + }); + } + + /* + * @return {!Promise<string>} A promise that rejects when there was an error + * initializing the PostMessageAPI connection. + */ + whenInitializationError() { + return this.initializationErrorResolver_.promise; + } + + /** @override */ + onInitializationError(origin) { + this.initializationErrorResolver_.reject(origin); + } + + /* + * @return {!Promise<string>} A promise that resolves when a parent access + * result was received. + */ + whenParentAccessResult() { + return this.parentAccessResultResolver_.promise; + } + + /** + * Signals to the owner that the parent access web widget completed. + * @private + * @param {string} parentAccessResultProto The result of the parent + * verification returned by the web widget. It is a base64 encoded + * serialized proto that contains the proof of verification that can be + * used by the handler. + */ + parentAccessResult_(parentAccessResultProto) { + this.parentAccessResultResolver_.resolve(parentAccessResultProto); + } +}
diff --git a/chrome/browser/resources/chromeos/smb_shares/BUILD.gn b/chrome/browser/resources/chromeos/smb_shares/BUILD.gn index e8dad71..01d43fc 100644 --- a/chrome/browser/resources/chromeos/smb_shares/BUILD.gn +++ b/chrome/browser/resources/chromeos/smb_shares/BUILD.gn
@@ -15,14 +15,14 @@ js_library("smb_share_dialog") { deps = [ - "//ui/webui/resources/cr_components/chromeos/smb_shares:add_smb_share_dialog.m", + "//ui/webui/resources/cr_components/chromeos/smb_shares:add_smb_share_dialog", "//ui/webui/resources/js:i18n_behavior.m", ] } js_library("smb_credentials_dialog") { deps = [ - "//ui/webui/resources/cr_components/chromeos/smb_shares:smb_browser_proxy.m", + "//ui/webui/resources/cr_components/chromeos/smb_shares:smb_browser_proxy", "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m", "//ui/webui/resources/cr_elements/cr_input:cr_input.m", "//ui/webui/resources/js:assert.m",
diff --git a/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.js b/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.js index 3677802..f12c32b 100644 --- a/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.js +++ b/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.js
@@ -7,7 +7,7 @@ import 'chrome://resources/cr_elements/cr_input/cr_input.m.js'; import './strings.m.js'; -import {SmbBrowserProxy, SmbBrowserProxyImpl} from 'chrome://resources/cr_components/chromeos/smb_shares/smb_browser_proxy.m.js'; +import {SmbBrowserProxy, SmbBrowserProxyImpl} from 'chrome://resources/cr_components/chromeos/smb_shares/smb_browser_proxy.js'; import {assert} from 'chrome://resources/js/assert.m.js'; import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/browser/resources/chromeos/smb_shares/smb_share_dialog.js b/chrome/browser/resources/chromeos/smb_shares/smb_share_dialog.js index 46a6256..b5ea2646 100644 --- a/chrome/browser/resources/chromeos/smb_shares/smb_share_dialog.js +++ b/chrome/browser/resources/chromeos/smb_shares/smb_share_dialog.js
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'chrome://resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.m.js'; +import 'chrome://resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.js'; import './strings.m.js'; import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/button_minimize.png b/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/button_minimize.png deleted file mode 100644 index 437c6f700..0000000 --- a/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/button_minimize.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close_bar.png b/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close_bar.png deleted file mode 100644 index 142adb8..0000000 --- a/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/2x/close_bar.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close_bar.png b/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close_bar.png deleted file mode 100644 index e70e5b6..0000000 --- a/chrome/browser/resources/chromeos/wallpaper_manager/images/ui/close_bar.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/history/app.html b/chrome/browser/resources/history/app.html index 9a71fd72..54a007e1 100644 --- a/chrome/browser/resources/history/app.html +++ b/chrome/browser/resources/history/app.html
@@ -33,8 +33,7 @@ #tabs { --cr-tabs-icon-margin-end: 8px; - --cr-tabs-margin-end: 16px; - --cr-tabs-margin-start: 16px; + --cr-tabs-tab-inline-padding: 16px; border-bottom: 1px solid var(--separator-color); display: flex; justify-content: center;
diff --git a/chrome/browser/resources/local_state/local_state.html b/chrome/browser/resources/local_state/local_state.html index 72795b9..6e98221 100644 --- a/chrome/browser/resources/local_state/local_state.html +++ b/chrome/browser/resources/local_state/local_state.html
@@ -2,6 +2,7 @@ <html lang="en"> <head> <meta charset="utf-8"> + <meta name="color-scheme" content="light dark"> <title>Local State Debug Page</title> <link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> <script type="module" src="local_state.js"></script>
diff --git a/chrome/browser/resources/print_preview/ui/destination_dialog_cros.ts b/chrome/browser/resources/print_preview/ui/destination_dialog_cros.ts index b391422..6f94f1afa 100644 --- a/chrome/browser/resources/print_preview/ui/destination_dialog_cros.ts +++ b/chrome/browser/resources/print_preview/ui/destination_dialog_cros.ts
@@ -4,7 +4,7 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; -import 'chrome://resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.m.js'; +import 'chrome://resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.js'; import 'chrome://resources/cr_elements/hidden_style_css.m.js'; import 'chrome://resources/cr_elements/shared_vars_css.m.js'; import 'chrome://resources/js/action_link.js';
diff --git a/chrome/browser/resources/safe_browsing/images/2x/malware_icon_v2.png b/chrome/browser/resources/safe_browsing/images/2x/malware_icon_v2.png deleted file mode 100644 index 31d8d8b..0000000 --- a/chrome/browser/resources/safe_browsing/images/2x/malware_icon_v2.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/safe_browsing/images/2x/phishing_icon.png b/chrome/browser/resources/safe_browsing/images/2x/phishing_icon.png deleted file mode 100644 index b537a01..0000000 --- a/chrome/browser/resources/safe_browsing/images/2x/phishing_icon.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/safe_browsing/images/2x/subresource_icon.png b/chrome/browser/resources/safe_browsing/images/2x/subresource_icon.png deleted file mode 100644 index 63df4005..0000000 --- a/chrome/browser/resources/safe_browsing/images/2x/subresource_icon.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/sandbox_internals/sandbox_internals.html b/chrome/browser/resources/sandbox_internals/sandbox_internals.html index 6a51ae6..eb67433 100644 --- a/chrome/browser/resources/sandbox_internals/sandbox_internals.html +++ b/chrome/browser/resources/sandbox_internals/sandbox_internals.html
@@ -2,6 +2,7 @@ <html lang="en"> <head> <meta charset="utf-8"> + <meta name="color-scheme" content="light dark"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Sandbox Status</title> <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
diff --git a/chrome/browser/resources/settings/chromeos/lazy_load.js b/chrome/browser/resources/settings/chromeos/lazy_load.js index 66f2e68..2370b5a 100644 --- a/chrome/browser/resources/settings/chromeos/lazy_load.js +++ b/chrome/browser/resources/settings/chromeos/lazy_load.js
@@ -55,7 +55,7 @@ import '../privacy_page/secure_dns.js'; import '../privacy_page/secure_dns_input.js'; -export {SmbBrowserProxyImpl, SmbMountResult} from 'chrome://resources/cr_components/chromeos/smb_shares/smb_browser_proxy.m.js'; +export {SmbBrowserProxyImpl, SmbMountResult} from 'chrome://resources/cr_components/chromeos/smb_shares/smb_browser_proxy.js'; export {LifetimeBrowserProxyImpl} from '../lifetime_browser_proxy.js'; export {PrivacyPageBrowserProxyImpl, SecureDnsMode, SecureDnsUiManagementMode} from '../privacy_page/privacy_page_browser_proxy.js'; export {CrostiniBrowserProxy, CrostiniBrowserProxyImpl} from './crostini_page/crostini_browser_proxy.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_files_page/smb_shares_page.js b/chrome/browser/resources/settings/chromeos/os_files_page/smb_shares_page.js index cace98d..d6a6112 100644 --- a/chrome/browser/resources/settings/chromeos/os_files_page/smb_shares_page.js +++ b/chrome/browser/resources/settings/chromeos/os_files_page/smb_shares_page.js
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import '//resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.m.js'; +import '//resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.js'; import '//resources/cr_elements/cr_button/cr_button.m.js'; import '//resources/cr_elements/policy/cr_policy_pref_indicator.m.js'; import '//resources/js/action_link.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_edit_printer_dialog.js b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_edit_printer_dialog.js index 3fd5bd3c..eb65ee2 100644 --- a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_edit_printer_dialog.js +++ b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_edit_printer_dialog.js
@@ -9,7 +9,7 @@ import '//resources/cr_elements/cr_button/cr_button.m.js'; import '//resources/cr_elements/cr_input/cr_input.m.js'; -import '//resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.m.js'; +import '//resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.js'; import '//resources/cr_elements/shared_style_css.m.js'; import '//resources/polymer/v3_0/iron-icon/iron-icon.js'; import '//resources/cr_components/chromeos/localized_link/localized_link.js';
diff --git a/chrome/browser/resources/settings/system_page/system_page.html b/chrome/browser/resources/settings/system_page/system_page.html index 8470efd1..6bc65d2e 100644 --- a/chrome/browser/resources/settings/system_page/system_page.html +++ b/chrome/browser/resources/settings/system_page/system_page.html
@@ -31,7 +31,7 @@ $i18n{proxySettingsPolicyLabel} </div> <cr-icon-button class="icon-external" - hidden$="[[isProxyEnforcedByPolicy_]]" + hidden$="[[!isProxyDefault_]]" aria-label="$i18n{proxySettingsLabel}"></cr-icon-button> <template is="dom-if" if="[[isProxyEnforcedByPolicy_]]"> <cr-policy-pref-indicator pref="[[prefs.proxy]]"
diff --git a/chrome/browser/resources/signin/sync_confirmation/images/ic_google.png b/chrome/browser/resources/signin/sync_confirmation/images/ic_google.png deleted file mode 100644 index f7602a5..0000000 --- a/chrome/browser/resources/signin/sync_confirmation/images/ic_google.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/resources/signin/sync_confirmation/images/ic_google_2x.png b/chrome/browser/resources/signin/sync_confirmation/images/ic_google_2x.png deleted file mode 100644 index 76d09858..0000000 --- a/chrome/browser/resources/signin/sync_confirmation/images/ic_google_2x.png +++ /dev/null Binary files differ
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetBottomSheetContent.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetBottomSheetContent.java index b85c3e6..60a77b5c 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetBottomSheetContent.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetBottomSheetContent.java
@@ -19,6 +19,7 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.ImageView; import android.widget.ImageView.ScaleType; +import android.widget.LinearLayout; import android.widget.ScrollView; import android.widget.TextView; @@ -32,6 +33,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.share.ChromeShareExtras.DetailedContentType; import org.chromium.chrome.browser.share.link_to_text.LinkToTextCoordinator.LinkGeneration; import org.chromium.chrome.browser.share.share_sheet.ShareSheetLinkToggleCoordinator.LinkToggleState; @@ -147,6 +149,33 @@ /*firstParty=*/false); thirdParty.addOnScrollListener( new ScrollEventReporter("SharingHubAndroid.ThirdPartyAppsScrolled")); + + if (shouldSwapFirstAndThirdPartyRows()) { + swapFirstAndThirdPartyRows(); + } + } + + boolean shouldSwapFirstAndThirdPartyRows() { + return ChromeFeatureList.isEnabled(ChromeFeatureList.SWAP_ANDROID_SHARE_HUB_ROWS) + || ChromeFeatureList.isEnabled(ChromeFeatureList.UPCOMING_SHARING_FEATURES); + } + + void swapFirstAndThirdPartyRows() { + View firstPartyRow = getContentView().findViewById(R.id.share_sheet_chrome_apps); + View thirdPartyRow = getContentView().findViewById(R.id.share_sheet_other_apps); + + LinearLayout layout = getContentView().findViewById(R.id.share_sheet_layout); + assert firstPartyRow.getParent() == layout; + assert thirdPartyRow.getParent() == layout; + + int firstPartyIndex = layout.indexOfChild(firstPartyRow); + int thirdPartyIndex = layout.indexOfChild(thirdPartyRow); + + assert thirdPartyIndex < firstPartyIndex; + layout.removeViewAt(firstPartyIndex); + layout.removeViewAt(thirdPartyIndex); + layout.addView(firstPartyRow, thirdPartyIndex); + layout.addView(thirdPartyRow, firstPartyIndex); } void createFirstPartyRecyclerViews(List<PropertyModel> firstPartyModels) {
diff --git a/chrome/browser/share/core/resources/share_targets.asciipb b/chrome/browser/share/core/resources/share_targets.asciipb index dc0d275f3..bd2d4d5 100644 --- a/chrome/browser/share/core/resources/share_targets.asciipb +++ b/chrome/browser/share/core/resources/share_targets.asciipb
@@ -8,7 +8,7 @@ ## ## Top level settings ## -version_id: 9 +version_id: 10 ## ## Share Targets @@ -488,55 +488,46 @@ icon_3x: "iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAAAXNSR0IArs4c6QAA" "AERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKAC" - "AAQAAAABAAAAPKADAAQAAAABAAAAPAAAAACL3+lcAAAI80lEQVRoBe1bbWwcxRl+" - "Z+9854+z6ziNnTj+hLRGpD5jJ05oK+qUEv6kqkNjn1AVktIf/VGJVi0VtKQqSQpC" - "oT9aKrU/qgqBS1R0jguhBcRHIW6JUOLU+CMoDQji80fimMRxbOLPu50+c8nJO7u3" - "e7t7Zwe1Gcm6mXm/5tl35t2Zd9ZEN8qNJ/A/9QTYUqIJhkdqOEWbGKP1xFkNEa/i" - "jApgMyDsMs6m0Ic/NoDGac6Uk4rCOnu/XfbBUo0r44CDHcO3U0zdhQE3c+KlbgbO" - "iI0Qo8PEWFtfS/kxNzrMZDIGuLZ9sBnKHuecrzcz5qYf4E9Cbk9fqOIlN/J6mbQB" - "39Y+8hWVR5/kRF/VK89kG8Df8ZDy0HuhsnfT0esaMKZuGY+pv8MavCedATiVZYz9" - "FWv/h72h8hGnsoLfFeD68PCXoxR7AfIlboxmQGaUKcp2N+tbcWo8eCiyO8pib19H" - "sGLIqzlXO+vCw/c5Hb9twHs5V4Ltg7/mKj1DnPxODWWcH2NQKdZW1x45IMZmV7/t" - "KR0Hy/lP7SpeVj5GB/pbK39mx6YtwMH2yC7O6Vk7Cq8Xj4cpO3tayw+msp8SsNhI" - "cDV25DMxja3RzCqkNCF6H7diswR89dUT64KC1VZKPjM0RucUrjRavbKsF7uqPrXc" - "YP0eSx9YP1tOa1Sm/saKyVR7fCrHYmntaqwMa2lfW5NNrTfl08ZVfsrLUmg+xun0" - "5Xl6ZXCawh9N0YKq5SaqyvfS+JxKk/M6wjU2TO3NZlPbK6vStFT1SU3LUM3xMrpr" - "bS79LXLFQLPbkQsdT2xeSV8vzZVEfPBybZE//veddQF64OgndG46RrcXZ9O2yjwq" - "8iv0vSNjkoy2oRIXY9+i7UvUk3o4GB78Fk46hxNMyX5DNwdoT/0K2v/vceo44xw0" - "sNIfm4rh1exk6qW+6ahKWQqL/y2onO5/+zz1jc9LPPqGhzzf7AmVvazvN1vDj+kZ" - "9e1NGCj2tfTLDUW0ozpPT07Z3l1TYAusUJTrVeJgpzC3f/CvMTo/E6OWmwLkMxs9" - "ZGKkPp5sEAaRuvDQJni3Nhmztm9tnifeTIB+MFhIdgOO8O79AOy0XJiN0b6NK+m1" - "baU0Oh0lkyV8TS2vqw1HNuhtGABj/tvan84gsCSKAC081nH3atrw+dS7znrwFFi5" - "J6FY91udn0XFOR7ah2X0zuisjmpsYlgiESEVA2BQmyUOk8bAVNRAqQhk0dNbiuGF" - "IqopzDLQEx0VAfNYmeBJ9ivWsghgL9iPGQYsEuCG8NA6nG/LkxnT970ymDxQCW/f" - "Ux2g9q1r6Pm7VuN1E6BAlhwbF+eGXqt1+30EqqM2PJvQgu1wZTA8Wp1oi1/pUcNn" - "TVqiVf3EJ3PUNTZLjXhVmJVbV/joVgS1XzSsoLN4rXw8uUBnphYox+Xm4go87LRw" - "mheYziTkJMCM8fV4KrZKNgb9yPGL9Nw3SqgkR1JjkBdeX5vnjf/dsSbHQLfbcWHW" - "OWCYlnJs0pRWOa+xa/wPd6yiB770Ofo7Nh5zmgBmV94N30VEaeeF36KV0bumSku0" - "qg99Go2vVSueTNNGrhgDZUobnFVqeSQPI8WVryVa1Y9h/S53cWeTS5gkwFjDEtEK" - "kNjYvz8+Z8WSUdoZBDyxn3ZaOJOdKAFGwLIZsq6aFftosxOL04Gl4j96fiYViy26" - "BBhTGvc89supiQXa+dYoDWM9L2XBbYaTzYY0FMbF3dVikQAjhEvERTbzmthxbX/t" - "LP382IX4e9ac0z2l89wMfXh5wZUCTOlJraAUpfEkB0CU3lta5mR1cRj/850llO1R" - "bB8ekumx6vvTKWnMVqwGGuM0oO2UPIwpfVpLtFMXHhYbebsnJTs6tTxvjUynPPtq" - "+Y11LmGSAOOMLW7qHJcnui/RqUvWB3LHSiEwNhOlvSfG3YguyugwSYA59x1Z5LRf" - "m8TB/Pv/HKPOs5mJpMIydn3xreuE9aE35SA9Slanlkk+xoCCpPsAbEm7E61AqnoD" - "zrrbKnLpi4U+Wo/DgxfTxk35bf8EPf0f92s3bpPRx7iRuFlrX/JwnMCVF7UMTuvd" - "F+boqf7LNIBTkRuw4hV0oOdS+mDFwDkzYJGidBycx9OGTxZ+5BSo4C9AirUFyb37" - "vpBPK7OvpoCc6IkB7KNd4/RSGplQrT2vV2nTtkU96XzDtO6G7Xo9s2iLfJQAI05I" - "hUiXFvk9JM69m4r9tBln4xwk3NyUDybm6bHuceq5mKHgx9iJ/taKRv1YjB4WHFx5" - "BGHjVT2zaEex+awuyKKfIGl3C9ZpukVkIn9/coKe/+hTBKp0tS3KezgHBmNJ6mHB" - "FgxH/gH7dxpFFnu2lObQ9qo8Eod6kTe2W8Q67YUnXx+eppeRKrqEW4TMFvZGf6ji" - "7mQ6k3sYnAD7EBLPXcTxZZVJOYLXkPhbgandiDx13Upf/LZgFTKLhchKimsTkTgX" - "ybfRaykekUB/E0BFbnlJCo58CvM8bKbbFIwQwCX4X+CNe82EU/UL5RmcpanMXaUz" - "OohX0U4zZssI4+fZP0Y+athMOFX/soMlNpTry37QalyWgLtCxaOkePHBGcvcFspq" - "NGnQ4JhpRfE0H2suOW+lxhKwEOzbUdrNFP5dKyXXnYZ1izfL7t6Wte+lGktKwEJB" - "b0tlGAHsV6mUXS86ZuC+vlDZITv2bQEWivAR2KP42Q/gy780zZBgLIwpe3tbyvab" - "sej7LaO0nlm0a9sjrXiizyB6y7fYyZiXsE+sWTz8XXBEhxMzjgEL5cGOsw2kRg8D" - "dJkTY5njZYP40LQZF949TnXantJaxSKQ5fj8G7ETP7isU1wsJ0bPMa+v0Q1YgcGV" - "h7Xg6w6N1Ktq7AC2GFu1/RmvM/a6hysPuwWaGE/agBOKbgtHtsaI4TMDbjihJHjc" - "/CJeHOcevqd/R+WbbuT1MhkDnFDccGgoGOVcfKqIy2i+LtHv5BcB6UPwI0awtv5Q" - "eb8T2VS8GQesNdj44kj5fFRtUlWR+uU1WIJVAIHrnMSVDptixCexMCMiY4ob2JMq" - "/smjb0eZ6+2s1v6N+o0n8H/wBP4LQA/UDbT71scAAAAASUVORK5CYII=" + "AAQAAAABAAAAPKADAAQAAAABAAAAPAAAAACL3+lcAAAHN0lEQVRoBe1bXWwUVRT+" + "Zme7/d1S2tJCS2kbsCDyo/yEIFCNUaORB4wRYgIPvkiiKC8kxMQQ4huJJiYY0BgD" + "4gMBxUCMoj6RUiBoqYGAAkWgLRT6R1na7na3uzt+Z7ZbZre7M1MUdpf0JJOZnTn3" + "zvnOOffcc+6dBSZoQgOPlQaUMWjePKiiNq8eirpNUZQliqYVjOFJ4xuaogxomtYE" + "LfQxrnkb8N3akFFc1fgD27c7HAU1m6A49zoUZRbBumKeZ8APWtBFQ9UAjnWOIqdH" + "e6nuDxw7pkVFd0Qv9PPAsnpNUXcoCnKgjfLEsGTED8ouGAQLiMkocyxgB7ZnPNgo" + "uhHQIKboLTnHAKYrLM5oyxqRybUOmpgM5DRcQ4FFgKL5hVwOBVmqAo5zhMIa/KEw" + "QhqfaWFjd2lxLZiMgzMGsKmEDgfyshxYMaMI6xdVYGX1ZBRmq7h5z4+DZ2/hwLnb" + "+OeuHwjHBEXTLlPx0B5gxYFspxPbXqjF5pXVcKn3R0Jxvgvzp7nx1jOVePfweRxv" + "7SfoYCqw2HrnfcmTsdNTswjw7UXl2FJfGwPW2GRueT6+XbcAC6fmMjJYd2ts+yiv" + "rSVTVJTlO/HBihoJ9aZUVZSL95fPIN4sU75UPrQGzEBUNyUfs3nYoaVVRSjOZpjg" + "MEhHspaKob1mMt3UJuW5VExzM0HLWMCcrHx++5E3zGnKF5DpyTgZ2NTWI2CztjDn" + "3Evdg/AN2wPdNRhAe/9wWs7Jok9rwHTpiz2D2Nd001L/gWAYO0+2wa8nIZlqYQL2" + "0bifnWjVLW2G+qvf23H4QhcQDJixpfSZtYVFPGZPl+8MYcOBszh6qQueoSACTCeD" + "HK9DtGpnvx8f/XoZH/5yWb+fUkQWL7eXaY2APnOzH6v3NmMF08rl1UUoZES+xdTy" + "p4s9aOM5HXPpePz2AUtLmWocKk50+HDiFt1WMhG6PCsI/T4rCDLFjV3yJ5yiJImR" + "tpJ7yzlK0qdKsaSdhJhotiM8UpwIv6SuxjbRtjbOtgFrFKC2KBtzmICojNxcRhnt" + "nmUlBgIhNF69E8E88sRBBT1RkouZPOJJKq1ebwDNNzystnT0gNOFXCWE+ppJWDy9" + "EBWFOcinFwnme74grvb50NzhQcO1vohSQuPP2e0BJthKJhO7X5+LBdMKE2qXQxk7" + "T1zHJ8dbI5ZgPl1Xmotv1s7H9Ek58XgJQoGfU93uU+3YcaoDamgIG5dOxQZWYjMm" + "5WJKgQtOKtZIEi+6B/1o6fHi88Y2HL7YDWWcJaltwFNZFS1naejOTt7k5bqSCGCR" + "ktadV+7GvKlu5DiTx8aFFW4Uu8L4Ys3TWP1kmSmv9FNFZcixpHIS9jTdwLbfrmBg" + "mNq2CTy59EbVivxUNoOyKTniqiRxW4nkZlRABX655im8Mb/cjG3Ms8KcSEGTrarY" + "/HMLgkFJdszfJZ0kV/2YVzycGy/MLKFlpzxQ52KE9Ysr8Fy1mxaJXYBN1mHKAee5" + "ZHHhwcUoYFDbsqoGJdlEH+dhiUA/+JsS9Zaie8/TS2ZJ+Wrt0al3aaOOZAhKBjcU" + "DPGsMWbYQMAOXPSQF2cVQ7WB2HbQMgr2MK7v+oaxr7kDh87dQvvdIZRyWnpl9hRs" + "XFaFygTTWrwMq2pL8GnDdYSC5kpKC8CSm2868hf2n2PhoVtVQytT1TO3vUwyenFo" + "w2KU5JkvG80ty4dTFhclITChtBjDX3M+/eFCd2QulflUQMvBTKrxuge7TraaQIg8" + "KnNn61kZw7Upb8oB9zFl3P9nB2toipJgzGpMYA6d70S/3zyNlKSsNJ9eYI439UGr" + "pXsAbRyzZgv4fRzfV3q9ppaTeOV2WY9Qaw7z1/znp12Dw7jjZZaUjGh1idxdAyw/" + "LSjfJO2NNk25S/uGgwjrpWBUpLHnMId1QPJlC3Lq7mzu0ykHHBm2FNJ8NtGrKzO8" + "Un1xf8+SUg7YUsJxMPBzB0vuxwqwJVoyTAC2o6VM5pmwcCZbz47sExa2o6VM5pmw" + "cCZbz47s/6uFJb1Ld7IHmAmvRaqr4wyGYjfNw2wVt3kwRh+iJKuUMLKtYy6B/h59" + "Ddycz155yA2slt5BbpX24LU5pfriWqK9pT1NHQQ08kK2abzah9OtHiyqdPNurCAq" + "C/se7i39+HfnSM0e+3xUM1wB8bAyPHKhE8/WFOvbL+G4XQaV1VbzTY9+JFpEGO2L" + "FzE+6Nh6NMlbI01k/dj4UZqxI6l6vNwril9pzM1Sx+wRRdsJr+wXyeeLViQbeHns" + "KxnJDkeyzzLCO14dxRljYX50O2D2vaWfwskxHkomxHj6EF5RitUyT6I+BZPxfswY" + "ppue0TeRjByZfC3xQTAZKAYwwtguXvZYgNbBEgsxGfDGlYcFpxsULbQ140GPgBUs" + "ICYj4NgowP8GaBVrmlCkNtL3q2npUo72jPrfw8ifPE7yTx7vaNe832PXe+MLOkbt" + "TFxPaCD9NfAvSsV9mGXcnZgAAAAASUVORK5CYII=" } targets {
diff --git a/chrome/browser/share/share_features.cc b/chrome/browser/share/share_features.cc index 51472e6d..d60fe0d4 100644 --- a/chrome/browser/share/share_features.cc +++ b/chrome/browser/share/share_features.cc
@@ -6,6 +6,8 @@ namespace share { +const base::Feature kSwapAndroidShareHubRows{"SwapAndroidShareHubRows", + base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kUpcomingSharingFeatures{"UpcomingSharingFeatures", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/share/share_features.h b/chrome/browser/share/share_features.h index 742f41ec..46e8b9ee2 100644 --- a/chrome/browser/share/share_features.h +++ b/chrome/browser/share/share_features.h
@@ -9,6 +9,7 @@ namespace share { +extern const base::Feature kSwapAndroidShareHubRows; extern const base::Feature kUpcomingSharingFeatures; bool AreUpcomingSharingFeaturesEnabled();
diff --git a/chrome/browser/themes/theme_service_unittest.cc b/chrome/browser/themes/theme_service_unittest.cc index 5ca51d3..0d47d90 100644 --- a/chrome/browser/themes/theme_service_unittest.cc +++ b/chrome/browser/themes/theme_service_unittest.cc
@@ -939,8 +939,13 @@ EXPECT_TRUE(registry_->GetInstalledExtension(scoper.extension_id())); } -// TODO(crbug.com/1056953): Fix and enable. -TEST_P(ThemeProviderRedirectedEquivalenceTest, DISABLED_GetColor) { +// TODO(crbug.com/1056953): Enable on Mac. +#if defined(OS_MAC) +#define MAYBE_GetColor DISABLED_GetColor +#else +#define MAYBE_GetColor GetColor +#endif +TEST_P(ThemeProviderRedirectedEquivalenceTest, MAYBE_GetColor) { const ui::ThemeProvider& theme_provider = ThemeService::GetThemeProviderForProfile(profile()); auto param_tuple = GetParam();
diff --git a/chrome/browser/translate/translate_manager_browsertest.cc b/chrome/browser/translate/translate_manager_browsertest.cc index e83440d..98921be8 100644 --- a/chrome/browser/translate/translate_manager_browsertest.cc +++ b/chrome/browser/translate/translate_manager_browsertest.cc
@@ -285,17 +285,22 @@ ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); - // Load a German page and detect it's language + // Load a page with hrefTranslate tags. AddTabAtIndex(0, GURL(embedded_test_server()->GetURL( "www.google.com", "/href_translate_test.html")), ui::PAGE_TRANSITION_TYPED); ResetObserver(); chrome_translate_client = GetChromeTranslateClient(); - if (chrome_translate_client->GetLanguageState().source_language() != "de") - WaitUntilLanguageDetermined(); + WaitUntilLanguageDetermined(); - EXPECT_EQ("de", + // TODO(crbug.com/1258185): Migrate to better mechanism for testing around + // language detection. All pages are detected as "fr". + // + // In the case of href translate, we don't actually care if the current + // page is french, only that it loaded and whether href translate + // updates the current language state or not. + EXPECT_EQ("fr", chrome_translate_client->GetLanguageState().source_language()); // Navigate to the French page by way of a link on the original page @@ -308,6 +313,9 @@ ASSERT_TRUE(content::ExecuteScript(web_contents, click_link_js)); // Detect language on the new page + // TODO(crbug.com/1258185): Migrate to better mechanism for testing around + // language detection. All pages are currently detected as "fr" due to the + // override. WaitUntilLanguageDetermined(); EXPECT_EQ("fr", chrome_translate_client->GetLanguageState().source_language()); @@ -337,6 +345,12 @@ command_line->AppendSwitchASCII( switches::kTranslateScriptURL, embedded_test_server()->GetURL("/mock_translate_script.js").spec()); + // TODO(crbug.com/1258185): Migrate to better mechanism for testing around + // language detection. + // All pages will have language detected as "fr". These tests are around + // the manager logic so the language detection behavior should be + // deterministic rather than relying on the page content. + command_line->AppendSwitch(::switches::kOverrideLanguageDetection); } void TearDownOnMainThread() override { language_determined_waiter_.reset(); @@ -359,26 +373,20 @@ std::string script_; }; -// Tests that the CLD (Compact Language Detection) works properly. +// Tests that language detection returns a response. +// TODO(crbug.com/1258185): Migrate to better mechanism for testing around +// language detection. Seeding the TFLite model can racy/flaky on browsertests +// so we override the response. IN_PROC_BROWSER_TEST_F(TranslateManagerBrowserTest, PageLanguageDetection) { ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); - // Open a new tab with a page in English. - AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/english_page.html")), + // Open a new tab with a page in French. + AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")), ui::PAGE_TRANSITION_TYPED); ResetObserver(); chrome_translate_client = GetChromeTranslateClient(); WaitUntilLanguageDetermined(); - EXPECT_EQ("en", - chrome_translate_client->GetLanguageState().source_language()); - - ResetObserver(); - // Now navigate to a page in French. - ASSERT_TRUE(ui_test_utils::NavigateToURL( - browser(), GURL(embedded_test_server()->GetURL("/french_page.html")))); - WaitUntilLanguageDetermined(); - EXPECT_EQ("fr", chrome_translate_client->GetLanguageState().source_language()); } @@ -460,7 +468,6 @@ // Disabled due to flakiness: https://crbug.com/1202065. IN_PROC_BROWSER_TEST_F(TranslateManagerBrowserTest, DISABLED_PageTranslationAboutBlank) { - SetTranslateScript(kTestValidScript); AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")), ui::PAGE_TRANSITION_TYPED); ResetObserver(); @@ -532,14 +539,16 @@ true); SetTranslateScript(kTestValidScript); - // Load a German page and detect it's language. + // Load a page with hrefTranslate tags. AddTabAtIndex( 0, GURL(embedded_test_server()->GetURL("/href_translate_test.html")), ui::PAGE_TRANSITION_TYPED); ResetObserver(); chrome_translate_client = GetChromeTranslateClient(); WaitUntilLanguageDetermined(); - EXPECT_EQ("de", + // TODO(crbug.com/1258185): Migrate to better mechanism for testing around + // language detection. All pages will return "fr" as the detected language. + EXPECT_EQ("fr", chrome_translate_client->GetLanguageState().source_language()); // Navigate to the French page by way of a link on the original page. @@ -552,6 +561,10 @@ ASSERT_TRUE(content::ExecuteScript(web_contents, click_link_js)); // Detect language on the new page. + // TODO(crbug.com/1258185): Migrate to better mechanism for testing around + // language detection. Note: this only tests that the source language was + // whatever the page was before. The real test is that the href translate + // update did not occur, tested by AutoTranslateTo() below and the histograms. WaitUntilLanguageDetermined(); EXPECT_EQ("fr", chrome_translate_client->GetLanguageState().source_language()); @@ -570,7 +583,7 @@ true); SetTranslateScript(kTestValidScript); - // Load a German page and detect it's language + // Load a page with hrefTranslate tags. AddTabAtIndex(0, GURL(embedded_test_server()->GetURL( "www.google.com", "/href_translate_test.html")), @@ -578,7 +591,7 @@ ResetObserver(); chrome_translate_client = GetChromeTranslateClient(); WaitUntilLanguageDetermined(); - EXPECT_EQ("de", + EXPECT_EQ("fr", chrome_translate_client->GetLanguageState().source_language()); // Navigate to the French page by way of a link on the original page. This @@ -594,6 +607,10 @@ ASSERT_TRUE(content::ExecuteScript(web_contents, click_link_js)); // Detect language on the new page. + // TODO(crbug.com/1258185): Migrate to better mechanism for testing around + // language detection. Note: this only tests that the source language was + // whatever the page was before. The real test is that the href translate + // update did not occur, tested by AutoTranslateTo() below and the histograms. WaitUntilLanguageDetermined(); EXPECT_EQ("fr", chrome_translate_client->GetLanguageState().source_language()); @@ -618,17 +635,20 @@ ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); chrome_translate_client->GetTranslateManager()->SetIgnoreMissingKeyForTesting( true); + SetTranslateScript(kTestValidScript); - // Load a German page and detect it's language + // Load a page with hrefTranslate tags. AddTabAtIndex(0, GURL(embedded_test_server()->GetURL( "www.google.com", "/href_translate_test.html")), ui::PAGE_TRANSITION_TYPED); ResetObserver(); chrome_translate_client = GetChromeTranslateClient(); + // TODO(crbug.com/1258185): Migrate to better mechanism for testing around + // language detection. All pages will return "fr" as the detected language. WaitUntilLanguageDetermined(); - EXPECT_EQ("de", + EXPECT_EQ("fr", chrome_translate_client->GetLanguageState().source_language()); // Navigate to the French page that thinks its in English by way of a link on @@ -671,17 +691,19 @@ true); SetTranslateScript(kTestValidScript); - // Load a German page and detect it's language. + // Load a page with hrefTranslate tags. AddTabAtIndex(0, GURL(embedded_test_server()->GetURL( "www.google.com", "/href_translate_test.html")), ui::PAGE_TRANSITION_TYPED); ResetObserver(); chrome_translate_client = GetChromeTranslateClient(); - if (chrome_translate_client->GetLanguageState().source_language() != "de") + // TODO(crbug.com/1258185): Migrate to better mechanism for testing around + // language detection. All pages will return "fr" as the detected language. + if (chrome_translate_client->GetLanguageState().source_language() != "fr") WaitUntilLanguageDetermined(); - EXPECT_EQ("de", + EXPECT_EQ("fr", chrome_translate_client->GetLanguageState().source_language()); // Use a link with no hrefLang to navigate to a French page. @@ -1031,9 +1053,11 @@ ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); - // Open a new tab with a page in English and translate to English to force an + // Open a new tab with a page in French and translate to French to force an // error. - AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/english_page.html")), + // TODO(crbug.com/1258185): Migrate to better mechanism for testing around + // language detection. All pages will return "fr" as the detected language. + AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/french_page.html")), ui::PAGE_TRANSITION_TYPED); ResetObserver(); chrome_translate_client = GetChromeTranslateClient(); @@ -1042,7 +1066,7 @@ // Translate the page through TranslateManager. TranslateManager* manager = chrome_translate_client->GetTranslateManager(); manager->TranslatePage( - chrome_translate_client->GetLanguageState().source_language(), "en", + chrome_translate_client->GetLanguageState().source_language(), "fr", true); WaitUntilPageTranslated(); @@ -1244,7 +1268,6 @@ } IN_PROC_BROWSER_TEST_F(TranslateManagerBrowserTest, TranslateSessionRestore) { - // Make restored tab active to (on some platforms) initiate language // detection. browser()->tab_strip_model()->ActivateTabAt( @@ -1288,7 +1311,7 @@ if (chrome_translate_client->GetLanguageState().source_language() != "de") WaitUntilLanguageDetermined(); - EXPECT_EQ("de", + EXPECT_EQ("fr", chrome_translate_client->GetLanguageState().source_language()); // Navigate to the French page by way of a link on the original page @@ -1368,9 +1391,13 @@ base::test::ScopedFeatureList scoped_feature_list_; }; +// TODO(crbug/1258234): All subframe translation tests are disabled now that +// CLD3 is no longer used. Re-enable if subframe translation is migrated to the +// new detection mechanism. + // Tests that the CLD (Compact Language Detection) works properly. IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - PageLanguageDetection) { + DISABLED_PageLanguageDetection) { // Open a new tab with a page in English. AddTabAtIndex(0, GURL(embedded_test_server()->GetURL("/english_page.html")), ui::PAGE_TRANSITION_TYPED); @@ -1396,7 +1423,7 @@ // override the HTML attribute. For all other languages, the HTML attribute // should be used. IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - PageLanguageDetectionConflict) { + DISABLED_PageLanguageDetectionConflict) { // Open a new tab with a page in French with incorrect HTML language // attribute specified. The language attribute should be overridden by the // language detection. @@ -1408,7 +1435,7 @@ ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); WaitUntilLanguageDetermined(); - EXPECT_EQ("fr", + EXPECT_EQ("de", chrome_translate_client->GetLanguageState().source_language()); // Open a new tab with a page in Korean with incorrect HTML language @@ -1428,7 +1455,7 @@ // Test that the translation was successful. IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - PageTranslationSuccess) { + DISABLED_PageTranslationSuccess) { base::HistogramTester histograms; SetTranslateScript(kTestValidScript); @@ -1460,7 +1487,7 @@ // Test that hrefTranslate is propagating properly IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - HrefTranslateSuccess) { + DISABLED_HrefTranslateSuccess) { base::HistogramTester histograms; ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); chrome_translate_client->GetTranslateManager()->SetIgnoreMissingKeyForTesting( @@ -1517,7 +1544,7 @@ // Test that hrefTranslate doesn't auto-translate if the originator of the // navigation isn't a Google origin. IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - HrefTranslateNotFromGoogle) { + DISABLED_HrefTranslateNotFromGoogle) { base::HistogramTester histograms; ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); chrome_translate_client->GetTranslateManager()->SetIgnoreMissingKeyForTesting( @@ -1531,7 +1558,7 @@ ResetObserver(); chrome_translate_client = GetChromeTranslateClient(); WaitUntilLanguageDetermined(); - EXPECT_EQ("de", + EXPECT_EQ("fr", chrome_translate_client->GetLanguageState().source_language()); // Navigate to the French page by way of a link on the original page @@ -1556,7 +1583,7 @@ // Test that hrefTranslate with an unsupported language doesn't trigger. IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - HrefTranslateUnsupported) { + DISABLED_HrefTranslateUnsupported) { base::HistogramTester histograms; ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); chrome_translate_client->GetTranslateManager()->SetIgnoreMissingKeyForTesting( @@ -1607,7 +1634,7 @@ // Test an href translate link to a conflicted page IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - HrefTranslateConflict) { + DISABLED_HrefTranslateConflict) { base::HistogramTester histograms; ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); chrome_translate_client->GetTranslateManager()->SetIgnoreMissingKeyForTesting( @@ -1622,7 +1649,7 @@ ResetObserver(); chrome_translate_client = GetChromeTranslateClient(); WaitUntilLanguageDetermined(); - EXPECT_EQ("de", + EXPECT_EQ("fr", chrome_translate_client->GetLanguageState().source_language()); // Navigate to the French page that thinks its in English by way of a link on @@ -1659,7 +1686,7 @@ // Test an href translate link without an href lang for the landing page IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - HrefTranslateNoHrefLang) { + DISABLED_HrefTranslateNoHrefLang) { base::HistogramTester histograms; ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); chrome_translate_client->GetTranslateManager()->SetIgnoreMissingKeyForTesting( @@ -1711,7 +1738,7 @@ // Test an href translate link that's overridden by the auto translate settings IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - HrefTranslateOverridenByAutoTranslate) { + DISABLED_HrefTranslateOverridenByAutoTranslate) { base::HistogramTester histograms; ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); chrome_translate_client->GetTranslateManager()->SetIgnoreMissingKeyForTesting( @@ -1766,7 +1793,7 @@ // Test if there was an error during translation. IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - PageTranslationError) { + DISABLED_PageTranslationError) { SetTranslateScript(kTestValidScript); ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); @@ -1788,7 +1815,7 @@ // Test if there was an error during translate library initialization. IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - PageTranslationInitializationError) { + DISABLED_PageTranslationInitializationError) { SetTranslateScript(kTestScriptInitializationError); ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); @@ -1817,7 +1844,7 @@ // Test the checks translate lib never gets ready and throws timeout. IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - PageTranslationAvailableTimeoutError) { + DISABLED_PageTranslationAvailableTimeoutError) { SetTranslateScript(kTestScriptAvailableTimeout); ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); @@ -1848,7 +1875,7 @@ // TODO(1064974): consolidate the common test logic here that is used between // several error type tests from different script inputs. IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - PageTranslationTranslateTimeoutError) { + DISABLED_PageTranslationTranslateTimeoutError) { SetTranslateScript(kTestScriptTranslateTimeout); ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); @@ -1877,7 +1904,7 @@ // Test the checks if both source and target languages mentioned are identical. IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - PageTranslationIdenticalLanguagesError) { + DISABLED_PageTranslationIdenticalLanguagesError) { SetTranslateScript(kTestScriptIdenticalLanguages); ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); @@ -1904,7 +1931,7 @@ // Test if there was an error during translatePage script execution. IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - PageTranslationUnexpectedScriptError) { + DISABLED_PageTranslationUnexpectedScriptError) { SetTranslateScript(kTestScriptUnexpectedScriptError); ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); @@ -1934,7 +1961,7 @@ // Test if securityOrigin mentioned in url is valid. IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - PageTranslationBadOriginError) { + DISABLED_PageTranslationBadOriginError) { SetTranslateScript(kTestScriptBadOrigin); ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); @@ -1963,7 +1990,7 @@ // Test if there was an error during script load. IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - PageTranslationScriptLoadError) { + DISABLED_PageTranslationScriptLoadError) { SetTranslateScript(kTestScriptLoadError); ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); @@ -1993,7 +2020,7 @@ // Test that session restore restores the translate infobar and other translate // settings. IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - PRE_TranslateSessionRestore) { + DISABLED_PRE_TranslateSessionRestore) { SessionStartupPref pref(SessionStartupPref::LAST); SessionStartupPref::SetStartupPref(browser()->profile(), pref); @@ -2011,7 +2038,7 @@ } IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - TranslateSessionRestore) { + DISABLED_TranslateSessionRestore) { // Make restored tab active to (on some platforms) initiate language // detection. browser()->tab_strip_model()->ActivateTabAt( @@ -2033,7 +2060,7 @@ // Test that hrefTranslate overrides manual translate IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - HrefTranslateOverridesManualTranslate) { + DISABLED_HrefTranslateOverridesManualTranslate) { ChromeTranslateClient* chrome_translate_client = GetChromeTranslateClient(); TranslateManager* manager = chrome_translate_client->GetTranslateManager(); manager->SetIgnoreMissingKeyForTesting(true); @@ -2078,7 +2105,7 @@ // Test that iframes can be translated. IN_PROC_BROWSER_TEST_F(TranslateManagerWithSubFrameSupportBrowserTest, - TranslateIframe) { + DISABLED_TranslateIframe) { base::HistogramTester histograms; SetTranslateScript(kTestValidScript); @@ -2251,9 +2278,14 @@ // Check that the translation service still works well. ResetObserver(); chrome_translate_client = GetChromeTranslateClient(); - if (chrome_translate_client->GetLanguageState().source_language() != "de") + // TODO(crbug.com/1258185): Migrate to better mechanism for testing around + // language detection. Subframe translation is disabled and not under + // experimentation otherwise, language detection return "fr". + std::string expected_lang = GetParam() ? "de" : "fr"; + if (chrome_translate_client->GetLanguageState().source_language() != + expected_lang) WaitUntilLanguageDetermined(); - EXPECT_EQ("de", + EXPECT_EQ(expected_lang, chrome_translate_client->GetLanguageState().source_language()); manager->TranslatePage( chrome_translate_client->GetLanguageState().source_language(), "en",
diff --git a/chrome/browser/translate/translate_model_service_browsertest.cc b/chrome/browser/translate/translate_model_service_browsertest.cc index 6e98855..d0ee1ad68 100644 --- a/chrome/browser/translate/translate_model_service_browsertest.cc +++ b/chrome/browser/translate/translate_model_service_browsertest.cc
@@ -77,7 +77,10 @@ class TranslateModelServiceDisabledBrowserTest : public InProcessBrowserTest { public: - TranslateModelServiceDisabledBrowserTest() = default; + TranslateModelServiceDisabledBrowserTest() { + scoped_feature_list_.InitAndDisableFeature( + translate::kTFLiteLanguageDetectionEnabled); + } void SetUp() override { origin_server_ = std::make_unique<net::EmbeddedTestServer>( @@ -97,6 +100,7 @@ private: GURL english_url_; std::unique_ptr<net::EmbeddedTestServer> origin_server_; + base::test::ScopedFeatureList scoped_feature_list_; }; IN_PROC_BROWSER_TEST_F(TranslateModelServiceDisabledBrowserTest,
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index bad5142..db151ba 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2838,6 +2838,7 @@ "//ash/webui/diagnostics_ui", "//ash/webui/file_manager:file_manager_ui", "//ash/webui/file_manager:file_manager_untrusted_ui", + "//ash/webui/firmware_update_ui", "//ash/webui/help_app_ui", "//ash/webui/help_app_ui/search:mojo_bindings", "//ash/webui/media_app_ui",
diff --git a/chrome/browser/ui/color/chrome_color_mixer.cc b/chrome/browser/ui/color/chrome_color_mixer.cc index ee2a4bc..7eea2018 100644 --- a/chrome/browser/ui/color/chrome_color_mixer.cc +++ b/chrome/browser/ui/color/chrome_color_mixer.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/color/chrome_color_mixer.h" #include "base/bind.h" +#include "build/build_config.h" #include "chrome/browser/ui/color/chrome_color_id.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/color/color_id.h" @@ -12,40 +13,50 @@ #include "ui/color/color_provider.h" #include "ui/color/color_recipe.h" #include "ui/color/color_transform.h" +#include "ui/gfx/color_palette.h" #include "ui/gfx/color_utils.h" namespace { -constexpr float kMinOmniboxToolbarContrast = 1.3f; +void AddBaseColors(bool dark_mode, ui::ColorMixer& mixer) { + if (dark_mode) { + mixer[kColorOmniboxBackground] = {gfx::kGoogleGrey900}; + mixer[kColorOmniboxText] = {SK_ColorWHITE}; -ui::ColorTransform ChooseOmniboxBgBlendTarget() { - return base::BindRepeating( - [](SkColor input_color, const ui::ColorMixer& mixer) { - const SkColor toolbar_color = mixer.GetResultColor(kColorToolbar); - const SkColor endpoint_color = - color_utils::GetEndpointColorWithMinContrast(toolbar_color); - return (color_utils::GetContrastRatio(toolbar_color, endpoint_color) >= - kMinOmniboxToolbarContrast) - ? endpoint_color - : color_utils::GetColorWithMaxContrast(endpoint_color); - }); + mixer[kColorToolbar] = {SkColorSetRGB(0x35, 0x36, 0x3A)}; + } else { + mixer[kColorOmniboxBackground] = {gfx::kGoogleGrey100}; + mixer[kColorOmniboxText] = {gfx::kGoogleGrey900}; + + mixer[kColorToolbar] = {SK_ColorWHITE}; + } } } // namespace -void AddChromeColorMixer(ui::ColorProvider* provider) { +void AddChromeColorMixer(ui::ColorProvider* provider, + const ui::ColorProviderManager::Key& key) { + const bool dark_mode = + key.color_mode == ui::ColorProviderManager::ColorMode::kDark; ui::ColorMixer& mixer = provider->AddMixer(); - // TODO(pkasting): Pre-color pipeline this is only enabled for custom themes. - // Agree on consistent behavior before enabling this. - mixer[kColorOmniboxBackground] = ui::BlendForMinContrast( - kColorToolbar, kColorToolbar, ChooseOmniboxBgBlendTarget(), - kMinOmniboxToolbarContrast); - mixer[kColorOmniboxText] = - ui::GetColorWithMaxContrast(kColorOmniboxBackground); - // TODO(tluk) Behavior change for dark mode to a darker toolbar color for - // better color semantics. Follow up with UX team before landing change. - mixer[kColorToolbar] = {ui::kColorPrimaryBackground}; +#if defined(OS_WIN) + const bool high_contrast_mode = + key.contrast_mode == ui::ColorProviderManager::ContrastMode::kHigh; + if (high_contrast_mode) { + // High contrast uses system colors. + mixer[kColorOmniboxBackground] = {ui::kColorNativeBtnFace}; + mixer[kColorOmniboxText] = {ui::kColorNativeBtnText}; + + mixer[kColorToolbar] = {ui::kColorNativeWindow}; + } else { + AddBaseColors(dark_mode, mixer); + } +#else + AddBaseColors(dark_mode, mixer); +#endif + + // Download shelf colors. mixer[kColorDownloadShelf] = {kColorToolbar}; mixer[kColorDownloadShelfButtonBackground] = {kColorDownloadShelf}; mixer[kColorDownloadShelfButtonText] =
diff --git a/chrome/browser/ui/color/chrome_color_mixer.h b/chrome/browser/ui/color/chrome_color_mixer.h index 3efc4bc..96454de 100644 --- a/chrome/browser/ui/color/chrome_color_mixer.h +++ b/chrome/browser/ui/color/chrome_color_mixer.h
@@ -5,12 +5,15 @@ #ifndef CHROME_BROWSER_UI_COLOR_CHROME_COLOR_MIXER_H_ #define CHROME_BROWSER_UI_COLOR_CHROME_COLOR_MIXER_H_ +#include "ui/color/color_provider_manager.h" + namespace ui { class ColorProvider; } // Adds a color mixer to |provider| that supplies default values for various // chrome/ colors before taking into account any custom themes. -void AddChromeColorMixer(ui::ColorProvider* provider); +void AddChromeColorMixer(ui::ColorProvider* provider, + const ui::ColorProviderManager::Key& key); #endif // CHROME_BROWSER_UI_COLOR_CHROME_COLOR_MIXER_H_
diff --git a/chrome/browser/ui/color/omnibox_color_mixer.cc b/chrome/browser/ui/color/omnibox_color_mixer.cc index bf15c6c..ba7c317 100644 --- a/chrome/browser/ui/color/omnibox_color_mixer.cc +++ b/chrome/browser/ui/color/omnibox_color_mixer.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/color/omnibox_color_mixer.h" #include "chrome/browser/ui/color/chrome_color_id.h" +#include "ui/color/color_id.h" #include "ui/color/color_mixer.h" #include "ui/color/color_provider.h" #include "ui/color/color_recipe.h" @@ -12,10 +13,9 @@ #include "ui/gfx/color_palette.h" #include "ui/gfx/color_utils.h" -void AddOmniboxColorMixer(ui::ColorProvider* provider, bool high_contrast) { +void AddOmniboxColorMixer(ui::ColorProvider* provider, + const ui::ColorProviderManager::Key& key) { ui::ColorMixer& mixer = provider->AddMixer(); - const float minimum_contrast = - high_contrast ? 6.0f : color_utils::kMinimumReadableContrastRatio; // Omnibox background colors. mixer[kColorOmniboxBackground] = @@ -26,12 +26,7 @@ // Omnibox text colors. mixer[kColorOmniboxText] = ui::GetResultingPaintColor( ui::FromTransformInput(), kColorOmniboxBackground); - { - auto& selected_text = mixer[kColorOmniboxResultsTextSelected]; - selected_text = {kColorOmniboxText}; - if (high_contrast) - selected_text += ui::ContrastInvert(ui::FromTransformInput()); - } + mixer[kColorOmniboxResultsTextSelected] = {kColorOmniboxText}; mixer[kColorOmniboxKeywordSelected] = ui::SelectBasedOnDarkInput( kColorOmniboxBackground, gfx::kGoogleGrey100, kColorOmniboxResultsUrl); @@ -49,15 +44,14 @@ kColorOmniboxResultsBackground, gfx::kGoogleGreyAlpha200); mixer[kColorOmniboxResultsBackgroundSelected] = ui::BlendTowardMaxContrast( ui::GetColorWithMaxContrast(kColorOmniboxResultsTextSelected), - gfx::kGoogleGreyAlpha300); + gfx::kGoogleGreyAlpha200); // Results icon colors. { - const auto results_icon = [minimum_contrast](ui::ColorId text_id, - ui::ColorId background_id) { + const auto results_icon = [](ui::ColorId text_id, + ui::ColorId background_id) { return ui::BlendForMinContrast(ui::DeriveDefaultIconColor(text_id), - background_id, absl::nullopt, - minimum_contrast); + background_id); }; mixer[kColorOmniboxResultsIcon] = results_icon(kColorOmniboxText, kColorOmniboxResultsBackground); @@ -68,14 +62,11 @@ // Dimmed text colors. { - const auto blend_with_clamped_contrast = [minimum_contrast]( - ui::ColorId foreground_id, - ui::ColorId background_id) { + const auto blend_with_clamped_contrast = [](ui::ColorId foreground_id, + ui::ColorId background_id) { return ui::BlendForMinContrast( foreground_id, foreground_id, - ui::BlendForMinContrast(background_id, background_id, absl::nullopt, - minimum_contrast), - minimum_contrast); + ui::BlendForMinContrast(background_id, background_id)); }; mixer[kColorOmniboxResultsTextDimmed] = blend_with_clamped_contrast( kColorOmniboxText, kColorOmniboxResultsBackgroundHovered); @@ -88,12 +79,11 @@ // Results URL colors. { - const auto url_color = [minimum_contrast](ui::ColorId id) { + const auto url_color = [](ui::ColorId id) { return ui::BlendForMinContrast( gfx::kGoogleBlue500, id, - ui::SelectBasedOnDarkInput(id, gfx::kGoogleBlue050, - gfx::kGoogleBlue900), - minimum_contrast); + ui::SelectBasedOnDarkInput(kColorOmniboxBackground, + gfx::kGoogleBlue050, gfx::kGoogleBlue900)); }; mixer[kColorOmniboxResultsUrl] = url_color(kColorOmniboxResultsBackgroundHovered); @@ -103,19 +93,21 @@ // Security chip colors. { - const auto security_chip_color = - [minimum_contrast](ui::ColorTransform transform) { - return ui::SelectBasedOnDarkInput( - kColorOmniboxBackground, - ui::BlendTowardMaxContrast(kColorOmniboxText, 0x18), - ui::BlendForMinContrast(std::move(transform), - kColorOmniboxBackgroundHovered, - absl::nullopt, minimum_contrast)); - }; + const auto security_chip_color = [](SkColor dark_input, + SkColor light_input) { + return ui::BlendForMinContrast( + ui::SelectBasedOnDarkInput(kColorOmniboxBackground, dark_input, + light_input), + kColorOmniboxBackgroundHovered); + }; + mixer[kColorOmniboxSecurityChipDangerous] = - security_chip_color(gfx::kGoogleRed600); + security_chip_color(gfx::kGoogleRed300, gfx::kGoogleRed600); + // TODO(weili): consider directly deriving from the omnibox text color such + // as using + // security_chip_color(ui::DeriveDefaultIconColor(kColorOmniboxText)). mixer[kColorOmniboxSecurityChipSecure] = - security_chip_color(ui::DeriveDefaultIconColor(kColorOmniboxText)); + security_chip_color(gfx::kGoogleGrey500, gfx::kGoogleGrey700); + mixer[kColorOmniboxSecurityChipDefault] = {kColorOmniboxSecurityChipSecure}; } - mixer[kColorOmniboxSecurityChipDefault] = {kColorOmniboxSecurityChipSecure}; }
diff --git a/chrome/browser/ui/color/omnibox_color_mixer.h b/chrome/browser/ui/color/omnibox_color_mixer.h index 4796817..773383c 100644 --- a/chrome/browser/ui/color/omnibox_color_mixer.h +++ b/chrome/browser/ui/color/omnibox_color_mixer.h
@@ -5,13 +5,15 @@ #ifndef CHROME_BROWSER_UI_COLOR_OMNIBOX_COLOR_MIXER_H_ #define CHROME_BROWSER_UI_COLOR_OMNIBOX_COLOR_MIXER_H_ +#include "ui/color/color_provider_manager.h" + namespace ui { class ColorProvider; } -// Adds a color mixer to |provider| that contains recipes for omnibox colors, -// given whether they should be |high_contrast|. -// TODO(pkasting): Perhaps |high_contrast| should be a bit on the ColorProvider. -void AddOmniboxColorMixer(ui::ColorProvider* provider, bool high_contrast); +// Adds a color mixer that contains recipes for omnibox colors to |provider| +// with |key|. +void AddOmniboxColorMixer(ui::ColorProvider* provider, + const ui::ColorProviderManager::Key& key); #endif // CHROME_BROWSER_UI_COLOR_OMNIBOX_COLOR_MIXER_H_
diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_edit_controller.cc b/chrome/browser/ui/omnibox/chrome_omnibox_edit_controller.cc index c676a6e..ca7d6bd 100644 --- a/chrome/browser/ui/omnibox/chrome_omnibox_edit_controller.cc +++ b/chrome/browser/ui/omnibox/chrome_omnibox_edit_controller.cc
@@ -42,10 +42,8 @@ auto navigation = chrome::OpenCurrentURL(browser_); - if (alternative_nav_match.destination_url.is_valid()) { - ChromeOmniboxNavigationObserver::Create(navigation.get(), profile_, text, - match, alternative_nav_match); - } + ChromeOmniboxNavigationObserver::Create(navigation.get(), profile_, text, + match, alternative_nav_match); #if BUILDFLAG(ENABLE_EXTENSIONS) extensions::MaybeShowExtensionControlledSearchNotification(
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc index f1f40a1..3eb8b7ab 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -2360,17 +2360,19 @@ return WebAppProvider::GetForTest(browser()->profile()); } - // Install a web app with protocol_handlers then register it with the - // ProtocolHandlerRegistry. This is sufficient for testing URL translation and - // launch at startup. + // Install a web app with `protocol_handlers` (and optionally `file_handlers`) + // then register it with the ProtocolHandlerRegistry. This is sufficient for + // testing URL translation and launch at startup. web_app::AppId InstallWebAppWithProtocolHandlers( - const std::vector<apps::ProtocolHandlerInfo>& protocol_handlers) { + const std::vector<apps::ProtocolHandlerInfo>& protocol_handlers, + const std::vector<apps::FileHandler>& file_handlers = {}) { std::unique_ptr<WebApplicationInfo> info = std::make_unique<WebApplicationInfo>(); info->start_url = GURL(kStartUrl); info->title = kAppName; info->user_display_mode = blink::mojom::DisplayMode::kStandalone; info->protocol_handlers = protocol_handlers; + info->file_handlers = file_handlers; web_app::AppId app_id = web_app::test::InstallWebApp(browser()->profile(), std::move(info)); @@ -2386,6 +2388,7 @@ run_loop.Quit(); })); run_loop.Run(); + return app_id; } @@ -2751,6 +2754,60 @@ ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile())); } +class StartupBrowserWebAppProtocolAndFileHandlingTest + : public StartupBrowserWebAppProtocolHandlingTest { + base::test::ScopedFeatureList feature_list_{ + blink::features::kFileHandlingAPI}; + base::test::ScopedFeatureList feature_list2_{ + features::kDesktopPWAsFileHandlingSettingsGated}; +}; + +// Verifies that a "file://" URL on the command line is treated as a file +// handling launch, not a protocol handling or URL launch. +IN_PROC_BROWSER_TEST_F(StartupBrowserWebAppProtocolAndFileHandlingTest, + WebAppLaunch_FileProtocol) { + // Install an app with protocol handlers and a handler for plain text files. + apps::ProtocolHandlerInfo protocol_handler; + const std::string handler_url = std::string(kStartUrl) + "/protocol=%s"; + protocol_handler.url = GURL(handler_url); + protocol_handler.protocol = "web+test"; + apps::FileHandler file_handler; + file_handler.action = GURL(std::string(kStartUrl) + "/file_handler"); + file_handler.accept.push_back({}); + file_handler.accept.back().mime_type = "text/plain"; + file_handler.accept.back().file_extensions = {".txt"}; + web_app::AppId app_id = + InstallWebAppWithProtocolHandlers({protocol_handler}, {file_handler}); + + // Skip the file handler dialog by simulating prior user approval of the API. + { + web_app::ScopedRegistryUpdate update(&provider()->sync_bridge()); + update->UpdateApp(app_id)->SetFileHandlerApprovalState( + web_app::ApiApprovalState::kAllowed); + } + + // Pass a file:// url on the command line. + SetUpCommandlineAndStart("file:///C:/test.txt", app_id); + + // Wait for app launch task to complete. + content::RunAllTasksUntilIdle(); + + // Check an app window is launched. + ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile())); + Browser* app_browser = FindOneOtherBrowser(browser()); + ASSERT_TRUE(app_browser); + EXPECT_TRUE(web_app::AppBrowserController::IsForWebApp(app_browser, app_id)); + + // Check the app is launched to the file handler URL and not the protocol URL. + TabStripModel* tab_strip = app_browser->tab_strip_model(); + ASSERT_EQ(1, tab_strip->count()); + content::WebContents* web_contents = tab_strip->GetWebContentsAt(0); + EXPECT_EQ(file_handler.action, web_contents->GetVisibleURL()); + + app_browser->window()->Close(); + ui_test_utils::WaitForBrowserToClose(app_browser); +} + #endif // defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) // These tests are not applicable to Chrome OS as neither initial preferences
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc index c920adbb..5b0ac45 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views.cc +++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -377,7 +377,9 @@ auto close_controls_view = std::make_unique<views::CloseImageButton>(base::BindRepeating( [](OverlayWindowViews* overlay) { - overlay->controller_->Close(/*should_pause_video=*/true); + // Only pause the video if play/pause is available. + const bool should_pause_video = overlay->show_play_pause_button_; + overlay->controller_->Close(should_pause_video); overlay->RecordButtonPressed(OverlayWindowControl::kClose); }, base::Unretained(this))); @@ -1011,7 +1013,8 @@ void OverlayWindowViews::OnNativeWidgetDestroyed() { views::Widget::OnNativeWidgetDestroyed(); - controller_->OnWindowDestroyed(/*should_pause_video=*/true); + controller_->OnWindowDestroyed( + /*should_pause_video=*/show_play_pause_button_); } gfx::Size OverlayWindowViews::GetMinimumSize() const { @@ -1351,6 +1354,10 @@ return back_to_tab_label_button_; } +views::CloseImageButton* OverlayWindowViews::close_button_for_testing() const { + return close_controls_view_; +} + gfx::Point OverlayWindowViews::close_image_position_for_testing() const { return close_controls_view_->origin(); }
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.h b/chrome/browser/ui/views/overlay/overlay_window_views.h index 9463083..b296734 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views.h +++ b/chrome/browser/ui/views/overlay/overlay_window_views.h
@@ -116,6 +116,7 @@ ToggleCameraButton* toggle_camera_button_for_testing() const; HangUpButton* hang_up_button_for_testing() const; BackToTabLabelButton* back_to_tab_label_button_for_testing() const; + views::CloseImageButton* close_button_for_testing() const; gfx::Point close_image_position_for_testing() const; gfx::Point resize_handle_position_for_testing() const; OverlayWindowViews::PlaybackState playback_state_for_testing() const;
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views_unittest.cc b/chrome/browser/ui/views/overlay/overlay_window_views_unittest.cc index ab328c7..54831f3 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views_unittest.cc +++ b/chrome/browser/ui/views/overlay/overlay_window_views_unittest.cc
@@ -5,12 +5,15 @@ #include <memory> #include <utility> +#include "chrome/browser/ui/views/overlay/close_image_button.h" #include "chrome/browser/ui/views/overlay/overlay_window_views.h" #include "chrome/browser/ui/views/overlay/track_image_button.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/views/chrome_views_test_base.h" +#include "content/public/browser/overlay_window.h" #include "content/public/browser/picture_in_picture_window_controller.h" #include "content/public/test/test_web_contents_factory.h" +#include "testing/gmock/include/gmock/gmock.h" #include "ui/compositor/layer.h" #include "ui/display/test/scoped_screen_override.h" #include "ui/display/test/test_screen.h" @@ -18,6 +21,7 @@ #include "ui/events/event.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/vector2d.h" +#include "ui/views/test/button_test_api.h" class TestPictureInPictureWindowController : public content::PictureInPictureWindowController { @@ -27,9 +31,9 @@ // PictureInPictureWindowController: void Show() override {} void FocusInitiator() override {} - void Close(bool) override {} + MOCK_METHOD(void, Close, (bool)); void CloseAndFocusInitiator() override {} - void OnWindowDestroyed(bool) override {} + MOCK_METHOD(void, OnWindowDestroyed, (bool)); content::OverlayWindow* GetWindowForTesting() override { return nullptr; } void UpdateLayerBounds() override {} bool IsPlayerActive() override { return false; } @@ -91,6 +95,10 @@ content::WebContents* web_contents() { return web_contents_; } + TestPictureInPictureWindowController& pip_window_controller() { + return pip_window_controller_; + } + private: TestingProfile profile_; content::TestWebContentsFactory web_contents_factory_; @@ -375,3 +383,42 @@ overlay_window().OnNativeFocus(); EXPECT_TRUE(overlay_window().AreControlsVisible()); } + +TEST_F(OverlayWindowViewsTest, OnlyPauseOnCloseWhenPauseIsAvailable) { + views::test::ButtonTestApi close_button_clicker( + overlay_window().close_button_for_testing()); + ui::MouseEvent dummy_event(ui::ET_MOUSE_PRESSED, gfx::Point(0, 0), + gfx::Point(0, 0), ui::EventTimeForNow(), 0, 0); + + // When the play/pause controls are visible, closing via the close button + // should pause the video. + overlay_window().SetPlayPauseButtonVisibility(true); + EXPECT_CALL(pip_window_controller(), Close(true)); + close_button_clicker.NotifyClick(dummy_event); + testing::Mock::VerifyAndClearExpectations(&pip_window_controller()); + + // When the play/pause controls are not visible, closing via the close button + // should not pause the video. + overlay_window().SetPlayPauseButtonVisibility(false); + EXPECT_CALL(pip_window_controller(), Close(false)); + close_button_clicker.NotifyClick(dummy_event); + testing::Mock::VerifyAndClearExpectations(&pip_window_controller()); +} + +TEST_F(OverlayWindowViewsTest, PauseOnWidgetCloseWhenPauseAvailable) { + // When the play/pause controls are visible, when the native widget is + // destroyed we should pause the underlying video. + overlay_window().SetPlayPauseButtonVisibility(true); + EXPECT_CALL(pip_window_controller(), OnWindowDestroyed(true)); + overlay_window().CloseNow(); + testing::Mock::VerifyAndClearExpectations(&pip_window_controller()); +} + +TEST_F(OverlayWindowViewsTest, DontPauseOnWidgetCloseWhenPauseNotAvailable) { + // When the play/pause controls are not visible, when the native widget is + // destroyed we should not pause the underlying video. + overlay_window().SetPlayPauseButtonVisibility(false); + EXPECT_CALL(pip_window_controller(), OnWindowDestroyed(false)); + overlay_window().CloseNow(); + testing::Mock::VerifyAndClearExpectations(&pip_window_controller()); +}
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view_browsertest.cc b/chrome/browser/ui/views/translate/translate_bubble_view_browsertest.cc index e6169aa..657aecb 100644 --- a/chrome/browser/ui/views/translate/translate_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/translate/translate_bubble_view_browsertest.cc
@@ -24,6 +24,7 @@ #include "chrome/test/base/ui_test_utils.h" #include "components/translate/core/browser/translate_manager.h" #include "components/translate/core/common/translate_switches.h" +#include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/ui_base_features.h" @@ -55,6 +56,9 @@ command_line->AppendSwitchASCII( switches::kTranslateScriptURL, embedded_test_server()->GetURL("/mock_translate_script.js").spec()); + // TODO(crbug.com/1258185): Migrate to better mechanism for testing around + // language detection. + command_line->AppendSwitch(::switches::kOverrideLanguageDetection); } void SetUpOnMainThread() override {
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view_interactive_uitest.cc b/chrome/browser/ui/views/translate/translate_bubble_view_interactive_uitest.cc index 3d0383ac..b9b7ac8 100644 --- a/chrome/browser/ui/views/translate/translate_bubble_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/translate/translate_bubble_view_interactive_uitest.cc
@@ -23,6 +23,7 @@ #include "components/translate/core/browser/translate_manager.h" #include "components/translate/core/common/translate_switches.h" #include "content/public/browser/storage_partition.h" +#include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" #include "content/public/test/network_connection_change_simulator.h" #include "content/public/test/url_loader_interceptor.h" @@ -81,6 +82,7 @@ views::View* view = ElementToView(element); view->HandleAccessibleAction(action_data); } + } // namespace class TranslateBubbleViewUITest @@ -114,6 +116,7 @@ command_line->AppendSwitchASCII(::switches::kInstallAutogeneratedTheme, "121,0,0"); } + command_line->AppendSwitch(::switches::kOverrideLanguageDetection); } void SetUpOnMainThread() override {
diff --git a/chrome/browser/ui/web_applications/web_app_launch_manager_unittest.cc b/chrome/browser/ui/web_applications/web_app_launch_manager_unittest.cc index 0b224e7d..19209ef 100644 --- a/chrome/browser/ui/web_applications/web_app_launch_manager_unittest.cc +++ b/chrome/browser/ui/web_applications/web_app_launch_manager_unittest.cc
@@ -203,43 +203,6 @@ run_loop.Run(); } -TEST_F(WebAppLaunchManagerUnitTest, LaunchApplication_ProtocolFile) { -#if defined(OS_WIN) - const base::FilePath::CharType kTestPath[] = - FILE_PATH_LITERAL("file:///C:/test_app_path/test_app_file.txt"); -#else - const base::FilePath::CharType kTestPath[] = - FILE_PATH_LITERAL("file:///C:/test_app_path/test_app_file.txt"); -#endif // defined(OS_WIN) - - base::RunLoop run_loop; - const absl::optional<GURL> protocol_handler_launch_url( - "file:///C:/test_app_path/test_app_file.txt"); - base::CommandLine command_line = CreateCommandLine(); - - command_line.AppendArg(protocol_handler_launch_url.value().spec()); - - apps::AppLaunchParams expected_results = CreateLaunchParams( - command_line, {base::FilePath(kTestPath)}, absl::nullopt, absl::nullopt); - - testing::StrictMock<MockWebAppLaunchManager> manager(profile()); - EXPECT_CALL(manager, LaunchWebApplication(testing::_, testing::_)) - .Times(1) - .WillOnce(testing::Invoke( - [&](apps::AppLaunchParams&& params, - base::OnceCallback<void(Browser * browser, - apps::mojom::LaunchContainer container)> - callback) { - ValidateLaunchParams(params, expected_results); - run_loop.Quit(); - })); - - manager.LaunchApplication(kTestAppId, command_line, - base::FilePath(kCurrentDirectory), absl::nullopt, - absl::nullopt, {}, base::DoNothing()); - run_loop.Run(); -} - TEST_F(WebAppLaunchManagerUnitTest, LaunchApplication_ProtocolDisallowed) { #if defined(OS_WIN) const base::FilePath::CharType kTestPath[] =
diff --git a/chrome/browser/ui/webui/about_ui.cc b/chrome/browser/ui/webui/about_ui.cc index 7a0c68c..25977df 100644 --- a/chrome/browser/ui/webui/about_ui.cc +++ b/chrome/browser/ui/webui/about_ui.cc
@@ -505,20 +505,15 @@ namespace about_ui { -void AppendHeader(std::string* output, int refresh, - const std::string& unescaped_title) { +void AppendHeader(std::string* output, const std::string& unescaped_title) { output->append("<!DOCTYPE HTML>\n<html>\n<head>\n"); + output->append("<meta charset='utf-8'>\n"); + output->append("<meta name='color-scheme' content='light dark'>\n"); if (!unescaped_title.empty()) { output->append("<title>"); output->append(net::EscapeForHTML(unescaped_title)); output->append("</title>\n"); } - output->append("<meta charset='utf-8'>\n"); - if (refresh > 0) { - output->append("<meta http-equiv='refresh' content='"); - output->append(base::NumberToString(refresh)); - output->append("'/>\n"); - } } void AppendBody(std::string *output) { @@ -539,7 +534,7 @@ std::string ChromeURLs() { std::string html; - AppendHeader(&html, 0, "Chrome URLs"); + AppendHeader(&html, "Chrome URLs"); AppendBody(&html); html += "<h2>List of Chrome URLs</h2>\n<ul>\n"; @@ -580,7 +575,7 @@ #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_OPENBSD) std::string AboutLinuxProxyConfig() { std::string data; - AppendHeader(&data, 0, + AppendHeader(&data, l10n_util::GetStringUTF8(IDS_ABOUT_LINUX_PROXY_CONFIG_TITLE)); data.append("<style>body { max-width: 70ex; padding: 2ex 5ex; }</style>"); AppendBody(&data);
diff --git a/chrome/browser/ui/webui/about_ui.h b/chrome/browser/ui/webui/about_ui.h index 703c359..9e29d5d 100644 --- a/chrome/browser/ui/webui/about_ui.h +++ b/chrome/browser/ui/webui/about_ui.h
@@ -61,8 +61,7 @@ namespace about_ui { // Helper functions -void AppendHeader(std::string* output, int refresh, - const std::string& unescaped_title); +void AppendHeader(std::string* output, const std::string& unescaped_title); void AppendBody(std::string *output); void AppendFooter(std::string *output);
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index c0e0e08..6e7de43 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -159,6 +159,8 @@ #include "ash/webui/diagnostics_ui/url_constants.h" #include "ash/webui/file_manager/file_manager_ui.h" #include "ash/webui/file_manager/url_constants.h" +#include "ash/webui/firmware_update_ui/firmware_update_app_ui.h" +#include "ash/webui/firmware_update_ui/url_constants.h" #include "ash/webui/help_app_ui/help_app_ui.h" #include "ash/webui/help_app_ui/url_constants.h" #include "ash/webui/media_app_ui/media_app_ui.h" @@ -870,6 +872,10 @@ if (url.host_piece() == ash::kChromeUIShortcutCustomizationAppHost) return &NewWebUI<ash::ShortcutCustomizationAppUI>; } + if (ash::features::IsFirmwareUpdaterAppEnabled()) { + if (url.host_piece() == ash::kChromeUIFirmwareUpdateAppHost) + return &NewWebUI<ash::FirmwareUpdateAppUI>; + } if (url.host_piece() == chromeos::multidevice::kChromeUIProximityAuthHost && !profile->IsOffTheRecord()) { return &NewWebUI<chromeos::multidevice::ProximityAuthUI>;
diff --git a/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui.cc b/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui.cc index 642f4f7..843c802a 100644 --- a/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui.cc +++ b/chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/webui/chromeos/parent_access/parent_access_ui.mojom.h" +#include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/generated_resources.h" @@ -21,6 +22,7 @@ #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "services/network/public/mojom/content_security_policy.mojom.h" #include "url/gurl.h" namespace chromeos { @@ -112,6 +114,8 @@ source->EnableReplaceI18nInJS(); // Forward data to the WebUI. + source->AddResourcePath("parent_access_controller.js", + IDR_PARENT_ACCESS_CONTROLLER_JS); source->AddResourcePath("parent_access_ui.js", IDR_PARENT_ACCESS_UI_JS); source->AddLocalizedString("pageTitle", IDS_PARENT_ACCESS_PAGE_TITLE); @@ -121,8 +125,14 @@ source->UseStringsJs(); source->SetDefaultResource(IDR_PARENT_ACCESS_HTML); source->AddString("webviewUrl", web_content_url_.spec()); - source->AddString("eventOriginFilter", - web_content_url_.DeprecatedGetOriginAsURL().spec()); + source->AddString("eventOriginFilter", web_content_url_.spec()); + + // Enables use of test_loader.html + webui::SetJSModuleDefaults(source.get()); + + // Allows loading of local content into an iframe for testing. + source->OverrideContentSecurityPolicy( + network::mojom::CSPDirectiveName::FrameSrc, "frame-src chrome://test/;"); content::WebUIDataSource::Add(profile, source.release()); }
diff --git a/chrome/browser/ui/webui/flags/flags_ui.cc b/chrome/browser/ui/webui/flags/flags_ui.cc index 1b59bf76..dfffec7 100644 --- a/chrome/browser/ui/webui/flags/flags_ui.cc +++ b/chrome/browser/ui/webui/flags/flags_ui.cc
@@ -90,6 +90,9 @@ source->AddResourcePath(flags_ui::kFlagsJS, IDR_FLAGS_UI_FLAGS_JS); source->AddResourcePath(flags_ui::kFlagsCSS, IDR_FLAGS_UI_FLAGS_CSS); +#if BUILDFLAG(IS_CHROMEOS_LACROS) + source->AddResourcePath(flags_ui::kFlagsSVG, IDR_OS_FLAGS_UI_FLAGS_SVG); +#endif source->SetDefaultResource(IDR_FLAGS_UI_FLAGS_HTML); source->UseStringsJs(); return source; @@ -179,6 +182,11 @@ source->AddLocalizedString("search-label", IDS_FLAGS_UI_SEARCH_LABEL); source->AddLocalizedString("search-placeholder", IDS_FLAGS_UI_SEARCH_PLACEHOLDER); +#if BUILDFLAG(IS_CHROMEOS_LACROS) + source->AddLocalizedString("os-flags-link", IDS_FLAGS_UI_OS_FLAGS_LINK); + source->AddLocalizedString("os-flags-text1", IDS_FLAGS_UI_OS_FLAGS_TEXT1); + source->AddLocalizedString("os-flags-text2", IDS_FLAGS_UI_OS_FLAGS_TEXT2); +#endif source->AddLocalizedString("title", IDS_FLAGS_UI_TITLE); source->AddLocalizedString("unavailable", IDS_FLAGS_UI_UNAVAILABLE_FEATURE); source->AddLocalizedString("searchResultsSingular", @@ -214,6 +222,14 @@ source->AddLocalizedString("search-label", IDS_FLAGS_UI_SEARCH_LABEL); source->AddLocalizedString("search-placeholder", IDS_DEPRECATED_FEATURES_SEARCH_PLACEHOLDER); +#if BUILDFLAG(IS_CHROMEOS_LACROS) + source->AddLocalizedString("os-flags-link", + IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_LINK); + source->AddLocalizedString("os-flags-text1", + IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_TEXT1); + source->AddLocalizedString("os-flags-text2", + IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_TEXT2); +#endif source->AddLocalizedString("title", IDS_DEPRECATED_FEATURES_TITLE); source->AddLocalizedString("unavailable", IDS_DEPRECATED_FEATURES_UNAVAILABLE_FEATURE);
diff --git a/chrome/browser/ui/webui/flags/flags_ui_handler.cc b/chrome/browser/ui/webui/flags/flags_ui_handler.cc index b1d5cb6..1efa3a1 100644 --- a/chrome/browser/ui/webui/flags/flags_ui_handler.cc +++ b/chrome/browser/ui/webui/flags/flags_ui_handler.cc
@@ -49,6 +49,12 @@ flags_ui::kResetAllFlags, base::BindRepeating(&FlagsUIHandler::HandleResetAllFlags, base::Unretained(this))); +#if defined(OS_CHROMEOS) + web_ui()->RegisterDeprecatedMessageCallback( + flags_ui::kCrosUrlFlagsRedirect, + base::BindRepeating(&FlagsUIHandler::HandleCrosUrlFlagsRedirect, + base::Unretained(this))); +#endif } void FlagsUIHandler::Init(flags_ui::FlagsStorage* flags_storage, @@ -180,3 +186,9 @@ DCHECK(flags_storage_); about_flags::ResetAllFlags(flags_storage_.get()); } + +#if defined(OS_CHROMEOS) +void FlagsUIHandler::HandleCrosUrlFlagsRedirect(const base::ListValue* args) { + about_flags::CrosUrlFlagsRedirect(); +} +#endif
diff --git a/chrome/browser/ui/webui/flags/flags_ui_handler.h b/chrome/browser/ui/webui/flags/flags_ui_handler.h index dc83326..b22d3f0 100644 --- a/chrome/browser/ui/webui/flags/flags_ui_handler.h +++ b/chrome/browser/ui/webui/flags/flags_ui_handler.h
@@ -57,6 +57,11 @@ // Callback for the "resetAllFlags" message. void HandleResetAllFlags(const base::ListValue* args); +#if defined(OS_CHROMEOS) + // Callback for the "CrosUrlFlagsRedirect" message. + void HandleCrosUrlFlagsRedirect(const base::ListValue* args); +#endif + private: std::unique_ptr<flags_ui::FlagsStorage> flags_storage_; flags_ui::FlagAccess access_;
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc index e8964f0..1560deda 100644 --- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc +++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
@@ -114,6 +114,8 @@ return search_query_mojom; } +} // namespace + // Creates a `mojom::QueryResultPtr` using the original `query`, if the query // was a continuation one, and the result of querying HistoryClustersService. mojom::QueryResultPtr QueryClustersResultToMojom(Profile* profile, @@ -177,8 +179,6 @@ return result_mojom; } -} // namespace - HistoryClustersHandler::HistoryClustersHandler( mojo::PendingReceiver<mojom::PageHandler> pending_page_handler, Profile* profile,
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h index fd503e2..e6754b9d 100644 --- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h +++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h
@@ -27,6 +27,14 @@ namespace history_clusters { +// Not in an anonymous namespace so that it can be tested. +// TODO(manukh) Try to setup a complete `HistoryClusterHandler` for testing so +// that we can test the public method `QueryClusters` directly instead. +mojom::QueryResultPtr QueryClustersResultToMojom(Profile* profile, + const std::string& query, + bool is_continuation, + QueryClustersResult result); + // Handles bidirectional communication between the history clusters page and the // browser. class HistoryClustersHandler : public mojom::PageHandler,
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters_handler_unittest.cc b/chrome/browser/ui/webui/history_clusters/history_clusters_handler_unittest.cc new file mode 100644 index 0000000..38f0536 --- /dev/null +++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler_unittest.cc
@@ -0,0 +1,176 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/history_clusters/history_clusters_handler.h" + +#include <memory> +#include <string> +#include <vector> + +#include "base/test/bind.h" +#include "base/time/time.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/browser/ui/webui/history_clusters/history_clusters_handler.h" +#include "chrome/test/base/testing_profile.h" +#include "components/history/core/browser/history_types.h" +#include "components/history/core/browser/url_row.h" +#include "components/history_clusters/core/history_clusters_types.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace history_clusters { + +namespace { + +Visit CreateVisit(std::string url, + float score, + std::vector<std::string> related_searches = {}) { + Visit visit; + visit.annotated_visit = { + {GURL{url}, 0}, {}, {}, {}, 0, 0, history::VisitSource::SOURCE_BROWSED}; + visit.annotated_visit.content_annotations.related_searches = related_searches; + visit.score = score; + visit.normalized_url = GURL{url}; + return visit; +} + +class HistoryClustersHandlerTest : public testing::Test { + public: + HistoryClustersHandlerTest() { + TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse( + &profile_, + base::BindRepeating(&TemplateURLServiceFactory::BuildInstanceFor)); + } + + // Everything must be called on Chrome_UIThread. + content::BrowserTaskEnvironment task_environment_; + + TestingProfile profile_; +}; + +TEST_F(HistoryClustersHandlerTest, QueryClustersResultToMojom_BelowTheFold) { + QueryClustersResult result; + + // High scoring visits should always be above the fold. + Cluster cluster1; + cluster1.cluster_id = 4; + cluster1.visits.push_back(CreateVisit("https://high-score-1", 1)); + cluster1.visits.push_back(CreateVisit("https://high-score-2", .8)); + cluster1.visits.push_back(CreateVisit("https://high-score-3", .5)); + cluster1.visits.push_back(CreateVisit("https://high-score-4", .5)); + cluster1.visits.push_back(CreateVisit("https://high-score-5", .5)); + cluster1.keywords.push_back(u"keyword"); + + // Low scoring visits should be above the fold only if they're one of top 4. + Cluster cluster2; + cluster2.cluster_id = 6; + cluster2.visits.push_back(CreateVisit("https://low-score-1", .4)); + cluster2.visits.push_back(CreateVisit("https://low-score-2", .4)); + cluster2.visits.push_back(CreateVisit("https://low-score-3", .4)); + cluster2.visits.push_back(CreateVisit("https://low-score-4", .4)); + cluster2.visits.push_back(CreateVisit("https://low-score-5", .4)); + cluster2.keywords.push_back(u"keyword"); + + // 0 scoring visits should be above the fold only if they're 1st. + Cluster cluster3; + cluster3.cluster_id = 8; + cluster3.visits.push_back(CreateVisit("https://zero-score-1", 0)); + cluster3.visits.push_back(CreateVisit("https://zero-score-2", 0)); + cluster3.keywords.push_back(u"keyword"); + + result.clusters.push_back(cluster1); + result.clusters.push_back(cluster2); + result.clusters.push_back(cluster3); + result.continuation_end_time = base::Time::FromDoubleT(10); + + mojom::QueryResultPtr mojom_result = + QueryClustersResultToMojom(&profile_, "query", false, result); + + EXPECT_EQ(mojom_result->query, "query"); + EXPECT_EQ(mojom_result->is_continuation, false); + EXPECT_EQ(mojom_result->continuation_end_time, base::Time::FromDoubleT(10)); + + ASSERT_EQ(mojom_result->clusters.size(), 3u); + + { + EXPECT_EQ(mojom_result->clusters[0]->id, 4); + EXPECT_EQ(mojom_result->clusters[0]->visit->below_the_fold, false); + const auto& related_visits = + mojom_result->clusters[0]->visit->related_visits; + ASSERT_EQ(related_visits.size(), 4u); + EXPECT_EQ(related_visits[0]->below_the_fold, false); + EXPECT_EQ(related_visits[1]->below_the_fold, false); + EXPECT_EQ(related_visits[2]->below_the_fold, false); + EXPECT_EQ(related_visits[3]->below_the_fold, false); + } + + { + EXPECT_EQ(mojom_result->clusters[1]->id, 6); + EXPECT_EQ(mojom_result->clusters[0]->visit->below_the_fold, false); + const auto& related_visits = + mojom_result->clusters[1]->visit->related_visits; + ASSERT_EQ(related_visits.size(), 4u); + EXPECT_EQ(related_visits[0]->below_the_fold, false); + EXPECT_EQ(related_visits[1]->below_the_fold, false); + EXPECT_EQ(related_visits[2]->below_the_fold, false); + EXPECT_EQ(related_visits[3]->below_the_fold, true); + } + + { + EXPECT_EQ(mojom_result->clusters[2]->id, 8); + ASSERT_EQ(mojom_result->clusters[2]->visit->related_visits.size(), 1u); + EXPECT_EQ(mojom_result->clusters[2]->visit->below_the_fold, false); + const auto& related_visits = + mojom_result->clusters[02]->visit->related_visits; + EXPECT_EQ(related_visits[0]->below_the_fold, true); + } +} + +TEST_F(HistoryClustersHandlerTest, QueryClustersResultToMojom_RelatedSearches) { + QueryClustersResult result; + + Cluster cluster; + cluster.cluster_id = 4; + // Should include the top visit's related searches. + cluster.visits.push_back( + CreateVisit("https://high-score-1", 0, {"one", "two"})); + // Should exclude duplicates (i.e. "one"). + cluster.visits.push_back(CreateVisit( + "https://high-score-2", 0, {"one", "three", "four", "five", "six"})); + // Visits without related searches shouldn't interrupt the coalescing. + cluster.visits.push_back(CreateVisit("https://high-score-3", 0)); + // Should include all related searches of a visit even if doing so surpasses + // the max related searches (8). + cluster.visits.push_back( + CreateVisit("https://high-score-4", 0, {"seven", "eight", "nine"})); + // Should not include related searches of more visits once the max related + // searches has been met. + cluster.visits.push_back(CreateVisit("https://high-score-5", 0, {"ten"})); + + result.clusters.push_back(cluster); + + mojom::QueryResultPtr mojom_result = + QueryClustersResultToMojom(&profile_, "query", false, result); + + ASSERT_EQ(mojom_result->clusters.size(), 1u); + EXPECT_EQ(mojom_result->clusters[0]->id, 4); + const auto& top_visit = mojom_result->clusters[0]->visit; + ASSERT_EQ(top_visit->related_searches.size(), 9u); + EXPECT_EQ(top_visit->related_searches[0]->query, "one"); + EXPECT_EQ(top_visit->related_searches[1]->query, "two"); + EXPECT_EQ(top_visit->related_searches[2]->query, "three"); + EXPECT_EQ(top_visit->related_searches[3]->query, "four"); + EXPECT_EQ(top_visit->related_searches[4]->query, "five"); + EXPECT_EQ(top_visit->related_searches[5]->query, "six"); + EXPECT_EQ(top_visit->related_searches[6]->query, "seven"); + EXPECT_EQ(top_visit->related_searches[7]->query, "eight"); + EXPECT_EQ(top_visit->related_searches[8]->query, "nine"); +} + +// TODO(manukh) Add a test case for `VisitToMojom`. + +} // namespace + +} // namespace history_clusters
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 127aae4..152dc79 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1634730693-1c185682232637b2c2d3c650f5aeb9a80256233b.profdata +chrome-linux-main-1634752541-572744bf9f2be8b51277460549979cdbbc07d02b.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 2752c48..27527c2e 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1634730693-f2650143caf423d84f61bf428a1350ddac3a0dd0.profdata +chrome-win32-main-1634741969-6e281f79072e3455c13dc660b2b3272b77cb0251.profdata
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni index b6ab95a2..d59cdea 100644 --- a/chrome/chrome_paks.gni +++ b/chrome/chrome_paks.gni
@@ -199,6 +199,7 @@ sources += [ "$root_gen_dir/ash/ash_camera_app_resources.pak", "$root_gen_dir/ash/ash_diagnostics_app_resources.pak", + "$root_gen_dir/ash/ash_firmware_update_app_resources.pak", "$root_gen_dir/ash/ash_help_app_resources.pak", "$root_gen_dir/ash/ash_media_app_resources.pak", "$root_gen_dir/ash/ash_os_feedback_resources.pak", @@ -246,6 +247,7 @@ "//ash/webui/file_manager/untrusted_resources:file_manager_untrusted_resources", "//ash/webui/resources:camera_app_resources", "//ash/webui/resources:diagnostics_app_resources", + "//ash/webui/resources:firmware_update_app_resources", "//ash/webui/resources:help_app_bundle_resources", "//ash/webui/resources:help_app_kids_magazine_bundle_resources", "//ash/webui/resources:help_app_resources",
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index c8ed2ac..2354f8b 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -5077,6 +5077,7 @@ "../browser/ui/webui/devtools_ui_data_source_unittest.cc", "../browser/ui/webui/discards/graph_dump_impl_unittest.cc", "../browser/ui/webui/favicon_source_unittest.cc", + "../browser/ui/webui/history_clusters/history_clusters_handler_unittest.cc", "../browser/ui/webui/signin/sync_confirmation_handler_unittest.cc", "../browser/upgrade_detector/build_state_unittest.cc", "../browser/upgrade_detector/mock_build_state_observer.cc", @@ -7936,6 +7937,8 @@ "base/ui_test_utils.h", "base/web_ui_browser_test.cc", "base/web_ui_browser_test.h", + "base/web_ui_test_data_source.cc", + "base/web_ui_test_data_source.h", "permissions/permission_request_manager_test_api.cc", "permissions/permission_request_manager_test_api.h", ] @@ -8474,6 +8477,8 @@ ] deps += [ ":pdf_extension_test_utils", + "//components/optimization_guide/core:test_support", + "//components/optimization_guide/proto:optimization_guide_proto", "//pdf:features", "//ui/base/dragdrop:types", "//ui/base/dragdrop/mojom",
diff --git a/chrome/test/base/mojo_web_ui_browser_test.cc b/chrome/test/base/mojo_web_ui_browser_test.cc index c9faaf9a21..0ae628cb 100644 --- a/chrome/test/base/mojo_web_ui_browser_test.cc +++ b/chrome/test/base/mojo_web_ui_browser_test.cc
@@ -8,7 +8,6 @@ #include "base/bind.h" #include "base/callback_helpers.h" -#include "base/path_service.h" #include "base/strings/utf_string_conversions.h" #include "base/test/bind.h" #include "chrome/browser/chrome_content_browser_client.h" @@ -114,12 +113,6 @@ void MojoWebUIBrowserTest::SetUpOnMainThread() { BaseWebUIBrowserTest::SetUpOnMainThread(); - base::FilePath pak_path; - ASSERT_TRUE(base::PathService::Get(base::DIR_MODULE, &pak_path)); - pak_path = pak_path.AppendASCII("browser_tests.pak"); - ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath( - pak_path, ui::kScaleFactorNone); - content::SetBrowserClientForTesting(test_content_browser_client_.get()); }
diff --git a/chrome/test/base/test_chrome_web_ui_controller_factory.cc b/chrome/test/base/test_chrome_web_ui_controller_factory.cc index 9d185fbd..2c72f8a 100644 --- a/chrome/test/base/test_chrome_web_ui_controller_factory.cc +++ b/chrome/test/base/test_chrome_web_ui_controller_factory.cc
@@ -7,6 +7,7 @@ #include "base/callback_helpers.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/test_data_source.h" +#include "chrome/test/base/web_ui_test_data_source.h" #include "content/public/browser/url_data_source.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui_controller.h" @@ -68,6 +69,10 @@ base::DoNothing()); content::URLDataSource::Add(profile, std::make_unique<TestDataSource>("webui")); + + content::WebUIDataSource* source = webui::CreateWebUITestDataSource(); + content::WebUIDataSource::Add(profile, source); + return controller; }
diff --git a/chrome/test/base/web_ui_browser_test.cc b/chrome/test/base/web_ui_browser_test.cc index b81bc5d5..14d5c8b5 100644 --- a/chrome/test/base/web_ui_browser_test.cc +++ b/chrome/test/base/web_ui_browser_test.cc
@@ -49,6 +49,7 @@ #include "content/public/test/test_navigation_observer.h" #include "net/base/filename_util.h" #include "services/network/public/mojom/content_security_policy.mojom.h" +#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_handle.h" using content::RenderFrameHost; @@ -500,6 +501,12 @@ void BaseWebUIBrowserTest::SetUpOnMainThread() { JavaScriptBrowserTest::SetUpOnMainThread(); + base::FilePath pak_path; + ASSERT_TRUE(base::PathService::Get(base::DIR_MODULE, &pak_path)); + pak_path = pak_path.AppendASCII("browser_tests.pak"); + ui::ResourceBundle::GetSharedInstance().AddDataPackFromPath( + pak_path, ui::kScaleFactorNone); + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(switches::kDevtoolsCodeCoverage)) { base::FilePath devtools_code_coverage_dir =
diff --git a/chrome/test/base/web_ui_test_data_source.cc b/chrome/test/base/web_ui_test_data_source.cc new file mode 100644 index 0000000..e378496 --- /dev/null +++ b/chrome/test/base/web_ui_test_data_source.cc
@@ -0,0 +1,22 @@ +// Copyright 2021 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/test/base/web_ui_test_data_source.h" + +#include "chrome/test/data/grit/webui_generated_test_resources.h" +#include "chrome/test/data/grit/webui_generated_test_resources_map.h" +#include "content/public/browser/web_ui_data_source.h" + +namespace webui { + +content::WebUIDataSource* CreateWebUITestDataSource() { + content::WebUIDataSource* source = + content::WebUIDataSource::Create("webui-test"); + source->AddResourcePaths(base::make_span(kWebuiGeneratedTestResources, + kWebuiGeneratedTestResourcesSize)); + + return source; +} + +} // namespace webui
diff --git a/chrome/test/base/web_ui_test_data_source.h b/chrome/test/base/web_ui_test_data_source.h new file mode 100644 index 0000000..498660b --- /dev/null +++ b/chrome/test/base/web_ui_test_data_source.h
@@ -0,0 +1,17 @@ +// Copyright 2021 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_TEST_BASE_WEB_UI_TEST_DATA_SOURCE_H_ +#define CHROME_TEST_BASE_WEB_UI_TEST_DATA_SOURCE_H_ + +#include "content/public/browser/web_ui_data_source.h" + +namespace webui { + +// Creates a data source for for chrome://webui-test/ URLs. +content::WebUIDataSource* CreateWebUITestDataSource(); + +} // namespace webui + +#endif // CHROME_TEST_BASE_WEB_UI_TEST_DATA_SOURCE_H_
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index bc3ca4d..8846748 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -452,6 +452,7 @@ "chromeos/crostini_installer_browsertest.js", "chromeos/crostini_upgrader_browsertest.js", "chromeos/diagnostics/diagnostics_browsertest.js", + "chromeos/firmware_update/firmware_update_browsertest.js", "chromeos/os_feedback_ui/os_feedback_browsertest.js", "chromeos/personalization_app/personalization_app_component_browsertest.js", "chromeos/personalization_app/personalization_app_controller_browsertest.js", @@ -475,6 +476,9 @@ "engagement/site_engagement_browsertest.js", "usb_internals_browsertest.js", ] + if (is_chromeos_ash) { + sources += [ "chromeos/parent_access/parent_access_browsertest.js" ] + } if (is_win || is_mac || is_linux || is_chromeos) { sources += [ "discards/discards_browsertest.js" ] }
diff --git a/chrome/test/data/webui/chromeos/BUILD.gn b/chrome/test/data/webui/chromeos/BUILD.gn index ccd3b5e..78c646f 100644 --- a/chrome/test/data/webui/chromeos/BUILD.gn +++ b/chrome/test/data/webui/chromeos/BUILD.gn
@@ -47,6 +47,7 @@ "ash_common:closure_compile", "diagnostics:closure_compile", "emoji_picker:closure_compile", + "firmware_update:closure_compile", "gaia_action_buttons:closure_compile", "os_feedback_ui:closure_compile", "personalization_app:closure_compile",
diff --git a/chrome/test/data/webui/chromeos/firmware_update/BUILD.gn b/chrome/test/data/webui/chromeos/firmware_update/BUILD.gn new file mode 100644 index 0000000..400e65d --- /dev/null +++ b/chrome/test/data/webui/chromeos/firmware_update/BUILD.gn
@@ -0,0 +1,29 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") + +js_type_check("closure_compile") { + is_polymer3 = true + closure_flags = default_closure_args + [ + "browser_resolver_prefix_replacements=\"chrome://firmware-update/=../../ash/webui/firmware_update_ui/resources/\"", + "js_module_root=../../chrome/test/data/webui/", + "js_module_root=./gen/chrome/test/data/webui/", + ] + deps = [ + ":firmware_update_test", + ":firmware_update_unified_test", + ] +} + +js_library("firmware_update_test") { + deps = [ + "../..:chai_assert", + "//ash/webui/firmware_update_ui/resources:firmware_update_app", + ] + externs_list = [ "$externs_path/mocha-2.5.js" ] +} + +js_library("firmware_update_unified_test") { +}
diff --git a/chrome/test/data/webui/chromeos/firmware_update/firmware_update_browsertest.js b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_browsertest.js new file mode 100644 index 0000000..dbc8e60 --- /dev/null +++ b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_browsertest.js
@@ -0,0 +1,60 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview Test suite for chrome://firmware-update. + * To run all tests in a single instance (default, faster): + * `browser_tests --gtest_filter=FirmwareUpdateApp*` + * + * To run each test in a new instance: + * `browser_tests --run-manual \ + * --gtest_filter=FirmwareUpdateAppBrowserTest.MANUAL_*` + * + * To run a single test suite, such as 'FirmwareUpdateApp': + * `browser_tests --run-manual --gtest_filter= \ + * FirmwareUpdateAppBrowserTest.MANUAL_FirmwareUpdateApp` + */ + +GEN_INCLUDE(['//chrome/test/data/webui/polymer_browser_test_base.js']); + +GEN('#include "ash/constants/ash_features.h"'); +GEN('#include "content/public/test/browser_test.h"'); + +/** + * @constructor + * @extends {PolymerTest} + */ +function FirmwareUpdateAppBrowserTest() {} + +FirmwareUpdateAppBrowserTest.prototype = { + __proto__: PolymerTest.prototype, + + browsePreload: 'chrome://firmware-update/test_loader.html' + + '?module=chromeos/firmware_update/' + + 'firmware_update_unified_test.js', + + featureList: {enabled: ['ash::features::kFirmwareUpdaterApp']}, +}; + +// List of names of suites in unified test to register for individual debugging. +// You must register all suites in unified test here as well for consistency, +// although technically is not necessary. +const debug_suites_list = [ + 'FirmwareUpdateApp', +]; + +TEST_F('FirmwareUpdateAppBrowserTest', 'All', function() { + assertDeepEquals( + debug_suites_list, test_suites_list, + 'List of registered tests suites and debug suites do not match.\n' + + 'Did you forget to add your test in debug_suites_list?'); + mocha.run(); +}); + +// Register each suite listed as individual tests for debugging purposes. +for (const suiteName of debug_suites_list) { + TEST_F('FirmwareUpdateAppBrowserTest', `MANUAL_${suiteName}`, function() { + runMochaSuite(suiteName); + }); +}
diff --git a/chrome/test/data/webui/chromeos/firmware_update/firmware_update_test.js b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_test.js new file mode 100644 index 0000000..5150fba1 --- /dev/null +++ b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_test.js
@@ -0,0 +1,31 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {FirmwareUpdateAppElement} from 'chrome://firmware-update/firmware_update_app.js'; + +import {assertEquals} from '../../chai_assert.js'; + +export function firmwareUpdateAppTest() { + /** @type {?FirmwareUpdateAppElement} */ + let page = null; + + setup(() => { + page = /** @type {!FirmwareUpdateAppElement} */ ( + document.createElement('firmware-update-app')); + document.body.appendChild(page); + }); + + teardown(() => { + page.remove(); + page = null; + }); + + test('LandingPageLoaded', () => { + // TODO(michaelcheco): Remove this stub test once the page has more + // capabilities to test. + assertEquals( + 'Firmware Update', + page.shadowRoot.querySelector('#header').textContent); + }); +} \ No newline at end of file
diff --git a/chrome/test/data/webui/chromeos/firmware_update/firmware_update_unified_test.js b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_unified_test.js new file mode 100644 index 0000000..bbe5382 --- /dev/null +++ b/chrome/test/data/webui/chromeos/firmware_update/firmware_update_unified_test.js
@@ -0,0 +1,16 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; + +import {firmwareUpdateAppTest} from './firmware_update_test.js'; + +window.test_suites_list = []; + +function runSuite(suiteName, testFn) { + window.test_suites_list.push(suiteName); + suite(suiteName, testFn); +} + +runSuite('FirmwareUpdateApp', firmwareUpdateAppTest);
diff --git a/chrome/test/data/webui/chromeos/parent_access/parent_access_browsertest.js b/chrome/test/data/webui/chromeos/parent_access/parent_access_browsertest.js new file mode 100644 index 0000000..40a55a3 --- /dev/null +++ b/chrome/test/data/webui/chromeos/parent_access/parent_access_browsertest.js
@@ -0,0 +1,30 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** @fileoverview Runs the Parent Access flow tests. */ + +GEN('#include "content/public/test/browser_test.h"'); + +var ParentAccessControllerTest = class extends testing.Test { + /** @override */ + get browsePreload() { + return 'chrome://parent-access/test_loader.html?module=' + + 'chromeos/parent_access/parent_access_controller_test.js'; + } + + /** @override */ + get isAsync() { + return true; + } + + /** @param {string} testName The name of the test to run. */ + runMochaTest(testName) { + runMochaTest(parent_access_controller_tests.suiteName, testName); + } +}; + +TEST_F('ParentAccessControllerTest', 'ParentAccessResultFnCalled', function() { + this.runMochaTest( + parent_access_controller_tests.TestNames.ParentAccessResultFnCalled); +});
diff --git a/chrome/test/data/webui/chromeos/parent_access/parent_access_controller_test.js b/chrome/test/data/webui/chromeos/parent_access/parent_access_controller_test.js new file mode 100644 index 0000000..3c133bf --- /dev/null +++ b/chrome/test/data/webui/chromeos/parent_access/parent_access_controller_test.js
@@ -0,0 +1,50 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import '../../mojo_webui_test_support.js'; + +import {ParentAccessController} from 'chrome://parent-access/parent_access_controller.js'; +import {assert} from 'chrome://resources/js/assert.m.js'; + + +const TARGET_URL = 'chrome://test/chromeos/parent_access/test_content.html'; + +window.parent_access_controller_tests = {}; +parent_access_controller_tests.suiteName = 'ParentAccessControllerTest'; + +/** @enum {string} */ +parent_access_controller_tests.TestNames = { + ParentAccessResultFnCalled: + 'tests that parent access result was passed through', +}; + +suite(parent_access_controller_tests.suiteName, function() { + let element; + let parentAccessController; + + setup(function() { + document.body.innerHTML = ''; + // The test uses an iframe instead of a webview because a webview + // can't load content from a chrome:// URL. This is OK because the + // functionality being tested here doesn't rely on webview features. + element = document.createElement('iframe'); + element.src = TARGET_URL; + document.body.appendChild(element); + }); + + test( + parent_access_controller_tests.TestNames.ParentAccessResultFnCalled, + async function() { + parentAccessController = new ParentAccessController( + element, 'chrome://test', 'chrome://test'); + + let parentAccessResult = await Promise.race([ + parentAccessController.whenParentAccessResult(), + parentAccessController.whenInitializationError() + ]); + + // Verify that the result received is the one set in test_content.html + assertEquals('1234567890', parentAccessResult); + }); +});
diff --git a/chrome/test/data/webui/chromeos/parent_access/parent_access_test_client.js b/chrome/test/data/webui/chromeos/parent_access/parent_access_test_client.js new file mode 100644 index 0000000..42c9f04 --- /dev/null +++ b/chrome/test/data/webui/chromeos/parent_access/parent_access_test_client.js
@@ -0,0 +1,25 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {PostMessageAPIClient} from 'chrome://resources/js/post_message_api_client.m.js'; + + +const serverOriginURLFilter = 'chrome://parent-access/'; + +class TestParentAccessAPIClient extends PostMessageAPIClient { + constructor() { + super(serverOriginURLFilter, null); + } + + /** + * @override + */ + onInitialized() { + this.callApiFn('onParentAccessResult', ['1234567890']); + } +} + +document.addEventListener('DOMContentLoaded', function() { + const parentAccessTestClient = new TestParentAccessAPIClient(); +});
diff --git a/chrome/test/data/webui/chromeos/parent_access/test_content.html b/chrome/test/data/webui/chromeos/parent_access/test_content.html new file mode 100644 index 0000000..4334771 --- /dev/null +++ b/chrome/test/data/webui/chromeos/parent_access/test_content.html
@@ -0,0 +1,5 @@ +<html> +<body> +<script type="module" src="chrome://test/chromeos/parent_access/parent_access_test_client.js"></script> +</body> +</html>
diff --git a/chrome/test/data/webui/cr_elements/BUILD.gn b/chrome/test/data/webui/cr_elements/BUILD.gn index f79a4a74..958f3a69 100644 --- a/chrome/test/data/webui/cr_elements/BUILD.gn +++ b/chrome/test/data/webui/cr_elements/BUILD.gn
@@ -413,7 +413,7 @@ "..:chai_assert", "//third_party/polymer/v3_0/components-chromium/iron-test-helpers:mock-interactions", "//ui/webui/resources/cr_elements/cr_input:cr_input.m", - "//ui/webui/resources/cr_elements/cr_searchable_drop_down:cr_searchable_drop_down.m", + "//ui/webui/resources/cr_elements/cr_searchable_drop_down:cr_searchable_drop_down", ] externs_list = [ "$externs_path/mocha-2.5.js" ] }
diff --git a/chrome/test/data/webui/cr_elements/cr_searchable_drop_down_tests.js b/chrome/test/data/webui/cr_elements/cr_searchable_drop_down_tests.js index bcf9b9a7..8b6c748 100644 --- a/chrome/test/data/webui/cr_elements/cr_searchable_drop_down_tests.js +++ b/chrome/test/data/webui/cr_elements/cr_searchable_drop_down_tests.js
@@ -3,7 +3,7 @@ // found in the LICENSE file. // clang-format off -import 'chrome://resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.m.js'; +import 'chrome://resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.js'; import {keyDownOn, move} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js'; import {flush, html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/chrome/test/data/webui/new_tab_page/app_test.js b/chrome/test/data/webui/new_tab_page/app_test.js index 30edeab..cd51aa7 100644 --- a/chrome/test/data/webui/new_tab_page/app_test.js +++ b/chrome/test/data/webui/new_tab_page/app_test.js
@@ -82,133 +82,62 @@ await flushTasks(); }); - test('customize dialog closed on start', () => { - // Assert. - assertFalse(!!app.shadowRoot.querySelector('ntp-customize-dialog')); - }); + suite('misc', () => { + test('customize dialog closed on start', () => { + // Assert. + assertFalse(!!app.shadowRoot.querySelector('ntp-customize-dialog')); + }); - test('clicking customize button opens customize dialog', async () => { - // Act. - $$(app, '#customizeButton').click(); - await flushTasks(); + test('clicking customize button opens customize dialog', async () => { + // Act. + $$(app, '#customizeButton').click(); + await flushTasks(); - // Assert. - assertTrue(!!app.shadowRoot.querySelector('ntp-customize-dialog')); - }); + // Assert. + assertTrue(!!app.shadowRoot.querySelector('ntp-customize-dialog')); + }); - test('setting theme updates customize dialog', async () => { - // Arrange. - $$(app, '#customizeButton').click(); - const theme = createTheme(); + test('logs height', async () => { + // Assert. + assertEquals(1, metrics.count('NewTabPage.Height')); + assertEquals( + 1, + metrics.count( + 'NewTabPage.Height', + Math.floor(document.documentElement.clientHeight))); + }); - // Act. - callbackRouterRemote.setTheme(theme); - await callbackRouterRemote.$.flushForTesting(); + test('realbox is not visible by default', async () => { + // Assert. + assertStyle($$(app, '#realbox'), 'visibility', 'hidden'); - // Assert. - assertDeepEquals( - theme, app.shadowRoot.querySelector('ntp-customize-dialog').theme); - }); + // Act. + callbackRouterRemote.setTheme(createTheme()); + await callbackRouterRemote.$.flushForTesting(); - test('setting theme updates ntp', async () => { - // Act. - callbackRouterRemote.setTheme(createTheme()); - await callbackRouterRemote.$.flushForTesting(); + // Assert. + assertStyle($$(app, '#realbox'), 'visibility', 'visible'); + }); - // Assert. - assertEquals(1, backgroundManager.getCallCount('setBackgroundColor')); - assertEquals( - 0xffff0000 /* red */, - (await backgroundManager.whenCalled('setBackgroundColor')).value); - assertStyle( - $$(app, '#content'), '--ntp-theme-text-color', 'rgba(0, 0, 255, 1)'); - assertEquals(1, backgroundManager.getCallCount('setShowBackgroundImage')); - assertFalse(await backgroundManager.whenCalled('setShowBackgroundImage')); - assertStyle($$(app, '#backgroundImageAttribution'), 'display', 'none'); - assertStyle($$(app, '#backgroundImageAttribution2'), 'display', 'none'); - assertFalse($$(app, '#logo').singleColored); - assertFalse($$(app, '#logo').dark); - assertEquals(0xffff0000, $$(app, '#logo').backgroundColor.value); - }); + test('open voice search event opens voice search overlay', async () => { + // Act. + $$(app, '#realbox').dispatchEvent(new Event('open-voice-search')); + await flushTasks(); - test('setting 3p theme shows attribution', async () => { - // Arrange. - const theme = createTheme(); - theme.backgroundImage = { - url: {url: 'https://foo.com'}, - attributionUrl: {url: 'chrome://theme/foo'}, - }; + // Assert. + assertTrue(!!app.shadowRoot.querySelector('ntp-voice-search-overlay')); + assertEquals(1, metrics.count('NewTabPage.VoiceActions')); + assertEquals( + 1, + metrics.count( + 'NewTabPage.VoiceActions', VoiceAction.kActivateSearchBox)); + }); - // Act. - callbackRouterRemote.setTheme(theme); - await callbackRouterRemote.$.flushForTesting(); - - assertNotStyle($$(app, '#themeAttribution'), 'display', 'none'); - assertEquals('chrome://theme/foo', $$(app, '#themeAttribution img').src); - }); - - test('realbox is not visible by default', async () => { - // Assert. - assertStyle($$(app, '#realbox'), 'visibility', 'hidden'); - - // Act. - callbackRouterRemote.setTheme(createTheme()); - await callbackRouterRemote.$.flushForTesting(); - - // Assert. - assertStyle($$(app, '#realbox'), 'visibility', 'visible'); - }); - - test('open voice search event opens voice search overlay', async () => { - // Act. - $$(app, '#realbox').dispatchEvent(new Event('open-voice-search')); - await flushTasks(); - - // Assert. - assertTrue(!!app.shadowRoot.querySelector('ntp-voice-search-overlay')); - assertEquals(1, metrics.count('NewTabPage.VoiceActions')); - assertEquals( - 1, - metrics.count( - 'NewTabPage.VoiceActions', VoiceAction.kActivateSearchBox)); - }); - - test('voice search keyboard shortcut', async () => { - // Test correct shortcut opens voice search. - // Act. - window.dispatchEvent(new KeyboardEvent('keydown', { - ctrlKey: true, - shiftKey: true, - code: 'Period', - })); - await flushTasks(); - - // Assert. - assertTrue(!!app.shadowRoot.querySelector('ntp-voice-search-overlay')); - assertEquals(1, metrics.count('NewTabPage.VoiceActions')); - assertEquals( - 1, - metrics.count( - 'NewTabPage.VoiceActions', VoiceAction.kActivateKeyboard)); - - // Test other shortcut doesn't close voice search. - // Act - window.dispatchEvent(new KeyboardEvent('keydown', { - ctrlKey: true, - shiftKey: true, - code: 'Enter', - })); - await flushTasks(); - - // Assert. - assertTrue(!!app.shadowRoot.querySelector('ntp-voice-search-overlay')); - }); - - if (isMac) { - test('keyboard shortcut opens voice search overlay on mac', async () => { + test('voice search keyboard shortcut', async () => { + // Test correct shortcut opens voice search. // Act. window.dispatchEvent(new KeyboardEvent('keydown', { - metaKey: true, + ctrlKey: true, shiftKey: true, code: 'Period', })); @@ -216,260 +145,339 @@ // Assert. assertTrue(!!app.shadowRoot.querySelector('ntp-voice-search-overlay')); + assertEquals(1, metrics.count('NewTabPage.VoiceActions')); + assertEquals( + 1, + metrics.count( + 'NewTabPage.VoiceActions', VoiceAction.kActivateKeyboard)); + + // Test other shortcut doesn't close voice search. + // Act + window.dispatchEvent(new KeyboardEvent('keydown', { + ctrlKey: true, + shiftKey: true, + code: 'Enter', + })); + await flushTasks(); + + // Assert. + assertTrue(!!app.shadowRoot.querySelector('ntp-voice-search-overlay')); }); - } - test('setting background image shows image', async () => { - // Arrange. - const theme = createTheme(); - theme.backgroundImage = {url: {url: 'https://img.png'}}; + if (isMac) { + test('keyboard shortcut opens voice search overlay on mac', async () => { + // Act. + window.dispatchEvent(new KeyboardEvent('keydown', { + metaKey: true, + shiftKey: true, + code: 'Period', + })); + await flushTasks(); - // Act. - backgroundManager.resetResolver('setShowBackgroundImage'); - callbackRouterRemote.setTheme(theme); - await callbackRouterRemote.$.flushForTesting(); - - // Assert. - assertEquals(1, backgroundManager.getCallCount('setShowBackgroundImage')); - assertTrue(await backgroundManager.whenCalled('setShowBackgroundImage')); - assertNotStyle( - $$(app, '#backgroundImageAttribution'), 'text-shadow', 'none'); - assertEquals(1, backgroundManager.getCallCount('setBackgroundImage')); - assertEquals( - 'https://img.png', - (await backgroundManager.whenCalled('setBackgroundImage')).url.url); - assertEquals(null, $$(app, '#logo').backgroundColor); + // Assert. + assertTrue(!!app.shadowRoot.querySelector('ntp-voice-search-overlay')); + }); + } }); - test('setting attributions shows attributions', async function() { - // Arrange. - const theme = createTheme(); - theme.backgroundImageAttribution1 = 'foo'; - theme.backgroundImageAttribution2 = 'bar'; - theme.backgroundImageAttributionUrl = {url: 'https://info.com'}; + suite('theming', () => { + test('setting theme updates customize dialog', async () => { + // Arrange. + $$(app, '#customizeButton').click(); + const theme = createTheme(); - // Act. - callbackRouterRemote.setTheme(theme); - await callbackRouterRemote.$.flushForTesting(); + // Act. + callbackRouterRemote.setTheme(theme); + await callbackRouterRemote.$.flushForTesting(); - // Assert. - assertNotStyle($$(app, '#backgroundImageAttribution'), 'display', 'none'); - assertNotStyle($$(app, '#backgroundImageAttribution2'), 'display', 'none'); - assertEquals( - 'https://info.com', - $$(app, '#backgroundImageAttribution').getAttribute('href')); - assertEquals( - 'foo', $$(app, '#backgroundImageAttribution1').textContent.trim()); - assertEquals( - 'bar', $$(app, '#backgroundImageAttribution2').textContent.trim()); - }); + // Assert. + assertDeepEquals( + theme, app.shadowRoot.querySelector('ntp-customize-dialog').theme); + }); - test('setting logo color colors logo', async function() { - // Arrange. - const theme = createTheme(); - theme.logoColor = {value: 0xffff0000}; + test('setting theme updates ntp', async () => { + // Act. + callbackRouterRemote.setTheme(createTheme()); + await callbackRouterRemote.$.flushForTesting(); - // Act. - callbackRouterRemote.setTheme(theme); - await callbackRouterRemote.$.flushForTesting(); + // Assert. + assertEquals(1, backgroundManager.getCallCount('setBackgroundColor')); + assertEquals( + 0xffff0000 /* red */, + (await backgroundManager.whenCalled('setBackgroundColor')).value); + assertStyle( + $$(app, '#content'), '--ntp-theme-text-color', 'rgba(0, 0, 255, 1)'); + assertEquals(1, backgroundManager.getCallCount('setShowBackgroundImage')); + assertFalse(await backgroundManager.whenCalled('setShowBackgroundImage')); + assertStyle($$(app, '#backgroundImageAttribution'), 'display', 'none'); + assertStyle($$(app, '#backgroundImageAttribution2'), 'display', 'none'); + assertFalse($$(app, '#logo').singleColored); + assertFalse($$(app, '#logo').dark); + assertEquals(0xffff0000, $$(app, '#logo').backgroundColor.value); + }); - // Assert. - assertTrue($$(app, '#logo').singleColored); - assertStyle($$(app, '#logo'), '--ntp-logo-color', 'rgba(255, 0, 0, 1)'); - }); + test('setting 3p theme shows attribution', async () => { + // Arrange. + const theme = createTheme(); + theme.backgroundImage = { + url: {url: 'https://foo.com'}, + attributionUrl: {url: 'chrome://theme/foo'}, + }; - test('preview background image', async () => { - const theme = createTheme(); - theme.backgroundImage = {url: {url: 'https://example.com/image.png'}}; - theme.backgroundImageAttribution1 = 'foo'; - theme.backgroundImageAttribution2 = 'bar'; - theme.backgroundImageAttributionUrl = {url: 'https://info.com'}; - callbackRouterRemote.setTheme(theme); - await callbackRouterRemote.$.flushForTesting(); - assertEquals(backgroundManager.getCallCount('setBackgroundImage'), 1); - assertEquals( - 'https://example.com/image.png', - (await backgroundManager.whenCalled('setBackgroundImage')).url.url); - assertEquals( - 'https://info.com/', $$(app, '#backgroundImageAttribution').href); - assertEquals('foo', $$(app, '#backgroundImageAttribution1').innerText); - assertEquals('bar', $$(app, '#backgroundImageAttribution2').innerText); - $$(app, '#customizeButton').click(); - await flushTasks(); - const dialog = app.shadowRoot.querySelector('ntp-customize-dialog'); - backgroundManager.resetResolver('setBackgroundImage'); - dialog.backgroundSelection = { - type: BackgroundSelectionType.IMAGE, - image: { - attribution1: '1', - attribution2: '2', - attributionUrl: {url: 'https://example.com'}, - imageUrl: {url: 'https://example.com/other.png'}, - }, - }; - assertEquals(1, backgroundManager.getCallCount('setBackgroundImage')); - assertEquals( - 'https://example.com/other.png', - (await backgroundManager.whenCalled('setBackgroundImage')).url.url); - assertEquals( - 'https://example.com/', $$(app, '#backgroundImageAttribution').href); - assertEquals('1', $$(app, '#backgroundImageAttribution1').innerText); - assertEquals('2', $$(app, '#backgroundImageAttribution2').innerText); - assertFalse($$(app, '#backgroundImageAttribution2').hidden); + // Act. + callbackRouterRemote.setTheme(theme); + await callbackRouterRemote.$.flushForTesting(); - backgroundManager.resetResolver('setBackgroundImage'); - dialog.backgroundSelection = {type: BackgroundSelectionType.NO_SELECTION}; - assertEquals(1, backgroundManager.getCallCount('setBackgroundImage')); - assertEquals( - 'https://example.com/image.png', - (await backgroundManager.whenCalled('setBackgroundImage')).url.url); - }); + assertNotStyle($$(app, '#themeAttribution'), 'display', 'none'); + assertEquals('chrome://theme/foo', $$(app, '#themeAttribution img').src); + }); - test('theme update when dialog closed clears selection', async () => { - const theme = createTheme(); - theme.backgroundImage = {url: {url: 'https://example.com/image.png'}}; - callbackRouterRemote.setTheme(theme); - await callbackRouterRemote.$.flushForTesting(); - assertEquals(1, backgroundManager.getCallCount('setBackgroundImage')); - assertEquals( - 'https://example.com/image.png', - (await backgroundManager.whenCalled('setBackgroundImage')).url.url); - $$(app, '#customizeButton').click(); - await flushTasks(); - const dialog = app.shadowRoot.querySelector('ntp-customize-dialog'); - backgroundManager.resetResolver('setBackgroundImage'); - dialog.backgroundSelection = { - type: BackgroundSelectionType.IMAGE, - image: { - attribution1: '1', - attribution2: '2', - attributionUrl: {url: 'https://example.com'}, - imageUrl: {url: 'https://example.com/other.png'}, - }, - }; - assertEquals(1, backgroundManager.getCallCount('setBackgroundImage')); - assertEquals( - 'https://example.com/other.png', - (await backgroundManager.whenCalled('setBackgroundImage')).url.url); - backgroundManager.resetResolver('setBackgroundImage'); - dialog.dispatchEvent(new Event('close')); - assertEquals(0, backgroundManager.getCallCount('setBackgroundImage')); - backgroundManager.resetResolver('setBackgroundImage'); - callbackRouterRemote.setTheme(theme); - await callbackRouterRemote.$.flushForTesting(); - assertEquals(2, backgroundManager.getCallCount('setBackgroundImage')); - assertEquals( - 'https://example.com/image.png', - (await backgroundManager.whenCalled('setBackgroundImage')).url.url); - }); + test('setting background image shows image', async () => { + // Arrange. + const theme = createTheme(); + theme.backgroundImage = {url: {url: 'https://img.png'}}; - test('theme updates add shortcut color', async () => { - const theme = createTheme(); - theme.mostVisited.useWhiteTileIcon = true; - callbackRouterRemote.setTheme(theme); - const mostVisited = $$(app, '#mostVisited'); - assertFalse(mostVisited.hasAttribute('use-white-tile-icon_')); - await callbackRouterRemote.$.flushForTesting(); - assertTrue(mostVisited.hasAttribute('use-white-tile-icon_')); - }); + // Act. + backgroundManager.resetResolver('setShowBackgroundImage'); + callbackRouterRemote.setTheme(theme); + await callbackRouterRemote.$.flushForTesting(); - test('theme updates use title pill', async () => { - const theme = createTheme(); - theme.mostVisited.useTitlePill = true; - callbackRouterRemote.setTheme(theme); - const mostVisited = $$(app, '#mostVisited'); - assertFalse(mostVisited.hasAttribute('use-title-pill_')); - await callbackRouterRemote.$.flushForTesting(); - assertTrue(mostVisited.hasAttribute('use-title-pill_')); - }); + // Assert. + assertEquals(1, backgroundManager.getCallCount('setShowBackgroundImage')); + assertTrue(await backgroundManager.whenCalled('setShowBackgroundImage')); + assertNotStyle( + $$(app, '#backgroundImageAttribution'), 'text-shadow', 'none'); + assertEquals(1, backgroundManager.getCallCount('setBackgroundImage')); + assertEquals( + 'https://img.png', + (await backgroundManager.whenCalled('setBackgroundImage')).url.url); + assertEquals(null, $$(app, '#logo').backgroundColor); + }); - test('theme updates is dark', async () => { - const theme = createTheme(); - theme.mostVisited.isDark = true; - callbackRouterRemote.setTheme(theme); - const mostVisited = $$(app, '#mostVisited'); - assertFalse(mostVisited.hasAttribute('is-dark_')); - await callbackRouterRemote.$.flushForTesting(); - assertTrue(mostVisited.hasAttribute('is-dark_')); - }); + test('setting attributions shows attributions', async function() { + // Arrange. + const theme = createTheme(); + theme.backgroundImageAttribution1 = 'foo'; + theme.backgroundImageAttribution2 = 'bar'; + theme.backgroundImageAttributionUrl = {url: 'https://info.com'}; - test('can show promo with browser command', async () => { - const promoBrowserCommandHandler = installMock( - CommandHandlerRemote, - mock => BrowserCommandProxy.getInstance().handler = mock); - promoBrowserCommandHandler.setResultFor( - 'canExecuteCommand', Promise.resolve({canExecute: true})); + // Act. + callbackRouterRemote.setTheme(theme); + await callbackRouterRemote.$.flushForTesting(); - const commandId = 123; // Unsupported command. - window.dispatchEvent(new MessageEvent('message', { - data: { - frameType: 'one-google-bar', - messageType: 'can-show-promo-with-browser-command', - commandId, - }, - source: window, - origin: window.origin, - })); + // Assert. + assertNotStyle($$(app, '#backgroundImageAttribution'), 'display', 'none'); + assertNotStyle( + $$(app, '#backgroundImageAttribution2'), 'display', 'none'); + assertEquals( + 'https://info.com', + $$(app, '#backgroundImageAttribution').getAttribute('href')); + assertEquals( + 'foo', $$(app, '#backgroundImageAttribution1').textContent.trim()); + assertEquals( + 'bar', $$(app, '#backgroundImageAttribution2').textContent.trim()); + }); - // Make sure the command is sent to the browser. - const expectedCommandId = - await promoBrowserCommandHandler.whenCalled('canExecuteCommand'); - // Unsupported commands get resolved to the default command before being - // sent to the browser. - assertEquals(Command.kUnknownCommand, expectedCommandId); + test('setting logo color colors logo', async function() { + // Arrange. + const theme = createTheme(); + theme.logoColor = {value: 0xffff0000}; - // Make sure the promo frame gets notified whether the promo can be shown. - const {data} = await eventToPromise('message', window); - assertEquals('can-show-promo-with-browser-command', data.messageType); - assertTrue(data[commandId]); - }); + // Act. + callbackRouterRemote.setTheme(theme); + await callbackRouterRemote.$.flushForTesting(); - test('executes promo browser command', async () => { - const promoBrowserCommandHandler = installMock( - CommandHandlerRemote, - mock => BrowserCommandProxy.getInstance().handler = mock); - promoBrowserCommandHandler.setResultFor( - 'executeCommand', Promise.resolve({commandExecuted: true})); + // Assert. + assertTrue($$(app, '#logo').singleColored); + assertStyle($$(app, '#logo'), '--ntp-logo-color', 'rgba(255, 0, 0, 1)'); + }); - const commandId = 123; // Unsupported command. - const clickInfo = {middleButton: true}; - window.dispatchEvent(new MessageEvent('message', { - data: { - frameType: 'one-google-bar', - messageType: 'execute-browser-command', - data: { - commandId, - clickInfo, + test('preview background image', async () => { + const theme = createTheme(); + theme.backgroundImage = {url: {url: 'https://example.com/image.png'}}; + theme.backgroundImageAttribution1 = 'foo'; + theme.backgroundImageAttribution2 = 'bar'; + theme.backgroundImageAttributionUrl = {url: 'https://info.com'}; + callbackRouterRemote.setTheme(theme); + await callbackRouterRemote.$.flushForTesting(); + assertEquals(backgroundManager.getCallCount('setBackgroundImage'), 1); + assertEquals( + 'https://example.com/image.png', + (await backgroundManager.whenCalled('setBackgroundImage')).url.url); + assertEquals( + 'https://info.com/', $$(app, '#backgroundImageAttribution').href); + assertEquals('foo', $$(app, '#backgroundImageAttribution1').innerText); + assertEquals('bar', $$(app, '#backgroundImageAttribution2').innerText); + $$(app, '#customizeButton').click(); + await flushTasks(); + const dialog = app.shadowRoot.querySelector('ntp-customize-dialog'); + backgroundManager.resetResolver('setBackgroundImage'); + dialog.backgroundSelection = { + type: BackgroundSelectionType.IMAGE, + image: { + attribution1: '1', + attribution2: '2', + attributionUrl: {url: 'https://example.com'}, + imageUrl: {url: 'https://example.com/other.png'}, }, - }, - source: window, - origin: window.origin, - })); + }; + assertEquals(1, backgroundManager.getCallCount('setBackgroundImage')); + assertEquals( + 'https://example.com/other.png', + (await backgroundManager.whenCalled('setBackgroundImage')).url.url); + assertEquals( + 'https://example.com/', $$(app, '#backgroundImageAttribution').href); + assertEquals('1', $$(app, '#backgroundImageAttribution1').innerText); + assertEquals('2', $$(app, '#backgroundImageAttribution2').innerText); + assertFalse($$(app, '#backgroundImageAttribution2').hidden); - // Make sure the command and click information are sent to the browser. - const [expectedCommandId, expectedClickInfo] = - await promoBrowserCommandHandler.whenCalled('executeCommand'); - // Unsupported commands get resolved to the default command before being - // sent to the browser. - assertEquals(Command.kUnknownCommand, expectedCommandId); - assertEquals(clickInfo, expectedClickInfo); + backgroundManager.resetResolver('setBackgroundImage'); + dialog.backgroundSelection = {type: BackgroundSelectionType.NO_SELECTION}; + assertEquals(1, backgroundManager.getCallCount('setBackgroundImage')); + assertEquals( + 'https://example.com/image.png', + (await backgroundManager.whenCalled('setBackgroundImage')).url.url); + }); - // Make sure the promo frame gets notified whether the command was executed. - const {data: commandExecuted} = await eventToPromise('message', window); - assertTrue(commandExecuted); + test('theme update when dialog closed clears selection', async () => { + const theme = createTheme(); + theme.backgroundImage = {url: {url: 'https://example.com/image.png'}}; + callbackRouterRemote.setTheme(theme); + await callbackRouterRemote.$.flushForTesting(); + assertEquals(1, backgroundManager.getCallCount('setBackgroundImage')); + assertEquals( + 'https://example.com/image.png', + (await backgroundManager.whenCalled('setBackgroundImage')).url.url); + $$(app, '#customizeButton').click(); + await flushTasks(); + const dialog = app.shadowRoot.querySelector('ntp-customize-dialog'); + backgroundManager.resetResolver('setBackgroundImage'); + dialog.backgroundSelection = { + type: BackgroundSelectionType.IMAGE, + image: { + attribution1: '1', + attribution2: '2', + attributionUrl: {url: 'https://example.com'}, + imageUrl: {url: 'https://example.com/other.png'}, + }, + }; + assertEquals(1, backgroundManager.getCallCount('setBackgroundImage')); + assertEquals( + 'https://example.com/other.png', + (await backgroundManager.whenCalled('setBackgroundImage')).url.url); + backgroundManager.resetResolver('setBackgroundImage'); + dialog.dispatchEvent(new Event('close')); + assertEquals(0, backgroundManager.getCallCount('setBackgroundImage')); + backgroundManager.resetResolver('setBackgroundImage'); + callbackRouterRemote.setTheme(theme); + await callbackRouterRemote.$.flushForTesting(); + assertEquals(2, backgroundManager.getCallCount('setBackgroundImage')); + assertEquals( + 'https://example.com/image.png', + (await backgroundManager.whenCalled('setBackgroundImage')).url.url); + }); + + test('theme updates add shortcut color', async () => { + const theme = createTheme(); + theme.mostVisited.useWhiteTileIcon = true; + callbackRouterRemote.setTheme(theme); + const mostVisited = $$(app, '#mostVisited'); + assertFalse(mostVisited.hasAttribute('use-white-tile-icon_')); + await callbackRouterRemote.$.flushForTesting(); + assertTrue(mostVisited.hasAttribute('use-white-tile-icon_')); + }); + + test('theme updates use title pill', async () => { + const theme = createTheme(); + theme.mostVisited.useTitlePill = true; + callbackRouterRemote.setTheme(theme); + const mostVisited = $$(app, '#mostVisited'); + assertFalse(mostVisited.hasAttribute('use-title-pill_')); + await callbackRouterRemote.$.flushForTesting(); + assertTrue(mostVisited.hasAttribute('use-title-pill_')); + }); + + test('theme updates is dark', async () => { + const theme = createTheme(); + theme.mostVisited.isDark = true; + callbackRouterRemote.setTheme(theme); + const mostVisited = $$(app, '#mostVisited'); + assertFalse(mostVisited.hasAttribute('is-dark_')); + await callbackRouterRemote.$.flushForTesting(); + assertTrue(mostVisited.hasAttribute('is-dark_')); + }); }); - test('logs height', async () => { - // Assert. - assertEquals(1, metrics.count('NewTabPage.Height')); - assertEquals( - 1, - metrics.count( - 'NewTabPage.Height', - Math.floor(document.documentElement.clientHeight))); + suite('promo', () => { + test('can show promo with browser command', async () => { + const promoBrowserCommandHandler = installMock( + CommandHandlerRemote, + mock => BrowserCommandProxy.getInstance().handler = mock); + promoBrowserCommandHandler.setResultFor( + 'canExecuteCommand', Promise.resolve({canExecute: true})); + + const commandId = 123; // Unsupported command. + window.dispatchEvent(new MessageEvent('message', { + data: { + frameType: 'one-google-bar', + messageType: 'can-show-promo-with-browser-command', + commandId, + }, + source: window, + origin: window.origin, + })); + + // Make sure the command is sent to the browser. + const expectedCommandId = + await promoBrowserCommandHandler.whenCalled('canExecuteCommand'); + // Unsupported commands get resolved to the default command before being + // sent to the browser. + assertEquals(Command.kUnknownCommand, expectedCommandId); + + // Make sure the promo frame gets notified whether the promo can be shown. + const {data} = await eventToPromise('message', window); + assertEquals('can-show-promo-with-browser-command', data.messageType); + assertTrue(data[commandId]); + }); + + test('executes promo browser command', async () => { + const promoBrowserCommandHandler = installMock( + CommandHandlerRemote, + mock => BrowserCommandProxy.getInstance().handler = mock); + promoBrowserCommandHandler.setResultFor( + 'executeCommand', Promise.resolve({commandExecuted: true})); + + const commandId = 123; // Unsupported command. + const clickInfo = {middleButton: true}; + window.dispatchEvent(new MessageEvent('message', { + data: { + frameType: 'one-google-bar', + messageType: 'execute-browser-command', + data: { + commandId, + clickInfo, + }, + }, + source: window, + origin: window.origin, + })); + + // Make sure the command and click information are sent to the browser. + const [expectedCommandId, expectedClickInfo] = + await promoBrowserCommandHandler.whenCalled('executeCommand'); + // Unsupported commands get resolved to the default command before being + // sent to the browser. + assertEquals(Command.kUnknownCommand, expectedCommandId); + assertEquals(clickInfo, expectedClickInfo); + + // Make sure the promo frame gets notified whether the command was + // executed. + const {data: commandExecuted} = await eventToPromise('message', window); + assertTrue(commandExecuted); + }); }); - suite('click recording', () => { + suite('clicks', () => { suiteSetup(() => { loadTimeData.overrideValues({ modulesEnabled: true,
diff --git a/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js b/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js index b9aa998..6703c40dbe 100644 --- a/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js +++ b/chrome/test/data/webui/new_tab_page/new_tab_page_browsertest.js
@@ -25,15 +25,32 @@ } }; -// TODO(https://crbug.com/1253309): Flaky on Linux debug builds. -GEN('#if defined(OS_LINUX) && !defined(NDEBUG)'); -GEN('#define MAYBE_NewTabPageAppTestAll DISABLED_All'); -GEN('#else'); -GEN('#define MAYBE_NewTabPageAppTestAll All'); -GEN('#endif'); +TEST_F('NewTabPageAppTest', 'Misc', function() { + runMochaSuite('NewTabPageAppTest misc'); +}); -TEST_F('NewTabPageAppTest', 'MAYBE_NewTabPageAppTestAll', function() { - mocha.run(); +TEST_F('NewTabPageAppTest', 'Theming', function() { + runMochaSuite('NewTabPageAppTest theming'); +}); + +TEST_F('NewTabPageAppTest', 'Promo', function() { + runMochaSuite('NewTabPageAppTest promo'); +}); + +TEST_F('NewTabPageAppTest', 'Clicks', function() { + runMochaSuite('NewTabPageAppTest clicks'); +}); + +TEST_F('NewTabPageAppTest', 'Modules', function() { + runMochaSuite('NewTabPageAppTest modules'); +}); + +TEST_F('NewTabPageAppTest', 'CounterfactualModules', function() { + runMochaSuite('NewTabPageAppTest counterfactual modules'); +}); + +TEST_F('NewTabPageAppTest', 'CustomizeUrl', function() { + runMochaSuite('NewTabPageAppTest customize URL'); }); var NewTabPageCustomizeDialogTest = class extends NewTabPageBrowserTest {
diff --git a/chrome/test/data/webui/settings/system_page_tests.js b/chrome/test/data/webui/settings/system_page_tests.js index aba7bee..b272f661 100644 --- a/chrome/test/data/webui/settings/system_page_tests.js +++ b/chrome/test/data/webui/settings/system_page_tests.js
@@ -123,7 +123,7 @@ // settings. expectFalse(control.hasAttribute('actionable')); expectEquals(null, control.querySelector('cr-policy-pref-indicator')); - expectFalse(showProxyButton.hidden); + expectTrue(showProxyButton.hidden); systemPage.set('prefs.proxy', { key: 'proxy',
diff --git a/chrome/test/nacl/nacl_browsertest.cc b/chrome/test/nacl/nacl_browsertest.cc index b1b2ff0..e9935a3 100644 --- a/chrome/test/nacl/nacl_browsertest.cc +++ b/chrome/test/nacl/nacl_browsertest.cc
@@ -309,8 +309,7 @@ // is used, the required 1GB sandbox address space is not reserved. // (see note in chrome/browser/nacl_host/test/nacl_gdb_browsertest.cc) #if defined(OS_WIN) - if (base::win::OSInfo::GetInstance()->wow64_status() == - base::win::OSInfo::WOW64_DISABLED && + if (base::win::OSInfo::GetInstance()->IsWowDisabled() && base::win::OSInfo::GetArchitecture() == base::win::OSInfo::X86_ARCHITECTURE) { return true;
diff --git a/chrome/test/nacl/pnacl_header_test.cc b/chrome/test/nacl/pnacl_header_test.cc index ed97c7e..8272c09 100644 --- a/chrome/test/nacl/pnacl_header_test.cc +++ b/chrome/test/nacl/pnacl_header_test.cc
@@ -28,7 +28,6 @@ void TestDispatcherHostDelegate::RequestBeginning( net::URLRequest* request, content::ResourceContext* resource_context, - content::AppCacheService* appcache_service, blink::mojom::ResourceType resource_type, std::vector<std::unique_ptr<content::ResourceThrottle>>* throttles) { // This checks the same condition as the one for PNaCl in
diff --git a/chrome/test/nacl/pnacl_header_test.h b/chrome/test/nacl/pnacl_header_test.h index 6108067..ba63323 100644 --- a/chrome/test/nacl/pnacl_header_test.h +++ b/chrome/test/nacl/pnacl_header_test.h
@@ -39,7 +39,6 @@ void RequestBeginning(net::URLRequest* request, content::ResourceContext* resource_context, - content::AppCacheService* appcache_service, blink::mojom::ResourceType resource_type, std::vector<std::unique_ptr<content::ResourceThrottle>>* throttles) override;
diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc index d18246d..6d5c8e7 100644 --- a/chrome/test/ppapi/ppapi_browsertest.cc +++ b/chrome/test/ppapi/ppapi_browsertest.cc
@@ -1530,8 +1530,7 @@ // Windows kernel, only 64-bit NaCl works. This test matches the condition // used in //components/nacl/browser/nacl_browser.cc::NaClIrtName to // choose which kind of NaCl nexe to load, so it better be right. - is32 = (base::win::OSInfo::GetInstance()->wow64_status() != - base::win::OSInfo::WOW64_ENABLED); + is32 = !base::win::OSInfo::GetInstance()->IsWowX86OnAMD64(); #endif if (is32) RunTestViaHTTP(STRIP_PREFIXES(NaClIRTStackAlignment));
diff --git a/chromecast/app/cast_main_delegate.cc b/chromecast/app/cast_main_delegate.cc index e07989e8..eb66e84 100644 --- a/chromecast/app/cast_main_delegate.cc +++ b/chromecast/app/cast_main_delegate.cc
@@ -75,17 +75,38 @@ logging::LoggingSettings settings; settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG | logging::LOG_TO_STDERR; -#if defined(OS_ANDROID) + const base::CommandLine* command_line(base::CommandLine::ForCurrentProcess()); std::string process_type = command_line->GetSwitchValueASCII(switches::kProcessType); + + // Must be created outside of the if scope below to avoid lifetime concerns. + std::string log_path_as_string; + if (command_line->HasSwitch(switches::kLogFile)) { + auto file_path = command_line->GetSwitchValuePath(switches::kLogFile); + DCHECK(!file_path.empty()); + log_path_as_string = file_path.value(); + + settings.logging_dest = logging::LOG_TO_ALL; + settings.log_file_path = log_path_as_string.c_str(); + settings.lock_log = logging::DONT_LOCK_LOG_FILE; + + // If this is the browser process, delete the old log file. Else, append to + // it. + settings.delete_old = process_type.empty() + ? logging::DELETE_OLD_LOG_FILE + : logging::APPEND_TO_OLD_LOG_FILE; + } + +#if defined(OS_ANDROID) // Browser process logs are recorded for attaching with crash dumps. if (process_type.empty()) { base::FilePath log_file; base::PathService::Get(FILE_CAST_ANDROID_LOG, &log_file); settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG | logging::LOG_TO_STDERR; - settings.log_file_path = log_file.value().c_str(); + log_path_as_string = log_file.value(); + settings.log_file_path = log_path_as_string.c_str(); settings.delete_old = logging::DELETE_OLD_LOG_FILE; } #endif // defined(OS_ANDROID) @@ -132,6 +153,10 @@ } } #endif // defined(OS_ANDROID) + + if (settings.logging_dest & logging::LOG_TO_FILE) { + LOG(INFO) << "Logging to file: " << settings.log_file_path; + } return false; }
diff --git a/chromecast/cast_core/BUILD.gn b/chromecast/cast_core/BUILD.gn index 92e1798..f4d48d1 100644 --- a/chromecast/cast_core/BUILD.gn +++ b/chromecast/cast_core/BUILD.gn
@@ -68,6 +68,7 @@ public_deps = [ "//base", + "//chromecast/common", "//chromecast/common/mojom", "//mojo/public/cpp/bindings", "//third_party/cast_core/public/src/proto/v2:url_rewrite_proto", @@ -250,6 +251,7 @@ "//base", "//chromecast/browser", "//chromecast/common:cors_exempt_headers", + "//content/public/common", "//media", ]
diff --git a/chromecast/cast_core/cast_runtime_content_browser_client.cc b/chromecast/cast_core/cast_runtime_content_browser_client.cc index c30db0ce..c1ebb4d8 100644 --- a/chromecast/cast_core/cast_runtime_content_browser_client.cc +++ b/chromecast/cast_core/cast_runtime_content_browser_client.cc
@@ -9,6 +9,7 @@ #include "chromecast/cast_core/cast_core_switches.h" #include "chromecast/cast_core/cast_runtime_service.h" #include "chromecast/common/cors_exempt_headers.h" +#include "content/public/common/content_switches.h" #include "media/base/cdm_factory.h" #include "third_party/blink/public/common/web_preferences/web_preferences.h" @@ -59,6 +60,21 @@ return nullptr; } +void CastRuntimeContentBrowserClient::AppendExtraCommandLineSwitches( + base::CommandLine* command_line, + int child_process_id) { + CastContentBrowserClient::AppendExtraCommandLineSwitches(command_line, + child_process_id); + + base::CommandLine* browser_command_line = + base::CommandLine::ForCurrentProcess(); + if (browser_command_line->HasSwitch(switches::kLogFile) && + !command_line->HasSwitch(switches::kLogFile)) { + const char* path[1] = {switches::kLogFile}; + command_line->CopySwitchesFrom(*browser_command_line, path, size_t{1}); + } +} + bool CastRuntimeContentBrowserClient::IsWebUIAllowedToMakeNetworkRequests( const url::Origin& origin) { return origin.host() == kCastWebUIHomeHost;
diff --git a/chromecast/cast_core/cast_runtime_content_browser_client.h b/chromecast/cast_core/cast_runtime_content_browser_client.h index 1ebbf6c..1b3678e 100644 --- a/chromecast/cast_core/cast_runtime_content_browser_client.h +++ b/chromecast/cast_core/cast_runtime_content_browser_client.h
@@ -33,6 +33,8 @@ ::media::mojom::FrameInterfaceFactory* frame_interfaces) override; // This function is used to allow/disallow WebUIs to make network requests. bool IsWebUIAllowedToMakeNetworkRequests(const url::Origin& origin) override; + void AppendExtraCommandLineSwitches(base::CommandLine* command_line, + int child_process_id) override; }; } // namespace chromecast
diff --git a/chromecast/cast_core/cast_runtime_service.cc b/chromecast/cast_core/cast_runtime_service.cc index cec7bba..e3eb6751 100644 --- a/chromecast/cast_core/cast_runtime_service.cc +++ b/chromecast/cast_core/cast_runtime_service.cc
@@ -23,6 +23,10 @@ return nullptr; } +CastWebService* CastRuntimeService::GetCastWebService() { + return nullptr; +} + void CastRuntimeService::InitializeInternal() {} void CastRuntimeService::FinalizeInternal() {}
diff --git a/chromecast/cast_core/cast_runtime_service.h b/chromecast/cast_core/cast_runtime_service.h index 4fee2b9..9541318 100644 --- a/chromecast/cast_core/cast_runtime_service.h +++ b/chromecast/cast_core/cast_runtime_service.h
@@ -31,6 +31,7 @@ class CastWindowManager; class WebCryptoServer; +class CastWebService; namespace media { class MediaPipelineBackendManager; @@ -66,6 +67,9 @@ virtual WebCryptoServer* GetWebCryptoServer(); virtual receiver::MediaManager* GetMediaManager(); + // Returns a pointer to CastWebService object with lifespan + // equal to CastRuntimeService main object. + virtual CastWebService* GetCastWebService(); // CastService overrides. void InitializeInternal() override;
diff --git a/chromecast/cast_core/cast_runtime_service_impl.cc b/chromecast/cast_core/cast_runtime_service_impl.cc index cee2d3c..80577ae 100644 --- a/chromecast/cast_core/cast_runtime_service_impl.cc +++ b/chromecast/cast_core/cast_runtime_service_impl.cc
@@ -63,4 +63,8 @@ return app_dispatcher_.GetCastMediaServiceGrpcEndpoint(); } +CastWebService* CastRuntimeServiceImpl::GetCastWebService() { + return app_dispatcher_.GetCastWebService(); +} + } // namespace chromecast
diff --git a/chromecast/cast_core/cast_runtime_service_impl.h b/chromecast/cast_core/cast_runtime_service_impl.h index 7b2e731..1cdb7610 100644 --- a/chromecast/cast_core/cast_runtime_service_impl.h +++ b/chromecast/cast_core/cast_runtime_service_impl.h
@@ -37,6 +37,7 @@ void StartInternal() override; void StopInternal() override; const std::string& GetAudioChannelEndpoint() override; + CastWebService* GetCastWebService() override; protected: // CastRuntimeMetricsRecorder::EventBuilderFactory overrides.
diff --git a/chromecast/cast_core/demo_platform_service.cc b/chromecast/cast_core/demo_platform_service.cc index 12b36249..28b66ca4 100644 --- a/chromecast/cast_core/demo_platform_service.cc +++ b/chromecast/cast_core/demo_platform_service.cc
@@ -172,6 +172,8 @@ #if !defined(__arm__) runtime_cmdline.AppendSwitchASCII("--ozone-platform", "x11"); #endif + runtime_cmdline.AppendSwitchASCII("--log-file", + "./runtime_logs/" + runtime_id_ + ".log"); runtime_cmdline.AppendSwitchASCII("--vmodule", "*runtime_*=2"); runtime_cmdline.AppendSwitchASCII("--cast-core-runtime-id", runtime_id_); runtime_cmdline.AppendSwitchASCII("--runtime-service-path",
diff --git a/chromecast/cast_core/runtime_application_base.cc b/chromecast/cast_core/runtime_application_base.cc index 8f6d425..da0b44f8 100644 --- a/chromecast/cast_core/runtime_application_base.cc +++ b/chromecast/cast_core/runtime_application_base.cc
@@ -100,6 +100,13 @@ GURL cast_application_url = ProcessWebView(core_app_stub_.get(), cast_web_view_->cast_web_contents()); + const std::vector<int32_t> feature_permissions; + const std::vector<std::string> additional_feature_permission_origins; + // TODO(b/203580094): Currently we assume the app is not audio only. + cast_web_view_->cast_web_contents()->SetAppProperties( + app_id(), cast_session_id(), false /*is_audio_app*/, cast_application_url, + false /*enforce_feature_permissions*/, feature_permissions, + additional_feature_permission_origins); cast_web_view_->cast_web_contents()->LoadUrl(cast_application_url); cast_web_view_->window()->GrantScreenAccess(); cast_web_view_->window()->CreateWindow( @@ -186,6 +193,10 @@ cast_web_view_->cast_web_contents()->ClosePage(); } + if (web_service_) { + web_service_->OnSessionDestroyed(cast_session_id()); + } + GrpcServer::Stop(); set_cast_session_id(std::string()); }
diff --git a/chromecast/cast_core/runtime_application_base.h b/chromecast/cast_core/runtime_application_base.h index 56dde1b..023bc7e1 100644 --- a/chromecast/cast_core/runtime_application_base.h +++ b/chromecast/cast_core/runtime_application_base.h
@@ -67,6 +67,9 @@ return task_runner_; } + // Returns a pointer to CastWebService. + CastWebService* cast_web_service() const { return web_service_; } + // RuntimeApplication implementation: bool Load(const cast::runtime::LoadApplicationRequest& request) override; bool Launch(const cast::runtime::LaunchApplicationRequest& request) override;
diff --git a/chromecast/cast_core/runtime_application_dispatcher.h b/chromecast/cast_core/runtime_application_dispatcher.h index 8ae067ee..c81ec7b 100644 --- a/chromecast/cast_core/runtime_application_dispatcher.h +++ b/chromecast/cast_core/runtime_application_dispatcher.h
@@ -68,6 +68,7 @@ GrpcMethod* callback) override; const std::string& GetCastMediaServiceGrpcEndpoint() const; + CastWebService* GetCastWebService() const { return web_service_.get(); } private: // This class handles asynchronously calling MetricsRecorderService->Record
diff --git a/chromecast/cast_core/url_rewrite_rules_adapter.cc b/chromecast/cast_core/url_rewrite_rules_adapter.cc index dfdbf3f..2b6aef3 100644 --- a/chromecast/cast_core/url_rewrite_rules_adapter.cc +++ b/chromecast/cast_core/url_rewrite_rules_adapter.cc
@@ -450,6 +450,15 @@ } // namespace +MojoIdentificationSettings::MojoIdentificationSettings( + const cast::v2::UrlRequestRewriteRules& rules) { + auto translated_rules = TranslateRewriteRules(rules); + substitutable_params = ConvertParamsToMojo(translated_rules); + application_settings = ConvertAppSettingsToMojo(translated_rules); + device_settings = ConvertDeviceSettingsToMojo(translated_rules); +} +MojoIdentificationSettings::~MojoIdentificationSettings() = default; + ParamRule::ParamRule() = default; ParamRule::~ParamRule() = default; ParamRule::ParamRule(ParamRule&&) = default;
diff --git a/chromecast/cast_core/url_rewrite_rules_adapter.h b/chromecast/cast_core/url_rewrite_rules_adapter.h index 9b560fe5..8ea0e25b 100644 --- a/chromecast/cast_core/url_rewrite_rules_adapter.h +++ b/chromecast/cast_core/url_rewrite_rules_adapter.h
@@ -12,6 +12,7 @@ #include "base/containers/flat_map.h" #include "base/containers/flat_set.h" #include "base/memory/weak_ptr.h" +#include "chromecast/common/identification_settings_manager.h" #include "chromecast/common/mojom/identification_settings.mojom.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "mojo/public/cpp/bindings/receiver.h" @@ -62,6 +63,18 @@ std::vector<ParamRule> params; }; +// This represents all-in-one rewrite rules translated into Mojo format in +// order to be passed to IdentificationSettingsManager. +struct MojoIdentificationSettings { + MojoIdentificationSettings(const cast::v2::UrlRequestRewriteRules& rules); + MojoIdentificationSettings() = delete; + ~MojoIdentificationSettings(); + + std::vector<mojom::SubstitutableParameterPtr> substitutable_params; + mojom::AppSettingsPtr application_settings; + mojom::DeviceSettingsPtr device_settings; +}; + // This class is responsible for taking URL rewrite rules as specified by the // gRPC proto and translating them to the IdentificationSettingsManager API. // Because the gRPC API is much more general, there is a lot of potential for
diff --git a/chromecast/cast_core/web_runtime_application.cc b/chromecast/cast_core/web_runtime_application.cc index fe2685c4..452e1a7 100644 --- a/chromecast/cast_core/web_runtime_application.cc +++ b/chromecast/cast_core/web_runtime_application.cc
@@ -4,6 +4,7 @@ #include "chromecast/cast_core/web_runtime_application.h" +#include "chromecast/browser/cast_web_service.h" #include "chromecast/cast_core/bindings_manager_web_runtime.h" #include "chromecast/cast_core/grpc_webui_controller_factory.h" #include "chromecast/cast_core/url_rewrite_rules_adapter.h" @@ -34,6 +35,17 @@ std::make_unique<UrlRewriteRulesAdapter>(request.url_rewrite_rules()); app_url_ = request.application_config().cast_web_app_config().url(); + auto* web_service = cast_web_service(); + if (web_service) { + MojoIdentificationSettings params(request.url_rewrite_rules()); + web_service->CreateSessionWithSubstitutions( + cast_session_id(), std::move(params.substitutable_params)); + web_service->UpdateAppSettingsForSession( + cast_session_id(), std::move(params.application_settings)); + web_service->UpdateDeviceSettingsForSession( + cast_session_id(), std::move(params.device_settings)); + } + return true; }
diff --git a/chromeos/components/projector_app/projector_message_handler.cc b/chromeos/components/projector_app/projector_message_handler.cc index 706e910..9183f61 100644 --- a/chromeos/components/projector_app/projector_message_handler.cc +++ b/chromeos/components/projector_app/projector_message_handler.cc
@@ -74,30 +74,30 @@ } void ProjectorMessageHandler::RegisterMessages() { - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "getAccounts", base::BindRepeating(&ProjectorMessageHandler::GetAccounts, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "canStartProjectorSession", base::BindRepeating(&ProjectorMessageHandler::CanStartProjectorSession, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "startProjectorSession", base::BindRepeating(&ProjectorMessageHandler::StartProjectorSession, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "getOAuthTokenForAccount", base::BindRepeating(&ProjectorMessageHandler::GetOAuthTokenForAccount, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "onError", base::BindRepeating(&ProjectorMessageHandler::OnError, base::Unretained(this))); - web_ui()->RegisterDeprecatedMessageCallback( + web_ui()->RegisterMessageCallback( "sendXhr", base::BindRepeating(&ProjectorMessageHandler::SendXhr, base::Unretained(this))); } @@ -111,11 +111,11 @@ base::Value(can_start)); } -void ProjectorMessageHandler::GetAccounts(const base::ListValue* args) { +void ProjectorMessageHandler::GetAccounts(base::Value::ConstListView args) { AllowJavascript(); // Check that there is only one argument which is the callback id. - DCHECK_EQ(args->GetList().size(), 1u); + DCHECK_EQ(args.size(), 1u); auto* controller = ash::ProjectorController::Get(); DCHECK(controller); @@ -135,31 +135,30 @@ response.push_back(std::move(account_info)); } - ResolveJavascriptCallback(args->GetList()[0], - base::Value(std::move(response))); + ResolveJavascriptCallback(args[0], base::Value(std::move(response))); } void ProjectorMessageHandler::CanStartProjectorSession( - const base::ListValue* args) { + base::Value::ConstListView args) { AllowJavascript(); // Check that there is only one argument which is the callback id. - DCHECK_EQ(args->GetList().size(), 1u); + DCHECK_EQ(args.size(), 1u); ResolveJavascriptCallback( - args->GetList()[0], + args[0], base::Value(ash::ProjectorController::Get()->CanStartNewSession())); } void ProjectorMessageHandler::StartProjectorSession( - const base::ListValue* args) { + base::Value::ConstListView args) { AllowJavascript(); // There are two arguments. The first is the callback and the second is a list // containing the account which we need to start the recording with. - DCHECK_EQ(args->GetList().size(), 2u); + DCHECK_EQ(args.size(), 2u); - const auto& func_args = args->GetList()[1]; + const auto& func_args = args[1]; DCHECK(func_args.is_list()); // The first entry is the drive directory to save the screen cast to. @@ -171,25 +170,25 @@ // and folder. auto* controller = ash::ProjectorController::Get(); if (!controller->CanStartNewSession()) { - ResolveJavascriptCallback(args->GetList()[0], base::Value(false)); + ResolveJavascriptCallback(args[0], base::Value(false)); return; } controller->StartProjectorSession(func_args.GetList()[0].GetString()); - ResolveJavascriptCallback(args->GetList()[0], base::Value(true)); + ResolveJavascriptCallback(args[0], base::Value(true)); } void ProjectorMessageHandler::GetOAuthTokenForAccount( - const base::ListValue* args) { + const base::Value::ConstListView args) { // Two arguments. The first is callback id, and the second is the list // containing the account for which to fetch the oauth token. - DCHECK_EQ(args->GetList().size(), 2u); + DCHECK_EQ(args.size(), 2u); - const auto& requested_account = args->GetList()[1]; + const auto& requested_account = args[1]; DCHECK(requested_account.is_list()); DCHECK_EQ(requested_account.GetList().size(), 1u); - auto& oauth_token_fetch_callback = args->GetList()[0].GetString(); + auto& oauth_token_fetch_callback = args[0].GetString(); const std::string& email = requested_account.GetList()[0].GetString(); oauth_token_fetcher_.GetAccessTokenFor( @@ -198,13 +197,13 @@ GetWeakPtr(), oauth_token_fetch_callback)); } -void ProjectorMessageHandler::SendXhr(const base::ListValue* args) { +void ProjectorMessageHandler::SendXhr(const base::Value::ConstListView args) { // Two arguments. The first is callback id, and the second is the list // containing function arguments for making the request. - DCHECK_EQ(args->GetList().size(), 2u); - const auto& callback_id = args->GetList()[0].GetString(); + DCHECK_EQ(args.size(), 2u); + const auto& callback_id = args[0].GetString(); - const auto& func_args = args->GetList()[1].GetList(); + const auto& func_args = args[1].GetList(); // Four function arguments: // 1. The request URL. // 2. The request method, for example: GET @@ -226,7 +225,7 @@ GetWeakPtr(), callback_id)); } -void ProjectorMessageHandler::OnError(const base::ListValue* args) { +void ProjectorMessageHandler::OnError(const base::Value::ConstListView args) { // TODO(b/195113693): Get the SWA dialog associated with this WebUI and close // it. }
diff --git a/chromeos/components/projector_app/projector_message_handler.h b/chromeos/components/projector_app/projector_message_handler.h index dfd3256b..c51148ee 100644 --- a/chromeos/components/projector_app/projector_message_handler.h +++ b/chromeos/components/projector_app/projector_message_handler.h
@@ -56,25 +56,25 @@ // Requested by the Projector SWA to list the available accounts (primary and // secondary accounts) in the current session. The list of accounts will be // used in the account picker in the SWA. - void GetAccounts(const base::ListValue* args); + void GetAccounts(const base::Value::ConstListView args); // Requested by the Projector SWA to check if it is possible to start a new // Projector session. - void CanStartProjectorSession(const base::ListValue* args); + void CanStartProjectorSession(const base::Value::ConstListView args); // Requested by the Projector SWA to start a new Projector session if it is // possible. - void StartProjectorSession(const base::ListValue* args); + void StartProjectorSession(const base::Value::ConstListView args); // Requested by the Projector SWA to get access to the OAuth token for the // account email provided in the `args`. - void GetOAuthTokenForAccount(const base::ListValue* args); + void GetOAuthTokenForAccount(const base::Value::ConstListView args); // Requested by the Projector SWA to send XHR request. - void SendXhr(const base::ListValue* args); + void SendXhr(const base::Value::ConstListView args); // Called by the Projector SWA when an error occurred. - void OnError(const base::ListValue* args); + void OnError(const base::Value::ConstListView args); // Called when OAuth token fetch request is completed by // ProjectorOAuthTokenFetcher. Resolves the javascript promise created by
diff --git a/components/BUILD.gn b/components/BUILD.gn index 1017c81..690cbc80 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -322,6 +322,8 @@ "//components/safe_browsing/content/browser/web_ui:unit_tests", "//components/safe_browsing/core/browser:token_fetcher_unit_tests", "//components/safe_browsing/core/browser/realtime:unit_tests", + "//components/safe_browsing/core/common:unit_tests", + "//components/safe_browsing/core/tailored_security_service:unit_tests", "//components/safety_check:unit_tests", "//components/security_interstitials/content:unit_tests", "//components/security_state/content:unit_tests",
diff --git a/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillProvider.java b/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillProvider.java index 90f2555..f09e696 100644 --- a/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillProvider.java +++ b/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillProvider.java
@@ -816,9 +816,12 @@ @CalledByNative private void onQueryDone(boolean success) { - mRequest.onQueryDone(success); + if (mRequest != null) { + mRequest.onQueryDone(success); + } mAutofillUMA.onServerTypeAvailable( - success ? mRequest.mFormData : null, /*afterSessionStarted*/ true); + (success && mRequest != null) ? mRequest.mFormData : null, + /*afterSessionStarted*/ true); mAutofillManager.onQueryDone(success); }
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java index 2f289db..9947fd90 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java
@@ -11,8 +11,10 @@ import static org.chromium.components.content_settings.PrefNames.NOTIFICATIONS_VIBRATE_ENABLED; import android.content.Context; +import android.content.Intent; import android.os.Build; import android.os.Bundle; +import android.provider.Settings; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.style.ForegroundColorSpan; @@ -454,6 +456,20 @@ SettingsNavigationSource.EXTRA_KEY, SettingsNavigationSource.OTHER); website_pref.getExtras().putInt( SettingsNavigationSource.EXTRA_KEY, navigationSource); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && mCategory.showSites(SiteSettingsCategory.Type.NOTIFICATIONS)) { + // In Android O+, users can manage Notification channels through App Info. If this + // is the case we send the user directly to Android Settings to modify the + // Notification exception. + String channelId = getSiteSettingsDelegate().getChannelIdForOrigin( + website_pref.site().getAddress().getOrigin()); + Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS); + intent.putExtra(Settings.EXTRA_CHANNEL_ID, channelId); + intent.putExtra( + Settings.EXTRA_APP_PACKAGE, preference.getContext().getPackageName()); + startActivityForResult( + intent, SingleWebsiteSettings.REQUEST_CODE_NOTIFICATION_CHANNEL_SETTINGS); + } else { buildPreferenceDialog(website_pref.site()).show(); }
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java index 13754db..5d67fdc66 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
@@ -94,6 +94,8 @@ // Buttons: public static final String PREF_RESET_SITE = "reset_site_button"; + public static final int REQUEST_CODE_NOTIFICATION_CHANNEL_SETTINGS = 1; + private static boolean arrayContains(int[] array, int element) { for (int e : array) { if (e == element) { @@ -174,8 +176,6 @@ // The callback to be run after this site is reset. private Observer mWebsiteSettingsObserver; - private static final int REQUEST_CODE_NOTIFICATION_CHANNEL_SETTINGS = 1; - private final SiteDataCleaner mSiteDataCleaner = new SiteDataCleaner(); // The website this page is displaying details about.
diff --git a/components/client_hints/browser/DEPS b/components/client_hints/browser/DEPS index df9f6ca..e821239 100644 --- a/components/client_hints/browser/DEPS +++ b/components/client_hints/browser/DEPS
@@ -4,4 +4,5 @@ "+content/public/browser", "+third_party/blink/public/common/user_agent", "+services/network/public/cpp/is_potentially_trustworthy.h", + "+services/network/public/cpp/client_hints.h" ]
diff --git a/components/client_hints/browser/client_hints.cc b/components/client_hints/browser/client_hints.cc index 09607156..0ba33bc 100644 --- a/components/client_hints/browser/client_hints.cc +++ b/components/client_hints/browser/client_hints.cc
@@ -8,18 +8,77 @@ #include "components/client_hints/browser/client_hints.h" +#include "base/command_line.h" +#include "base/json/json_reader.h" #include "base/metrics/histogram_macros.h" #include "base/time/time.h" #include "components/client_hints/common/client_hints.h" +#include "components/client_hints/common/switches.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings_types.h" #include "components/content_settings/core/common/content_settings_utils.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" +#include "services/network/public/cpp/client_hints.h" #include "services/network/public/cpp/is_potentially_trustworthy.h" namespace client_hints { +namespace { +base::flat_map<url::Origin, std::vector<network::mojom::WebClientHintsType>> +ParseInitializeClientHintsStroage() { + auto results = + base::flat_map<url::Origin, + std::vector<network::mojom::WebClientHintsType>>(); + + std::string raw_client_hint_json = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kInitializeClientHintsStorage); + + absl::optional<base::Value> maybe_value = + base::JSONReader::Read(raw_client_hint_json); + + if (!maybe_value || !maybe_value->is_dict()) { + LOG(WARNING) + << "The 'initialize-client-hints-storage' switch value could not be " + << "properly parsed."; + return {}; + } + + for (auto entry : maybe_value->DictItems()) { + url::Origin origin = url::Origin::Create(GURL(entry.first)); + if (origin.opaque() || origin.scheme() != url::kHttpsScheme) { + LOG(WARNING) + << "The url '" << entry.first + << "' cannot be associated to client hints and will be ignored."; + continue; + } + + if (!entry.second.is_string()) { + LOG(WARNING) << "The value associated with the origin \"" + << origin.Serialize() << "\" could not be recognized as a " + << "valid string and will be ignored."; + continue; + } + + absl::optional<std::vector<network::mojom::WebClientHintsType>> + maybe_parsed_accept_ch = + network::ParseClientHintsHeader(entry.second.GetString()); + + if (!maybe_parsed_accept_ch) { + LOG(WARNING) << "Could not parse the following client hint token list: " + << entry.second.GetString(); + continue; + } + + results[origin] = maybe_parsed_accept_ch.value(); + } + + return results; +} + +} // namespace + ClientHints::ClientHints( content::BrowserContext* context, network::NetworkQualityTracker* network_quality_tracker, @@ -35,6 +94,17 @@ DCHECK(network_quality_tracker_); DCHECK(settings_map_); DCHECK(cookie_settings_); + + if (!context->IsOffTheRecord() && + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kInitializeClientHintsStorage)) { + auto command_line_hints = ParseInitializeClientHintsStroage(); + + for (const auto& origin_hints_pair : command_line_hints) { + PersistClientHints(origin_hints_pair.first, origin_hints_pair.second, + base::Days(1000000)); + } + } } ClientHints::~ClientHints() = default;
diff --git a/components/client_hints/common/BUILD.gn b/components/client_hints/common/BUILD.gn index 5dbb50d..92d8b6c 100644 --- a/components/client_hints/common/BUILD.gn +++ b/components/client_hints/common/BUILD.gn
@@ -6,6 +6,8 @@ sources = [ "client_hints.cc", "client_hints.h", + "switches.cc", + "switches.h", ] deps = [ "//components/content_settings/core/common",
diff --git a/components/client_hints/common/switches.cc b/components/client_hints/common/switches.cc new file mode 100644 index 0000000..ed666f8 --- /dev/null +++ b/components/client_hints/common/switches.cc
@@ -0,0 +1,23 @@ +// Copyright 2021 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/client_hints/common/switches.h" + +namespace client_hints { +namespace switches { + +// Pre-load the client hint storage. Takes a JSON dict, with each key being an +// origin (RFC 6454 Section 6.2) and each value a comma-separated list of client +// hint tokens (RFC 8942 Section 3.1, client-hints-infrastructure Section 7.1). +// +// Each origin/token-list entry will be parsed and persisted to the Client Hints +// storage as though the token-list had come through an Accept-CH response +// header from a navigation from the origin. +// +// The initialization will only apply to non-OffTheRecord profiles, meaning +// incognito or guest profiles will not have the storage applied. +const char kInitializeClientHintsStorage[] = "initialize-client-hints-storage"; + +} // namespace switches +} // namespace client_hints \ No newline at end of file
diff --git a/components/client_hints/common/switches.h b/components/client_hints/common/switches.h new file mode 100644 index 0000000..5bcd49e5 --- /dev/null +++ b/components/client_hints/common/switches.h
@@ -0,0 +1,16 @@ +// Copyright 2021 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_CLIENT_HINTS_COMMON_SWITCHES_H_ +#define COMPONENTS_CLIENT_HINTS_COMMON_SWITCHES_H_ + +namespace client_hints { +namespace switches { + +extern const char kInitializeClientHintsStorage[]; + +} // namespace switches +} // namespace client_hints + +#endif // COMPONENTS_CLIENT_HINTS_COMMON_SWITCHES_H_ \ No newline at end of file
diff --git a/components/desks_storage/core/local_desk_data_manager.h b/components/desks_storage/core/local_desk_data_manager.h index 0daebc3c5..d7ac601 100644 --- a/components/desks_storage/core/local_desk_data_manager.h +++ b/components/desks_storage/core/local_desk_data_manager.h
@@ -16,9 +16,9 @@ #include "components/desks_storage/core/desk_model.h" namespace ash { -class DesksTemplatesTest; class DeskTemplate; -} +class OverviewTestBase; +} // namespace ash namespace desks_storage { // The LocalDeskDataManager is the local storage implementation of @@ -66,7 +66,7 @@ bool IsSyncing() const override; private: - friend class ash::DesksTemplatesTest; + friend class ash::OverviewTestBase; // Loads desk templates from |local_path_| into cache if the cache is not // loaded yet.
diff --git a/components/download/internal/background_service/ios/background_download_task_helper_unittest.mm b/components/download/internal/background_service/ios/background_download_task_helper_unittest.mm index 4d80ca4..3bd30ce 100644 --- a/components/download/internal/background_service/ios/background_download_task_helper_unittest.mm +++ b/components/download/internal/background_service/ios/background_download_task_helper_unittest.mm
@@ -86,7 +86,10 @@ } // Verifies non success http code is treated as error. -TEST_F(BackgroundDownloadTaskHelperTest, DownloadErrorNonSuccessHttpCode) { +// TODO(crbug.com/1261881):Disabled test because it fails multiple builders. +// Re-enable it when fixed. +TEST_F(BackgroundDownloadTaskHelperTest, + DISABLED_DownloadErrorNonSuccessHttpCode) { base::RunLoop loop; Download("/notfound", base::BindLambdaForTesting([&](bool success,
diff --git a/components/exo/seat.cc b/components/exo/seat.cc index 690277a8..51101d6 100644 --- a/components/exo/seat.cc +++ b/components/exo/seat.cc
@@ -75,7 +75,7 @@ } void Seat::SetFocusChangedCallback(FocusChangedCallback callback) { - focus_changed_callback_ = std::move(callback); + focus_changed_callbacks_.push_back(std::move(callback)); OnWindowFocused(WMHelper::GetInstance()->GetActiveWindow(), nullptr); } @@ -289,9 +289,9 @@ Surface* const lost_focus_surface = GetTargetSurfaceForKeyboardFocus(lost_focus); - if (!focus_changed_callback_.is_null()) { - focus_changed_callback_.Run(gaining_focus_surface, lost_focus_surface, - !!gained_focus); + for (auto& focus_changed_callback : focus_changed_callbacks_) { + focus_changed_callback.Run(gaining_focus_surface, lost_focus_surface, + !!gained_focus); } for (auto& observer_list : priority_observer_list_) { for (auto& observer : observer_list)
diff --git a/components/exo/seat.h b/components/exo/seat.h index 79d369a..b93760e 100644 --- a/components/exo/seat.h +++ b/components/exo/seat.h
@@ -222,7 +222,7 @@ gfx::PointF last_pointer_location_; - FocusChangedCallback focus_changed_callback_; + std::vector<FocusChangedCallback> focus_changed_callbacks_; bool was_shutdown_ = false;
diff --git a/components/exo/seat_unittest.cc b/components/exo/seat_unittest.cc index 1cc4570..53edf2d 100644 --- a/components/exo/seat_unittest.cc +++ b/components/exo/seat_unittest.cc
@@ -603,5 +603,25 @@ EXPECT_FALSE(seat.get_drag_drop_operation_for_testing()); } +TEST_F(SeatTest, CanSetFocusChangedCallbackMoreThanOnce) { + TestSeat seat; + bool cb_1_called = false; + bool cb_2_called = false; + + seat.SetFocusChangedCallback(base::BindLambdaForTesting( + [&](Surface* a, Surface* b, bool gained_or_lost) { + cb_1_called = true; + })); + seat.SetFocusChangedCallback(base::BindLambdaForTesting( + [&](Surface* a, Surface* b, bool gained_or_lost) { + cb_2_called = true; + })); + + seat.OnWindowFocused(nullptr, nullptr); + + EXPECT_TRUE(cb_1_called); + EXPECT_TRUE(cb_2_called); +} + } // namespace } // namespace exo
diff --git a/components/flags_strings.grdp b/components/flags_strings.grdp index 6ba855d..88a5c541 100644 --- a/components/flags_strings.grdp +++ b/components/flags_strings.grdp
@@ -49,6 +49,26 @@ <message name="IDS_FLAGS_UI_RELAUNCH" translateable="false" desc="Label for button that restarts chrome os."> Restart </message> + <message name="IDS_FLAGS_UI_OS_FLAGS_TEXT1" translateable="false" desc="Begin label text which directs a user to a second dialog in ChromeOS showing OS specific flags - enclosing url link."> + Looking for browser flags? Visit + </message> + <message name="IDS_FLAGS_UI_OS_FLAGS_TEXT2" translateable="false" desc="End label text which directs a user to a second dialog in ChromeOS showing OS specific flags - enclosing url link."> + . + </message> + <message name="IDS_FLAGS_UI_OS_FLAGS_LINK" translateable="false" desc="Label for button that will call a new window which allows to change ChromeOS system flags."> + chrome://flags + </message> + </if> + <if expr="lacros"> + <message name="IDS_FLAGS_UI_OS_FLAGS_TEXT1" translateable="false" desc="Begin label text which directs a user to a second dialog in ChromeOS showing OS specific flags - enclosing url link."> + Looking for the ChromeOS flags? Visit + </message> + <message name="IDS_FLAGS_UI_OS_FLAGS_TEXT2" translateable="false" desc="End label text which directs a user to a second dialog in ChromeOS showing OS specific flags - enclosing url link."> + . + </message> + <message name="IDS_FLAGS_UI_OS_FLAGS_LINK" translateable="false" desc="Label for button that will call a new window which allows to change ChromeOS system flags."> + os://flags + </message> </if> <if expr="not chromeos"> <message name="IDS_FLAGS_UI_RELAUNCH" translateable="false" desc="Label for button that relaunches chrome."> @@ -103,6 +123,26 @@ <message name="IDS_DEPRECATED_FEATURES_RELAUNCH" desc="Label for button that restarts chrome os."> Restart </message> + <message name="IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_TEXT1" desc="Begin label text which directs a user to a second dialog in ChromeOS showing OS specific flags - enclosing url link."> + Looking for browser flags? Visit + </message> + <message name="IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_TEXT2" desc="End label text which directs a user to a second dialog in ChromeOS showing OS specific flags - enclosing url link."> + . + </message> + <message name="IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_LINK" desc="Label for button that will call a new window which allows to change ChromeOS system flags."> + chrome://flags + </message> + </if> + <if expr="lacros"> + <message name="IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_TEXT1" desc="Begin label text which directs a user to a second dialog in ChromeOS showing OS specific flags - enclosing url link."> + Looking for the ChromeOS flags? Visit + </message> + <message name="IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_TEXT2" desc="End label text which directs a user to a second dialog in ChromeOS showing OS specific flags - enclosing url link."> + . + </message> + <message name="IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_LINK" desc="Label for button that will call a new window which allows to change ChromeOS system flags."> + os://flags + </message> </if> <if expr="not chromeos"> <message name="IDS_DEPRECATED_FEATURES_RELAUNCH" desc="Label for button that relaunches chrome.">
diff --git a/components/flags_strings_grdp/IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_LINK.png.sha1 b/components/flags_strings_grdp/IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_LINK.png.sha1 new file mode 100644 index 0000000..efb6fe4d --- /dev/null +++ b/components/flags_strings_grdp/IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_LINK.png.sha1
@@ -0,0 +1 @@ +43f29eefc7c45a2e38dcfe6b0e317932bd4e9f59 \ No newline at end of file
diff --git a/components/flags_strings_grdp/IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_TEXT1.png.sha1 b/components/flags_strings_grdp/IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_TEXT1.png.sha1 new file mode 100644 index 0000000..efb6fe4d --- /dev/null +++ b/components/flags_strings_grdp/IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_TEXT1.png.sha1
@@ -0,0 +1 @@ +43f29eefc7c45a2e38dcfe6b0e317932bd4e9f59 \ No newline at end of file
diff --git a/components/flags_strings_grdp/IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_TEXT2.png.sha1 b/components/flags_strings_grdp/IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_TEXT2.png.sha1 new file mode 100644 index 0000000..efb6fe4d --- /dev/null +++ b/components/flags_strings_grdp/IDS_DEPRECATED_FLAGS_UI_OS_FLAGS_TEXT2.png.sha1
@@ -0,0 +1 @@ +43f29eefc7c45a2e38dcfe6b0e317932bd4e9f59 \ No newline at end of file
diff --git a/components/flags_ui/flags_ui_constants.cc b/components/flags_ui/flags_ui_constants.cc index 8e51c44..e7af9fa8 100644 --- a/components/flags_ui/flags_ui_constants.cc +++ b/components/flags_ui/flags_ui_constants.cc
@@ -9,12 +9,18 @@ // Resource paths. const char kFlagsJS[] = "flags.js"; const char kFlagsCSS[] = "flags.css"; +#if defined(OS_CHROMEOS) +const char kFlagsSVG[] = "os_flags_app_icon.svg"; +#endif // Message handlers. const char kEnableExperimentalFeature[] = "enableExperimentalFeature"; const char kRequestExperimentalFeatures[] = "requestExperimentalFeatures"; const char kSetOriginListFlag[] = "setOriginListFlag"; const char kResetAllFlags[] = "resetAllFlags"; +#if defined(OS_CHROMEOS) +const char kCrosUrlFlagsRedirect[] = "crosUrlFlagsRedirect"; +#endif const char kRestartBrowser[] = "restartBrowser"; // Other values.
diff --git a/components/flags_ui/flags_ui_constants.h b/components/flags_ui/flags_ui_constants.h index 76e2397c..a38ca6c 100644 --- a/components/flags_ui/flags_ui_constants.h +++ b/components/flags_ui/flags_ui_constants.h
@@ -11,6 +11,9 @@ // Must match the resource file names. extern const char kFlagsJS[]; extern const char kFlagsCSS[]; +#if defined(OS_CHROMEOS) +extern const char kFlagsSVG[]; +#endif // Message handlers. // Must match the constants used in the resource files. @@ -18,6 +21,9 @@ extern const char kRequestExperimentalFeatures[]; extern const char kSetOriginListFlag[]; extern const char kResetAllFlags[]; +#if defined(OS_CHROMEOS) +extern const char kCrosUrlFlagsRedirect[]; +#endif extern const char kRestartBrowser[]; // Other values.
diff --git a/components/flags_ui/resources/flags.css b/components/flags_ui/resources/flags.css index 2814095..43dfef4 100644 --- a/components/flags_ui/resources/flags.css +++ b/components/flags_ui/resources/flags.css
@@ -541,6 +541,37 @@ text-align: right; /* csschecker-disable-line left-right */ } +.os-link-container { + align-items: center; + border: 1px solid rgb(232, 234, 237); + border-radius: 4px; + display: flex; + font-size: 14px; + line-height: 20px; + margin-bottom: 28px; + padding: 12px; +} + +@media (prefers-color-scheme: dark) { + .os-link-container { + border: 1px solid rgb(18, 21, 23); + } +} + +.os-link-icon { + background-image: url(chrome://flags/os_flags_app_icon.svg); + background-size: 16px 16px; + height: 16px; + margin-inline-end: 16px; + width: 16px; +} + +#os-link-href { + font-size: 14px; + line-height: 20px; + padding-inline-start: 4px; +} + @media (max-width: 360px) { #experiment-reset-all { font-size: .65rem;
diff --git a/components/flags_ui/resources/flags.html b/components/flags_ui/resources/flags.html index a77bcc3..b8a318cc 100644 --- a/components/flags_ui/resources/flags.html +++ b/components/flags_ui/resources/flags.html
@@ -42,6 +42,17 @@ </div> <div id="body-container" style="visibility:hidden"> <div id="flagsTemplate"> +<if expr="lacros"> + <div class="os-link-container"> + <span class="os-link-icon"></span> + <span aria-hidden="true" id="os-link-desc">$i18n{os-flags-text1}</span> + <a href="#" id="os-link-href" tabindex="4" aria-describedby="os-link-desc"> + $i18n{os-flags-link} + </a> + <span aria-hidden="true">$i18n{os-flags-text2}</span> + </div> +</if> + <div class="flex-container"> <div class="flex"><h1 class="section-header-title">$i18n{heading}</h1></div> <span id="version" class="flex">$i18n{version}</span> @@ -70,7 +81,7 @@ <a href="#tab-content-available" id="tab-available" class="tab" role="tab" aria-selected="true" aria-controls="panel1" - tabindex="4">$i18n{available}</a> + tabindex="5">$i18n{available}</a> <div id="tab-content-available" class="tab-content" role="tabpanel" aria-labelledby="tab-available" aria-hidden="false"> </div> @@ -94,14 +105,14 @@ <textarea class="experiment-origin-list-value" jsvalues=".internal_name:internal_name; .value:origin_list_value; aria-labelledby:internal_name + '_name'" - tabindex="6"></textarea> + tabindex="7"></textarea> </div> <a class="permalink" jsvalues="href: '#' + internal_name" - jscontent="'#' + internal_name" tabindex="6"></a> + jscontent="'#' + internal_name" tabindex="7"></a> </div> <div class="flex experiment-actions"> <div jsdisplay="options && options.length > 0"> - <select class="experiment-select" tabindex="6" + <select class="experiment-select" tabindex="7" jsvalues=".internal_name:internal_name;.disabled:!enabled; aria-labelledby:internal_name + '_name'"> <option jsvalues=".selected:selected;" @@ -110,7 +121,7 @@ </option> </select> </div> - <select class="experiment-enable-disable" tabindex="6" + <select class="experiment-enable-disable" tabindex="7" jsdisplay="enabled !== undefined" jsvalues=".internal_name:internal_name; aria-labelledby:internal_name + '_name'"> @@ -141,14 +152,14 @@ <textarea class="experiment-origin-list-value" jsvalues=".internal_name:internal_name; .value:origin_list_value; aria-labelledby:internal_name + '_name'" - tabindex="6"></textarea> + tabindex="7"></textarea> </div> <a class="permalink" jsvalues="href: '#' + internal_name" - jscontent="'#' + internal_name" tabindex="6"></a> + jscontent="'#' + internal_name" tabindex="7"></a> </div> <div class="flex experiment-actions"> <div jsdisplay="options && options.length > 0"> - <select class="experiment-select" tabindex="6" + <select class="experiment-select" tabindex="7" jsvalues=".internal_name:internal_name;.disabled:!enabled; aria-labelledby:internal_name + '_name'"> <option jsvalues=".selected:selected;" @@ -158,7 +169,7 @@ </select> </div> <!-- Represent enabled / disabled options in a drop down --> - <select class="experiment-enable-disable" tabindex="6" + <select class="experiment-enable-disable" tabindex="7" jsdisplay="enabled !== undefined" jsvalues=".internal_name:internal_name; aria-labelledby:internal_name + '_name'"> @@ -178,7 +189,7 @@ <li> <a href="#tab-content-unavailable" id="tab-unavailable" class="tab" role="tab" aria-selected="false" aria-controls="panel2" - tabindex="5">$i18n{unavailable}</a> + tabindex="6">$i18n{unavailable}</a> <div id="tab-content-unavailable" class="tab-content" role="tabpanel" aria-labelledby="tab-unavailable" aria-hidden="false"> <div class="experiment" @@ -196,7 +207,7 @@ </p> <a class="permalink" jsvalues="href: '#' + internal_name" - jscontent="'#' + internal_name" tabindex="8"></a> + jscontent="'#' + internal_name" tabindex="9"></a> </div> <div class="flex experiment-actions">$i18n{not-available-platform}</div> </div>
diff --git a/components/flags_ui/resources/flags.js b/components/flags_ui/resources/flags.js index b3062814..0a0f511 100644 --- a/components/flags_ui/resources/flags.js +++ b/components/flags_ui/resources/flags.js
@@ -126,6 +126,10 @@ } $('experiment-reset-all').onclick = resetAllFlags; + const crosUrlFlagsRedirectButton = $('os-link-href'); + if (crosUrlFlagsRedirectButton) { + crosUrlFlagsRedirectButton.onclick = crosUrlFlagsRedirect; + } highlightReferencedFlag(); const search = FlagSearch.getInstance(); @@ -214,6 +218,10 @@ requestExperimentalFeaturesData(); } +function crosUrlFlagsRedirect() { + chrome.send('crosUrlFlagsRedirect'); +} + /** * Show the restart toast. * @param {boolean} show Setting to toggle showing / hiding the toast. @@ -348,8 +356,9 @@ if (!node.internal_name) { return; } - chrome.send('enableExperimentalFeature', [String(node.internal_name), - String(enable)]); + chrome.send( + 'enableExperimentalFeature', + [String(node.internal_name), String(enable)]); experimentChangesUiUpdates(node, enable ? 1 : 0); } @@ -377,8 +386,9 @@ if (!node.internal_name) { return; } - chrome.send('enableExperimentalFeature', - [String(node.internal_name) + '@' + index, 'true']); + chrome.send( + 'enableExperimentalFeature', + [String(node.internal_name) + '@' + index, 'true']); experimentChangesUiUpdates(node, index); } @@ -463,8 +473,8 @@ if (!this.initialized) { this.searchBox_.addEventListener('input', this.debounceSearch.bind(this)); - document.querySelector('.clear-search').addEventListener('click', - this.clearSearch.bind(this)); + document.querySelector('.clear-search') + .addEventListener('click', this.clearSearch.bind(this)); window.addEventListener('keyup', function(e) { if (document.activeElement.nodeName === 'TEXTAREA') { @@ -562,29 +572,31 @@ let matches = 0; for (let i = 0, j = searchContent.link.length; i < j; i++) { if (this.highlightMatchInElement(searchTerm, searchContent.title[i])) { - this.resetHighlights(searchContent.description[i], + this.resetHighlights( + searchContent.description[i], searchContent.description[i].textContent); - this.resetHighlights(searchContent.link[i], - searchContent.link[i].textContent); + this.resetHighlights( + searchContent.link[i], searchContent.link[i].textContent); matches++; continue; } - if (this.highlightMatchInElement(searchTerm, - searchContent.description[i])) { - this.resetHighlights(searchContent.title[i], - searchContent.title[i].textContent); - this.resetHighlights(searchContent.link[i], - searchContent.link[i].textContent); + if (this.highlightMatchInElement( + searchTerm, searchContent.description[i])) { + this.resetHighlights( + searchContent.title[i], searchContent.title[i].textContent); + this.resetHighlights( + searchContent.link[i], searchContent.link[i].textContent); matches++; continue; } // Match links, replace spaces with hyphens as flag names don't // have spaces. - if (this.highlightMatchInElement(searchTerm.replace(/\s/, '-'), - searchContent.link[i])) { - this.resetHighlights(searchContent.title[i], - searchContent.title[i].textContent); - this.resetHighlights(searchContent.description[i], + if (this.highlightMatchInElement( + searchTerm.replace(/\s/, '-'), searchContent.link[i])) { + this.resetHighlights( + searchContent.title[i], searchContent.title[i].textContent); + this.resetHighlights( + searchContent.description[i], searchContent.description[i].textContent); matches++; } @@ -649,8 +661,8 @@ if (this.searchIntervalId_) { clearTimeout(this.searchIntervalId_); } - this.searchIntervalId_ = setTimeout(this.doSearch.bind(this), - FlagSearch.SEARCH_DEBOUNCE_TIME_MS); + this.searchIntervalId_ = setTimeout( + this.doSearch.bind(this), FlagSearch.SEARCH_DEBOUNCE_TIME_MS); } };
diff --git a/components/flags_ui/resources/os_flags_app_icon.svg b/components/flags_ui/resources/os_flags_app_icon.svg new file mode 100644 index 0000000..ebb6d1f --- /dev/null +++ b/components/flags_ui/resources/os_flags_app_icon.svg
@@ -0,0 +1 @@ +<svg width="192" height="192" viewBox="0 0 192 192" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="a" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="8" y="8" width="176" height="176"><circle cx="96" cy="96" r="88" fill="#C4C4C4"/></mask><g mask="url(#a)"><path fill="#5F6368" d="M0 0h192v192H0z"/></g><path d="M97.05 46l43.301 25v50L97.05 146l-43.301-25V71L97.05 46z" stroke="#87FFC5" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><path d="M140.35 71v50l-43.3 25V96l43.3-25zm-86.7 0l43.301 25 .001 49.999-43.301-25L53.65 71z" stroke="#87FFC5" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg> \ No newline at end of file
diff --git a/components/history_clusters/core/history_clusters_service.cc b/components/history_clusters/core/history_clusters_service.cc index fabd4d69..4157d071 100644 --- a/components/history_clusters/core/history_clusters_service.cc +++ b/components/history_clusters/core/history_clusters_service.cc
@@ -46,6 +46,15 @@ namespace { +// Is the transition user-visible. +bool IsTransitionUserVisible(int32_t transition) { + ui::PageTransition page_transition = ui::PageTransitionFromInt(transition); + return (ui::PAGE_TRANSITION_CHAIN_END & transition) != 0 && + ui::PageTransitionIsMainFrame(page_transition) && + !ui::PageTransitionCoreTypeIs(page_transition, + ui::PAGE_TRANSITION_KEYWORD_GENERATED); +} + // Gets persisted `AnnotatedVisit`s to cluster including both persisted visits // from the history DB and incomplete visits. // - We don't want incomplete visits to be mysteriously missing from the @@ -157,6 +166,12 @@ continue; } + // Discard any incomplete visits that are not visible to the user. + if (!IsTransitionUserVisible( + incomplete_visit_context_annotations.visit_row.transition)) { + continue; + } + // Compute `referring_visit_of_redirect_chain_start` for each incomplete // visit. const auto& first_redirect = backend->GetRedirectChainStart(
diff --git a/components/history_clusters/core/history_clusters_service_unittest.cc b/components/history_clusters/core/history_clusters_service_unittest.cc index 8657c87..5ffa9e2 100644 --- a/components/history_clusters/core/history_clusters_service_unittest.cc +++ b/components/history_clusters/core/history_clusters_service_unittest.cc
@@ -6,6 +6,7 @@ #include <memory> #include <string> +#include <vector> #include "base/callback_forward.h" #include "base/containers/contains.h" @@ -154,9 +155,13 @@ // Add an incomplete visit context annotations to the in memory incomplete // visit map. Does not touch the history database. - void AddIncompleteVisit(history::URLID url_id, - history::VisitID visit_id, - base::Time visit_time) { + void AddIncompleteVisit( + history::URLID url_id, + history::VisitID visit_id, + base::Time visit_time, + ui::PageTransition transition = ui::PageTransitionFromInt( + ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CHAIN_START | + ui::PAGE_TRANSITION_CHAIN_END)) { // It's not possible to have an incomplete visit with URL or visit set but // not the other. The IDs must either both be 0 or both be non-zero. ASSERT_FALSE(url_id ^ visit_id); @@ -166,6 +171,7 @@ incomplete_visit_context_annotations.url_row.set_id(url_id); incomplete_visit_context_annotations.visit_row.visit_id = visit_id; incomplete_visit_context_annotations.visit_row.visit_time = visit_time; + incomplete_visit_context_annotations.visit_row.transition = transition; incomplete_visit_context_annotations.status.history_rows = url_id; next_navigation_id_++; } @@ -388,7 +394,7 @@ } TEST_F(HistoryClustersServiceTest, QueryClustersIncompleteAndPersistedVisits) { - // Create persisted visits 1, 2, & 3. + // Create persisted visits 1, 2, 3. AddHardcodedTestDataToHistoryService(); auto days_ago = [](int days) { return base::Time::Now() - base::Days(days); }; @@ -401,6 +407,11 @@ AddIncompleteVisit(7, 7, days_ago(93)); // Too old. AddIncompleteVisit(3, 3, days_ago(90)); // Visit 3 was added to the history // database with source synched. + AddIncompleteVisit( + 10, 10, days_ago(1), + ui::PageTransitionFromInt( + 805306372)); // Visit 10 was added to the history database with + // a non-visible page transition. history_clusters_service_->QueryClusters( /*query=*/"", /*end_time=*/base::Time::Now(), /* max_count=*/0,
diff --git a/components/history_clusters/core/history_clusters_types.h b/components/history_clusters/core/history_clusters_types.h index 52ab096..bcc0bcb 100644 --- a/components/history_clusters/core/history_clusters_types.h +++ b/components/history_clusters/core/history_clusters_types.h
@@ -30,7 +30,7 @@ // A list of visits that have been de-duplicated into this visit. std::vector<Visit> duplicate_visits; - // The normalized URL for the visit (i.e. a SRP URL normalized based on the + // The normalized URL for the visit (i.e. an SRP URL normalized based on the // user's default search provider). GURL normalized_url; }; @@ -51,7 +51,7 @@ // The keywords associated with this cluster that should never be explicitly // presented within the UI. // TODO(tommycli): Eliminate this field after removing the usage in - // `PopulateClusterKeywordCache()`. + // `PopulateClusterKeywordCache()`. std::vector<std::u16string> keywords; };
diff --git a/components/metrics/clean_exit_beacon.cc b/components/metrics/clean_exit_beacon.cc index 16db148..261c384 100644 --- a/components/metrics/clean_exit_beacon.cc +++ b/components/metrics/clean_exit_beacon.cc
@@ -8,11 +8,13 @@ #include <utility> #include "base/check_op.h" +#include "base/command_line.h" #include "base/compiler_specific.h" #include "base/cxx17_backports.h" #include "base/files/file_util.h" #include "base/json/json_file_value_serializer.h" #include "base/json/json_string_value_serializer.h" +#include "base/logging.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" @@ -24,6 +26,7 @@ #include "components/prefs/pref_service.h" #include "components/variations/pref_names.h" #include "components/variations/service/variations_safe_mode_constants.h" +#include "components/variations/variations_switches.h" #if defined(OS_WIN) #include <windows.h> @@ -142,6 +145,37 @@ return nullptr; } +// Returns the channel to use for setting up the Extended Variations Safe Mode +// experiment. +// +// This is needed for tests in which there is a mismatch between (a) the channel +// on which the bot is running (and thus the channel plumbed through to the +// CleanExitBeacon's ctor) and (b) the channel that we wish to use for running a +// particular test. This mismatch can cause failures (crbug/1259550) when (a) +// the channel on which the bot is running is a channel to which the Extended +// Variations Safe Mode experiment does not apply and (b) a test uses a channel +// on which the experiment does apply. +// +// TODO(crbug/1241702): Clean up this function once the experiment is over. +version_info::Channel GetChannel(version_info::Channel channel) { + const std::string forced_channel = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + variations::switches::kFakeVariationsChannel); + + if (!forced_channel.empty()) { + if (forced_channel == "stable") + return version_info::Channel::STABLE; + if (forced_channel == "beta") + return version_info::Channel::BETA; + if (forced_channel == "dev") + return version_info::Channel::DEV; + if (forced_channel == "canary") + return version_info::Channel::CANARY; + DVLOG(1) << "Invalid channel provided: " << forced_channel; + } + return channel; +} + #if !defined(OS_ANDROID) && !defined(OS_IOS) // Sets up the Extended Variations Safe Mode experiment, which is enabled on // only some channels. If assigned to an experiment group, returns the name of @@ -176,7 +210,7 @@ local_state_(local_state), initial_browser_last_live_timestamp_( local_state->GetTime(prefs::kStabilityBrowserLastLiveTimeStamp)), - channel_(channel) { + channel_(GetChannel(channel)) { DCHECK_NE(PrefService::INITIALIZATION_STATUS_WAITING, local_state_->GetInitializationStatus()); // TODO(crbug/1248239, crbug/1255305): Remove the below line once the Extended
diff --git a/components/nacl/browser/nacl_browser.cc b/components/nacl/browser/nacl_browser.cc index 6d80397..7e8dfbc 100644 --- a/components/nacl/browser/nacl_browser.cc +++ b/components/nacl/browser/nacl_browser.cc
@@ -48,8 +48,7 @@ #if defined(ARCH_CPU_X86_64) bool is64 = true; #elif defined(OS_WIN) - bool is64 = (base::win::OSInfo::GetInstance()->wow64_status() == - base::win::OSInfo::WOW64_ENABLED); + bool is64 = base::win::OSInfo::GetInstance()->IsWowX86OnAMD64(); #else bool is64 = false; #endif
diff --git a/components/nacl/browser/nacl_process_host.cc b/components/nacl/browser/nacl_process_host.cc index 85a520d5..f75cb65 100644 --- a/components/nacl/browser/nacl_process_host.cc +++ b/components/nacl/browser/nacl_process_host.cc
@@ -154,8 +154,7 @@ namespace { bool RunningOnWOW64() { - return (base::win::OSInfo::GetInstance()->wow64_status() == - base::win::OSInfo::WOW64_ENABLED); + return base::win::OSInfo::GetInstance()->IsWowX86OnAMD64(); } } // namespace
diff --git a/components/password_manager/core/browser/fake_password_store_backend.cc b/components/password_manager/core/browser/fake_password_store_backend.cc index 70121f44..4a362d3 100644 --- a/components/password_manager/core/browser/fake_password_store_backend.cc +++ b/components/password_manager/core/browser/fake_password_store_backend.cc
@@ -123,6 +123,11 @@ return nullptr; } +void FakePasswordStoreBackend::GetSyncStatus( + base::OnceCallback<void(bool)> callback) { + NOTIMPLEMENTED(); +} + LoginsResult FakePasswordStoreBackend::GetAllLoginsInternal() { LoginsResult result; for (const auto& elements : stored_passwords_) {
diff --git a/components/password_manager/core/browser/fake_password_store_backend.h b/components/password_manager/core/browser/fake_password_store_backend.h index edf5b267..efe045c3 100644 --- a/components/password_manager/core/browser/fake_password_store_backend.h +++ b/components/password_manager/core/browser/fake_password_store_backend.h
@@ -61,6 +61,7 @@ FieldInfoStore* GetFieldInfoStore() override; std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> CreateSyncControllerDelegate() override; + void GetSyncStatus(base::OnceCallback<void(bool)> callback) override; LoginsResult GetAllLoginsInternal(); LoginsResult GetAutofillableLoginsInternal();
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc index f585bf8..aed160f 100644 --- a/components/password_manager/core/browser/login_database.cc +++ b/components/password_manager/core/browser/login_database.cc
@@ -1477,10 +1477,7 @@ DCHECK(db_.is_open()); - // Get all autofillable (not blocklisted) logins. - sql::Statement s( - db_.GetCachedStatement(SQL_FROM_HERE, blocklisted_statement_.c_str())); - s.BindInt(0, 0); // blocklisted = false + sql::Statement s(db_.GetUniqueStatement("SELECT * FROM logins")); std::vector<PasswordForm> forms_to_be_deleted; @@ -1770,7 +1767,6 @@ *statement, /*decrypt_and_fill_password_value=*/true, &primary_key, new_form.get()); if (result == ENCRYPTION_RESULT_SERVICE_FAILURE) { - LOG(ERROR) << "Encryption service unavailable"; return FormRetrievalResult::kEncrytionServiceFailure; } if (result == ENCRYPTION_RESULT_ITEM_FAILURE) { @@ -1796,9 +1792,6 @@ } if (!statement->Succeeded()) { - LOG(ERROR) << "is_valid()=" << statement->is_valid(); - LOG(ERROR) << "Error=" << db_.GetErrorCode(); - LOG(ERROR) << db_.GetErrorMessage(); return FormRetrievalResult::kDbError; } return FormRetrievalResult::kSuccess;
diff --git a/components/password_manager/core/browser/login_database_unittest.cc b/components/password_manager/core/browser/login_database_unittest.cc index 7bb4f51..97c2daf 100644 --- a/components/password_manager/core/browser/login_database_unittest.cc +++ b/components/password_manager/core/browser/login_database_unittest.cc
@@ -1999,7 +1999,8 @@ // |should_be_corrupted| flag is active. PasswordForm AddDummyLogin(const std::string& unique_string, const GURL& origin, - bool should_be_corrupted); + bool should_be_corrupted, + bool blocklisted); base::FilePath database_path() const { return database_path_; } @@ -2019,7 +2020,8 @@ PasswordForm LoginDatabaseUndecryptableLoginsTest::AddDummyLogin( const std::string& unique_string, const GURL& origin, - bool should_be_corrupted) { + bool should_be_corrupted, + bool blocklisted) { // Create a dummy password form. const std::u16string unique_string16 = ASCIIToUTF16(unique_string); PasswordForm form; @@ -2029,6 +2031,7 @@ form.password_element = unique_string16; form.password_value = unique_string16; form.signon_realm = origin.DeprecatedGetOriginAsURL().spec(); + form.blocked_by_user = blocklisted; { LoginDatabase db(database_path(), IsAccountStore(false)); @@ -2061,9 +2064,15 @@ } TEST_F(LoginDatabaseUndecryptableLoginsTest, DeleteUndecryptableLoginsTest) { - auto form1 = AddDummyLogin("foo1", GURL("https://foo1.com/"), false); - auto form2 = AddDummyLogin("foo2", GURL("https://foo2.com/"), true); - auto form3 = AddDummyLogin("foo3", GURL("https://foo3.com/"), false); + auto form1 = + AddDummyLogin("foo1", GURL("https://foo1.com/"), + /*should_be_corrupted=*/false, /*blocklisted=*/false); + auto form2 = + AddDummyLogin("foo2", GURL("https://foo2.com/"), + /*should_be_corrupted=*/true, /*blocklisted=*/false); + auto form3 = + AddDummyLogin("foo3", GURL("https://foo3.com/"), + /*should_be_corrupted=*/true, /*blocklisted=*/true); LoginDatabase db(database_path(), IsAccountStore(false)); base::HistogramTester histogram_tester; @@ -2074,12 +2083,16 @@ std::vector<std::unique_ptr<PasswordForm>> result; EXPECT_FALSE(db.GetAutofillableLogins(&result)); EXPECT_TRUE(result.empty()); + EXPECT_FALSE(db.GetBlocklistLogins(&result)); + EXPECT_TRUE(result.empty()); // Delete undecryptable logins and make sure we can get valid logins. EXPECT_EQ(DatabaseCleanupResult::kSuccess, db.DeleteUndecryptableLogins()); EXPECT_TRUE(db.GetAutofillableLogins(&result)); + EXPECT_THAT(result, UnorderedElementsAre(Pointee(form1))); - EXPECT_THAT(result, UnorderedElementsAre(Pointee(form1), Pointee(form3))); + EXPECT_TRUE(db.GetBlocklistLogins(&result)); + EXPECT_THAT(result, IsEmpty()); RunUntilIdle(); #else @@ -2088,7 +2101,7 @@ // Check histograms. #if defined(OS_MAC) - histogram_tester.ExpectUniqueSample("PasswordManager.CleanedUpPasswords", 1, + histogram_tester.ExpectUniqueSample("PasswordManager.CleanedUpPasswords", 2, 1); histogram_tester.ExpectUniqueSample( "PasswordManager.DeleteUndecryptableLoginsReturnValue", @@ -2104,8 +2117,9 @@ #if defined(OS_MAC) TEST_F(LoginDatabaseUndecryptableLoginsTest, PasswordRecoveryDisabledGetLogins) { - AddDummyLogin("foo1", GURL("https://foo1.com/"), false); - AddDummyLogin("foo2", GURL("https://foo2.com/"), true); + AddDummyLogin("foo1", GURL("https://foo1.com/"), false, + /*blocklisted=*/false); + AddDummyLogin("foo2", GURL("https://foo2.com/"), true, /*blocklisted=*/false); LoginDatabase db(database_path(), IsAccountStore(false)); ASSERT_TRUE(db.Init()); @@ -2118,8 +2132,9 @@ } TEST_F(LoginDatabaseUndecryptableLoginsTest, KeychainLockedTest) { - AddDummyLogin("foo1", GURL("https://foo1.com/"), false); - AddDummyLogin("foo2", GURL("https://foo2.com/"), true); + AddDummyLogin("foo1", GURL("https://foo1.com/"), false, + /*blocklisted=*/false); + AddDummyLogin("foo2", GURL("https://foo2.com/"), true, /*blocklisted=*/false); OSCryptMocker::SetBackendLocked(true); LoginDatabase db(database_path(), IsAccountStore(false));
diff --git a/components/password_manager/core/browser/mock_password_store_backend.h b/components/password_manager/core/browser/mock_password_store_backend.h index c255ea1..6b12b44 100644 --- a/components/password_manager/core/browser/mock_password_store_backend.h +++ b/components/password_manager/core/browser/mock_password_store_backend.h
@@ -79,6 +79,10 @@ CreateSyncControllerDelegate, (), (override)); + MOCK_METHOD(void, + GetSyncStatus, + (base::OnceCallback<void(bool)>), + (override)); }; } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_backend.h b/components/password_manager/core/browser/password_store_backend.h index 6da940d..8cb2976 100644 --- a/components/password_manager/core/browser/password_store_backend.h +++ b/components/password_manager/core/browser/password_store_backend.h
@@ -115,6 +115,10 @@ virtual std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> CreateSyncControllerDelegate() = 0; + // Tells whether backend is actively syncing data. Callback is called on a + // main sequence. + virtual void GetSyncStatus(base::OnceCallback<void(bool)> callback) = 0; + // Factory function for creating the backend. The Local backend requires the // provided `login_db` for storage and Android backend for migration purposes. static std::unique_ptr<PasswordStoreBackend> Create(
diff --git a/components/password_manager/core/browser/password_store_backend_migration_decorator.cc b/components/password_manager/core/browser/password_store_backend_migration_decorator.cc index 90e7a8fc..3ba15b1 100644 --- a/components/password_manager/core/browser/password_store_backend_migration_decorator.cc +++ b/components/password_manager/core/browser/password_store_backend_migration_decorator.cc
@@ -153,6 +153,11 @@ return active_backend_->CreateSyncControllerDelegate(); } +void PasswordStoreBackendMigrationDecorator::GetSyncStatus( + base::OnceCallback<void(bool)> callback) { + return active_backend_->GetSyncStatus(std::move(callback)); +} + void PasswordStoreBackendMigrationDecorator::StartMigration() { migrator_ = std::make_unique<BuiltInBackendToAndroidBackendMigrator>(prefs_); migrator_->StartMigrationIfNecessary();
diff --git a/components/password_manager/core/browser/password_store_backend_migration_decorator.h b/components/password_manager/core/browser/password_store_backend_migration_decorator.h index 2d93dd3..6aba9b22 100644 --- a/components/password_manager/core/browser/password_store_backend_migration_decorator.h +++ b/components/password_manager/core/browser/password_store_backend_migration_decorator.h
@@ -73,6 +73,7 @@ FieldInfoStore* GetFieldInfoStore() override; std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> CreateSyncControllerDelegate() override; + void GetSyncStatus(base::OnceCallback<void(bool)> callback) override; // Creates 'migrator_' and starts migration process. void StartMigration();
diff --git a/components/password_manager/core/browser/password_store_impl.cc b/components/password_manager/core/browser/password_store_impl.cc index 149690d..6234c3e 100644 --- a/components/password_manager/core/browser/password_store_impl.cc +++ b/components/password_manager/core/browser/password_store_impl.cc
@@ -422,6 +422,16 @@ weak_ptr_factory_.GetWeakPtr())); } +void PasswordStoreImpl::GetSyncStatus(base::OnceCallback<void(bool)> callback) { + DCHECK(!was_shutdown_); + DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); + background_task_runner_->PostTaskAndReplyWithResult( + FROM_HERE, + base::BindOnce(&PasswordStoreImpl::IsSyncEnabled, + base::Unretained(this)), // Safe until `Shutdown()`. + std::move(callback)); +} + void PasswordStoreImpl::AddSiteStats(const InteractionsStats& stats) { DCHECK(!was_shutdown_); DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); @@ -715,4 +725,11 @@ login_db_->field_info_table().RemoveRowsByTime(remove_begin, remove_end); } +bool PasswordStoreImpl::IsSyncEnabled() const { + DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); + if (!sync_bridge_ || !sync_bridge_->change_processor()) + return false; + return sync_bridge_->change_processor()->IsTrackingMetadata(); +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_impl.h b/components/password_manager/core/browser/password_store_impl.h index dd19a363..90514d9 100644 --- a/components/password_manager/core/browser/password_store_impl.h +++ b/components/password_manager/core/browser/password_store_impl.h
@@ -115,6 +115,7 @@ FieldInfoStore* GetFieldInfoStore() override; std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> CreateSyncControllerDelegate() override; + void GetSyncStatus(base::OnceCallback<void(bool)> callback) override; // SmartBubbleStatsStore: void AddSiteStats(const InteractionsStats& stats) override; @@ -191,6 +192,8 @@ // and bubble statistics. void ReportMetrics(); + bool IsSyncEnabled() const; + // Used to trigger DCHECKs if tasks are posted after shut down. bool was_shutdown_{false};
diff --git a/components/password_manager/core/browser/password_store_proxy_backend.cc b/components/password_manager/core/browser/password_store_proxy_backend.cc index e308f77..5ab9a2f0 100644 --- a/components/password_manager/core/browser/password_store_proxy_backend.cc +++ b/components/password_manager/core/browser/password_store_proxy_backend.cc
@@ -16,6 +16,7 @@ #include "base/ranges/algorithm.h" #include "base/strings/strcat.h" #include "components/password_manager/core/browser/field_info_table.h" +#include "components/password_manager/core/common/password_manager_features.h" #include "components/sync/model/proxy_model_type_controller_delegate.h" namespace password_manager { @@ -126,6 +127,14 @@ absl::optional<LoginsResult> first_result_; }; +void InvokeCallbackIfShadowingAllowed(base::OnceClosure callback, + bool sync_enabled) { + if (sync_enabled && base::FeatureList::IsEnabled( + features::kUnifiedPasswordManagerShadowAndroid)) { + std::move(callback).Run(); + } +} + } // namespace PasswordStoreProxyBackend::PasswordStoreProxyBackend( @@ -165,8 +174,15 @@ base::BindOnce(&GetAllLoginsAsyncMetricsRecorder::RecordMainResult, handler) .Then(std::move(callback))); - shadow_backend_->GetAllLoginsAsync(base::BindOnce( - &GetAllLoginsAsyncMetricsRecorder::RecordShadowResult, handler)); + + auto sync_status_callback = base::BindOnce( + &PasswordStoreBackend::GetAllLoginsAsync, + base::Unretained(shadow_backend_), + base::BindOnce(&GetAllLoginsAsyncMetricsRecorder::RecordShadowResult, + handler)); + + GetSyncStatus(base::BindOnce(&InvokeCallbackIfShadowingAllowed, + std::move(sync_status_callback))); } void PasswordStoreProxyBackend::GetAutofillableLoginsAsync( @@ -247,4 +263,9 @@ return main_backend_->CreateSyncControllerDelegate(); } +void PasswordStoreProxyBackend::GetSyncStatus( + base::OnceCallback<void(bool)> callback) { + return main_backend_->GetSyncStatus(std::move(callback)); +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_store_proxy_backend.h b/components/password_manager/core/browser/password_store_proxy_backend.h index 15f7a25..9df4eab 100644 --- a/components/password_manager/core/browser/password_store_proxy_backend.h +++ b/components/password_manager/core/browser/password_store_proxy_backend.h
@@ -64,6 +64,8 @@ std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> CreateSyncControllerDelegate() override; + void GetSyncStatus(base::OnceCallback<void(bool)> callback) override; + PasswordStoreBackend* const main_backend_; PasswordStoreBackend* const shadow_backend_; };
diff --git a/components/password_manager/core/browser/password_store_proxy_backend_unittest.cc b/components/password_manager/core/browser/password_store_proxy_backend_unittest.cc index 338ca11..88067d8 100644 --- a/components/password_manager/core/browser/password_store_proxy_backend_unittest.cc +++ b/components/password_manager/core/browser/password_store_proxy_backend_unittest.cc
@@ -12,10 +12,12 @@ #include "base/callback_helpers.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/mock_callback.h" +#include "base/test/scoped_feature_list.h" #include "components/password_manager/core/browser/mock_password_store_backend.h" #include "components/password_manager/core/browser/password_form_digest.h" #include "components/password_manager/core/browser/password_manager_test_utils.h" #include "components/password_manager/core/browser/password_store_change.h" +#include "components/password_manager/core/common/password_manager_features.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -66,6 +68,9 @@ PasswordStoreProxyBackendTest() { proxy_backend_ = std::make_unique<PasswordStoreProxyBackend>( &main_backend_, &shadow_backend_); + + feature_list_.InitAndEnableFeature( + features::kUnifiedPasswordManagerShadowAndroid); } void TearDown() override { @@ -81,6 +86,7 @@ MockPasswordStoreBackend& shadow_backend() { return shadow_backend_; } private: + base::test::ScopedFeatureList feature_list_; std::unique_ptr<PasswordStoreProxyBackend> proxy_backend_; StrictMock<MockPasswordStoreBackend> main_backend_; StrictMock<MockPasswordStoreBackend> shadow_backend_; @@ -135,6 +141,9 @@ .WillOnce(WithArg<0>(Invoke([](LoginsReply reply) -> void { std::move(reply).Run(CreateTestLogins()); }))); + EXPECT_CALL(main_backend(), GetSyncStatus) + .WillOnce(WithArg<0>( + Invoke([](auto callback) { std::move(callback).Run(true); }))); EXPECT_CALL(shadow_backend(), GetAllLoginsAsync) .WillOnce(WithArg<0>(Invoke([](LoginsReply reply) -> void { std::move(reply).Run(CreateTestLogins()); @@ -278,6 +287,36 @@ proxy_backend().CreateSyncControllerDelegate(); } +TEST_F(PasswordStoreProxyBackendTest, NoShadowGetAllLoginsWhenSyncDisabled) { + base::HistogramTester histogram_tester; + base::MockCallback<LoginsReply> mock_reply; + std::vector<std::unique_ptr<PasswordForm>> expected_logins = + CreateTestLogins(); + EXPECT_CALL(mock_reply, + Run(UnorderedPasswordFormElementsAre(&expected_logins))); + EXPECT_CALL(main_backend(), GetAllLoginsAsync) + .WillOnce(WithArg<0>(Invoke([](LoginsReply reply) -> void { + std::move(reply).Run(CreateTestLogins()); + }))); + EXPECT_CALL(main_backend(), GetSyncStatus) + .WillOnce(WithArg<0>( + Invoke([](auto callback) { std::move(callback).Run(false); }))); + EXPECT_CALL(shadow_backend(), GetAllLoginsAsync).Times(0); + proxy_backend().GetAllLoginsAsync(mock_reply.Get()); + + std::string prefix = + "PasswordManager.PasswordStoreProxyBackend.GetAllLoginsAsync."; + + histogram_tester.ExpectTotalCount(prefix + "Diff.Abs", 0); + histogram_tester.ExpectTotalCount(prefix + "MainMinusShadow.Abs", 0); + histogram_tester.ExpectTotalCount(prefix + "ShadowMinusMain.Abs", 0); + histogram_tester.ExpectTotalCount(prefix + "InconsistentPasswords.Abs", 0); + histogram_tester.ExpectTotalCount(prefix + "Diff.Rel", 0); + histogram_tester.ExpectTotalCount(prefix + "MainMinusShadow.Rel", 0); + histogram_tester.ExpectTotalCount(prefix + "ShadowMinusMain.Rel", 0); + histogram_tester.ExpectTotalCount(prefix + "InconsistentPasswords.Rel", 0); +} + // Holds the main and shadow backend's logins and the expected number of common // and different logins. struct LoginsMetricsParam { @@ -331,6 +370,9 @@ .WillOnce(WithArg<0>(Invoke([&p](LoginsReply reply) -> void { std::move(reply).Run(p.GetMainLogins()); }))); + EXPECT_CALL(main_backend(), GetSyncStatus) + .WillOnce(WithArg<0>( + Invoke([](auto callback) { std::move(callback).Run(true); }))); EXPECT_CALL(shadow_backend(), GetAllLoginsAsync) .WillOnce(WithArg<0>(Invoke([&p](LoginsReply reply) -> void { std::move(reply).Run(p.GetShadowLogins());
diff --git a/components/password_manager/core/browser/test_password_store.cc b/components/password_manager/core/browser/test_password_store.cc index 2f9c539..22e3dc6 100644 --- a/components/password_manager/core/browser/test_password_store.cc +++ b/components/password_manager/core/browser/test_password_store.cc
@@ -252,6 +252,10 @@ return nullptr; } +void TestPasswordStore::GetSyncStatus(base::OnceCallback<void(bool)> callback) { + NOTIMPLEMENTED(); +} + bool TestPasswordStore::IsAccountStore() const { return is_account_store_.value(); }
diff --git a/components/password_manager/core/browser/test_password_store.h b/components/password_manager/core/browser/test_password_store.h index cd17f61a..c673353 100644 --- a/components/password_manager/core/browser/test_password_store.h +++ b/components/password_manager/core/browser/test_password_store.h
@@ -98,6 +98,7 @@ FieldInfoStore* GetFieldInfoStore() override; std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> CreateSyncControllerDelegate() override; + void GetSyncStatus(base::OnceCallback<void(bool)> callback) override; private: LoginsResult GetAllLoginsInternal();
diff --git a/components/policy/core/common/policy_service_impl.cc b/components/policy/core/common/policy_service_impl.cc index fb78d71..716aeb8f 100644 --- a/components/policy/core/common/policy_service_impl.cc +++ b/components/policy/core/common/policy_service_impl.cc
@@ -126,6 +126,8 @@ PolicyMap::Entry* policy_entry_mutable = policies->GetMutable(policy_name); policy_entry_mutable->SetIgnored(); + policy_entry_mutable->AddMessage(PolicyMap::MessageType::kError, + IDS_POLICY_IGNORED_CHROME_PROFILE); } } }
diff --git a/components/policy_strings.grdp b/components/policy_strings.grdp index 316b71f..b43443a 100644 --- a/components/policy_strings.grdp +++ b/components/policy_strings.grdp
@@ -570,6 +570,9 @@ <message name="IDS_POLICY_IGNORED_MANDATORY_REPORTING_POLICY" desc="Text explaining that the policy MetricsReportingEnabled can not be forced to enabled anymore"> This policy cannot be set to "True" and be mandatory, therefore it was changed to recommended. </message> + <message name="IDS_POLICY_IGNORED_CHROME_PROFILE" desc="Text explaining that the policy cannot be set at the Chrome profile level and is therefore ignored."> + This policy cannot be set at the Chrome profile level and will be ignored. + </message> <if expr="not is_macosx"> <message name="IDS_POLICY_SPELLCHECK_UNKNOWN_LANGUAGE" desc="Warning message in the policy summary page for the spellcheck policies when a language is unrecognized or unsupported."> List entry "<ph name="LANGUAGE_ID">$1<ex>xx-YY</ex></ph>": Unknown or unsupported language.
diff --git a/components/policy_strings_grdp/IDS_POLICY_IGNORED_CHROME_PROFILE.png.sha1 b/components/policy_strings_grdp/IDS_POLICY_IGNORED_CHROME_PROFILE.png.sha1 new file mode 100644 index 0000000..e0c30575 --- /dev/null +++ b/components/policy_strings_grdp/IDS_POLICY_IGNORED_CHROME_PROFILE.png.sha1
@@ -0,0 +1 @@ +e2d25184dafde6742995652f5f8224f74cf9a216 \ No newline at end of file
diff --git a/components/resources/flags_ui_resources.grdp b/components/resources/flags_ui_resources.grdp index 1f46be7..cec4ade 100644 --- a/components/resources/flags_ui_resources.grdp +++ b/components/resources/flags_ui_resources.grdp
@@ -3,4 +3,7 @@ <include name="IDR_FLAGS_UI_FLAGS_HTML" file="../flags_ui/resources/flags.html" preprocess="true" type="BINDATA" /> <include name="IDR_FLAGS_UI_FLAGS_JS" file="../flags_ui/resources/flags.js" preprocess="true" type="BINDATA" /> <include name="IDR_FLAGS_UI_FLAGS_CSS" file="../flags_ui/resources/flags.css" preprocess="true" type="BINDATA" /> + <if expr="lacros"> + <include name="IDR_OS_FLAGS_UI_FLAGS_SVG" file="../flags_ui/resources/os_flags_app_icon.svg" preprocess="true" type="BINDATA" /> + </if> </grit-part>
diff --git a/components/safe_browsing/core/browser/verdict_cache_manager.cc b/components/safe_browsing/core/browser/verdict_cache_manager.cc index 7a4bce6d..2535217 100644 --- a/components/safe_browsing/core/browser/verdict_cache_manager.cc +++ b/components/safe_browsing/core/browser/verdict_cache_manager.cc
@@ -52,7 +52,7 @@ const int kPageLoadTokenBytes = 32; // The expiration time of a page load token. -const int kPageLoadTokenExpireMinute = 30; +const int kPageLoadTokenExpireMinute = 5; // A helper class to include all match params. It is used as a centralized // place to determine if the current cache entry should be considered as a @@ -374,6 +374,11 @@ return most_matching_verdict_type; } +bool HasPageLoadTokenExpired(int64_t token_time_msec) { + return base::Time::Now() - base::Time::FromJavaTime(token_time_msec) > + base::Minutes(kPageLoadTokenExpireMinute); +} + } // namespace VerdictCacheManager::VerdictCacheManager( @@ -605,9 +610,14 @@ ChromeUserPopulation::PageLoadToken VerdictCacheManager::GetPageLoadToken( const GURL& url) { std::string hostname = url.host(); - return base::Contains(page_load_token_map_, hostname) - ? page_load_token_map_[hostname] - : ChromeUserPopulation::PageLoadToken(); + if (!base::Contains(page_load_token_map_, hostname)) { + return ChromeUserPopulation::PageLoadToken(); + } + + ChromeUserPopulation::PageLoadToken token = page_load_token_map_[hostname]; + return HasPageLoadTokenExpired(token.token_time_msec()) + ? ChromeUserPopulation::PageLoadToken() + : token; } void VerdictCacheManager::ScheduleNextCleanUpAfterInterval( @@ -706,9 +716,7 @@ void VerdictCacheManager::CleanUpExpiredPageLoadTokens() { base::EraseIf(page_load_token_map_, [&](const auto& hostname_token_pair) { ChromeUserPopulation::PageLoadToken token = hostname_token_pair.second; - return base::Time::Now() - - base::Time::FromJavaTime(token.token_time_msec()) > - base::Minutes(kPageLoadTokenExpireMinute); + return HasPageLoadTokenExpired(token.token_time_msec()); }); base::UmaHistogramCounts10000("SafeBrowsing.PageLoadToken.TokenCount", page_load_token_map_.size());
diff --git a/components/safe_browsing/core/browser/verdict_cache_manager_unittest.cc b/components/safe_browsing/core/browser/verdict_cache_manager_unittest.cc index 8013b2a..8f1dde7a 100644 --- a/components/safe_browsing/core/browser/verdict_cache_manager_unittest.cc +++ b/components/safe_browsing/core/browser/verdict_cache_manager_unittest.cc
@@ -780,4 +780,17 @@ ASSERT_FALSE(token4.has_token_value()); } +TEST_F(VerdictCacheManagerTest, TestGetExpiredPageLoadToken) { + GURL url("https://www.example.com/path"); + cache_manager_->CreatePageLoadToken(url); + ChromeUserPopulation::PageLoadToken token = + cache_manager_->GetPageLoadToken(url); + ASSERT_TRUE(token.has_token_value()); + + task_environment_.FastForwardBy(base::Minutes(6)); + token = cache_manager_->GetPageLoadToken(url); + // Token is not found because it has already expired. + ASSERT_FALSE(token.has_token_value()); +} + } // namespace safe_browsing
diff --git a/components/safe_browsing/core/tailored_security_service/BUILD.gn b/components/safe_browsing/core/tailored_security_service/BUILD.gn new file mode 100644 index 0000000..157052f --- /dev/null +++ b/components/safe_browsing/core/tailored_security_service/BUILD.gn
@@ -0,0 +1,41 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("tailored_security_service") { + sources = [ + "tailored_security_service.cc", + "tailored_security_service.h", + ] + + deps = [ + "//base", + "//base:i18n", + "//components/keyed_service/core", + "//components/query_parser", + "//components/signin/public/identity_manager", + "//components/url_formatter", + "//components/variations", + "//google_apis", + "//net", + "//services/network/public/cpp", + "//services/network/public/mojom", + "//url", + ] +} + +source_set("unit_tests") { + testonly = true + sources = [ "tailored_security_service_unittest.cc" ] + deps = [ + ":tailored_security_service", + "//base", + "//base/test:test_support", + "//components/sync:test_support", + "//net:test_support", + "//services/network:test_support", + "//services/network/public/cpp", + "//testing/gtest", + "//url", + ] +}
diff --git a/components/safe_browsing/core/tailored_security_service/DEPS b/components/safe_browsing/core/tailored_security_service/DEPS new file mode 100644 index 0000000..fc13cbf --- /dev/null +++ b/components/safe_browsing/core/tailored_security_service/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+components/signin/public/identity_manager", +] \ No newline at end of file
diff --git a/components/safe_browsing/core/tailored_security_service/OWNERS b/components/safe_browsing/core/tailored_security_service/OWNERS new file mode 100644 index 0000000..a8846f4 --- /dev/null +++ b/components/safe_browsing/core/tailored_security_service/OWNERS
@@ -0,0 +1,2 @@ +bdea@chromium.org +drubery@chromium.org \ No newline at end of file
diff --git a/components/safe_browsing/core/tailored_security_service/tailored_security_service.cc b/components/safe_browsing/core/tailored_security_service/tailored_security_service.cc new file mode 100644 index 0000000..2ce66e0 --- /dev/null +++ b/components/safe_browsing/core/tailored_security_service/tailored_security_service.cc
@@ -0,0 +1,394 @@ +// Copyright (c) 2021 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/safe_browsing/core/tailored_security_service/tailored_security_service.h" + +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "base/json/json_reader.h" +#include "base/json/json_writer.h" +#include "base/metrics/histogram_macros.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "base/time/time.h" +#include "base/values.h" +#include "components/signin/public/identity_manager/access_token_info.h" +#include "components/signin/public/identity_manager/identity_manager.h" +#include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h" +#include "components/signin/public/identity_manager/scope_set.h" +#include "google_apis/gaia/gaia_urls.h" +#include "google_apis/gaia/google_service_auth_error.h" +#include "net/base/load_flags.h" +#include "net/base/url_util.h" +#include "net/http/http_status_code.h" +#include "net/http/http_util.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/cpp/simple_url_loader.h" +#include "services/network/public/mojom/url_response_head.mojom.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/gurl.h" + +namespace safe_browsing { +namespace { + +const int kRepeatingCheckTailoredSecurityBitDelayInMinutes = 5; + +constexpr char kAPIScope[] = + "https://www.googleapis.com/auth/chrome-safe-browsing"; + +const char kQueryTailoredSecurityServiceUrl[] = + "https://history.google.com/history/api/lookup?client=aesb"; + +// The maximum number of retries for the SimpleURLLoader requests. +const size_t kMaxRetries = 1; + +// Returns a Google account that can be used for getting a token. +// TODO(drubery): This prioritizes the primary account but instead should +// use the list of accounts with refresh tokens and select the one that +// should actually be queried. +CoreAccountId GetAccountForRequest( + const signin::IdentityManager* identity_manager) { + CoreAccountInfo result = + identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSync); + if (result.IsEmpty()) { + std::vector<CoreAccountInfo> all_accounts = + identity_manager->GetAccountsWithRefreshTokens(); + if (!all_accounts.empty()) + result = all_accounts.front(); + } + return result.account_id; +} + +class RequestImpl : public TailoredSecurityService::Request { + public: + RequestImpl(signin::IdentityManager* identity_manager, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + const GURL& url, + TailoredSecurityService::CompletionCallback callback, + const net::NetworkTrafficAnnotationTag& traffic_annotation) + : identity_manager_(identity_manager), + url_loader_factory_(std::move(url_loader_factory)), + url_(url), + callback_(std::move(callback)), + traffic_annotation_(traffic_annotation) { + DCHECK(identity_manager_); + DCHECK(url_loader_factory_); + } + ~RequestImpl() override = default; + + // Returns the response code received from the server, which will only be + // valid if the request succeeded. + int GetResponseCode() const override { return response_code_; } + + // Returns the contents of the response body received from the server. + const std::string& GetResponseBody() const override { return response_body_; } + + void SetPostData(const std::string& post_data) override { + post_data_ = post_data; + } + + bool IsPending() const override { return is_pending_; } + + private: + friend class safe_browsing::TailoredSecurityService; + + void OnAccessTokenFetchComplete(GoogleServiceAuthError error, + signin::AccessTokenInfo access_token_info) { + access_token_fetcher_.reset(); + + if (error.state() != GoogleServiceAuthError::NONE) { + is_pending_ = false; + UMA_HISTOGRAM_BOOLEAN( + "SafeBrowsing.TailoredSecurityService.OAuthTokenCompletion", false); + UMA_HISTOGRAM_ENUMERATION( + "SafeBrowsing.TailoredSecurityService.OAuthTokenErrorState", + error.state(), GoogleServiceAuthError::NUM_STATES); + std::move(callback_).Run(this, false); + + // It is valid for the callback to delete |this|, so do not access any + // members below here. + return; + } + + DCHECK(!access_token_info.token.empty()); + access_token_ = access_token_info.token; + + UMA_HISTOGRAM_BOOLEAN( + "SafeBrowsing.TailoredSecurityService.OAuthTokenCompletion", true); + + // Got an access token -- start the actual API request. + auto resource_request = std::make_unique<network::ResourceRequest>(); + resource_request->url = url_; + resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit; + resource_request->method = post_data_ ? "POST" : "GET"; + resource_request->headers.SetHeader(net::HttpRequestHeaders::kAuthorization, + "Bearer " + access_token_info.token); + resource_request->headers.SetHeader( + "X-Developer-Key", GaiaUrls::GetInstance()->oauth2_chrome_client_id()); + + simple_url_loader_ = network::SimpleURLLoader::Create( + std::move(resource_request), traffic_annotation_); + simple_url_loader_->SetRetryOptions(kMaxRetries, + network::SimpleURLLoader::RETRY_ON_5XX); + simple_url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + url_loader_factory_.get(), + base::BindOnce(&RequestImpl::OnSimpleLoaderComplete, + base::Unretained(this))); + } + + // Tells the request to get an access token and make the call to OnePlatform. + void Start() override { + access_token_fetcher_ = + identity_manager_->CreateAccessTokenFetcherForAccount( + GetAccountForRequest(identity_manager_), + /*oauth_consumer_name=*/"tailored_security_service", {kAPIScope}, + base::BindOnce(&RequestImpl::OnAccessTokenFetchComplete, + base::Unretained(this)), + signin::AccessTokenFetcher::Mode::kImmediate); + is_pending_ = true; + } + + void Shutdown() override {} + + void OnSimpleLoaderComplete(std::unique_ptr<std::string> response_body) { + response_code_ = -1; + if (simple_url_loader_->ResponseInfo() && + simple_url_loader_->ResponseInfo()->headers) { + response_code_ = + simple_url_loader_->ResponseInfo()->headers->response_code(); + } + simple_url_loader_.reset(); + + UMA_HISTOGRAM_CUSTOM_ENUMERATION( + "SafeBrowsing.TailoredSecurityService.OAuthTokenResponseCode", + net::HttpUtil::MapStatusCodeForHistogram(response_code_), + net::HttpUtil::GetStatusCodesForHistogram()); + + // If the response code indicates that the token might not be valid, + // invalidate the token and try again. + if (response_code_ == net::HTTP_UNAUTHORIZED && ++auth_retry_count_ <= 1) { + signin::ScopeSet oauth_scopes; + oauth_scopes.insert(kAPIScope); + identity_manager_->RemoveAccessTokenFromCache( + GetAccountForRequest(identity_manager_), oauth_scopes, access_token_); + access_token_.clear(); + Start(); + return; + } + + if (response_body) { + response_body_ = std::move(*response_body); + } else { + response_body_.clear(); + } + is_pending_ = false; + std::move(callback_).Run(this, true); + // It is valid for the callback to delete |this|, so do not access any + // members below here. + } + + signin::IdentityManager* identity_manager_; + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; + + // The URL of the API endpoint. + GURL url_; + // POST data to be sent with the request (may be empty). + absl::optional<std::string> post_data_; + + std::unique_ptr<signin::AccessTokenFetcher> access_token_fetcher_; + + // The current OAuth2 access token. + std::string access_token_; + + // Handles the actual API requests after the OAuth token is acquired. + std::unique_ptr<network::SimpleURLLoader> simple_url_loader_; + + // Holds the response code received from the server. + int response_code_ = 0; + + // Holds the response body received from the server. + std::string response_body_ = ""; + + // The number of times this request has already been retried due to + // authorization problems. + int auth_retry_count_ = 0; + + // The callback to execute when the query is complete. + TailoredSecurityService::CompletionCallback callback_; + + // True if the request was started and has not yet completed, otherwise false. + bool is_pending_ = false; + + // Network traffic annotation used to create SimpleURLLoader for this + // request. + const net::NetworkTrafficAnnotationTag traffic_annotation_; +}; + +} // namespace + +TailoredSecurityService::Request::Request() = default; + +TailoredSecurityService::Request::~Request() = default; + +TailoredSecurityService::TailoredSecurityService( + signin::IdentityManager* identity_manager, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) + : identity_manager_(identity_manager), + url_loader_factory_(std::move(url_loader_factory)) { + // Register a repeating timer to get the tailored security bit every 5 + // minutes. + timer_.Start(FROM_HERE, + base::Minutes(kRepeatingCheckTailoredSecurityBitDelayInMinutes), + this, &TailoredSecurityService::QueryTailoredSecurityBit); +} + +TailoredSecurityService::~TailoredSecurityService() = default; + +std::unique_ptr<TailoredSecurityService::Request> +TailoredSecurityService::CreateRequest( + const GURL& url, + CompletionCallback callback, + const net::NetworkTrafficAnnotationTag& traffic_annotation) { + return std::make_unique<RequestImpl>(identity_manager_, url_loader_factory_, + url, std::move(callback), + traffic_annotation); +} + +size_t +TailoredSecurityService::GetNumberOfPendingTailoredSecurityServiceRequests() { + return pending_tailored_security_requests_.size(); +} + +void TailoredSecurityService::QueryTailoredSecurityBit() { + static constexpr net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("tailored_security_service", + R"( + semantics { + description: + "Queries history.google.com to find out if user has Account level" + "Enhanced Safe Browsing enabled." + trigger: + "This request is sent every 5 minutes as long as the user does not" + "have Enhanced Safe Browsing set for their Chrome profile." + data: + "An OAuth2 token authenticating the user." + sender: "Safe Browsing" + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: NO + setting: + "To disable this feature, users uncheck the setting in Account Settings." + chrome_policy { + SafeBrowsingEnabled { + policy_options {mode: MANDATORY} + SafeBrowsingEnabled: false + } + } + })"); + + StartRequest( + base::BindOnce(&TailoredSecurityService::OnTailoredSecurityBitRetrieved, + weak_ptr_factory_.GetWeakPtr()), + traffic_annotation); +} + +void TailoredSecurityService::StartRequest( + QueryTailoredSecurityBitCallback callback, + const net::NetworkTrafficAnnotationTag& traffic_annotation) { + DCHECK(!is_shut_down_); + + // Wrap the original callback into a generic completion callback. + CompletionCallback completion_callback = base::BindOnce( + &TailoredSecurityService::QueryTailoredSecurityBitCompletionCallback, + weak_ptr_factory_.GetWeakPtr(), std::move(callback)); + GURL url(kQueryTailoredSecurityServiceUrl); + std::unique_ptr<Request> request = + CreateRequest(url, std::move(completion_callback), traffic_annotation); + Request* request_ptr = request.get(); + pending_tailored_security_requests_[request.get()] = std::move(request); + if (pending_tailored_security_requests_[request_ptr]) { + request_ptr->Start(); + } +} + +void TailoredSecurityService::OnTailoredSecurityBitRetrieved(bool is_enabled) { + // To be implemented. +} + +void TailoredSecurityService::QueryTailoredSecurityBitCompletionCallback( + QueryTailoredSecurityBitCallback callback, + Request* request, + bool success) { + DCHECK(!is_shut_down_); + + std::unique_ptr<Request> request_ptr = + std::move(pending_tailored_security_requests_[request]); + pending_tailored_security_requests_.erase(request); + + base::Value response_value; + bool tailored_security_service_enabled = false; + if (success) { + response_value = ReadResponse(request); + tailored_security_service_enabled = + response_value.is_none() + ? false + : response_value.FindBoolKey("history_recording_enabled") + .value_or(false); + } + + std::move(callback).Run(tailored_security_service_enabled); +} + +void TailoredSecurityService::SetTailoredSecurityBitForTesting( + bool is_enabled, + QueryTailoredSecurityBitCallback callback, + const net::NetworkTrafficAnnotationTag& traffic_annotation) { + // Wrap the original callback into a generic completion callback. + CompletionCallback completion_callback = base::BindOnce( + &TailoredSecurityService::QueryTailoredSecurityBitCompletionCallback, + weak_ptr_factory_.GetWeakPtr(), std::move(callback)); + + GURL url(kQueryTailoredSecurityServiceUrl); + std::unique_ptr<Request> request = + CreateRequest(url, std::move(completion_callback), traffic_annotation); + + base::DictionaryValue enable_tailored_security_service; + enable_tailored_security_service.SetBoolean("history_recording_enabled", + is_enabled); + std::string post_data; + base::JSONWriter::Write(enable_tailored_security_service, &post_data); + request->SetPostData(post_data); + + request->Start(); + Request* request_ptr = request.get(); + pending_tailored_security_requests_[request_ptr] = std::move(request); +} + +// static +base::Value TailoredSecurityService::ReadResponse(Request* request) { + base::Value result = base::Value(); + if (request->GetResponseCode() == net::HTTP_OK) { + absl::optional<base::Value> json_value = + base::JSONReader::Read(request->GetResponseBody()); + if (json_value && json_value.value().is_dict()) + result = std::move(*json_value); + else + DLOG(WARNING) << "Non-JSON response received from server."; + } + return result; +} + +void TailoredSecurityService::Shutdown() { + // |pending_tailored_security_requests_| owns the pending Request, + // clearing it will destroy all of them. + pending_tailored_security_requests_.clear(); + timer_.Stop(); + is_shut_down_ = true; +} + +} // namespace safe_browsing \ No newline at end of file
diff --git a/components/safe_browsing/core/tailored_security_service/tailored_security_service.h b/components/safe_browsing/core/tailored_security_service/tailored_security_service.h new file mode 100644 index 0000000..8be42aa --- /dev/null +++ b/components/safe_browsing/core/tailored_security_service/tailored_security_service.h
@@ -0,0 +1,146 @@ +// Copyright (c) 2021 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_SAFE_BROWSING_CORE_TAILORED_SECURITY_SERVICE_TAILORED_SECURITY_SERVICE_H_ +#define COMPONENTS_SAFE_BROWSING_CORE_TAILORED_SECURITY_SERVICE_TAILORED_SECURITY_SERVICE_H_ + +#include <stddef.h> + +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/timer/timer.h" +#include "components/keyed_service/core/keyed_service.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "url/gurl.h" + +namespace base { +class Value; +} + +namespace signin { +class IdentityManager; +} + +namespace network { +class SharedURLLoaderFactory; +} + +namespace safe_browsing { + +// Provides an API for querying Google servers for a user's tailored security +// account Opt-In. +class TailoredSecurityService : public KeyedService { + public: + // Handles all the work of making an API request. This class encapsulates + // the entire state of the request. When an instance is destroyed, all + // aspects of the request are cancelled. + class Request { + public: + virtual ~Request(); + + Request(const Request&) = delete; + Request& operator=(const Request&) = delete; + + // Returns true if the request is "pending" (i.e., it has been started, but + // is not yet completed). + virtual bool IsPending() const = 0; + + // Returns the response code received from the server, which will only be + // valid if the request succeeded. + virtual int GetResponseCode() const = 0; + + // Returns the contents of the response body received from the server. + virtual const std::string& GetResponseBody() const = 0; + + virtual void SetPostData(const std::string& post_data) = 0; + + // Tells the request to begin. + virtual void Start() = 0; + + virtual void Shutdown() = 0; + + protected: + Request(); + }; + + using QueryTailoredSecurityBitCallback = + base::OnceCallback<void(bool is_enabled)>; + + using CompletionCallback = base::OnceCallback<void(Request*, bool success)>; + + TailoredSecurityService( + signin::IdentityManager* identity_manager, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); + ~TailoredSecurityService() override; + + // Queries whether TailoredSecurity is enabled on the server. + void QueryTailoredSecurityBit(); + + // Starts the request to send to the backend to retrieve the bit. + void StartRequest(QueryTailoredSecurityBitCallback callback, + const net::NetworkTrafficAnnotationTag& traffic_annotation); + + // Sets the state of tailored security bit to |is_enabled| for testing. + void SetTailoredSecurityBitForTesting( + bool is_enabled, + QueryTailoredSecurityBitCallback callback, + const net::NetworkTrafficAnnotationTag& traffic_annotation); + + // KeyedService implementation: + void Shutdown() override; + + protected: + // This function is pulled out for testing purposes. Caller takes ownership of + // the new Request. + virtual std::unique_ptr<Request> CreateRequest( + const GURL& url, + CompletionCallback callback, + const net::NetworkTrafficAnnotationTag& traffic_annotation); + + // Used for tests. + size_t GetNumberOfPendingTailoredSecurityServiceRequests(); + + // Extracts a JSON-encoded HTTP response into a dictionary. + static base::Value ReadResponse(Request* request); + + // Called by `request` when a tailored security service query has completed. + // Unpacks the response and calls `callback`, which is the original callback + // that was passed to QueryTailoredSecurityBit(). + void QueryTailoredSecurityBitCompletionCallback( + QueryTailoredSecurityBitCallback callback, + Request* request, + bool success); + void OnTailoredSecurityBitRetrieved(bool is_enabled); + + private: + // Stores pointer to IdentityManager instance. It must outlive the + // TailoredSecurityService and can be null during tests. + signin::IdentityManager* identity_manager_; + + // Request context getter to use. + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; + + // Pending TailoredSecurity queries to be canceled if not complete by + // profile shutdown. + std::map<Request*, std::unique_ptr<Request>> + pending_tailored_security_requests_; + + // Timer to periodically check tailored security bit. + base::RepeatingTimer timer_; + + bool is_shut_down_ = false; + + base::WeakPtrFactory<TailoredSecurityService> weak_ptr_factory_{this}; +}; + +} // namespace safe_browsing + +#endif // COMPONENTS_SAFE_BROWSING_CORE_TAILORED_SECURITY_SERVICE_TAILORED_SECURITY_SERVICE_H_ \ No newline at end of file
diff --git a/components/safe_browsing/core/tailored_security_service/tailored_security_service_unittest.cc b/components/safe_browsing/core/tailored_security_service/tailored_security_service_unittest.cc new file mode 100644 index 0000000..8c0746c --- /dev/null +++ b/components/safe_browsing/core/tailored_security_service/tailored_security_service_unittest.cc
@@ -0,0 +1,415 @@ +// Copyright 2021 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/safe_browsing/core/tailored_security_service/tailored_security_service.h" + +#include <memory> + +#include "base/bind.h" +#include "base/location.h" +#include "base/macros.h" +#include "base/run_loop.h" +#include "base/task/single_thread_task_runner.h" +#include "base/test/task_environment.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/values.h" +#include "net/http/http_status_code.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::Return; + +namespace safe_browsing { + +namespace { + +const char kQueryTailoredSecurityServiceUrl[] = + "https://history.google.com/history/api/lookup?client=aesb"; + +// A testing tailored security service that does extra checks and creates a +// TestRequest instead of a normal request. +class TestingTailoredSecurityService : public TailoredSecurityService { + public: + explicit TestingTailoredSecurityService( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) + // NOTE: Simply pass null object for IdentityManager. + // TailoredSecurityService's only usage of this object is to fetch access + // tokens via RequestImpl, and TestingTailoredSecurityService deliberately + // replaces this flow with TestRequest. + : TailoredSecurityService(nullptr, url_loader_factory) {} + ~TestingTailoredSecurityService() override = default; + + std::unique_ptr<TailoredSecurityService::Request> CreateRequest( + const GURL& url, + CompletionCallback callback, + const net::NetworkTrafficAnnotationTag& traffic_annotation) override; + + // This is sorta an override but override and static don't mix. + // This function just calls TailoredSecurityService::ReadResponse. + static base::Value ReadResponse(Request* request); + + const std::string& GetExpectedPostData( + TailoredSecurityService::Request* request); + + std::string GetExpectedTailoredSecurityServiceValue(); + + void SetTailoredSecurityServiceCallback(bool is_enabled); + + void GetTailoredSecurityServiceCallback(bool is_enabled); + + void MultipleRequestsCallback(bool is_enabled); + + void SetExpectedURL(const GURL& expected_url) { + expected_url_ = expected_url; + } + + void SetExpectedTailoredSecurityServiceValue(bool expected_value) { + expected_tailored_security_service_value_ = expected_value; + } + + void SetExpectedPostData(const std::string& expected_data) { + current_expected_post_data_ = expected_data; + } + + void EnsureNoPendingRequestsRemain() { + EXPECT_EQ(0u, GetNumberOfPendingTailoredSecurityServiceRequests()); + } + + void Shutdown() override; + + private: + GURL expected_url_; + bool expected_tailored_security_service_value_; + std::string current_expected_post_data_; + std::map<Request*, std::string> expected_post_data_; +}; + +// A testing request class that allows expected values to be filled in. +class TestRequest : public TailoredSecurityService::Request { + public: + TestRequest(const GURL& url, + TailoredSecurityService::CompletionCallback callback, + int response_code, + const std::string& response_body) + : tailored_security_service_(nullptr), + url_(url), + callback_(std::move(callback)), + response_code_(response_code), + response_body_(response_body), + is_pending_(false) {} + + TestRequest(const GURL& url, + TailoredSecurityService::CompletionCallback callback, + TestingTailoredSecurityService* tailored_security_service) + : tailored_security_service_(tailored_security_service), + url_(url), + callback_(std::move(callback)), + response_code_(net::HTTP_OK), + is_pending_(false) { + response_body_ = + std::string("{\"history_recording_enabled\":") + + tailored_security_service->GetExpectedTailoredSecurityServiceValue() + + ("}"); + } + + ~TestRequest() override = default; + + // safe_browsing::Request overrides + bool IsPending() const override { return is_pending_; } + int GetResponseCode() const override { return response_code_; } + const std::string& GetResponseBody() const override { return response_body_; } + void SetPostData(const std::string& post_data) override { + post_data_ = post_data; + } + + void Shutdown() override { is_shut_down_ = true; } + + void Start() override { + is_pending_ = true; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&TestRequest::MimicReturnFromFetch, + base::Unretained(this))); + } + + void MimicReturnFromFetch() { + // Mimic a successful fetch and return. We don't actually send out a request + // in unittests. + if (is_shut_down_) + return; + EXPECT_EQ(tailored_security_service_->GetExpectedPostData(this), + post_data_); + std::move(callback_).Run(this, true); + } + + private: + TestingTailoredSecurityService* tailored_security_service_; + GURL url_; + TailoredSecurityService::CompletionCallback callback_; + int response_code_; + std::string response_body_; + std::string post_data_; + bool is_pending_; + bool is_shut_down_ = false; +}; + +std::unique_ptr<TailoredSecurityService::Request> +TestingTailoredSecurityService::CreateRequest( + const GURL& url, + CompletionCallback callback, + const net::NetworkTrafficAnnotationTag& traffic_annotation) { + EXPECT_EQ(expected_url_, url); + std::unique_ptr<TailoredSecurityService::Request> request = + std::make_unique<TestRequest>(url, std::move(callback), this); + expected_post_data_[request.get()] = current_expected_post_data_; + return request; +} + +base::Value TestingTailoredSecurityService::ReadResponse(Request* request) { + return TailoredSecurityService::ReadResponse(request); +} + +void TestingTailoredSecurityService::SetTailoredSecurityServiceCallback( + bool is_enabled) { + EXPECT_EQ(expected_tailored_security_service_value_, is_enabled); +} + +void TestingTailoredSecurityService::GetTailoredSecurityServiceCallback( + bool is_enabled) { + EXPECT_EQ(expected_tailored_security_service_value_, is_enabled); +} + +void TestingTailoredSecurityService::MultipleRequestsCallback(bool is_enabled) { + EXPECT_EQ(expected_tailored_security_service_value_, is_enabled); +} + +const std::string& TestingTailoredSecurityService::GetExpectedPostData( + Request* request) { + return expected_post_data_[request]; +} + +std::string +TestingTailoredSecurityService::GetExpectedTailoredSecurityServiceValue() { + if (expected_tailored_security_service_value_) + return "true"; + return "false"; +} + +void TestingTailoredSecurityService::Shutdown() { + for (auto request : expected_post_data_) { + request.first->Shutdown(); + } + expected_post_data_.clear(); +} + +} // namespace + +// A test class used for testing the TailoredSecurityService class. +// In order for TailoredSecurityService to be valid, we must have a valid +// ProfileSyncService. Using the ProfileSyncServiceMock class allows to +// assign specific return values as needed to make sure the tailored security +// service is available. +class TailoredSecurityServiceTest : public testing::Test { + public: + TailoredSecurityServiceTest() + : test_shared_loader_factory_( + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_)), + tailored_security_service_(test_shared_loader_factory_) {} + + ~TailoredSecurityServiceTest() override = default; + + void TearDown() override { + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + run_loop.QuitClosure()); + run_loop.Run(); + } + + TestingTailoredSecurityService* tailored_security_service() { + return &tailored_security_service_; + } + + void Shutdown() { tailored_security_service_.Shutdown(); } + + private: + base::test::SingleThreadTaskEnvironment task_environment_; + network::TestURLLoaderFactory test_url_loader_factory_; + scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_; + TestingTailoredSecurityService tailored_security_service_; +}; + +TEST_F(TailoredSecurityServiceTest, GetTailoredSecurityServiceEnabled) { + tailored_security_service()->SetExpectedURL( + GURL(kQueryTailoredSecurityServiceUrl)); + tailored_security_service()->SetExpectedTailoredSecurityServiceValue(true); + tailored_security_service()->StartRequest( + base::BindOnce( + &TestingTailoredSecurityService::GetTailoredSecurityServiceCallback, + base::Unretained(tailored_security_service())), + TRAFFIC_ANNOTATION_FOR_TESTS); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce( + &TestingTailoredSecurityService::EnsureNoPendingRequestsRemain, + base::Unretained(tailored_security_service()))); +} + +TEST_F(TailoredSecurityServiceTest, + SetTailoredSecurityBitEnabledForTestingTrue) { + tailored_security_service()->SetExpectedURL( + GURL(kQueryTailoredSecurityServiceUrl)); + tailored_security_service()->SetExpectedTailoredSecurityServiceValue(true); + tailored_security_service()->SetExpectedPostData( + "{\"history_recording_enabled\":true}"); + tailored_security_service()->SetTailoredSecurityBitForTesting( + true, + base::BindOnce( + &TestingTailoredSecurityService::SetTailoredSecurityServiceCallback, + base::Unretained(tailored_security_service())), + TRAFFIC_ANNOTATION_FOR_TESTS); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce( + &TestingTailoredSecurityService::EnsureNoPendingRequestsRemain, + base::Unretained(tailored_security_service()))); +} + +TEST_F(TailoredSecurityServiceTest, SetTailoredSecurityBitForTestingFalse) { + tailored_security_service()->SetExpectedURL( + GURL(kQueryTailoredSecurityServiceUrl)); + tailored_security_service()->SetExpectedTailoredSecurityServiceValue(false); + tailored_security_service()->SetExpectedPostData( + "{\"history_recording_enabled\":false}"); + tailored_security_service()->SetTailoredSecurityBitForTesting( + false, + base::BindOnce( + &TestingTailoredSecurityService::SetTailoredSecurityServiceCallback, + base::Unretained(tailored_security_service())), + TRAFFIC_ANNOTATION_FOR_TESTS); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce( + &TestingTailoredSecurityService::EnsureNoPendingRequestsRemain, + base::Unretained(tailored_security_service()))); +} + +TEST_F(TailoredSecurityServiceTest, MultipleRequests) { + tailored_security_service()->SetExpectedURL( + GURL(kQueryTailoredSecurityServiceUrl)); + tailored_security_service()->SetExpectedTailoredSecurityServiceValue(false); + tailored_security_service()->SetExpectedPostData( + "{\"history_recording_enabled\":false}"); + tailored_security_service()->SetTailoredSecurityBitForTesting( + false, + base::BindOnce(&TestingTailoredSecurityService::MultipleRequestsCallback, + base::Unretained(tailored_security_service())), + TRAFFIC_ANNOTATION_FOR_TESTS); + + tailored_security_service()->SetExpectedURL( + GURL(kQueryTailoredSecurityServiceUrl)); + tailored_security_service()->SetExpectedPostData(""); + tailored_security_service()->StartRequest( + base::BindOnce(&TestingTailoredSecurityService::MultipleRequestsCallback, + base::Unretained(tailored_security_service())), + TRAFFIC_ANNOTATION_FOR_TESTS); + + // Check that both requests are no longer pending. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce( + &TestingTailoredSecurityService::EnsureNoPendingRequestsRemain, + base::Unretained(tailored_security_service()))); +} + +TEST_F(TailoredSecurityServiceTest, VerifyReadResponse) { + // Test that properly formatted response with good response code returns true + // as expected. + std::unique_ptr<TailoredSecurityService::Request> request( + new TestRequest(GURL(kQueryTailoredSecurityServiceUrl), base::DoNothing(), + net::HTTP_OK, /* response code */ + "{\n" /* response body */ + " \"history_recording_enabled\": true\n" + "}")); + // ReadResponse deletes the request + base::Value response_value = + TestingTailoredSecurityService::ReadResponse(request.get()); + EXPECT_TRUE( + response_value.FindBoolKey("history_recording_enabled").value_or(false)); + // Test that properly formatted response with good response code returns false + // as expected. + std::unique_ptr<TailoredSecurityService::Request> request2(new TestRequest( + GURL(kQueryTailoredSecurityServiceUrl), base::DoNothing(), net::HTTP_OK, + "{\n" + " \"history_recording_enabled\": false\n" + "}")); + // ReadResponse deletes the request + base::Value response_value2 = + TestingTailoredSecurityService::ReadResponse(request2.get()); + EXPECT_FALSE( + response_value2.FindBoolKey("history_recording_enabled").value_or(false)); + + // Test that a bad response code returns false. + std::unique_ptr<TailoredSecurityService::Request> request3( + new TestRequest(GURL(kQueryTailoredSecurityServiceUrl), base::DoNothing(), + net::HTTP_UNAUTHORIZED, + "{\n" + " \"history_recording_enabled\": true\n" + "}")); + // ReadResponse deletes the request + base::Value response_value3 = + TestingTailoredSecurityService::ReadResponse(request3.get()); + EXPECT_TRUE(response_value3.is_none()); + + // Test that improperly formatted response returns false. + // Note: we expect to see a warning when running this test similar to + // "Non-JSON response received from history server". + // This test tests how that situation is handled. + std::unique_ptr<TailoredSecurityService::Request> request4(new TestRequest( + GURL(kQueryTailoredSecurityServiceUrl), base::DoNothing(), net::HTTP_OK, + "{\n" + " \"history_recording_enabled\": not true\n" + "}")); + // ReadResponse deletes the request + base::Value response_value4 = + TestingTailoredSecurityService::ReadResponse(request4.get()); + EXPECT_TRUE(response_value4.is_none()); + + // Test that improperly formatted response (different key) returns false. + std::unique_ptr<TailoredSecurityService::Request> request5(new TestRequest( + GURL(kQueryTailoredSecurityServiceUrl), base::DoNothing(), net::HTTP_OK, + "{\n" + " \"history_recording\": true\n" + "}")); + // ReadResponse deletes the request + base::Value response_value5 = + TestingTailoredSecurityService::ReadResponse(request5.get()); + EXPECT_FALSE( + response_value2.FindBoolKey("history_recording_enabled").value_or(false)); +} + +TEST_F(TailoredSecurityServiceTest, TestShutdown) { + tailored_security_service()->SetExpectedURL( + GURL(kQueryTailoredSecurityServiceUrl)); + tailored_security_service()->SetExpectedTailoredSecurityServiceValue(false); + tailored_security_service()->SetTailoredSecurityBitForTesting( + false, + base::BindOnce(&TestingTailoredSecurityService::MultipleRequestsCallback, + base::Unretained(tailored_security_service())), + TRAFFIC_ANNOTATION_FOR_TESTS); + + tailored_security_service()->SetExpectedURL( + GURL(kQueryTailoredSecurityServiceUrl)); + tailored_security_service()->StartRequest( + base::BindOnce(&TestingTailoredSecurityService::MultipleRequestsCallback, + base::Unretained(tailored_security_service())), + TRAFFIC_ANNOTATION_FOR_TESTS); + + Shutdown(); +} + +} // namespace safe_browsing \ No newline at end of file
diff --git a/components/security_interstitials/core/browser/resources/list_of_interstitials.html b/components/security_interstitials/core/browser/resources/list_of_interstitials.html index ccef806..026903b 100644 --- a/components/security_interstitials/core/browser/resources/list_of_interstitials.html +++ b/components/security_interstitials/core/browser/resources/list_of_interstitials.html
@@ -1,5 +1,7 @@ <html> <head> + <meta charset="utf-8"> + <meta name="color-scheme" content="light dark"> <title>Interstitials</title> <meta name="viewport" content="width=device-width"> <style>
diff --git a/components/services/heap_profiling/public/cpp/heap_profiling_trace_source_unittest.cc b/components/services/heap_profiling/public/cpp/heap_profiling_trace_source_unittest.cc index 261ffa2..9ca519b 100644 --- a/components/services/heap_profiling/public/cpp/heap_profiling_trace_source_unittest.cc +++ b/components/services/heap_profiling/public/cpp/heap_profiling_trace_source_unittest.cc
@@ -31,6 +31,7 @@ void TearDown() override { // Be sure there is no pending/running tasks. task_environment_.RunUntilIdle(); + tracing::PerfettoTracedProcess::TearDownForTesting(); } void BeginTrace() {
diff --git a/components/translate/content/browser/content_translate_driver.cc b/components/translate/content/browser/content_translate_driver.cc index 49e546a..5177eab 100644 --- a/components/translate/content/browser/content_translate_driver.cc +++ b/components/translate/content/browser/content_translate_driver.cc
@@ -388,7 +388,6 @@ void ContentTranslateDriver::OnLanguageDetectionModelFile( GetLanguageDetectionModelCallback callback, base::File model_file) { - DCHECK(model_file.IsValid()); std::move(callback).Run(std::move(model_file)); }
diff --git a/components/translate/content/browser/translate_model_service.cc b/components/translate/content/browser/translate_model_service.cc index e4f8b1d..05728a2 100644 --- a/components/translate/content/browser/translate_model_service.cc +++ b/components/translate/content/browser/translate_model_service.cc
@@ -66,7 +66,14 @@ /*model_metadata=*/absl::nullopt, this); } -TranslateModelService::~TranslateModelService() = default; +TranslateModelService::~TranslateModelService() { + for (auto& pending_request : pending_model_requests_) { + // Clear any pending requests, no model file is acceptable as shutdown is + // happening. + std::move(pending_request).Run(base::File()); + } + pending_model_requests_.clear(); +} void TranslateModelService::Shutdown() { // This and the optimization guide are keyed services, currently optimization @@ -79,6 +86,12 @@ FROM_HERE, base::BindOnce(&CloseModelFile, std::move(*language_detection_model_file_))); } + for (auto& pending_request : pending_model_requests_) { + // Clear any pending requests, no model file is acceptable as shutdown is + // happening. + std::move(pending_request).Run(base::File()); + } + pending_model_requests_.clear(); } void TranslateModelService::OnModelUpdated( @@ -124,7 +137,9 @@ if (!language_detection_model_file_) { if (pending_model_requests_.size() < kMaxPendingRequestsAllowed) { pending_model_requests_.emplace_back(std::move(callback)); + return; } + std::move(callback).Run(base::File()); return; } // The model must be valid at this point.
diff --git a/components/translate/content/renderer/translate_agent.cc b/components/translate/content/renderer/translate_agent.cc index d8efcf17..195bde4 100644 --- a/components/translate/content/renderer/translate_agent.cc +++ b/components/translate/content/renderer/translate_agent.cc
@@ -24,7 +24,6 @@ #include "components/translate/content/renderer/isolated_world_util.h" #include "components/translate/core/common/translate_constants.h" #include "components/translate/core/common/translate_metrics.h" -#include "components/translate/core/common/translate_switches.h" #include "components/translate/core/common/translate_util.h" #include "components/translate/core/language_detection/language_detection_model.h" #include "components/translate/core/language_detection/language_detection_util.h" @@ -76,6 +75,16 @@ return *instance; } +// Returns if the language detection should be overridden so that a default +// result is returned immediately. +bool ShouldOverrideLanguageDetectionForTesting() { + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(::switches::kOverrideLanguageDetection)) { + return true; + } + return false; +} + } // namespace namespace translate { @@ -198,6 +207,19 @@ std::string detection_model_version; float model_reliability_score = 0.0; + if (ShouldOverrideLanguageDetectionForTesting()) { + std::string language = "fr"; + LanguageDetectionDetails details; + details.adopted_language = language; + details.contents = contents; + ResetPage(); + GetTranslateHandler()->RegisterPage( + receiver_.BindNewPipeAndPassRemote( + main_frame->GetTaskRunner(blink::TaskType::kInternalTranslation)), + details, !details.has_notranslate && !language.empty()); + return; + } + std::string language; if (translate::IsTFLiteLanguageDetectionEnabled()) { translate::LanguageDetectionModel& language_detection_model =
diff --git a/components/translate/core/common/translate_util.cc b/components/translate/core/common/translate_util.cc index f9acc6d..749e597 100644 --- a/components/translate/core/common/translate_util.cc +++ b/components/translate/core/common/translate_util.cc
@@ -8,6 +8,7 @@ #include "base/command_line.h" #include "base/metrics/field_trial_params.h" +#include "build/build_config.h" #include "components/translate/core/common/translate_switches.h" namespace translate { @@ -26,7 +27,15 @@ base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kTFLiteLanguageDetectionEnabled{ - "TFLiteLanguageDetectionEnabled", base::FEATURE_DISABLED_BY_DEFAULT}; + "TFLiteLanguageDetectionEnabled", +#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_WIN) || \ + defined(OS_MAC) + base::FEATURE_ENABLED_BY_DEFAULT +#else // !defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(OS_WIN) && + // !defined(OS_MAC) + base::FEATURE_DISABLED_BY_DEFAULT +#endif +}; GURL GetTranslateSecurityOrigin() { std::string security_origin(kSecurityOrigin);
diff --git a/components/variations/variations_seed_store.cc b/components/variations/variations_seed_store.cc index cd43ff3..3ef06da 100644 --- a/components/variations/variations_seed_store.cc +++ b/components/variations/variations_seed_store.cc
@@ -431,6 +431,17 @@ return VerifySeedSignature(seed_bytes, base64_seed_signature); } +// It is intentional that country-related prefs are retained for regular seeds +// and cleared for safe seeds. +// +// For regular seeds, the prefs are kept for two reasons. First, it's better to +// have some idea of a country recently associated with the device. Second, some +// past, country-gated launches started relying on the VariationsService- +// provided country when they retired server-side configs. +// +// The safe seed prefs are needed to correctly apply a safe seed, so if the safe +// seed is cleared, there's no reason to retain them as they may be incorrect +// for the next safe seed. void VariationsSeedStore::ClearPrefs(SeedType seed_type) { if (seed_type == SeedType::LATEST) { local_state_->ClearPref(prefs::kVariationsCompressedSeed);
diff --git a/content/browser/accessibility/accessibility_tree_formatter_utils_mac.h b/content/browser/accessibility/accessibility_tree_formatter_utils_mac.h index f1a8234..b4ee3bf1 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_utils_mac.h +++ b/content/browser/accessibility/accessibility_tree_formatter_utils_mac.h
@@ -112,6 +112,11 @@ const id target, const ui::AXPropertyNode& property_node) const; + // Invokes a property node for a given dictionary. + OptionalNSObject InvokeForDictionary( + const id target, + const ui::AXPropertyNode& property_node) const; + // Returns a parameterized attribute parameter by a property node. OptionalNSObject ParamByPropertyNode(const ui::AXPropertyNode&) const;
diff --git a/content/browser/accessibility/accessibility_tree_formatter_utils_mac.mm b/content/browser/accessibility/accessibility_tree_formatter_utils_mac.mm index c84d096..e5fc628 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_utils_mac.mm +++ b/content/browser/accessibility/accessibility_tree_formatter_utils_mac.mm
@@ -189,6 +189,9 @@ if ([target isKindOfClass:[NSArray class]]) return InvokeForArray(target, property_node); + if ([target isKindOfClass:[NSDictionary class]]) + return InvokeForDictionary(target, property_node); + LOG(ERROR) << "Unexpected target type for " << property_node.ToFlatString(); return OptionalNSObject::Error(); } @@ -321,6 +324,20 @@ return OptionalNSObject(target[*maybe_index]); } +OptionalNSObject AttributeInvoker::InvokeForDictionary( + const id target, + const AXPropertyNode& property_node) const { + if (property_node.arguments.size() > 0) { + LOG(ERROR) << "dictionary key is expected, got: " + << property_node.ToString(); + return OptionalNSObject::Error(); + } + + NSString* key = PropertyNodeToString(property_node); + NSDictionary* dictionary = target; + return OptionalNSObject::NotNilOrError(dictionary[key]); +} + OptionalNSObject AttributeInvoker::GetValue( const std::string& property_name, const OptionalNSObject& param) const {
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index b954b06..b0b4ac5 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -211,6 +211,8 @@ NSString* const NSAccessibilityMathSuperscriptAttribute = @"AXMathSuperscript"; NSString* const NSAccessibilityMathUnderAttribute = @"AXMathUnder"; NSString* const NSAccessibilityMathOverAttribute = @"AXMathOver"; +NSString* const NSAccessibilityMathPostscriptsAttribute = @"AXMathPostscripts"; +NSString* const NSAccessibilityMathPrescriptsAttribute = @"AXMathPrescripts"; // Private attributes that can be used for testing text markers, e.g. in dump // tree tests. @@ -863,6 +865,8 @@ @"mathFractionDenominator"}, {NSAccessibilityMathFractionNumeratorAttribute, @"mathFractionNumerator"}, {NSAccessibilityMathOverAttribute, @"mathOver"}, + {NSAccessibilityMathPostscriptsAttribute, @"mathPostscripts"}, + {NSAccessibilityMathPrescriptsAttribute, @"mathPrescripts"}, {NSAccessibilityMathRootIndexAttribute, @"mathRootIndex"}, {NSAccessibilityMathRootRadicandAttribute, @"mathRootRadicand"}, {NSAccessibilityMathSubscriptAttribute, @"mathSubscript"}, @@ -1148,6 +1152,74 @@ return nil; } +static NSDictionary* createMathSubSupScriptsPair( + BrowserAccessibilityCocoa* subscript, + BrowserAccessibilityCocoa* superscript) { + BrowserAccessibilityCocoa* nodes[2]; + NSString* keys[2]; + NSUInteger count = 0; + if (subscript) { + nodes[count] = subscript; + keys[count] = NSAccessibilityMathSubscriptAttribute; + count++; + } + if (superscript) { + nodes[count] = superscript; + keys[count] = NSAccessibilityMathSuperscriptAttribute; + count++; + } + return [[NSDictionary alloc] initWithObjects:nodes forKeys:keys count:count]; +} + +- (NSArray*)mathPostscripts { + if (![self instanceActive] || + [self internalRole] != ax::mojom::Role::kMathMLMultiscripts) + return nil; + NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease]; + bool foundBaseElement = false; + BrowserAccessibilityCocoa* subscript = nullptr; + for (BrowserAccessibilityCocoa* child in [self children]) { + if ([child internalRole] == ax::mojom::Role::kMathMLPrescriptDelimiter) + break; + if (!foundBaseElement) { + foundBaseElement = true; + continue; + } + if (!subscript) { + subscript = child; + continue; + } + BrowserAccessibilityCocoa* superscript = child; + [ret addObject:createMathSubSupScriptsPair(subscript, superscript)]; + subscript = nullptr; + } + return [ret count] ? ret : nil; +} + +- (NSArray*)mathPrescripts { + if (![self instanceActive] || + [self internalRole] != ax::mojom::Role::kMathMLMultiscripts) + return nil; + NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease]; + bool foundPrescriptDelimiter = false; + BrowserAccessibilityCocoa* subscript = nullptr; + for (BrowserAccessibilityCocoa* child in [self children]) { + if (!foundPrescriptDelimiter) { + foundPrescriptDelimiter = + ([child internalRole] == ax::mojom::Role::kMathMLPrescriptDelimiter); + continue; + } + if (!subscript) { + subscript = child; + continue; + } + BrowserAccessibilityCocoa* superscript = child; + [ret addObject:createMathSubSupScriptsPair(subscript, superscript)]; + subscript = nullptr; + } + return [ret count] ? ret : nil; +} + - (NSArray*)AXChildren { return [self children]; } @@ -3726,6 +3798,11 @@ NSAccessibilityMathBaseAttribute, NSAccessibilityMathUnderAttribute, NSAccessibilityMathOverAttribute ]]; + } else if ([self internalRole] == ax::mojom::Role::kMathMLMultiscripts) { + [ret addObjectsFromArray:@[ + NSAccessibilityMathPostscriptsAttribute, + NSAccessibilityMathPrescriptsAttribute + ]]; } // Caret navigation and text selection attributes.
diff --git a/content/browser/accessibility/dump_accessibility_scripts_browsertest.cc b/content/browser/accessibility/dump_accessibility_scripts_browsertest.cc index cbbe17a..a8256bc1 100644 --- a/content/browser/accessibility/dump_accessibility_scripts_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_scripts_browsertest.cc
@@ -237,6 +237,11 @@ RunTypedTest<kMacMathML>(FILE_PATH_LITERAL("subsup-attributes.html")); } +IN_PROC_BROWSER_TEST_P(DumpAccessibilityScriptTest, + MathMLMultiscriptsAttributes) { + RunTypedTest<kMacMathML>(FILE_PATH_LITERAL("multiscripts-attributes.html")); +} + #endif } // namespace content
diff --git a/content/browser/aggregation_service/aggregatable_report_assembler.cc b/content/browser/aggregation_service/aggregatable_report_assembler.cc index ed334556..10596f1f 100644 --- a/content/browser/aggregation_service/aggregatable_report_assembler.cc +++ b/content/browser/aggregation_service/aggregatable_report_assembler.cc
@@ -13,6 +13,7 @@ #include "base/check_op.h" #include "base/containers/contains.h" #include "base/memory/ptr_util.h" +#include "base/memory/scoped_refptr.h" #include "base/ranges/algorithm.h" #include "base/time/default_clock.h" #include "content/browser/aggregation_service/aggregatable_report.h" @@ -21,6 +22,7 @@ #include "content/browser/aggregation_service/aggregation_service_network_fetcher_impl.h" #include "content/browser/aggregation_service/public_key.h" #include "content/public/browser/storage_partition.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/origin.h" @@ -38,6 +40,18 @@ std::make_unique<AggregatableReport::Provider>()) {} AggregatableReportAssembler::AggregatableReportAssembler( + AggregatableReportManager* manager, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) + : AggregatableReportAssembler( + std::make_unique<AggregationServiceKeyFetcher>( + manager, + AggregationServiceNetworkFetcherImpl:: + CreateForTesting( // IN-TEST + base::DefaultClock::GetInstance(), + std::move(url_loader_factory))), + std::make_unique<AggregatableReport::Provider>()) {} + +AggregatableReportAssembler::AggregatableReportAssembler( std::unique_ptr<AggregationServiceKeyFetcher> fetcher, std::unique_ptr<AggregatableReport::Provider> report_provider) : fetcher_(std::move(fetcher)), @@ -73,6 +87,15 @@ std::move(fetcher), std::move(report_provider))); } +// static +std::unique_ptr<AggregatableReportAssembler> +AggregatableReportAssembler::CreateForTesting( + AggregatableReportManager* manager, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { + return base::WrapUnique( + new AggregatableReportAssembler(manager, std::move(url_loader_factory))); +} + void AggregatableReportAssembler::AssembleReport( AggregatableReportRequest report_request, AssemblyCallback callback) {
diff --git a/content/browser/aggregation_service/aggregatable_report_assembler.h b/content/browser/aggregation_service/aggregatable_report_assembler.h index 5481746..15060c35 100644 --- a/content/browser/aggregation_service/aggregatable_report_assembler.h +++ b/content/browser/aggregation_service/aggregatable_report_assembler.h
@@ -21,6 +21,13 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "url/origin.h" +template <class T> +class scoped_refptr; + +namespace network { +class SharedURLLoaderFactory; +} // namespace network + namespace content { class AggregatableReportManager; @@ -53,8 +60,8 @@ // the possibility of unbounded memory growth static constexpr size_t kMaxSimultaneousRequests = 1000; - explicit AggregatableReportAssembler(AggregatableReportManager* manager, - StoragePartition* storage_partition); + AggregatableReportAssembler(AggregatableReportManager* manager, + StoragePartition* storage_partition); // Not copyable or movable. AggregatableReportAssembler(const AggregatableReportAssembler& other) = delete; @@ -66,6 +73,12 @@ std::unique_ptr<AggregationServiceKeyFetcher> fetcher, std::unique_ptr<AggregatableReport::Provider> report_provider); + // Used by the aggregation service tool to inject a `url_loader_factory` to + // AggregationServiceNetworkFetcherImpl if one is provided. + static std::unique_ptr<AggregatableReportAssembler> CreateForTesting( + AggregatableReportManager* manager, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); + // Fetches the necessary public keys and uses it to construct an // AggregatableReport from the information in `report_request`. See the // AggregatableReport documentation for more detail on the returned report. @@ -100,6 +113,11 @@ std::unique_ptr<AggregationServiceKeyFetcher> fetcher, std::unique_ptr<AggregatableReport::Provider> report_provider); + // For testing only. + AggregatableReportAssembler( + AggregatableReportManager* manager, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); + // Called when a result is returned from the key fetcher. Handles throwing // errors on a failed fetch, waiting for both results to return and calling // into `OnBothPublicKeysFetched()` when appropriate.
diff --git a/content/browser/aggregation_service/aggregatable_report_sender.cc b/content/browser/aggregation_service/aggregatable_report_sender.cc index de4902a..6eb57de4 100644 --- a/content/browser/aggregation_service/aggregatable_report_sender.cc +++ b/content/browser/aggregation_service/aggregatable_report_sender.cc
@@ -11,6 +11,7 @@ #include "base/callback.h" #include "base/check.h" #include "base/json/json_string_value_serializer.h" +#include "base/memory/ptr_util.h" #include "base/memory/scoped_refptr.h" #include "base/metrics/histogram_functions.h" #include "base/time/time.h" @@ -32,13 +33,31 @@ AggregatableReportSender::AggregatableReportSender( StoragePartition* storage_partition) - : storage_partition_(storage_partition) {} + : storage_partition_(storage_partition) { + DCHECK(storage_partition_); +} + +AggregatableReportSender::AggregatableReportSender( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) + : url_loader_factory_(std::move(url_loader_factory)) { + DCHECK(url_loader_factory_); +} AggregatableReportSender::~AggregatableReportSender() = default; +// static +std::unique_ptr<AggregatableReportSender> +AggregatableReportSender::CreateForTesting( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { + return base::WrapUnique( + new AggregatableReportSender(std::move(url_loader_factory))); +} + void AggregatableReportSender::SendReport(const GURL& url, const base::Value& contents, ReportSentCallback callback) { + DCHECK(storage_partition_ || url_loader_factory_); + // The browser process URLLoaderFactory is not created by default, so don't // create it until it is directly needed. if (!url_loader_factory_) { @@ -121,11 +140,6 @@ std::move(callback))); } -void AggregatableReportSender::SetURLLoaderFactoryForTesting( - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { - url_loader_factory_ = url_loader_factory; -} - void AggregatableReportSender::OnReportSent( UrlLoaderList::iterator it, ReportSentCallback callback,
diff --git a/content/browser/aggregation_service/aggregatable_report_sender.h b/content/browser/aggregation_service/aggregatable_report_sender.h index fce045a1..d2fd9f0 100644 --- a/content/browser/aggregation_service/aggregatable_report_sender.h +++ b/content/browser/aggregation_service/aggregatable_report_sender.h
@@ -58,16 +58,20 @@ const base::Value& contents, ReportSentCallback callback); - // Tests inject a TestURLLoaderFactory so they can mock the network response. - // Also called by the aggregation service tool to inject a - // network::mojom::URLLoaderFactory. - void SetURLLoaderFactoryForTesting( + // Used by tests to inject a TestURLLoaderFactory so they can mock the + // network response. Also used by the aggregation service tool to inject a + // `url_loader_factory` if one is provided. + static std::unique_ptr<AggregatableReportSender> CreateForTesting( scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); private: // This is a std::list so that iterators remain valid during modifications. using UrlLoaderList = std::list<std::unique_ptr<network::SimpleURLLoader>>; + // For testing only. + explicit AggregatableReportSender( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); + // Called when headers are available for a sent report. void OnReportSent(UrlLoaderList::iterator it, ReportSentCallback callback, @@ -76,7 +80,7 @@ // Reports that are actively being sent. UrlLoaderList loaders_in_progress_; - // Must outlive `this`. + // Might be `nullptr` for testing, otherwise must outlive `this`. StoragePartition* storage_partition_; // Lazily accessed URLLoaderFactory used for network requests.
diff --git a/content/browser/aggregation_service/aggregatable_report_sender_unittest.cc b/content/browser/aggregation_service/aggregatable_report_sender_unittest.cc index 3ba1c83..ce29ec3 100644 --- a/content/browser/aggregation_service/aggregatable_report_sender_unittest.cc +++ b/content/browser/aggregation_service/aggregatable_report_sender_unittest.cc
@@ -13,7 +13,6 @@ #include "content/public/test/browser_task_environment.h" #include "net/base/isolation_info.h" #include "net/base/load_flags.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/public/mojom/url_response_head.mojom.h" #include "services/network/test/test_url_loader_factory.h" @@ -39,21 +38,14 @@ public: AggregatableReportSenderTest() : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME), - sender_(std::make_unique<AggregatableReportSender>( - /*storage_partition=*/nullptr)), - shared_url_loader_factory_( + sender_(AggregatableReportSender::CreateForTesting( base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( - &test_url_loader_factory_)) { - sender_->SetURLLoaderFactoryForTesting(shared_url_loader_factory_); - } + &test_url_loader_factory_))) {} protected: content::BrowserTaskEnvironment task_environment_; - std::unique_ptr<AggregatableReportSender> sender_; network::TestURLLoaderFactory test_url_loader_factory_; - - private: - scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_; + std::unique_ptr<AggregatableReportSender> sender_; }; TEST_F(AggregatableReportSenderTest, ReportSent_RequestAttributesSet) {
diff --git a/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc b/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc index 6b5e6d9..207c0e8b 100644 --- a/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc +++ b/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc
@@ -10,6 +10,8 @@ #include "base/bind.h" #include "base/callback.h" +#include "base/check.h" +#include "base/memory/ptr_util.h" #include "base/memory/scoped_refptr.h" #include "base/time/clock.h" #include "base/time/time.h" @@ -46,19 +48,41 @@ AggregationServiceNetworkFetcherImpl::AggregationServiceNetworkFetcherImpl( const base::Clock* clock, StoragePartition* storage_partition) - : clock_(*clock), storage_partition_(*storage_partition) {} + : clock_(*clock), storage_partition_(storage_partition) { + DCHECK(clock); + DCHECK(storage_partition_); +} + +AggregationServiceNetworkFetcherImpl::AggregationServiceNetworkFetcherImpl( + const base::Clock* clock, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) + : clock_(*clock), url_loader_factory_(std::move(url_loader_factory)) { + DCHECK(clock); + DCHECK(url_loader_factory_); +} AggregationServiceNetworkFetcherImpl::~AggregationServiceNetworkFetcherImpl() = default; +// static +std::unique_ptr<AggregationServiceNetworkFetcherImpl> +AggregationServiceNetworkFetcherImpl::CreateForTesting( + const base::Clock* clock, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { + return base::WrapUnique(new AggregationServiceNetworkFetcherImpl( + clock, std::move(url_loader_factory))); +} + void AggregationServiceNetworkFetcherImpl::FetchPublicKeys( const url::Origin& origin, NetworkFetchCallback callback) { + DCHECK(storage_partition_ || url_loader_factory_); + // The browser process URLLoaderFactory is not created by default, so don't // create it until it is directly needed. if (!url_loader_factory_) { url_loader_factory_ = - storage_partition_.GetURLLoaderFactoryForBrowserProcess(); + storage_partition_->GetURLLoaderFactoryForBrowserProcess(); } GURL public_key_url = GetPublicKeyUrl(origin); @@ -128,11 +152,6 @@ kMaxJsonSize); } -void AggregationServiceNetworkFetcherImpl::SetURLLoaderFactoryForTesting( - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { - url_loader_factory_ = url_loader_factory; -} - void AggregationServiceNetworkFetcherImpl::OnSimpleLoaderComplete( UrlLoaderList::iterator it, const url::Origin& origin,
diff --git a/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.h b/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.h index 377b32e7..2d346da 100644 --- a/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.h +++ b/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.h
@@ -36,8 +36,7 @@ class CONTENT_EXPORT AggregationServiceNetworkFetcherImpl : public AggregationServiceKeyFetcher::NetworkFetcher { public: - // `clock` and `storage_partition` must be non-null pointers that are valid as - // long as this object. + // `clock` must be a non-null pointer that is valid as long as this object. AggregationServiceNetworkFetcherImpl(const base::Clock* clock, StoragePartition* storage_partition); AggregationServiceNetworkFetcherImpl( @@ -49,8 +48,11 @@ void FetchPublicKeys(const url::Origin& origin, NetworkFetchCallback callback) override; - // Tests inject a TestURLLoaderFactory so they can mock the network response. - void SetURLLoaderFactoryForTesting( + // Used by tests to inject a TestURLLoaderFactory so they can mock the + // network response. Also used by the aggregation service tool to inject a + // `url_loader_factory` if one is provided. + static std::unique_ptr<AggregationServiceNetworkFetcherImpl> CreateForTesting( + const base::Clock* clock, scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); private: @@ -63,6 +65,11 @@ // This is a std::list so that iterators remain valid during modifications. using UrlLoaderList = std::list<std::unique_ptr<network::SimpleURLLoader>>; + // For testing only. + AggregationServiceNetworkFetcherImpl( + const base::Clock* clock, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); + // Invoked from SimpleURLLoader after download is complete. void OnSimpleLoaderComplete(UrlLoaderList::iterator it, const url::Origin& origin, @@ -87,7 +94,8 @@ const base::Clock& clock_; - StoragePartition& storage_partition_; + // Might be `nullptr` for testing, otherwise must outlive `this`. + StoragePartition* storage_partition_; // Lazily accessed URLLoaderFactory used for network requests. scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
diff --git a/content/browser/aggregation_service/aggregation_service_network_fetcher_impl_unittest.cc b/content/browser/aggregation_service/aggregation_service_network_fetcher_impl_unittest.cc index c2d5ed7..2a7d01be 100644 --- a/content/browser/aggregation_service/aggregation_service_network_fetcher_impl_unittest.cc +++ b/content/browser/aggregation_service/aggregation_service_network_fetcher_impl_unittest.cc
@@ -20,7 +20,6 @@ #include "net/http/http_status_code.h" #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "services/network/public/cpp/resource_request.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/url_loader_completion_status.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/public/mojom/url_response_head.mojom.h" @@ -58,23 +57,17 @@ public: AggregationServiceNetworkFetcherTest() : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME), - network_fetcher_(std::make_unique<AggregationServiceNetworkFetcherImpl>( + network_fetcher_(AggregationServiceNetworkFetcherImpl::CreateForTesting( task_environment_.GetMockClock(), - /*storage_partition=*/nullptr)), - shared_url_loader_factory_( base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( - &test_url_loader_factory_)) { - network_fetcher_->SetURLLoaderFactoryForTesting(shared_url_loader_factory_); - } + &test_url_loader_factory_))) {} protected: content::BrowserTaskEnvironment task_environment_; - - std::unique_ptr<AggregationServiceNetworkFetcherImpl> network_fetcher_; network::TestURLLoaderFactory test_url_loader_factory_; + std::unique_ptr<AggregationServiceNetworkFetcherImpl> network_fetcher_; private: - scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_; data_decoder::test::InProcessDataDecoder in_process_data_decoder_; };
diff --git a/content/browser/appcache/appcache_internals_ui.cc b/content/browser/appcache/appcache_internals_ui.cc index 26a1d05d..3ba3699 100644 --- a/content/browser/appcache/appcache_internals_ui.cc +++ b/content/browser/appcache/appcache_internals_ui.cc
@@ -390,10 +390,6 @@ StoragePartition* storage_partition) { auto proxy = base::MakeRefCounted<Proxy>(weak_ptr_factory_.GetWeakPtr(), storage_partition->GetPath()); - auto* appcache_service = static_cast<StoragePartitionImpl*>(storage_partition) - ->GetAppCacheService(); - if (appcache_service) - proxy->Initialize(appcache_service); appcache_proxies_.emplace_back(std::move(proxy)); }
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc index 02e748a..8b769654 100644 --- a/content/browser/browser_context.cc +++ b/content/browser/browser_context.cc
@@ -70,10 +70,6 @@ using perfetto::protos::pbzero::ChromeBrowserContext; using perfetto::protos::pbzero::ChromeTrackEvent; -void SaveSessionStateOnIOThread(AppCacheServiceImpl* appcache_service) { - appcache_service->set_force_keep_session_state(); -} - base::WeakPtr<storage::BlobStorageContext> BlobStorageContextGetterForBrowser( scoped_refptr<ChromeBlobStorageContext> blob_context) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -266,16 +262,6 @@ base::BindOnce(&storage::DatabaseTracker::SetForceKeepSessionState, base::WrapRefCounted(database_tracker))); - if (BrowserThread::IsThreadInitialized(BrowserThread::IO)) { - auto* appcache_service = static_cast<AppCacheServiceImpl*>( - storage_partition->GetAppCacheService()); - if (appcache_service) { - GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, - base::BindOnce(&SaveSessionStateOnIOThread, appcache_service)); - } - } - storage_partition->GetCookieManagerForBrowserProcess() ->SetForceKeepSessionState();
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index d025cf9f..b897fbc 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc
@@ -88,7 +88,6 @@ #include "services/shape_detection/public/mojom/shape_detection_service.mojom.h" #include "services/shape_detection/public/mojom/textdetection.mojom.h" #include "third_party/blink/public/common/features.h" -#include "third_party/blink/public/mojom/appcache/appcache.mojom.h" #include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom.h" #include "third_party/blink/public/mojom/background_sync/background_sync.mojom.h" #include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom.h" @@ -638,11 +637,6 @@ // Documents/frames void PopulateFrameBinders(RenderFrameHostImpl* host, mojo::BinderMap* map) { - if (StoragePartition::IsAppCacheEnabled()) { - map->Add<blink::mojom::AppCacheBackend>(base::BindRepeating( - &RenderFrameHostImpl::CreateAppCacheBackend, base::Unretained(host))); - } - map->Add<blink::mojom::AudioContextManager>(base::BindRepeating( &RenderFrameHostImpl::GetAudioContextManager, base::Unretained(host)));
diff --git a/content/browser/file_system_access/file_system_access_manager_impl.cc b/content/browser/file_system_access/file_system_access_manager_impl.cc index be72e69..55f4553 100644 --- a/content/browser/file_system_access/file_system_access_manager_impl.cc +++ b/content/browser/file_system_access/file_system_access_manager_impl.cc
@@ -48,6 +48,7 @@ #include "storage/browser/file_system/file_system_operation_runner.h" #include "storage/browser/file_system/file_system_url.h" #include "storage/browser/file_system/file_system_util.h" +#include "storage/browser/quota/quota_manager_proxy.h" #include "storage/common/file_system/file_system_types.h" #include "storage/common/file_system/file_system_util.h" #include "third_party/blink/public/common/storage_key/storage_key.h"
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index ee96ce7..59285cc 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -9542,28 +9542,6 @@ std::move(receiver), ComputeTopFrameOrigin(GetLastCommittedOrigin())); } -void RenderFrameHostImpl::CreateAppCacheBackend( - mojo::PendingReceiver<blink::mojom::AppCacheBackend> receiver) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(StoragePartition::IsAppCacheEnabled()); - SCOPED_CRASH_KEY_STRING64( - "CreateAppCacheBackend", "data", - base::StringPrintf( - "f=%d br=%d irfl=%d iiand=%d fid=%d", frame_.is_bound(), - broker_receiver_.is_bound(), IsRenderFrameLive(), - GetProcess()->IsInitializedAndNotDead(), - RenderProcessHost::FromID(GetProcess()->GetID()) != nullptr)); - - auto* storage_partition_impl = - static_cast<StoragePartitionImpl*>(GetProcess()->GetStoragePartition()); - auto* appcache_service = storage_partition_impl->GetAppCacheService(); - // CreateAppCacheBackend should only be called if AppCache is enabled - // (which implies the service exists). - DCHECK(appcache_service); - appcache_service->CreateBackend(GetProcess()->GetID(), routing_id_, - std::move(receiver)); -} - void RenderFrameHostImpl::GetAudioContextManager( mojo::PendingReceiver<blink::mojom::AudioContextManager> receiver) { AudioContextManagerImpl::Create(this, std::move(receiver));
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index 6cf303a..f6526f45 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -1621,9 +1621,6 @@ // Set the `frame_` for sending messages to the renderer process. void SetMojomFrameRemote(mojo::PendingAssociatedRemote<mojom::Frame>); - void CreateAppCacheBackend( - mojo::PendingReceiver<blink::mojom::AppCacheBackend> receiver); - void GetAudioContextManager( mojo::PendingReceiver<blink::mojom::AudioContextManager> receiver);
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc index c897f4d..3755ca1 100644 --- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -3501,8 +3501,29 @@ .party_context()); } +class RenderFrameHostImplNoStrictSiteIsolationOnAndroidBrowserTest + : public RenderFrameHostImplBrowserTest { + public: + RenderFrameHostImplNoStrictSiteIsolationOnAndroidBrowserTest() = default; + ~RenderFrameHostImplNoStrictSiteIsolationOnAndroidBrowserTest() override = + default; + + void SetUpCommandLine(base::CommandLine* command_line) override { + RenderFrameHostImplBrowserTest::SetUpCommandLine(command_line); + +#if defined(OS_ANDROID) + // On Android, --site-per-process may be passed on some bots to force strict + // site isolation. That causes this test too create a lot of processes and + // time out due to running too slowly, so force this test to run without + // strict site isolation on Android. This is ok since this test doesn't + // actually care about process isolation. + command_line->RemoveSwitch(switches::kSitePerProcess); +#endif + } +}; + IN_PROC_BROWSER_TEST_F( - RenderFrameHostImplBrowserTest, + RenderFrameHostImplNoStrictSiteIsolationOnAndroidBrowserTest, ComputeIsolationInfoForNavigationPartyContextExceedMaxSize) { GURL url = embedded_test_server()->GetURL( "a.com",
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 1784863..6100853 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3470,6 +3470,7 @@ switches::kMSEAudioBufferSizeLimitMb, switches::kMSEVideoBufferSizeLimitMb, switches::kNoZygote, + switches::kOverrideLanguageDetection, switches::kPerfettoDisableInterning, switches::kPpapiInProcess, switches::kProfilingAtStart,
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index 4e0cfa2..3f6e4198 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -1112,9 +1112,6 @@ if (GetContentIndexContext()) GetContentIndexContext()->Shutdown(); - if (GetAppCacheService()) - GetAppCacheService()->Shutdown(); - if (GetGeneratedCodeCacheContext()) GetGeneratedCodeCacheContext()->Shutdown(); } @@ -1224,11 +1221,6 @@ service_worker_context_ = new ServiceWorkerContextWrapper(browser_context_); service_worker_context_->set_storage_partition(this); - if (StoragePartition::IsAppCacheEnabled()) { - appcache_service_ = base::MakeRefCounted<ChromeAppCacheService>( - quota_manager_proxy, weak_factory_.GetWeakPtr()); - } - dedicated_worker_service_ = std::make_unique<DedicatedWorkerServiceImpl>(); native_io_context_ = base::MakeRefCounted<NativeIOContextImpl>(); @@ -1445,11 +1437,6 @@ return quota_manager_.get(); } -ChromeAppCacheService* StoragePartitionImpl::GetAppCacheService() { - DCHECK(initialized_); - return appcache_service_.get(); -} - BackgroundSyncContextImpl* StoragePartitionImpl::GetBackgroundSyncContext() { DCHECK(initialized_); return background_sync_context_.get(); @@ -2797,10 +2784,6 @@ g_test_quota_settings = settings; } -bool StoragePartition::IsAppCacheEnabled() { - return base::FeatureList::IsEnabled(blink::features::kAppCache); -} - mojo::PendingRemote<network::mojom::CookieAccessObserver> StoragePartitionImpl::CreateCookieAccessObserverForServiceWorker() { mojo::PendingRemote<network::mojom::CookieAccessObserver> remote;
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h index 8e825fa..53217f2 100644 --- a/content/browser/storage_partition_impl.h +++ b/content/browser/storage_partition_impl.h
@@ -20,7 +20,6 @@ #include "build/chromeos_buildflags.h" #include "components/services/storage/public/mojom/partition.mojom.h" #include "components/services/storage/public/mojom/storage_service.mojom-forward.h" -#include "content/browser/appcache/chrome_appcache_service.h" #include "content/browser/background_sync/background_sync_context_impl.h" #include "content/browser/broadcast_channel/broadcast_channel_service.h" #include "content/browser/child_process_security_policy_impl.h" @@ -43,6 +42,8 @@ #include "mojo/public/cpp/bindings/remote.h" #include "services/network/public/mojom/cookie_manager.mojom.h" #include "services/network/public/mojom/network_context.mojom.h" +#include "storage/browser/quota/quota_client_type.h" +#include "storage/browser/quota/quota_settings.h" #include "third_party/blink/public/common/tokens/tokens.h" #include "third_party/blink/public/mojom/dom_storage/dom_storage.mojom.h" @@ -148,7 +149,6 @@ CreateURLLoaderNetworkObserverForNavigationRequest( int frame_tree_id) override; storage::QuotaManager* GetQuotaManager() override; - ChromeAppCacheService* GetAppCacheService() override; BackgroundSyncContextImpl* GetBackgroundSyncContext() override; storage::FileSystemContext* GetFileSystemContext() override; FontAccessContext* GetFontAccessContext() override; @@ -536,7 +536,6 @@ scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter_; scoped_refptr<QuotaContext> quota_context_; scoped_refptr<storage::QuotaManager> quota_manager_; - scoped_refptr<ChromeAppCacheService> appcache_service_; scoped_refptr<storage::FileSystemContext> filesystem_context_; scoped_refptr<storage::DatabaseTracker> database_tracker_; scoped_refptr<DOMStorageContextWrapper> dom_storage_context_;
diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc index ef2839b9..696dab54 100644 --- a/content/browser/storage_partition_impl_map.cc +++ b/content/browser/storage_partition_impl_map.cc
@@ -23,7 +23,6 @@ #include "base/task/thread_pool.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" -#include "content/browser/appcache/chrome_appcache_service.h" #include "content/browser/background_fetch/background_fetch_context.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/code_cache/generated_code_cache_context.h" @@ -463,14 +462,9 @@ InitializeResourceContext(browser_context_); } - if (StoragePartition::IsAppCacheEnabled()) { - partition->GetAppCacheService()->Initialize( - in_memory ? base::FilePath() - : partition->GetPath().Append(kAppCacheDirname), - browser_context_, browser_context_->GetSpecialStoragePolicy()); - } else if (!in_memory) { - // If AppCache is not enabled, clean up any on disk storage. This is the - // path that will execute once AppCache has been fully removed from Chrome. + if (!in_memory) { + // Clean up any lingering AppCache user data on disk, now that AppCache + // has been deprecated and removed. base::ThreadPool::PostTask( FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, base::BindOnce(
diff --git a/content/browser/storage_partition_impl_unittest.cc b/content/browser/storage_partition_impl_unittest.cc index d089bb50..069f305 100644 --- a/content/browser/storage_partition_impl_unittest.cc +++ b/content/browser/storage_partition_impl_unittest.cc
@@ -59,6 +59,7 @@ #include "services/network/cookie_manager.h" #include "storage/browser/quota/quota_client_type.h" #include "storage/browser/quota/quota_manager.h" +#include "storage/browser/quota/quota_manager_proxy.h" #include "storage/browser/test/mock_quota_client.h" #include "storage/browser/test/mock_quota_manager.h" #include "storage/browser/test/mock_special_storage_policy.h"
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index c5af8e4a..c9b4d05 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -577,6 +577,7 @@ "javatests/src/org/chromium/content/browser/accessibility/TestViewStructureInterface.java", "javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java", "javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java", + "javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java", "javatests/src/org/chromium/content/browser/accessibility/captioning/CaptioningChangeDelegateTest.java", "javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplPixelTest.java", "javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTest.java", @@ -604,6 +605,7 @@ data = [ "//content/test/data/accessibility/event/", + "//content/test/data/accessibility/html/", "//content/test/data/android/", "//content/test/data/media/", ]
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherIntegrationTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherIntegrationTest.java index 9c18683a..f29ff59 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherIntegrationTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherIntegrationTest.java
@@ -19,6 +19,7 @@ import org.chromium.base.process_launcher.ChildConnectionAllocator; import org.chromium.base.process_launcher.ChildProcessConnection; import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.UrlUtils; import org.chromium.content_public.browser.ContentFeatureList; @@ -106,6 +107,10 @@ @Test @MediumTest + // This test may run with --site-per-process, which also enables a feature to maintain a + // spare renderer process. The spare process interferes with assertions on the number of + // process connections in this test, so disable it. + @CommandLineFlags.Add({"disable-features=SpareRendererForSitePerProcess"}) public void testCrossDomainNavigationDoNotLoseImportance() throws Throwable { final TestChildProcessConnectionFactory factory = new TestChildProcessConnectionFactory(); final List<TestChildProcessConnection> connections = factory.getConnections(); @@ -154,6 +159,10 @@ @Test @MediumTest + // This test may run with --site-per-process, which also enables a feature to maintain a + // spare renderer process. The spare process interferes with assertions on the number of + // process connections in this test, so disable it. + @CommandLineFlags.Add({"disable-features=SpareRendererForSitePerProcess"}) public void testIntentionalKillToFreeServiceSlot() throws Throwable { final TestChildProcessConnectionFactory factory = new TestChildProcessConnectionFactory(); final List<TestChildProcessConnection> connections = factory.getConnections();
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellActivityTestRule.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellActivityTestRule.java index 65954b2..ca5d3d6 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellActivityTestRule.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellActivityTestRule.java
@@ -12,6 +12,7 @@ import android.annotation.SuppressLint; import android.os.Bundle; +import android.os.Environment; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; @@ -23,9 +24,13 @@ import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; +import org.chromium.base.test.util.UrlUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_shell_apk.ContentShellActivityTestRule; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.lang.reflect.Method; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; @@ -35,8 +40,19 @@ */ @SuppressLint("VisibleForTests") public class AccessibilityContentShellActivityTestRule extends ContentShellActivityTestRule { + // Test output error messages. + protected static final String EVENTS_ERROR = + "Generated events and actions did not match expectations."; + protected static final String EXPECTATIONS_NULL = + "Test expectations were null, perhaps the file is missing?"; + protected static final String RESULTS_NULL = + "Test results were null, did you add the tracker to WebContentsAccessibilityImpl?"; + protected static final String MISSING_FILE_ERROR = + "Input file could not be read, perhaps the file is missing?"; + // Member variables required for testing framework. Although they are the same object, we will // instantiate an object of type |AccessibilityNodeProvider| for convenience. + protected static final String BASE_DIRECTORY = "/chromium_tests_root"; public AccessibilityNodeProvider mNodeProvider; public WebContentsAccessibilityImpl mWcax; @@ -48,6 +64,26 @@ } /** + * Helper methods for setup of a basic web contents accessibility unit test. + * + * This method replaces the usual setUp() method annotated with @Before because we wish to + * load different data with each test, but the process is the same for all tests. + * + * Leaving a commented @Before annotation on each method as a reminder/context clue. + */ + /* @Before */ + protected void setupTestFromFile(String file) { + // Verify file exists before beginning the test. + verifyInputFile(file); + + launchContentShellWithUrl(UrlUtils.getIsolatedTestFileUrl(file)); + waitForActiveShellToBeDoneLoading(); + setupTestFramework(); + setAccessibilityDelegate(); + sendReadyForTestSignal(); + } + + /** * Helper method to set up our tests. This method replaces the @Before method. * Leaving a commented @Before annotation on method as a reminder/context clue. */ @@ -95,7 +131,7 @@ * Helper method to call AccessibilityNodeInfo.getChildId and convert to a virtual * view ID using reflection, since the needed methods are hidden. */ - private int getChildId(AccessibilityNodeInfo node, int index) { + protected int getChildId(AccessibilityNodeInfo node, int index) { try { Method getChildIdMethod = AccessibilityNodeInfo.class.getMethod("getChildId", int.class); @@ -247,9 +283,47 @@ /** * Helper method to generate results from the |AccessibilityActionAndEventTracker|. + * * @return String List of all actions and events performed during test. */ public String getTrackerResults() { return mTracker.results(); } + + /** + * Read the contents of a file, and return as a String. + * + * @param file File to read (including path and name) + * @return String Contents of the given file. + */ + protected String readExpectationFile(String file) { + String directory = Environment.getExternalStorageDirectory().getPath() + BASE_DIRECTORY; + + try { + File expectedFile = new File(directory, "/" + file); + FileInputStream fis = new FileInputStream(expectedFile); + + byte[] data = new byte[(int) expectedFile.length()]; + fis.read(data); + fis.close(); + + return new String(data); + } catch (IOException e) { + throw new AssertionError(EXPECTATIONS_NULL, e); + } + } + + /** + * Check that a given file exists on disk. + * + * @param file String - file to check, including path and name + */ + protected void verifyInputFile(String file) { + String directory = Environment.getExternalStorageDirectory().getPath() + BASE_DIRECTORY; + + File expectedFile = new File(directory, "/" + file); + Assert.assertTrue(MISSING_FILE_ERROR + " could not find the directory: " + directory + + ", and/or file: " + expectedFile.getPath(), + expectedFile.exists()); + } }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java index 5de5e9b4..9e140076 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java
@@ -4,11 +4,12 @@ package org.chromium.content.browser.accessibility; +import static org.chromium.content.browser.accessibility.AccessibilityContentShellActivityTestRule.EVENTS_ERROR; +import static org.chromium.content.browser.accessibility.AccessibilityContentShellActivityTestRule.RESULTS_NULL; + import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.os.Build; -import android.os.Bundle; -import android.os.Environment; import androidx.test.filters.SmallTest; @@ -20,16 +21,10 @@ import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.FlakyTest; import org.chromium.base.test.util.MinAndroidSdkLevel; -import org.chromium.base.test.util.UrlUtils; import org.chromium.content_public.browser.test.ContentJUnit4ClassRunner; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.concurrent.ExecutionException; - /** - * Tests for WebContentsAccessibilityImpl integration with AT. + * Tests for WebContentsAccessibilityImpl integration with accessibility services. */ @RunWith(ContentJUnit4ClassRunner.class) @MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP) @@ -37,18 +32,7 @@ @SuppressLint("VisibleForTests") @Batch(Batch.UNIT_TESTS) public class WebContentsAccessibilityEventsTest { - // Test output error messages. - private static final String EVENTS_ERROR = - "Generated events and actions did not match expectations."; - private static final String EXPECTATIONS_NULL = - "Test expectations were null, perhaps the file is missing?"; - private static final String RESULTS_NULL = - "Test results were null, did you remember to add the tracker to WCAI?"; - private static final String MISSING_FILE_ERROR = - "Input file could not be read, perhaps the file is missing?"; - - // Member variables required for testing framework - private static final String BASE_DIRECTORY = "/chromium_tests_root"; + // File path that holds all the relevant tests. private static final String BASE_FILE_PATH = "content/test/data/accessibility/event/"; private static final String EMPTY_EXPECTATIONS_FILE = "EmptyExpectationsFile"; @@ -57,26 +41,6 @@ new AccessibilityContentShellActivityTestRule(); /** - * Helper methods for setup of a basic web contents accessibility unit test. - * - * This method replaces the usual setUp() method annotated with @Before because we wish to - * load different data with each test, but the process is the same for all tests. - * - * Leaving a commented @Before annotation on each method as a reminder/context clue. - */ - /* @Before */ - protected void setupTestFromFile(String filepath) { - // Verify file exists before beginning the test. - verifyInputFile(filepath); - - mActivityTestRule.launchContentShellWithUrl(UrlUtils.getIsolatedTestFileUrl(filepath)); - mActivityTestRule.waitForActiveShellToBeDoneLoading(); - mActivityTestRule.setupTestFramework(); - mActivityTestRule.setAccessibilityDelegate(); - mActivityTestRule.sendReadyForTestSignal(); - } - - /** * Perform a single test which will: * 1. Open the given HTML file * 2. Execute the javascript method "go()" @@ -102,7 +66,7 @@ */ private void performTestWithRepeatCounter(String inputFile, String expectationFile, int count) { // Build page from given file and enable testing framework, set a tracker. - setupTestFromFile(BASE_FILE_PATH + inputFile); + mActivityTestRule.setupTestFromFile(BASE_FILE_PATH + inputFile); // Execute method a given number of times. for (int i = 0; i < count; i++) { @@ -127,7 +91,7 @@ private void performTestWithJavascriptMethod( String inputFile, String expectationFile, String javascriptMethod) { // Build page from given file and enable testing framework, set a tracker. - setupTestFromFile(BASE_FILE_PATH + inputFile); + mActivityTestRule.setupTestFromFile(BASE_FILE_PATH + inputFile); // Execute given javascript function. executeJS(javascriptMethod); @@ -149,9 +113,9 @@ if (expectationFile.equals(EMPTY_EXPECTATIONS_FILE)) { expectedResults = ""; } else { - expectedResults = readExpectationFile(expectationFile); + expectedResults = + mActivityTestRule.readExpectationFile(BASE_FILE_PATH + expectationFile); } - Assert.assertNotNull(EXPECTATIONS_NULL, expectedResults); String actualResults = getTrackerResults(); Assert.assertNotNull(RESULTS_NULL, actualResults); @@ -161,59 +125,11 @@ expectedResults, actualResults); } - /** - * Read the contents of a file, and return as a String. - * - * @param fileName Filename to read - * @return String Contents of the given file. - */ - private String readExpectationFile(String fileName) { - String directory = Environment.getExternalStorageDirectory().getPath() + BASE_DIRECTORY; - - try { - File expectedFile = new File(directory, "/" + BASE_FILE_PATH + fileName); - FileInputStream fis = new FileInputStream(expectedFile); - - byte[] data = new byte[(int) expectedFile.length()]; - fis.read(data); - fis.close(); - - return new String(data); - } catch (IOException e) { - return null; - } - } - - /** - * Check that a given file exists on disk. - * @param fileName String - file to check - */ - private void verifyInputFile(String fileName) { - String directory = Environment.getExternalStorageDirectory().getPath() + BASE_DIRECTORY; - - File expectedFile = new File(directory, "/" + fileName); - Assert.assertTrue(MISSING_FILE_ERROR, expectedFile.exists()); - } - // Helper pass-through methods to make tests easier to read. - private <T> int waitForNodeMatching( - AccessibilityContentShellTestUtils.AccessibilityNodeInfoMatcher<T> matcher, T element) { - return mActivityTestRule.waitForNodeMatching(matcher, element); - } - - private boolean performActionOnUiThread(int viewId, int action, Bundle args) - throws ExecutionException { - return mActivityTestRule.performActionOnUiThread(viewId, action, args); - } - private void executeJS(String method) { mActivityTestRule.executeJS(method); } - private void focusNode(int virtualViewId) throws Throwable { - mActivityTestRule.focusNode(virtualViewId); - } - private String getTrackerResults() { return mActivityTestRule.getTrackerResults(); }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java new file mode 100644 index 0000000..1b71e45 --- /dev/null +++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTreeTest.java
@@ -0,0 +1,331 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.content.browser.accessibility; + +import static org.chromium.content.browser.accessibility.AccessibilityContentShellActivityTestRule.EVENTS_ERROR; +import static org.chromium.content.browser.accessibility.AccessibilityContentShellActivityTestRule.RESULTS_NULL; +import static org.chromium.content.browser.accessibility.AccessibilityContentShellTestUtils.sClassNameMatcher; +import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.ACTION_CONTEXT_CLICK; +import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.ACTION_SHOW_ON_SCREEN; +import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EXTRAS_KEY_UNCLIPPED_BOTTOM; +import static org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl.EXTRAS_KEY_UNCLIPPED_TOP; + +import android.annotation.SuppressLint; +import android.annotation.TargetApi; +import android.os.Build; +import android.os.Bundle; +import android.text.InputType; +import android.view.accessibility.AccessibilityNodeInfo; + +import androidx.test.filters.SmallTest; + +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.util.MinAndroidSdkLevel; +import org.chromium.content_public.browser.test.ContentJUnit4ClassRunner; + +import java.lang.reflect.Method; + +/** + * Tests for WebContentsAccessibilityImpl integration with accessibility services. + */ +@RunWith(ContentJUnit4ClassRunner.class) +@MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP) +@TargetApi(Build.VERSION_CODES.LOLLIPOP) +@SuppressLint("VisibleForTests") +public class WebContentsAccessibilityTreeTest { + // File path that holds all the relevant tests. + private static final String BASE_FILE_PATH = "content/test/data/accessibility/html/"; + + @Rule + public AccessibilityContentShellActivityTestRule mActivityTestRule = + new AccessibilityContentShellActivityTestRule(); + + /** + * Perform a single test which will: + * 1. Open the given HTML file + * 2. Generate the full AccessibilityNodeInfo tree + * 3. Read expectations file and compare with results + * + * @param inputFile HTML test input file + * @param inputFile HTML test input file + * @param expectationFile TXT expectations file + * @param expectationFilePath directory that holds the test files + */ + private void performTest(String inputFile, String expectationFile, String expectationFilePath) { + // Build page from given file and enable testing framework. + mActivityTestRule.setupTestFromFile(expectationFilePath + inputFile); + + // Generate full AccessibilityNodeInfo tree and verify results. + assertResults(expectationFilePath + expectationFile, generateAccessibilityNodeInfoTree()); + } + + /** + * Helper method to compare test outputs with expected results. Reads content of expectations + * file, asserts non-null, then compares with results. + * + * @param expectationFile File of the expectations for the test (including path) + * @param actualResults Actual results generated by the accessibility code + */ + private void assertResults(String expectationFile, String actualResults) { + String expectedResults = mActivityTestRule.readExpectationFile(expectationFile); + + Assert.assertNotNull(RESULTS_NULL, actualResults); + Assert.assertEquals(EVENTS_ERROR + "\n\nExpected:\n" + expectedResults + "\n\nActual:\n" + + actualResults + "\n\n", + expectedResults, actualResults); + } + + /** + * Generate the full AccessibilityNodeInfo tree as a String of text. + * + * @return String The AccessibilityNodeInfo tree in text form + */ + private String generateAccessibilityNodeInfoTree() { + StringBuilder builder = new StringBuilder(); + + // Find the root node and generate its string. + int rootNodevvId = + mActivityTestRule.waitForNodeMatching(sClassNameMatcher, "android.webkit.WebView"); + AccessibilityNodeInfo nodeInfo = createAccessibilityNodeInfo(rootNodevvId); + builder.append(customToString(nodeInfo)); + + // Recursively generate strings for all descendants. + for (int i = 0; i < nodeInfo.getChildCount(); ++i) { + int childId = mActivityTestRule.getChildId(nodeInfo, i); + AccessibilityNodeInfo childNodeInfo = createAccessibilityNodeInfo(childId); + recursivelyFormatTree(childNodeInfo, builder, "++"); + } + + return builder.toString(); + } + + /** + * Recursively add AccessibilityNodeInfo descendants to the given builder. + * + * @param node Given object to print all descendants for + * @param builder builder to add generated Strings to + * @param indent prefix to indent each generation, e.g. "++" + */ + private void recursivelyFormatTree( + AccessibilityNodeInfo node, StringBuilder builder, String indent) { + builder.append("\n").append(indent).append(customToString(node)); + for (int j = 0; j < node.getChildCount(); ++j) { + int childId = mActivityTestRule.getChildId(node, j); + AccessibilityNodeInfo childNodeInfo = createAccessibilityNodeInfo(childId); + recursivelyFormatTree(childNodeInfo, builder, indent + "++"); + } + } + + // Helper method to create an AccessibilityNodeInfo object. + private AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { + return mActivityTestRule.mNodeProvider.createAccessibilityNodeInfo(virtualViewId); + } + + /** + * Helper method to use reflection to convert AccessibilityNodeInfo actions to human- + * readable text. The method is private so we set accessible to true. + * + * @param node The object that contains the action + * @param action Action int to convert to a String + * @return String Human-readable representation of the action int + */ + @SuppressLint("SoonBlockedPrivateApi") + private String getSymbolicName(AccessibilityNodeInfo node, int action) { + try { + Method getActionSymbolicName = AccessibilityNodeInfo.class.getDeclaredMethod( + "getActionSymbolicName", int.class); + getActionSymbolicName.setAccessible(true); + return (String) getActionSymbolicName.invoke(node, Integer.valueOf(action)); + } catch (Exception ex) { + Assert.fail("Unable to call hidden AccessibilityNodeInfo method: " + ex.toString()); + return ""; + } + } + + /** + * Helper method to perform a custom toString on a given AccessibilityNodeInfo object. + * + * @param node Object to create a toString for + * @return String Custom toString result for the given object + */ + private String customToString(AccessibilityNodeInfo node) { + StringBuilder builder = new StringBuilder(); + + // Classname and text should always be printed. + builder.append(node.getClassName()); + builder.append("; text: ").append(node.getText()).append(";"); + + // Text properties - Only print when non-null + if (node.getContentDescription() != null) { + builder.append(" contentDescription: ") + .append(node.getContentDescription()) + .append(";"); + } + if (node.getViewIdResourceName() != null) { + builder.append(" viewIdResName: ").append(node.getViewIdResourceName()).append(";"); + } + if (node.getError() != null) { + builder.append(" error: ").append(node.getError()).append(";"); + } + + // Boolean properties - Only print when set to true. + if (node.canOpenPopup()) { + builder.append(" canOpenPopUp"); + } + if (node.isCheckable()) { + builder.append(" checkable"); + } + if (node.isChecked()) { + builder.append(" checked"); + } + if (node.isClickable()) { + builder.append(" clickable"); + } + if (node.isContentInvalid()) { + builder.append(" contentInvalid:"); + } + if (node.isDismissable()) { + builder.append(" dismissable"); + } + if (node.isEditable()) { + builder.append(" editable"); + } + if (node.isEnabled()) { + builder.append(" enabled"); + } + if (node.isFocusable()) { + builder.append(" focusable"); + } + if (node.isFocused()) { + builder.append(" focused"); + } + if (node.isMultiLine()) { + builder.append(" multiLine"); + } + if (node.isPassword()) { + builder.append(" password"); + } + if (node.isScrollable()) { + builder.append(" scrollable"); + } + if (node.isSelected()) { + builder.append(" selected"); + } + if (node.isVisibleToUser()) { + builder.append(" visibleToUser"); + } + + // Integer properties - Only print when not default values. + if (node.getInputType() != InputType.TYPE_NULL) { + builder.append("; inputType: ").append(node.getInputType()); + } + if (node.getTextSelectionStart() != -1) { + builder.append("; textSelectionStart: ").append(node.getTextSelectionStart()); + } + if (node.getTextSelectionEnd() != -1) { + builder.append("; textSelectionEnd: ").append(node.getTextSelectionEnd()); + } + if (node.getMaxTextLength() != -1) { + builder.append("; maxTextLength: ").append(node.getMaxTextLength()); + } + + // Child objects - print for non-null cases. + if (node.getCollectionInfo() != null) { + builder.append("; CollectionInfo: ") + .append(collectionInfoToString(node.getCollectionInfo())); + } + if (node.getCollectionItemInfo() != null) { + builder.append("; CollectionItemInfo: ") + .append(collectionItemInfoToString(node.getCollectionItemInfo())); + } + if (node.getRangeInfo() != null) { + builder.append("; RangeInfo: ").append(rangeInfoToString(node.getRangeInfo())); + } + + // Actions and Bundle extras - Always print. + builder.append("; actions: ").append(actionsToString(node)); + builder.append("; bundle: ").append(bundleToString(node.getExtras())); + + return builder.toString(); + } + + // Various helper methods to print custom toStrings for objects. + private String collectionInfoToString(AccessibilityNodeInfo.CollectionInfo info) { + return "[" + info.isHierarchical() + ", " + info.getSelectionMode() + ", " + + info.getRowCount() + ", " + info.getColumnCount() + "]"; + } + + private String collectionItemInfoToString(AccessibilityNodeInfo.CollectionItemInfo info) { + return "[" + info.isHeading() + ", " + info.isSelected() + ", " + info.getRowIndex() + ", " + + info.getRowSpan() + ", " + info.getColumnIndex() + ", " + info.getColumnSpan() + + "]"; + } + + private String rangeInfoToString(AccessibilityNodeInfo.RangeInfo info) { + return "[" + info.getType() + ", " + info.getCurrent() + ", " + info.getMin() + ", " + + info.getMax() + "]"; + } + + private String actionsToString(AccessibilityNodeInfo node) { + StringBuilder builder = new StringBuilder(); + builder.append("["); + for (AccessibilityNodeInfo.AccessibilityAction action : node.getActionList()) { + // Four actions are set on all nodes, so ignore those when printing the tree. + if (action.getId() == AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT + || action.getId() == AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT + || action.getId() == ACTION_SHOW_ON_SCREEN + || action.getId() == ACTION_CONTEXT_CLICK) { + continue; + } + + builder.append(getSymbolicName(node, action.getId())).append(", "); + } + // Remove the extra comma for cleanliness + if (builder.length() > 2) { + builder.setLength(builder.length() - 2); + } + + builder.append("]"); + return builder.toString(); + } + + private String bundleToString(Bundle extras) { + StringBuilder builder = new StringBuilder(); + builder.append("["); + for (String key : extras.keySet()) { + // Two Bundle extras are related to bounding boxes, these should be ignored so the + // tests can safely run on varying devices and not be screen-dependent. + if (key.equals(EXTRAS_KEY_UNCLIPPED_TOP) || key.equals(EXTRAS_KEY_UNCLIPPED_BOTTOM)) { + continue; + } + + // Since every node has a few Bundle extras, and some are often empty, we will only + // print non-null and not empty values. + if (extras.get(key).toString().isEmpty()) { + continue; + } + + builder.append(key).append(" - ").append(extras.get(key).toString()).append(", "); + } + // Remove the extra comma for cleanliness + if (builder.length() > 2) { + builder.setLength(builder.length() - 2); + } + + builder.append("]"); + return builder.toString(); + } + + @Test + @SmallTest + public void test_tableSimple() { + performTest( + "table-simple.html", "table-simple-expected-android-external.txt", BASE_FILE_PATH); + } +} \ No newline at end of file
diff --git a/content/public/browser/storage_partition.h b/content/public/browser/storage_partition.h index b3b1c728..3d9ba5e7 100644 --- a/content/public/browser/storage_partition.h +++ b/content/public/browser/storage_partition.h
@@ -60,7 +60,6 @@ namespace content { -class AppCacheService; class BackgroundSyncContext; class BrowserContext; class ContentIndexContext; @@ -134,7 +133,6 @@ int frame_tree_node_id) = 0; virtual storage::QuotaManager* GetQuotaManager() = 0; - virtual AppCacheService* GetAppCacheService() = 0; virtual BackgroundSyncContext* GetBackgroundSyncContext() = 0; virtual storage::FileSystemContext* GetFileSystemContext() = 0; virtual FontAccessContext* GetFontAccessContext() = 0; @@ -320,8 +318,6 @@ static void SetDefaultQuotaSettingsForTesting( const storage::QuotaSettings* settings); - static bool IsAppCacheEnabled(); - protected: virtual ~StoragePartition() {} };
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 1746ffa4..f4b85de 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -615,6 +615,10 @@ // Number of worker threads used to rasterize content. const char kNumRasterThreads[] = "num-raster-threads"; +// Overrides the language detection result determined based on the page +// contents. +const char kOverrideLanguageDetection[] = "override-language-detection"; + // Runs PPAPI (Pepper) plugins in-process. const char kPpapiInProcess[] = "ppapi-in-process";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 1cc5f21..394f7d2 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -175,6 +175,7 @@ CONTENT_EXPORT extern const char kNoUnsandboxedZygote[]; CONTENT_EXPORT extern const char kNoZygote[]; CONTENT_EXPORT extern const char kNumRasterThreads[]; +CONTENT_EXPORT extern const char kOverrideLanguageDetection[]; CONTENT_EXPORT extern const char kPpapiInProcess[]; extern const char kPpapiPluginLauncher[]; CONTENT_EXPORT extern const char kPpapiPluginProcess[];
diff --git a/content/public/test/test_aggregation_service.cc b/content/public/test/test_aggregation_service.cc index eb58206..74a91ba 100644 --- a/content/public/test/test_aggregation_service.cc +++ b/content/public/test/test_aggregation_service.cc
@@ -6,13 +6,17 @@ #include <memory> +#include "base/memory/scoped_refptr.h" #include "content/test/test_aggregation_service_impl.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" namespace content { std::unique_ptr<TestAggregationService> TestAggregationService::Create( - const base::Clock* clock) { - return std::make_unique<TestAggregationServiceImpl>(clock); + const base::Clock* clock, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { + return std::make_unique<TestAggregationServiceImpl>( + clock, std::move(url_loader_factory)); } } // namespace content \ No newline at end of file
diff --git a/content/public/test/test_aggregation_service.h b/content/public/test/test_aggregation_service.h index aa0ede7b..6464b90 100644 --- a/content/public/test/test_aggregation_service.h +++ b/content/public/test/test_aggregation_service.h
@@ -36,9 +36,11 @@ public: virtual ~TestAggregationService() = default; - // Creates an instance of the service. + // Creates an instance of the service. Aggregatable reports will be sent + // using the provided `url_loader_factory`. static std::unique_ptr<TestAggregationService> Create( - const base::Clock* clock); + const base::Clock* clock, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); // Sets whether to disable the AggregatableReport's payload(s) being encrypted // after serialization. @@ -51,12 +53,6 @@ const std::string& json_string, base::OnceCallback<void(bool)> callback) = 0; - // Sets the provided URL loader factory. This will be called by the - // aggregation service tool to inject a network::mojom::URLLoaderFactory to - // send an aggregatable report over network. - virtual void SetURLLoaderFactory( - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) = 0; - // Sends the aggregatable report to the specified reporting endpoint `url`. // `callback` will be run once completed which returns whether the report was // sent successfully.
diff --git a/content/public/test/test_storage_partition.cc b/content/public/test/test_storage_partition.cc index 3cf9378..5a80968f 100644 --- a/content/public/test/test_storage_partition.cc +++ b/content/public/test/test_storage_partition.cc
@@ -67,10 +67,6 @@ return quota_manager_; } -AppCacheService* TestStoragePartition::GetAppCacheService() { - return app_cache_service_; -} - BackgroundSyncContext* TestStoragePartition::GetBackgroundSyncContext() { return background_sync_context_; }
diff --git a/content/public/test/test_storage_partition.h b/content/public/test/test_storage_partition.h index 4f280d2..e850e8dd7 100644 --- a/content/public/test/test_storage_partition.h +++ b/content/public/test/test_storage_partition.h
@@ -22,7 +22,6 @@ namespace content { -class AppCacheService; class BackgroundSyncContext; class DevToolsBackgroundServicesContext; class DOMStorageContext; @@ -89,11 +88,6 @@ } storage::QuotaManager* GetQuotaManager() override; - void set_app_cache_service(AppCacheService* service) { - app_cache_service_ = service; - } - AppCacheService* GetAppCacheService() override; - void set_file_system_context(storage::FileSystemContext* context) { file_system_context_ = context; } @@ -229,7 +223,6 @@ network::mojom::NetworkContext* network_context_ = nullptr; network::mojom::CookieManager* cookie_manager_for_browser_process_ = nullptr; storage::QuotaManager* quota_manager_ = nullptr; - AppCacheService* app_cache_service_ = nullptr; BackgroundSyncContext* background_sync_context_ = nullptr; storage::FileSystemContext* file_system_context_ = nullptr; storage::DatabaseTracker* database_tracker_ = nullptr;
diff --git a/content/test/data/accessibility/html/table-simple-expected-android-external.txt b/content/test/data/accessibility/html/table-simple-expected-android-external.txt new file mode 100644 index 0000000..59c2a1cf --- /dev/null +++ b/content/test/data/accessibility/html/table-simple-expected-android-external.txt
@@ -0,0 +1,11 @@ +android.webkit.WebView; text: Table example; enabled focusable focused scrollable visibleToUser; actions: [ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, ACTION_CLEAR_FOCUS, ACTION_ACCESSIBILITY_FOCUS]; bundle: [AccessibilityNodeInfo.chromeRole - rootWebArea, ACTION_ARGUMENT_HTML_ELEMENT_STRING_VALUES - ARTICLE,BUTTON,CHECKBOX,COMBOBOX,CONTROL,FOCUSABLE,FRAME,GRAPHIC,H1,H2,H3,H4,H5,H6,HEADING,LANDMARK,LINK,LIST,LIST_ITEM,MAIN,MEDIA,RADIO,SECTION,TABLE,TEXT_FIELD,UNVISITED_LINK,VISITED_LINK] +++android.widget.GridView; text: ; enabled visibleToUser; CollectionInfo: [false, 0, 3, 2]; actions: [ACTION_ACCESSIBILITY_FOCUS]; bundle: [AccessibilityNodeInfo.roleDescription - table, AccessibilityNodeInfo.chromeRole - table] +++++android.view.View; text: ; enabled visibleToUser; actions: [ACTION_ACCESSIBILITY_FOCUS]; bundle: [AccessibilityNodeInfo.chromeRole - row] +++++++android.view.View; text: Pair; enabled visibleToUser; CollectionItemInfo: [true, false, 0, 1, 0, 1]; actions: [ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, ACTION_ACCESSIBILITY_FOCUS]; bundle: [AccessibilityNodeInfo.roleDescription - column header, AccessibilityNodeInfo.chromeRole - columnHeader] +++++++android.view.View; text: Single; enabled visibleToUser; CollectionItemInfo: [true, false, 0, 1, 1, 1]; actions: [ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, ACTION_ACCESSIBILITY_FOCUS]; bundle: [AccessibilityNodeInfo.roleDescription - column header, AccessibilityNodeInfo.chromeRole - columnHeader] +++++android.view.View; text: ; enabled visibleToUser; actions: [ACTION_ACCESSIBILITY_FOCUS]; bundle: [AccessibilityNodeInfo.chromeRole - row] +++++++android.view.View; text: AB; enabled visibleToUser; CollectionItemInfo: [false, false, 1, 1, 0, 1]; actions: [ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, ACTION_ACCESSIBILITY_FOCUS]; bundle: [AccessibilityNodeInfo.chromeRole - cell] +++++++android.view.View; text: B; enabled visibleToUser; CollectionItemInfo: [false, false, 1, 1, 1, 1]; actions: [ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, ACTION_ACCESSIBILITY_FOCUS]; bundle: [AccessibilityNodeInfo.chromeRole - cell] +++++android.view.View; text: ; enabled visibleToUser; actions: [ACTION_ACCESSIBILITY_FOCUS]; bundle: [AccessibilityNodeInfo.chromeRole - row] +++++++android.view.View; text: CD; enabled visibleToUser; CollectionItemInfo: [false, false, 2, 1, 0, 1]; actions: [ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, ACTION_ACCESSIBILITY_FOCUS]; bundle: [AccessibilityNodeInfo.chromeRole - cell] +++++++android.view.View; text: D; enabled visibleToUser; CollectionItemInfo: [false, false, 2, 1, 1, 1]; actions: [ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, ACTION_ACCESSIBILITY_FOCUS]; bundle: [AccessibilityNodeInfo.chromeRole - cell] \ No newline at end of file
diff --git a/content/test/data/accessibility/mac/mathml/multiscripts-attributes-expected-mac.txt b/content/test/data/accessibility/mac/mathml/multiscripts-attributes-expected-mac.txt new file mode 100644 index 0000000..1112f6a --- /dev/null +++ b/content/test/data/accessibility/mac/mathml/multiscripts-attributes-expected-mac.txt
@@ -0,0 +1,31 @@ +multiscripts1.AXMathPrescripts.count=3 +multiscripts1.AXMathPrescripts[0].AXMathSuperscript.AXChildren[0].AXValue='pre2' +multiscripts1.AXMathPrescripts[1].AXMathSubscript.AXChildren[0].AXValue='pre3' +multiscripts1.AXMathPrescripts[1].AXMathSuperscript.AXChildren[0].AXValue='pre4' +multiscripts1.AXMathPrescripts[2].AXMathSubscript.AXChildren[0].AXValue='pre5' +multiscripts1.AXMathPrescripts[2].AXMathSuperscript.AXChildren[0].AXValue='pre6' +multiscripts1.AXMathPostscripts.count=3 +multiscripts1.AXMathPostscripts[0].AXMathSubscript.AXChildren[0].AXValue='post1' +multiscripts1.AXMathPostscripts[0].AXMathSuperscript.AXChildren[0].AXValue='post2' +multiscripts1.AXMathPostscripts[1].AXMathSubscript.AXChildren[0].AXValue='post3' +multiscripts1.AXMathPostscripts[1].AXMathSuperscript.AXChildren[0].AXValue='post4' +multiscripts1.AXMathPostscripts[2].AXMathSubscript.AXChildren[0].AXValue='post5' +multiscripts1.AXMathPostscripts[2].AXMathSuperscript.AXChildren[0].AXValue='post6' +multiscripts2.AXMathPrescripts.count=2 +multiscripts2.AXMathPrescripts[0].AXMathSubscript.AXChildren[0].AXValue='pre1' +multiscripts2.AXMathPrescripts[0].AXMathSuperscript.AXChildren.count=0 +multiscripts2.AXMathPrescripts[1].AXMathSubscript.AXChildren.count=0 +multiscripts2.AXMathPrescripts[1].AXMathSuperscript.AXChildren[0].AXValue='pre4' +multiscripts2.AXMathPostscripts.count=2 +multiscripts2.AXMathPostscripts[0].AXMathSubscript.AXChildren[0].AXValue='post1' +multiscripts2.AXMathPostscripts[0].AXMathSuperscript.AXChildren.count=0 +multiscripts2.AXMathPostscripts[1].AXMathSubscript.AXChildren.count=0 +multiscripts2.AXMathPostscripts[1].AXMathSuperscript.AXChildren[0].AXValue='post4' +multiscripts3.AXMathPrescripts=NULL +multiscripts3.AXMathPostscripts.count=1 +multiscripts3.AXMathPostscripts[0].AXMathSuperscript.AXChildren[0].AXValue='2' +multiscripts3.AXMathPostscripts[0].AXMathSubscript.AXChildren[0].AXValue='1' +multiscripts4.AXMathPrescripts.count=1 +multiscripts4.AXMathPrescripts[0].AXMathSuperscript.AXChildren[0].AXValue='2' +multiscripts4.AXMathPrescripts[0].AXMathSubscript.AXChildren[0].AXValue='1' +multiscripts4.AXMathPostscripts=NULL
diff --git a/content/test/data/accessibility/mac/mathml/multiscripts-attributes.html b/content/test/data/accessibility/mac/mathml/multiscripts-attributes.html new file mode 100644 index 0000000..dfdde27 --- /dev/null +++ b/content/test/data/accessibility/mac/mathml/multiscripts-attributes.html
@@ -0,0 +1,82 @@ +<!DOCTYPE html> +<!-- +@MAC-SCRIPT: + multiscripts1.AXMathPrescripts.count + multiscripts1.AXMathPrescripts[0].AXMathSuperscript.AXChildren[0].AXValue + multiscripts1.AXMathPrescripts[1].AXMathSubscript.AXChildren[0].AXValue + multiscripts1.AXMathPrescripts[1].AXMathSuperscript.AXChildren[0].AXValue + multiscripts1.AXMathPrescripts[2].AXMathSubscript.AXChildren[0].AXValue + multiscripts1.AXMathPrescripts[2].AXMathSuperscript.AXChildren[0].AXValue + multiscripts1.AXMathPostscripts.count + multiscripts1.AXMathPostscripts[0].AXMathSubscript.AXChildren[0].AXValue + multiscripts1.AXMathPostscripts[0].AXMathSuperscript.AXChildren[0].AXValue + multiscripts1.AXMathPostscripts[1].AXMathSubscript.AXChildren[0].AXValue + multiscripts1.AXMathPostscripts[1].AXMathSuperscript.AXChildren[0].AXValue + multiscripts1.AXMathPostscripts[2].AXMathSubscript.AXChildren[0].AXValue + multiscripts1.AXMathPostscripts[2].AXMathSuperscript.AXChildren[0].AXValue + +@MAC-SCRIPT: + multiscripts2.AXMathPrescripts.count + multiscripts2.AXMathPrescripts[0].AXMathSubscript.AXChildren[0].AXValue + multiscripts2.AXMathPrescripts[0].AXMathSuperscript.AXChildren.count + multiscripts2.AXMathPrescripts[1].AXMathSubscript.AXChildren.count + multiscripts2.AXMathPrescripts[1].AXMathSuperscript.AXChildren[0].AXValue + multiscripts2.AXMathPostscripts.count + multiscripts2.AXMathPostscripts[0].AXMathSubscript.AXChildren[0].AXValue + multiscripts2.AXMathPostscripts[0].AXMathSuperscript.AXChildren.count + multiscripts2.AXMathPostscripts[1].AXMathSubscript.AXChildren.count + multiscripts2.AXMathPostscripts[1].AXMathSuperscript.AXChildren[0].AXValue + +@MAC-SCRIPT: + multiscripts3.AXMathPrescripts + multiscripts3.AXMathPostscripts.count + multiscripts3.AXMathPostscripts[0].AXMathSuperscript.AXChildren[0].AXValue + multiscripts3.AXMathPostscripts[0].AXMathSubscript.AXChildren[0].AXValue + +@MAC-SCRIPT: + multiscripts4.AXMathPrescripts.count + multiscripts4.AXMathPrescripts[0].AXMathSuperscript.AXChildren[0].AXValue + multiscripts4.AXMathPrescripts[0].AXMathSubscript.AXChildren[0].AXValue + multiscripts4.AXMathPostscripts +--> +<math> + <mmultiscripts id="multiscripts1"> + <mtext>base</mtext> + <mtext>post1</mtext> + <mtext>post2</mtext> + <mtext>post3</mtext> + <mtext>post4</mtext> + <mtext>post5</mtext> + <mtext>post6</mtext> + <mprescripts/> + <mtext>pre1</mtext> + <mtext>pre2</mtext> + <mtext>pre3</mtext> + <mtext>pre4</mtext> + <mtext>pre5</mtext> + <mtext>pre6</mtext> + </mmultiscripts> + <mmultiscripts id="multiscripts2"> + <mtext>base</mtext> + <mtext>post1</mtext> + <none/> + <none/> + <mtext>post4</mtext> + <mprescripts/> + <mtext>pre1</mtext> + <none/> + <none/> + <mtext>pre4</mtext> + </mmultiscripts> + <mmultiscripts id="multiscripts3"> + <mtext>base</mtext> + <mn>1</mn> + <mn>2</mn> + </mmultiscripts> + <mmultiscripts id="multiscripts4"> + <mtext>base</mtext> + <mprescripts/> + <mn>1</mn> + <mn>2</mn> + </mmultiscripts> +</math>
diff --git a/content/test/fuzzer/file_system_manager_mojolpm_fuzzer.cc b/content/test/fuzzer/file_system_manager_mojolpm_fuzzer.cc index 3cc87a165..74c32d8d 100644 --- a/content/test/fuzzer/file_system_manager_mojolpm_fuzzer.cc +++ b/content/test/fuzzer/file_system_manager_mojolpm_fuzzer.cc
@@ -25,6 +25,7 @@ #include "content/public/test/test_content_client_initializer.h" #include "content/test/fuzzer/file_system_manager_mojolpm_fuzzer.pb.h" #include "mojo/core/embedder/embedder.h" +#include "storage/browser/quota/quota_manager_proxy.h" #include "storage/browser/quota/special_storage_policy.h" #include "storage/browser/test/mock_special_storage_policy.h" #include "storage/browser/test/test_file_system_context.h"
diff --git a/content/test/test_aggregation_service_impl.cc b/content/test/test_aggregation_service_impl.cc index f36db0a..d37c7b80 100644 --- a/content/test/test_aggregation_service_impl.cc +++ b/content/test/test_aggregation_service_impl.cc
@@ -29,13 +29,16 @@ namespace content { -TestAggregationServiceImpl::TestAggregationServiceImpl(const base::Clock* clock) +TestAggregationServiceImpl::TestAggregationServiceImpl( + const base::Clock* clock, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) : clock_(*clock), storage_(base::SequenceBound<AggregationServiceStorageSql>( base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}), /*run_in_memory=*/true, /*path_to_database=*/base::FilePath(), - clock)) { + clock)), + sender_(AggregatableReportSender::CreateForTesting(url_loader_factory)) { DCHECK(clock); } @@ -75,11 +78,6 @@ .Then(base::BindOnce(std::move(callback), true)); } -void TestAggregationServiceImpl::SetURLLoaderFactory( - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { - sender_->SetURLLoaderFactoryForTesting(url_loader_factory); -} - void TestAggregationServiceImpl::SendReport( const GURL& url, const base::Value& contents,
diff --git a/content/test/test_aggregation_service_impl.h b/content/test/test_aggregation_service_impl.h index 4f3f599..5e857e80 100644 --- a/content/test/test_aggregation_service_impl.h +++ b/content/test/test_aggregation_service_impl.h
@@ -34,7 +34,9 @@ public: // `clock` must be a non-null pointer to TestAggregationServiceImpl that is // valid as long as this object. - explicit TestAggregationServiceImpl(const base::Clock* clock); + TestAggregationServiceImpl( + const base::Clock* clock, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); TestAggregationServiceImpl(const TestAggregationServiceImpl& other) = delete; TestAggregationServiceImpl& operator=( const TestAggregationServiceImpl& other) = delete; @@ -49,8 +51,6 @@ void SetPublicKeys(const url::Origin& origin, const std::string& json_string, base::OnceCallback<void(bool)> callback) override; - void SetURLLoaderFactory(scoped_refptr<network::SharedURLLoaderFactory> - url_loader_factory) override; void SendReport(const GURL& url, const base::Value& contents, base::OnceCallback<void(bool)> callback) override;
diff --git a/content/test/test_aggregation_service_impl_unittest.cc b/content/test/test_aggregation_service_impl_unittest.cc index 7164796..00254a94 100644 --- a/content/test/test_aggregation_service_impl_unittest.cc +++ b/content/test/test_aggregation_service_impl_unittest.cc
@@ -8,11 +8,14 @@ #include <string> #include <vector> +#include "base/memory/scoped_refptr.h" #include "base/run_loop.h" #include "base/test/bind.h" #include "base/test/task_environment.h" #include "content/browser/aggregation_service/aggregation_service_test_utils.h" #include "content/browser/aggregation_service/public_key.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" #include "url/origin.h" @@ -24,10 +27,15 @@ TestAggregationServiceImplTest() : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME), impl_(std::make_unique<TestAggregationServiceImpl>( - task_environment_.GetMockClock())) {} + task_environment_.GetMockClock(), + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_))) {} + + private: + base::test::TaskEnvironment task_environment_; + network::TestURLLoaderFactory test_url_loader_factory_; protected: - base::test::TaskEnvironment task_environment_; std::unique_ptr<TestAggregationServiceImpl> impl_; };
diff --git a/content/utility/utility_main.cc b/content/utility/utility_main.cc index 37a72a3..15d5fe6 100644 --- a/content/utility/utility_main.cc +++ b/content/utility/utility_main.cc
@@ -217,16 +217,6 @@ // base::RandBytes() will CHECK fail when v8 is initialized. base::RandBytes(&buffer, sizeof(buffer)); - if (sandbox_type == sandbox::policy::SandboxType::kNetwork) { - // Network service process needs FWPUCLNT.DLL to be loaded before sandbox - // lockdown otherwise getaddrinfo fails. - HMODULE fwpuclnt_pin = ::LoadLibrary(L"FWPUCLNT.DLL"); - UNREFERENCED_PARAMETER(fwpuclnt_pin); - // Network service process needs urlmon.dll to be loaded before sandbox - // lockdown otherwise CoInternetCreateSecurityManager fails. - HMODULE urlmon_pin = ::LoadLibrary(L"urlmon.dll"); - UNREFERENCED_PARAMETER(urlmon_pin); - } g_utility_target_services->LowerToken(); } #endif
diff --git a/docs/README.md b/docs/README.md index d8fc9151..f28c179 100644 --- a/docs/README.md +++ b/docs/README.md
@@ -180,7 +180,7 @@ * [Using Crashpad with `content_shell`](testing/using_crashpad_with_content_shell.md) - Capture stack traces on layout test crashes without an attached debugger * [Test Descriptions](testing/test_descriptions.md) - Unit test targets that can be - built, with associated desciptions. + built, with associated descriptions. * [Fuzz Testing](../testing/libfuzzer/README.md) - Fuzz testing in Chromium. * [IPC Fuzzer](testing/ipc_fuzzer.md) - Fuzz testing of Chromium IPC interfaces. * [Running Chrome tests with AddressSanitizer (asan) and LeakSanitizer (lsan)](testing/linux_running_asan_tests.md) - @@ -203,7 +203,7 @@ * [Linux Proxy Config](linux/proxy_config.md) - Network proxy sources on Linux * [Debugging SSL on Linux](linux/debugging_ssl.md) - Tips on debugging SSL code in Linux -* [Linux Cert Managment](linux/cert_management.md) - Managing X.509 +* [Linux Cert Management](linux/cert_management.md) - Managing X.509 Certificates in Linux * [Tips for Debugging on Linux](linux/debugging.md) * [Linux GTK Theme Integration](linux/gtk_theme_integration.md) - Having @@ -341,7 +341,7 @@ * [BRLTTY in Chrome OS](accessibility/brltty.md) - Chrome OS integration with BRLTTY to support refreshable braille displays * [PATTS on Chrome OS](accessibility/patts.md) - Notes on the PATTS speech - sythesis engine used on Chrome OS + synthesis engine used on Chrome OS * [VoiceOver](ios/voiceover.md) - Using Apple's VoiceOver feature with Chromium on iOS.
diff --git a/docs/accessibility/brltty.md b/docs/accessibility/brltty.md index cd921d01..67fa216 100644 --- a/docs/accessibility/brltty.md +++ b/docs/accessibility/brltty.md
@@ -222,7 +222,7 @@ 2. modify the way in which brltty gets run. -In particular, look at the invokation of the minijail in +In particular, look at the invocation of the minijail in third_party/chromiumos-overlay/app-accessibility/brltty/files/brltty
diff --git a/docs/accessibility/espeak.md b/docs/accessibility/espeak.md index c3305f8..e09e0618 100644 --- a/docs/accessibility/espeak.md +++ b/docs/accessibility/espeak.md
@@ -2,7 +2,7 @@ Chrome OS comes with a port of the open-source eSpeak-NG speech synthesis engine. eSpeak-NG is lower quality than Google's "PATTS" speech engine, -but it's faster, uses less resouces, and supports more languages. +but it's faster, uses less resources, and supports more languages. [Read more about Text-to-Speech in Chrome](tts.md).
diff --git a/docs/accessibility/offscreen.md b/docs/accessibility/offscreen.md index 8658c7f6..d514142 100644 --- a/docs/accessibility/offscreen.md +++ b/docs/accessibility/offscreen.md
@@ -31,7 +31,7 @@ As background, [MSDN](https://msdn.microsoft.com/en-us/library/dd373609(VS.85).aspx) defines Offscreen as an object is not rendered, but not because it was -programatically hidden: +programmatically hidden: >The object is clipped or has scrolled out of view, but it is not programmatically hidden. If the user makes the viewport larger, more of the @@ -51,7 +51,7 @@ true. ## Invisible -A node is marked Invisible in Chrome if it is hidden programatically. In some +A node is marked Invisible in Chrome if it is hidden programmatically. In some cases, invisible nodes are simply excluded from the accessibility tree. Chrome defines invisible as:
diff --git a/docs/accessibility/overview.md b/docs/accessibility/overview.md index 0bbbdb8..72c95f9 100644 --- a/docs/accessibility/overview.md +++ b/docs/accessibility/overview.md
@@ -354,7 +354,7 @@ To compactly store the bounding box of every character on the page, we split the text into *inline text boxes*, sometimes called *text runs*. For example, in a typical paragraph, each line of text would be its own -inline text box. In general, an inline text box or text run contians a +inline text box. In general, an inline text box or text run contains a sequence of text characters that are all oriented in the same direction, in a line, with the same font, size, and style.
diff --git a/docs/accessibility/switch_access.md b/docs/accessibility/switch_access.md index 3d27858f..f9ca2a18 100644 --- a/docs/accessibility/switch_access.md +++ b/docs/accessibility/switch_access.md
@@ -328,7 +328,7 @@ #### background.js This file is the first one run. Its primary job is to create an instance of -SwitchAccess, although it als overifies that there is not more than one instance +SwitchAccess, although it also overifies that there is not more than one instance of Switch Access running simultaneously (this would normally happen on the sign in page).
diff --git a/docs/design/gpu_synchronization.md b/docs/design/gpu_synchronization.md index fff5d9b..76bada51 100644 --- a/docs/design/gpu_synchronization.md +++ b/docs/design/gpu_synchronization.md
@@ -39,7 +39,7 @@ ## Use case overview -The core scenario is synchronizing read and write access to a shared resorce, +The core scenario is synchronizing read and write access to a shared resource, for example drawing an image into an offscreen texture and compositing the result into a final image. The drawing operations need to be completed before reading to ensure correct output. A typical effect of wrong synchronization is
diff --git a/docs/disassemble_code.md b/docs/disassemble_code.md index 13d68b1..90c6e43 100644 --- a/docs/disassemble_code.md +++ b/docs/disassemble_code.md
@@ -63,7 +63,7 @@ ``` You probably will want to add some more command line options to this, -depending on your usual build paralellism. +depending on your usual build parallelism. ## Getting the right objdump
diff --git a/docs/documentation_best_practices.md b/docs/documentation_best_practices.md index 623e18b..b8c9e954 100644 --- a/docs/documentation_best_practices.md +++ b/docs/documentation_best_practices.md
@@ -93,7 +93,7 @@ * Who maintains this directory and where I can learn more? 4. **Design docs, PRDs**: A good design doc or PRD discusses the proposed - implementation at length for the purpose of collecting feeback on that + implementation at length for the purpose of collecting feedback on that design. However, once the code is implemented, design docs should serve as archives of these decisions, not as half-correct docs (they are often misused). See
diff --git a/docs/enterprise/add_new_policy.md b/docs/enterprise/add_new_policy.md index 144f134..0fa0fc1 100644 --- a/docs/enterprise/add_new_policy.md +++ b/docs/enterprise/add_new_policy.md
@@ -37,7 +37,7 @@ sure you get the version and feature flags (such as dynamic_refresh and supported_on) right. - Here are the most used attributes. Please note that, all attributes - below other than `supported_on`, `future_on' and + below other than `supported_on`, `future_on` and `default_for_enterprise_users` do not change the code behavior. - `supported_on` and `future_on`: They control the platforms that the policy supports. `supported_on` is used for released platforms with
diff --git a/docs/gpu/gpu_testing.md b/docs/gpu/gpu_testing.md index ecdb0e0..f426e68 100644 --- a/docs/gpu/gpu_testing.md +++ b/docs/gpu/gpu_testing.md
@@ -551,7 +551,7 @@ pages showing the image produced by the image and the approved image that most closely matches it. -Note that for the tests which programatically check colors in certain regions of +Note that for the tests which programmatically check colors in certain regions of the image (tests with `expected_colors` fields in [pixel_test_pages]), there likely won't be a closest approved image since those tests only upload data to Gold in the event of a failure.
diff --git a/docs/gpu/images/wrangler.png b/docs/gpu/images/wrangler.png deleted file mode 100644 index ff269644..0000000 --- a/docs/gpu/images/wrangler.png +++ /dev/null Binary files differ
diff --git a/docs/infra/cq.md b/docs/infra/cq.md index b32698d..ee00b8b 100644 --- a/docs/infra/cq.md +++ b/docs/infra/cq.md
@@ -146,7 +146,7 @@ * It should be possible for any committer to replicate any testing run; i.e. tests and their data must be in the public repository. * Median cycle time needs to be under 40 minutes for trybots. 90th percentile - should be around an hour (preferrably shorter). + should be around an hour (preferably shorter). * Configurations need to catch enough failures to be worth adding to the CQ. Running builds on every CL requires a significant amount of compute resources. If a configuration only fails once every couple of weeks on the waterfalls,
diff --git a/docs/initialize_blink_features.md b/docs/initialize_blink_features.md index bb6ab5f..3e44a64 100644 --- a/docs/initialize_blink_features.md +++ b/docs/initialize_blink_features.md
@@ -55,7 +55,7 @@ \[1]: `base::FeatureList::IsEnabled(features::kNewFeatureX)` is still false. These combinations are suitable for features there are fully implemented at blink side. Otherwise normally the blink feature should not have a status so -that the Chromium feature can fully controll the feature. +that the Chromium feature can fully control the feature. \[2]: This combination is counter-intuitive and should be avoided.
diff --git a/docs/installation_at_vmware.md b/docs/installation_at_vmware.md index 6feae63..7d33888 100644 --- a/docs/installation_at_vmware.md +++ b/docs/installation_at_vmware.md
@@ -10,7 +10,7 @@ 1. Create a New Virtual Machine 1. Do not selecting any OP-sys (other-other-etc) 1. Delete your newly created hardisc (lets say you named it as Chrome) -1. Move downloaded harddisc to the same folder as othere VMware files for this +1. Move downloaded harddisc to the same folder as other VMware files for this Virtual Machine 1. Rename your downloaded hardisc to newly created Virtual Machine original name (in my example it was Chrome)
diff --git a/docs/ios/build_instructions.md b/docs/ios/build_instructions.md index b735d704..a90c4ba 100644 --- a/docs/ios/build_instructions.md +++ b/docs/ios/build_instructions.md
@@ -237,7 +237,7 @@ request such a mobile provisioning profile from Apple. You can inspect the file passed via the `-e` flag to the `codesign.py` script -to check which capabilites are required for the mobile provisioning profile +to check which capabilities are required for the mobile provisioning profile (e.g. `src/build/config/ios/entitlements.plist` for the above build error, remember that the paths are relative to the build directory, not to the source directory).
diff --git a/docs/memory/tools.md b/docs/memory/tools.md index 602f99c..7968d40 100644 --- a/docs/memory/tools.md +++ b/docs/memory/tools.md
@@ -40,7 +40,7 @@ circles. ### Blindspots - * Statistics are self-reported. If the MemoryDumpProvider implemenation does + * Statistics are self-reported. If the MemoryDumpProvider implementation does not fully cover the resource usage of the subsystem, those resources will not be accounted. @@ -157,7 +157,7 @@ | ------- | ----- | | Out of process heap profiling start mode. | This option is somewhat misnamed. It tells OOPHP which processes to profile at startup. Other processes can selected manually later via chrome://memory-internals even if this is set to "disabled". | | Keep track of even the small allocations in memlog heap dumps. | By default, small allocations are not emitted in the heap dump to reduce dump size. Enabling this track _all_ allocations. | -| The type of stack to record for memlog heap dumps | If possible, use Native stack frames as that provides the best information. When those are not availble either due to performance for build (eg, no frame-pointers on arm32 official) configurations, using trace events for a "pseudo stack" can give good information too. | +| The type of stack to record for memlog heap dumps | If possible, use Native stack frames as that provides the best information. When those are not available either due to performance for build (eg, no frame-pointers on arm32 official) configurations, using trace events for a "pseudo stack" can give good information too. | | Heap profiling | Deprecated. Enables the in-process heap profiler. Functionality should be fully subsumed by preceeding options. | #### Saving a heap dump @@ -168,7 +168,7 @@ 2. Symbolize trace using [`symbolize_trace.py`](../../third_party/catapult/tracing/bin/symbolize_trace). If the Chrome binary was built locally, pass the flag "--is-local-build". 3. Analyze resuing heap dump using [`diff_heap_profiler.py`](#diff-heap-profiler), or [Heap Profile view in Chrome Tracing](#tracing-heap-profile) -On deskop, using chrome://memory-internals to take a heap dump is more reliable +On desktop, using chrome://memory-internals to take a heap dump is more reliable as it directly saves the heapdump to a file instead of passing the serialized data through the chrome://tracing renderer process which can easily OOM. For Android, this native file saving was harder to implement and would still leave the @@ -259,10 +259,10 @@ such as the Windows Paged and Non-paged pools) as side effects of user mode calls nor do they account for memory that does not go through new/malloc (manulaly callling `mmap()`, or `VirtualAlloc()`). Querying a full view of -these allocaitons usually requires admin privileges, the semantics change +these allocations usually requires admin privileges, the semantics change per platform, and the performance can vary from being "constant-ish" to being dependent on virtual space size (eg, probing allocation via -VirtualQueryEx or parsing /proc/self/maps) or number of proccesses in the +VirtualQueryEx or parsing /proc/self/maps) or number of processes in the system (NTQuerySystemInformation). As an example of error in measurement, PartitionAlloc did not account for
diff --git a/docs/native_relocations.md b/docs/native_relocations.md index 22ad0c82..2b7ff299 100644 --- a/docs/native_relocations.md +++ b/docs/native_relocations.md
@@ -30,7 +30,7 @@ [cros]: https://chromium-review.googlesource.com/c/chromiumos/overlays/chromiumos-overlay/+/1210982 ### Windows Relocations (PE Format) - * For PE files, relocaitons are stored in per-code-page + * For PE files, relocations are stored in per-code-page [`.reloc` sections][win_relocs]. * Each relocation is stored using 2 bytes. Each `.reloc` section has a small overhead as well.
diff --git a/docs/proxy_auto_config.md b/docs/proxy_auto_config.md index c45a91076..d47372a 100644 --- a/docs/proxy_auto_config.md +++ b/docs/proxy_auto_config.md
@@ -1,7 +1,7 @@ # Proxy Auto Config Using WPAD Most systems support manually configuring a proxy for web access, but this is -cumbersome and kind of techical, so Chrome also supports +cumbersome and kind of technical, so Chrome also supports [WPAD](http://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol) for proxy configuration (enabled if "automatically detect proxy settings" is enabled on Windows).
diff --git a/docs/security/lookalikes/lookalike-domains.md b/docs/security/lookalikes/lookalike-domains.md index b5af759..2fd7b64c 100644 --- a/docs/security/lookalikes/lookalike-domains.md +++ b/docs/security/lookalikes/lookalike-domains.md
@@ -10,12 +10,13 @@ fraud. In addition to [Google Safe Browsing](https://safebrowsing.google.com/) -protections, Chrome attempts to detect these lookalike domains using a number of -on-device heuristics. These heuristics compare the visited URL against domains -that the user has visited previously and other popular domains. +protections, Chrome attempts to detect these lookalike domains by comparing the +URL you visited with other URLs that are either very popular, or that you have +visited previously. These checks all happen within Chrome -- Chrome does not +communicate with Google to perform these checks. When Chrome detects a potential lookalike domain, it may block the page and show -a full-page warning, or it may show a warning overlay, depending on how certain +a full-page warning, or it may show a pop-up warning, depending on how certain Chrome is that the site is a spoof. These warnings typically have a "Did you mean ...?" message. @@ -24,13 +25,13 @@ |  |  | These warnings do not indicate that the site the user has visited is malicious. -They only indicate that the site looks like another site, and the user should -make sure that they're on the site that they expected. +The warnings indicate that the site looks like another site, and that the user +should make sure that they are visiting the site that they expected. ## Examples of lookalike domains -Chrome's heuristics are designed to detect spoofing techniques in the wild. Some -example "lookalike" patterns include: +Chrome's checks are designed to detect spoofing techniques in the wild. Some +example "lookalike" patterns that trigger warnings include: * Domains that are a small edit-distance away from other domains, such as `goog0le.com`. @@ -44,31 +45,30 @@ domains that users without technical backgrounds may confuse for another site. -## Heuristics are imperfect +## Lookalike checks are imperfect -Like all heuristics, Chrome's heuristics are not always right. For instance, -attackers can choose lookalike domains that Chrome is unable to detect. Our -intent with Chrome's lookalike heuristics is not to make spoofing impossible, +Chrome's lookalike checks are not always right. Chrome can not detect all +lookalike domains, and often lookalike domains are not malicious. Our +intent with Chrome's lookalike warnings is not to make spoofing impossible, but to force attackers to use less convincing lookalikes, allowing users to notice spoofs more easily. -In addition to not catching all spoofs, Chrome's heuristics also label some -benign pages as lookalikes. We have several approaches to minimize these -mistakes: +While Chrome's checks sometimes label some benign pages as lookalikes, we use +several approaches to minimize mistakes: - * Heuristics are tuned to minimize warnings on legitimate pages. + * Checks are tuned to minimize warnings on legitimate pages. * Users are never prohibited from visiting the site requested, and the warnings shown are designed to be helpful and informative, rather than scary. * We monitor what sites trigger the most warnings on a regular basis, and - disable warnings on identified false positives. - * For domains used internally, we provide an [Enterprise + disable warnings when we identify mistakes. + * For domains used in company environments, we provide an [Enterprise Policy](https://cloud.google.com/docs/chrome-enterprise/policies/?policy=LookalikeWarningAllowlistDomains) - allowing businesses to selectively disable these warnings as needed for their + allowing businesses to selectively disable warnings as needed for their users. - * For several months following the roll-out of new heuristics, we accept - appeals from site operators whose sites have been incorrectly flagged. - * Heuristics launching in Chrome 88 or later will trigger a console message - informing site owners of the issue for at least one release prior to + * For several months following the roll-out of new lookalike checks, we accept + review requests from site operators whose sites have been flagged. + * New lookalike checks launching in Chrome 88 or later will trigger a console + message informing site owners of the issue for at least one release prior to triggering user-visible warnings. @@ -90,22 +90,21 @@ It is possible to remove warnings on sites where Chrome is incorrectly showing a warning. * If you are the owner of both the site showing the warning and the site that - Chrome thinks users should visit, you can - [**verify ownership of both sites**](#automated-warning-removal). + Chrome thinks users should visit, you can use our + [**automated warning removal process**](#automated-warning-removal). * If you are not the owner of both sites, or you can't follow the automated process, you can [**request a manual review**](#requesting-a-manual-review). - - + + ### Automated warning removal If you own both the site where Chrome is showing a warning, as well as the site that Chrome is recommending, you can suppress these warnings by proving that you -control both sites. To do this, Chrome uses a special form of +control both sites using a special form of [Digital Asset Links](https://developers.google.com/digital-asset-links). #### Instructions -1. Assuming you own both `example.com` and `example.net`, create a file -named `assetlinks.json` and put the following contents in it: +1. Create a file named `assetlinks.json` containing the following: ``` [{ "relation": ["lookalikes/allowlist"], @@ -115,17 +114,19 @@ "target" : { "namespace": "web", "site": "https://example.net"} }] ``` - -2. Upload this file to the following URLs: - - `https://example.com/.well-known/assetlinks.json` - - `https://example.net/.well-known/assetlinks.json` -3. Fill out a self-verification [request](https://forms.gle/DsoM64EmSZ5H4bNd8). +2. Replace `example.com` and `example.net` with the domain where the warning is + shown, and with the domain that Chrome recommends users visit. Do not use + subdomains (e.g. use "example.com", not "www.example.com"). +3. Upload this file to both of your sites at `/.well-known/assetlinks.json`. For + instance, in our example, you would upload the files at both + `https://example.com/.well-known/assetlinks.json` and + `https://example.net/.well-known/assetlinks.json`. +4. Fill out a self-verification [request](https://forms.gle/DsoM64EmSZ5H4bNd8). Once you submit the request, please allow a few days for all warnings to stop. If verification fails, you should be notified via email within a few hours. If you don't get an email indicating verification failure and your sites still show -a warning after a week, please submit a manual review -[request](https://forms.gle/BxV3JGbCbRjucDxq6). +a warning after a week, please submit a manual review using the process below. Important notes: * You must keep the `assetlinks.json` file in place so long as you wish to @@ -139,23 +140,18 @@ ### Requesting a manual review If a site triggers erroneous lookalike warnings in Chrome, -you can ask for a manual appeal. These appeals are evaluated manually, and we -can suppress the warning for all Chrome users when necessary. +you can ask for a manual review. Please only use this process if you are unable +to use the [Automated Process](#automated-warning-removal) above. In some +cases, we may require that you use the automated process to demonstrate that +you control both sites. -In the case of compelling spoofs, we may ask you to demonstrate that you not -only own the site on which the warning is shown, but the site that Chrome -believes that your site is spoofing. We may also opt to suppress warnings, but -only for a limited period of time (generally 6 months). This is generally used -for cases where a site is changing its domain name. +Requests for manual review are generally considered for six months following +after that warning would have started (i.e. after Chrome introduces the check). +After that time, we encourage developers to test their new sites in Chrome to +ensure that their new domain does not trigger warnings. -Appeals for domains triggered by a given heuristic are generally considered for -the 6 months following the release of that heuristic. These six months are -designed to allow Chrome to detect most existing sites that trigger the -heuristic erroneously. After that time, we encourage developers to test their -new sites in Chrome to ensure that their new domain does not trigger warnings. - -If you are a site owner and would like to request an appeal, please fill out -a [request](https://forms.gle/BxV3JGbCbRjucDxq6). +If you would like to request a review, please fill out a +[request](https://forms.gle/BxV3JGbCbRjucDxq6). #### Reasons an appeal might be denied @@ -172,5 +168,6 @@ For newly created sites, we encourage domain owners to choose domains that do not look like domains used by other sites commonly visited by your users. -Many warnings are also only encountered by a small fraction of users who happen -to intersect with both sites. See a further description of this above. +Please keep in mind that many warnings are only encountered by a small fraction +of users (those who visit both sites). See +[above](#not-all-users-see-all-warning) for details.
diff --git a/docs/speed/benchmark/harnesses/system_health.md b/docs/speed/benchmark/harnesses/system_health.md index cf5f49e..baafae3 100644 --- a/docs/speed/benchmark/harnesses/system_health.md +++ b/docs/speed/benchmark/harnesses/system_health.md
@@ -151,7 +151,7 @@ If there is a good reason for your stories to be added, please make one CL for each of the new stories so they can be landed (and reverted if needed) individually. On each CL, make sure that the perf trybots all pass before -comitting. +committing. Once your patch makes it through the CQ, you’re done… unless your story starts failing on some random platform, in which case the perf bot sheriff will very
diff --git a/docs/speed/benchmark/harnesses/webrtc_perf.md b/docs/speed/benchmark/harnesses/webrtc_perf.md index 59498c9..bded3b3 100644 --- a/docs/speed/benchmark/harnesses/webrtc_perf.md +++ b/docs/speed/benchmark/harnesses/webrtc_perf.md
@@ -20,7 +20,7 @@ The [`webrtc.py`](../../../../tools/perf/benchmarks/webrtc.py) benchmark specifies which metrics should be collected for the test pages, and extra options that we pass to the test to fake the real camera -and skip assing permission to get access to the video and audio from the user. +and skip assign permission to get access to the video and audio from the user. ## Running the Tests
diff --git a/docs/speed/binary_size/metrics.md b/docs/speed/binary_size/metrics.md index c410877..e454c6e8 100644 --- a/docs/speed/binary_size/metrics.md +++ b/docs/speed/binary_size/metrics.md
@@ -14,7 +14,7 @@ ### Alerting - * Alerts are sheriffed as part of the main perf sherif rotation. + * Alerts are sheriffed as part of the main perf sheriff rotation. * Alerts generally fire for ~100kb jumps. ## Metrics for Android
diff --git a/docs/speed/bot_health_sheriffing/images/som_alert_bug.png b/docs/speed/bot_health_sheriffing/images/som_alert_bug.png deleted file mode 100644 index 199691e9..0000000 --- a/docs/speed/bot_health_sheriffing/images/som_alert_bug.png +++ /dev/null Binary files differ
diff --git a/docs/speed/bot_health_sheriffing/images/som_duplicate_alert.png b/docs/speed/bot_health_sheriffing/images/som_duplicate_alert.png deleted file mode 100644 index 740dafc..0000000 --- a/docs/speed/bot_health_sheriffing/images/som_duplicate_alert.png +++ /dev/null Binary files differ
diff --git a/docs/speed/bot_health_sheriffing/images/som_first_alert.png b/docs/speed/bot_health_sheriffing/images/som_first_alert.png deleted file mode 100644 index 1525264..0000000 --- a/docs/speed/bot_health_sheriffing/images/som_first_alert.png +++ /dev/null Binary files differ
diff --git a/docs/speed/debug-janks-resources/frame-not-submitted.png b/docs/speed/debug-janks-resources/frame-not-submitted.png deleted file mode 100644 index 845dd56b..0000000 --- a/docs/speed/debug-janks-resources/frame-not-submitted.png +++ /dev/null Binary files differ
diff --git a/docs/speed/debug-janks-resources/frame-presented-missed.png b/docs/speed/debug-janks-resources/frame-presented-missed.png deleted file mode 100644 index 18fedc02..0000000 --- a/docs/speed/debug-janks-resources/frame-presented-missed.png +++ /dev/null Binary files differ
diff --git a/docs/speed/debug-janks-resources/frame-sequence-frame-flow.png b/docs/speed/debug-janks-resources/frame-sequence-frame-flow.png deleted file mode 100644 index 8c72d08..0000000 --- a/docs/speed/debug-janks-resources/frame-sequence-frame-flow.png +++ /dev/null Binary files differ
diff --git a/docs/speed/debug-janks-resources/gpu-process-threads.png b/docs/speed/debug-janks-resources/gpu-process-threads.png deleted file mode 100644 index 212e4d7..0000000 --- a/docs/speed/debug-janks-resources/gpu-process-threads.png +++ /dev/null Binary files differ
diff --git a/docs/speed/debug-janks-resources/select-timing.png b/docs/speed/debug-janks-resources/select-timing.png deleted file mode 100644 index 487e2066..0000000 --- a/docs/speed/debug-janks-resources/select-timing.png +++ /dev/null Binary files differ
diff --git a/docs/speed/images/chrome_speed_color.png b/docs/speed/images/chrome_speed_color.png deleted file mode 100644 index c9c634765..0000000 --- a/docs/speed/images/chrome_speed_color.png +++ /dev/null Binary files differ
diff --git a/docs/speed/microbenchmark_regressions.md b/docs/speed/microbenchmark_regressions.md index 31f49f5..5dc4a59 100644 --- a/docs/speed/microbenchmark_regressions.md +++ b/docs/speed/microbenchmark_regressions.md
@@ -35,7 +35,7 @@ ### No-op refactors that prevent AFDO -It's also possible to make no-op changes to code, cauing the previous AFDO data +It's also possible to make no-op changes to code, causing the previous AFDO data to be inapplicable (e.g. function name change). This can result in apparent regressions which recover spontaneously once new AFDO data is generated based on the new code. E.g. https://crbug.com/855544 was a specific case of this. One way
diff --git a/docs/speed/speed_domains.md b/docs/speed/speed_domains.md index 1aaf7b1..ebf480f 100644 --- a/docs/speed/speed_domains.md +++ b/docs/speed/speed_domains.md
@@ -49,7 +49,7 @@ ## Responsiveness Responsiveness domain focuses on making sure all websites have smooth transitions -by serving 60fps, and that the click to action time is not noticible. +by serving 60fps, and that the click to action time is not noticeable. * Performance-Responsiveness [Bug Queue](https://bugs.chromium.org/p/chromium/issues/list?can=2&q=Performance%3DResponsiveness)
diff --git a/docs/sublime_ide.md b/docs/sublime_ide.md index 3a0d24e..e8ec1d9 100644 --- a/docs/sublime_ide.md +++ b/docs/sublime_ide.md
@@ -255,7 +255,7 @@ perform [https://cs.chromium.org](https://cs.chromium.org) cross-reference searches in your editor. This gives you the call graph, overrides, references, declaration, and definition of most of the code. The results are as fresh as -the search engine's index so uncomitted changes won't be reflected. +the search engine's index so uncommitted changes won't be reflected. More information on Chromium X-Ref's functionality (including keyboard and mouse shortcuts) can be found on the [Chromium X-Refs
diff --git a/docs/sync/uss/client_tag_based_model_type_processor.md b/docs/sync/uss/client_tag_based_model_type_processor.md index a66a107..5c0b6d5 100644 --- a/docs/sync/uss/client_tag_based_model_type_processor.md +++ b/docs/sync/uss/client_tag_based_model_type_processor.md
@@ -32,7 +32,7 @@ ## Processor State Machines The processor sits between the model bridge and the sync engine. It has -knowledge of what state each is in based on the calls it has receieved and +knowledge of what state each is in based on the calls it has received and performed. The states are not stored explicitly, but are implicit based on state stored in the processor. Here are the states of each, with notes on their transitions and how to determine them.
diff --git a/docs/ui/animation_builder/images/animation_builder2.png b/docs/ui/animation_builder/images/animation_builder2.png deleted file mode 100644 index 59023ce7..0000000 --- a/docs/ui/animation_builder/images/animation_builder2.png +++ /dev/null Binary files differ
diff --git a/docs/ui/animation_builder/images/animation_builder3.png b/docs/ui/animation_builder/images/animation_builder3.png deleted file mode 100644 index ba764b2..0000000 --- a/docs/ui/animation_builder/images/animation_builder3.png +++ /dev/null Binary files differ
diff --git a/docs/ui/create/examples/login_dialog.md b/docs/ui/create/examples/login_dialog.md index 10f9c15..0b20b6d 100644 --- a/docs/ui/create/examples/login_dialog.md +++ b/docs/ui/create/examples/login_dialog.md
@@ -95,31 +95,36 @@ : BubbleDialogDelegateView(anchor_view, anchor_position) { ... const LayoutProvider* provider = LayoutProvider::Get(); - set_margins( - provider->GetDialogInsetsForContentType(views::DialogContentType::kControl, views::DialogContentType::kControl)); + set_margins(provider->GetDialogInsetsForContentType( + views::DialogContentType::kControl, views::DialogContentType::kControl)); const int related_control_padding = provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL); const int label_padding = provider->GetDistanceMetric(views::DISTANCE_RELATED_LABEL_HORIZONTAL); - GridLayout* layout = SetLayoutManager(std::make_unique<GridLayout>()); - ColumnSet* column_set = layout->AddColumnSet(0); - column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, - GridLayout::kFixedSize, GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, label_padding); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1.0, - GridLayout::USE_PREF, 0, 0); + SetLayoutManager(std::make_unique<views::TableLayout>()) + ->AddColumn(views::LayoutAlignment::kStart, + views::LayoutAlignment::kStretch, + views::TableLayout::kFixedSize, + views::TableLayout::kUsePreferred, 0, 0) + .AddPaddingColumn(TableLayout::kFixedSize, label_padding) + .AddColumn(views::LayoutAlignment::kStretch, + views::LayoutAlignment::kStretch, 1.0f, + views::TableLayout::kUsePreferred, 0, 0) + .AddRows(1, views::TableLayout::kFixedSize) + .AddPaddingRow(TableLayout::kFixedSize, related_control_padding) + .AddRows(1, views::TableLayout::kFixedSize); } ``` -This creates a 2x2 [`GridLayout`](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/layout/grid_layout.h) +This creates a 2x2 [`TableLayout`](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/layout/table_layout.h) with horizontal padding specified by the layout constant `DISTANCE_RELATED_LABEL_HORIZONTAL`. The first column will hold the form’s [`Label`](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/controls/label.h)s and the second will hold the [`Textfield`](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/controls/textfield/textfield.h)s for user input. -To help with adding rows to the `GridLayout`, add the following scoped helper +To help with adding rows to the `TableLayout`, add the following scoped helper and relevant headers. @@ -129,19 +134,18 @@ #include <string> #include "ui/views/controls/label.h" -#include "ui/views/layout/grid_layout.h" +#include "ui/views/layout/table_layout.h" #include "ui/views/layout/layout_provider.h" ... namespace { // Adds a label textfield pair to the login dialog's layout. -views::Textfield* AddFormRow(views::GridLayout* layout, +views::Textfield* AddFormRow(views::View* parent, const std::u16string& label_text) { - layout->StartRow(0, 0); views::Label* label = - layout->AddView(std::make_unique<views::Label>(label_text)); + parent->AddChildView(std::make_unique<views::Label>(label_text)); views::Textfield* textfield = - layout->AddView(std::make_unique<views::Textfield>()); + parent->AddChildView(std::make_unique<views::Textfield>()); textfield->SetAssociatedLabel(label); constexpr int kDefaultTextfieldWidth = 30; constexpr int kMinimumTextfieldWidth = 5; @@ -154,11 +158,12 @@ ... ``` -This creates a new [`GridLayout`](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/layout/grid_layout.h) -row for a given field in our form. The call to +The call to [`SetAssociatedLabel()`](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/controls/textfield/textfield.h;l=250;drc=291180454e079aa5c3677dc3f3eaf619a1cf1d42) sets the accessible label relationship between the -[`Label`](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/controls/label.h) and the [`Textfield`](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/controls/textfield/textfield.h) +[`Label`](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/controls/label.h) +and the +[`Textfield`](https://source.chromium.org/chromium/chromium/src/+/main:ui/views/controls/textfield/textfield.h) and copies the `Label`’s accessible name to the `Textfield`. @@ -210,12 +215,10 @@ SetButtonLabel(ui::DIALOG_BUTTON_OK, l10n_util::GetStringUTF16( IDS_STARTER_DIALOG_OK_BUTTON_LABEL)); ... - username_ = AddFormRow(layout, l10n_util::GetStringUTF16( + username_ = AddFormRow(this, l10n_util::GetStringUTF16( IDS_LOGIN_DIALOG_USERNAME_ACCESSIBLE_NAME)); - layout->AddPaddingRow(0, related_control_padding); - - password_ = AddFormRow(layout, l10n_util::GetStringUTF16( + password_ = AddFormRow(this, l10n_util::GetStringUTF16( IDS_LOGIN_DIALOG_PASSWORD_ACCESSIBLE_NAME)); password_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD); } @@ -333,7 +336,6 @@ ``` cpp views::Textfield* AddFormRow(LoginBubbleDialogView* bubble, - views::GridLayout* layout, const std::u16string& label_text) { ... textfield->set_controller(bubble); @@ -358,13 +360,10 @@ SetButtonEnabled(ui::DIALOG_BUTTON_OK, false); ... username_ = AddFormRow( - this, layout, + this, l10n_util::GetStringUTF16(IDS_LOGIN_DIALOG_USERNAME_ACCESSIBLE_NAME)); - - layout->AddPaddingRow(0, related_control_padding); - password_ = AddFormRow( - this, layout, + this, l10n_util::GetStringUTF16(IDS_LOGIN_DIALOG_PASSWORD_ACCESSIBLE_NAME)); password_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD); } @@ -440,18 +439,16 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/views/border.h" #include "ui/views/controls/label.h" -#include "ui/views/layout/grid_layout.h" +#include "ui/views/layout/table_layout.h" #include "ui/views/layout/layout_provider.h" namespace { // Adds a label textfield pair to the login dialog's layout. Textfield* AddFormRow(LoginBubbleDialogView* bubble, - GridLayout* layout, const std::u16string& label_text) { - layout->StartRow(0, 0); - Label* label = layout->AddView(std::make_unique<Label>(label_text)); - Textfield* textfield = layout->AddView(std::make_unique<Textfield>()); + Label* label = bubble->AddChildView(std::make_unique<Label>(label_text)); + Textfield* textfield = bubble->AddChildView(std::make_unique<Textfield>()); textfield->SetAssociatedLabel(label); textfield->set_controller(bubble); constexpr int kDefaultTextfieldWidth = 30; @@ -505,29 +502,32 @@ l10n_util::GetStringUTF16(IDS_EXAMPLE_LOGIN_DIALOG_OK_BUTTON_LABEL)); const LayoutProvider* provider = LayoutProvider::Get(); - set_margins( - provider->GetDialogInsetsForContentType(views::DialogContentType::kControl, views::DialogContentType::kControl)); + set_margins(provider->GetDialogInsetsForContentType( + views::DialogContentType::kControl, views::DialogContentType::kControl)); const int related_control_padding = provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL); const int label_padding = provider->GetDistanceMetric(views::DISTANCE_RELATED_LABEL_HORIZONTAL); - GridLayout* layout = SetLayoutManager(std::make_unique<GridLayout>()); - ColumnSet* column_set = layout->AddColumnSet(0); - column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, - GridLayout::kFixedSize, GridLayout::USE_PREF, 0, 0); - column_set->AddPaddingColumn(0, label_padding); - column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1.0, - GridLayout::USE_PREF, 0, 0); + + SetLayoutManager(std::make_unique<views::TableLayout>()) + ->AddColumn(views::LayoutAlignment::kStart, + views::LayoutAlignment::kStretch, + views::TableLayout::kFixedSize, + views::TableLayout::kUsePreferred, 0, 0) + .AddPaddingColumn(TableLayout::kFixedSize, label_padding) + .AddColumn(views::LayoutAlignment::kStretch, + views::LayoutAlignment::kStretch, 1.0f, + views::TableLayout::kUsePreferred, 0, 0) + .AddRows(1, views::TableLayout::kFixedSize) + .AddPaddingRow(TableLayout::kFixedSize, related_control_padding) + .AddRows(1, views::TableLayout::kFixedSize); username_ = - AddFormRow(this, layout, + AddFormRow(this, l10n_util::GetStringUTF16( IDS_EXAMPLE_LOGIN_DIALOG_USERNAME_ACCESSIBLE_NAME)); - - layout->AddPaddingRow(0, related_control_padding); - password_ = - AddFormRow(this, layout, + AddFormRow(this, l10n_util::GetStringUTF16( IDS_EXAMPLE_LOGIN_DIALOG_PASSWORD_ACCESSIBLE_NAME)); password_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
diff --git a/docs/ui/learn/bestpractices/layout.md b/docs/ui/learn/bestpractices/layout.md index fed019a..14c6060 100644 --- a/docs/ui/learn/bestpractices/layout.md +++ b/docs/ui/learn/bestpractices/layout.md
@@ -464,19 +464,19 @@ |||---||| -## Use GridLayout with caution +## Use TableLayout with caution -[`GridLayout`][] is a `LayoutManager` used for tabular layouts. Much like +[`TableLayout`][] is a `LayoutManager` used for tabular layouts. Much like table-based layout in HTML, it can achieve almost any desired effect, and in some scenarios (e.g. creating an actual table) is the best tool. Used indiscriminately, it can be cryptic, verbose, and error-prone. Accordingly, -**use `GridLayout` only when creating a true grid, not simply for selective -horizontal and vertical alignment.** For simple layouts, [`BoxLayout`][] and -[`FlexLayout`][] are better choices; for more complex layouts, representing -sections or groups hierarchically may result in simpler inner layouts that -can be nested within an overall layout. +**use `TableLayout` only when creating a true grid or table, not simply for +selective horizontal and vertical alignment.** For simple layouts, +[`BoxLayout`][] and [`FlexLayout`][] are better choices; for more complex +layouts, representing sections or groups hierarchically may result in simpler +inner layouts that can be nested within an overall layout. -[`GridLayout`]: https://source.chromium.org/chromium/chromium/src/+/main:ui/views/layout/grid_layout.h;l=79;drc=8cab3382ac9b70b7ecfe29ae03b1b7ee8f4e01fa +[`TableLayout`]: https://source.chromium.org/chromium/chromium/src/+/main:ui/views/layout/table_layout.h;l=73;drc=f513afe81fca508d22153b192f1fab33e2c444fa [`BoxLayout`]: https://source.chromium.org/chromium/chromium/src/+/main:ui/views/layout/box_layout.h;l=28;drc=5b9e43d976aca377588875fc59c5348ede02a8b5 [`FlexLayout`]: https://source.chromium.org/chromium/chromium/src/+/main:ui/views/layout/flex_layout.h;l=73;drc=62bf27aca5418212ceadd8daf9188d2aa437bfcc @@ -486,7 +486,7 @@ **Avoid** -The following old code uses a [`GridLayout`][] to create a HoverButton with +The following old code uses a [`TableLayout`][] to create a HoverButton with a stacked title and subtitle flanked on by views on both sides. ##### @@ -519,65 +519,65 @@ std::unique_ptr<views::View> secondary_view, ...) { ... - views::GridLayout* grid_layout = + views::TableLayout* table_layout = SetLayoutManager( - std::make_unique<views::GridLayout>()); + std::make_unique<views::TableLayout>()); ... - constexpr int kColumnSetId = 0; - views::ColumnSet* columns = - grid_layout->AddColumnSet(kColumnSetId); - columns->AddColumn( - views::GridLayout::CENTER, - views::GridLayout::CENTER, - views::GridLayout::kFixedSize, - views::GridLayout::USE_PREF, 0, 0); - columns->AddPaddingColumn( - views::GridLayout::kFixedSize, + table_layout->AddColumn( + views::LayoutAlignment::kCenter, + views::LayoutAlignment::kCenter, + views::TableLayout::kFixedSize, + views::TableLayout::kUsePreferred, 0, 0); + table_layout->AddPaddingColumn( + views::TableLayout::kFixedSize, icon_label_spacing); - columns->AddColumn( - views::GridLayout::FILL, - views::GridLayout::FILL, - 1.0, views::GridLayout::USE_PREF, 0, 0); + table_layout->AddColumn( + views::LayoutAlignment::kStretch, + views::LayoutAlignment::kStretch, 1.0f, + views::TableLayout::kUsePreferred, 0, 0); ... - grid_layout->StartRow( - views::GridLayout::kFixedSize, kColumnSetId, + table_layout->AddRows( + 1, views::TableLayout::kFixedSize, row_height); - icon_view_ = grid_layout->AddView( + icon_view_ = AddChildView( std::move(icon_view), 1, num_labels); ... auto title_wrapper = std::make_unique<SingleLineStyledLabelWrapper>( title); title_ = title_wrapper->label(); - grid_layout->AddView(std::move(title_wrapper)); + AddChildView(std::move(title_wrapper)); if (secondary_view) { - columns->AddColumn( - views::GridLayout::CENTER, - views::GridLayout::CENTER, - views::GridLayout::kFixedSize, - views::GridLayout::USE_PREF, 0, 0); + table_layout->AddColumn( + views::LayoutAlignment::kCenter, + views::LayoutAlignment::kCenter, + views::TableLayout::kFixedSize, + views::TableLayout::kUsePreferred, 0, 0); ... - secondary_view_ = - grid_layout->AddView( - std::move(secondary_view), 1, num_labels); + secondary_view_ = AddChildView( + std::move(secondary_view), 1, num_labels); ... } if (!subtitle.empty()) { - grid_layout->StartRow( - views::GridLayout::kFixedSize, kColumnSetId, + table_layout->AddRows( + 1, views::TableLayout::kFixedSize, row_height); auto subtitle_label = std::make_unique<views::Label>( subtitle, views::style::CONTEXT_BUTTON, views::style::STYLE_SECONDARY); ... - grid_layout->SkipColumns(1); + AddChildView(std::make_unique<views::View>()); subtitle_ = - grid_layout->AddView(std::move(subtitle_label)); + AddChildView(std::move(subtitle_label)); } ... } + + + + ``` ##### @@ -715,6 +715,13 @@ ``` cpp ... + + + + + + + ``` |||---||| @@ -1157,10 +1164,6 @@ - - - - void TimeView::SetupLabels() { horizontal_label_.reset(new views::Label()); SetupLabel(horizontal_label_.get()); @@ -1250,33 +1253,29 @@ } TimeView::VerticalLabelView::VerticalLabelView() { - views::GridLayout* layout = - SetLayoutManager( - std::make_unique<views::GridLayout>()); views::Label* label_hours = AddChildView(std::make_unique<views::Label>()); views::Label* label_minutes = AddChildView(std::make_unique<views::Label>()); SetupLabel(label_hours); SetupLabel(label_minutes); - const int kColumnId = 0; - views::ColumnSet* columns = - layout->AddColumnSet(kColumnId); - columns->AddPaddingColumn( - 0, kVerticalClockLeftPadding); - columns->AddColumn( - views::GridLayout::TRAILING, - views::GridLayout::CENTER, - 0, views::GridLayout::USE_PREF, 0, 0); - layout->AddPaddingRow(0, kClockLeadingPadding); - layout->StartRow(0, kColumnId); - // Add the views as existing since ownership isn't - // being transferred. - layout->AddExistingView(label_hours); - layout->StartRow(0, kColumnId); - layout->AddExistingView(label_minutes); - layout->AddPaddingRow( - 0, kVerticalClockMinutesTopOffset); + SetLayoutManager( + std::make_unique<views::TableLayout>()) + ->AddPaddingColumn( + views::TableLayout::kFixedSize, + kVerticalClockLeftPadding) + .AddColumn( + views::LayoutAlignment::kEnd, + views::LayoutAlignment::kCenter, + views::TableLayout::kFixedSize, + views::TableLayout::kUsePreferred, 0, 0) + .AddPaddingRow( + views::TableLayout::kFixedSize, + kClockLeadingPadding) + .AddRows(2, views::TableLayout::kFixedSize) + .AddPaddingRow( + views::TableLayout::kFixedSize, + kVerticalClockMinutesTopOffset); ... }
diff --git a/docs/ui/ui_devtools/images/location_bar_view_properties.png b/docs/ui/ui_devtools/images/location_bar_view_properties.png deleted file mode 100644 index ced7b68..0000000 --- a/docs/ui/ui_devtools/images/location_bar_view_properties.png +++ /dev/null Binary files differ
diff --git a/docs/ui/views/overview.md b/docs/ui/views/overview.md index 810311e2..1a94ae5 100644 --- a/docs/ui/views/overview.md +++ b/docs/ui/views/overview.md
@@ -76,7 +76,7 @@ layout for horizontal and vertical arrangements of views. Other commonly-used layouts managers are [BoxLayout], a predecessor of -FlexLayout, and [GridLayout], which provides a flexible row-and-column +FlexLayout, and [TableLayout], which provides a flexible row-and-column system. ### Painting @@ -159,8 +159,9 @@ [DialogDelegate]: https://cs.chromium.org/chromium/src/ui/views/window/dialog_delegate.h [DialogDelegateView]: https://cs.chromium.org/chromium/src/ui/views/window/dialog_delegate.h [FillLayout]: https://cs.chromium.org/chromium/src/ui/views/layout/fill_layout.h +[FlexLayout]: https://cs.chromium.org/chromium/src/ui/views/layout/flex_layout.h [FocusManager]: https://cs.chromium.org/chromium/src/ui/views/focus/focus_manager.h -[GridLayout]: https://cs.chromium.org/chromium/src/ui/views/layout/grid_layout.h +[TableLayout]: https://cs.chromium.org/chromium/src/ui/views/layout/table_layout.h [NonClientView]: https://cs.chromium.org/chromium/src/ui/views/window/non_client_view.h [NonClientFrameView]: https://cs.chromium.org/chromium/src/ui/views/window/non_client_view.h
diff --git a/docs/updater/protocol_3_1.md b/docs/updater/protocol_3_1.md index 01d5a822..28f20574 100644 --- a/docs/updater/protocol_3_1.md +++ b/docs/updater/protocol_3_1.md
@@ -150,7 +150,7 @@ with a semantic meaning of "unknown") do not need to increase the protocol version. Removals of values with specified defaults from the protocol do not need to increase the protocol version, since the default value can be assumed by -compatible enpoints. All other changes to the protocol may require a new version +compatible endpoints. All other changes to the protocol may require a new version number. ### Timing & Backoff
diff --git a/docs/vscode.md b/docs/vscode.md index 891d5b0..ec20e62 100644 --- a/docs/vscode.md +++ b/docs/vscode.md
@@ -145,7 +145,7 @@ * `Ctrl+K, Ctrl+S` opens the key bindings editor. * ``Ctrl+` `` toggles the built-in terminal. * `Ctrl+Shift+M` toggles the problems view (linter warnings, compile errors - and warnings). You'll swicth a lot between terminal and problem view during + and warnings). You'll switch a lot between terminal and problem view during compilation. * `Alt+O` switches between the source/header file. * `Ctrl+G` jumps to a line.
diff --git "a/infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Android Tests \050dbg\051 \050L Nexus5\051/properties.textpb" "b/infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Android Tests \050dbg\051 \050N Nexus5X\051/properties.textpb" similarity index 100% rename from "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Android Tests \050dbg\051 \050L Nexus5\051/properties.textpb" rename to "infra/config/generated/builders/webrtc.fyi/WebRTC Chromium FYI Android Tests \050dbg\051 \050N Nexus5X\051/properties.textpb"
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 898729b39..52ca082 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -76164,7 +76164,7 @@ } } builders { - name: "WebRTC Chromium FYI Android Tests (dbg) (L Nexus5)" + name: "WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" @@ -76202,7 +76202,7 @@ } } builders { - name: "WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)" + name: "WebRTC Chromium FYI Android Tests (dbg) (N Nexus5X)" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" dimensions: "os:Ubuntu-16.04|Ubuntu-18.04"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg index 027e3548..ce65bf2 100644 --- a/infra/config/generated/luci/luci-milo.cfg +++ b/infra/config/generated/luci/luci-milo.cfg
@@ -12347,16 +12347,16 @@ short_name: "64" } builders { - name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Android Tests (dbg) (L Nexus5)" - category: "android|debug|tester" - short_name: "L" - } - builders { name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)" category: "android|debug|tester" short_name: "M" } builders { + name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Android Tests (dbg) (N Nexus5X)" + category: "android|debug|tester" + short_name: "N" + } + builders { name: "buildbucket/luci.chromium.webrtc.fyi/WebRTC Chromium FYI Android Builder" category: "android|release" short_name: "32"
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg index 441e2da..b3b0619 100644 --- a/infra/config/generated/luci/luci-scheduler.cfg +++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -3399,20 +3399,6 @@ } } job { - id: "WebRTC Chromium FYI Android Tests (dbg) (L Nexus5)" - realm: "webrtc.fyi" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "webrtc.fyi" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium.webrtc.fyi" - builder: "WebRTC Chromium FYI Android Tests (dbg) (L Nexus5)" - } -} -job { id: "WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)" realm: "webrtc.fyi" acls { @@ -3427,6 +3413,20 @@ } } job { + id: "WebRTC Chromium FYI Android Tests (dbg) (N Nexus5X)" + realm: "webrtc.fyi" + acls { + role: TRIGGERER + granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" + } + acl_sets: "webrtc.fyi" + buildbucket { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.webrtc.fyi" + builder: "WebRTC Chromium FYI Android Tests (dbg) (N Nexus5X)" + } +} +job { id: "WebRTC Chromium FYI Linux Builder" realm: "webrtc.fyi" acl_sets: "webrtc.fyi"
diff --git a/infra/config/subprojects/webrtc/consoles/chromium.webrtc.fyi.star b/infra/config/subprojects/webrtc/consoles/chromium.webrtc.fyi.star index 9f3b05c..3db89a6 100644 --- a/infra/config/subprojects/webrtc/consoles/chromium.webrtc.fyi.star +++ b/infra/config/subprojects/webrtc/consoles/chromium.webrtc.fyi.star
@@ -21,16 +21,16 @@ short_name = "64", ), luci.console_view_entry( - builder = "webrtc.fyi/WebRTC Chromium FYI Android Tests (dbg) (L Nexus5)", - category = "android|debug|tester", - short_name = "L", - ), - luci.console_view_entry( builder = "webrtc.fyi/WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)", category = "android|debug|tester", short_name = "M", ), luci.console_view_entry( + builder = "webrtc.fyi/WebRTC Chromium FYI Android Tests (dbg) (N Nexus5X)", + category = "android|debug|tester", + short_name = "N", + ), + luci.console_view_entry( builder = "webrtc.fyi/WebRTC Chromium FYI Android Builder", category = "android|release", short_name = "32",
diff --git a/infra/config/subprojects/webrtc/webrtc.fyi.star b/infra/config/subprojects/webrtc/webrtc.fyi.star index 19b371a9d..0e4bcef 100644 --- a/infra/config/subprojects/webrtc/webrtc.fyi.star +++ b/infra/config/subprojects/webrtc/webrtc.fyi.star
@@ -63,13 +63,13 @@ ) builder( - name = "WebRTC Chromium FYI Android Tests (dbg) (L Nexus5)", - triggered_by = ["WebRTC Chromium FYI Android Builder (dbg)"], + name = "WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)", + triggered_by = ["WebRTC Chromium FYI Android Builder ARM64 (dbg)"], ) builder( - name = "WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)", - triggered_by = ["WebRTC Chromium FYI Android Builder ARM64 (dbg)"], + name = "WebRTC Chromium FYI Android Tests (dbg) (N Nexus5X)", + triggered_by = ["WebRTC Chromium FYI Android Builder (dbg)"], ) builder(
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/disabled_tab_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/disabled_tab_view_controller.mm index 52d2be6f..234cabd 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/disabled_tab_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/disabled_tab_view_controller.mm
@@ -11,6 +11,7 @@ #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #import "ios/chrome/common/string_util.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" +#import "ios/chrome/common/ui/util/constraints_ui_util.h" #include "ios/chrome/grit/ios_strings.h" #import "net/base/mac/url_conversions.h" #include "ui/base/l10n/l10n_util.h" @@ -129,13 +130,9 @@ [scrollView addSubview:container]; [self.view addSubview:scrollView]; - NSLayoutConstraint* scrollViewHeightConstraint = [scrollView.heightAnchor - constraintEqualToAnchor:container.heightAnchor - constant:(self.scrollViewContentInsets.top + - self.scrollViewContentInsets.bottom)]; - scrollViewHeightConstraint.priority = UILayoutPriorityDefaultLow; - scrollViewHeightConstraint.active = YES; - self.scrollViewHeight = scrollViewHeightConstraint; + self.scrollViewHeight = VerticalConstraintsWithInset( + container, scrollView, + self.scrollViewContentInsets.top + self.scrollViewContentInsets.bottom); [NSLayoutConstraint activateConstraints:@[ [topLabel.topAnchor constraintEqualToAnchor:container.topAnchor
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_empty_state_view.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_empty_state_view.mm index 55bb8971..c84e018 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_empty_state_view.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_empty_state_view.mm
@@ -125,13 +125,9 @@ [scrollView addSubview:container]; [self addSubview:scrollView]; - NSLayoutConstraint* scrollViewHeightConstraint = [scrollView.heightAnchor - constraintEqualToAnchor:container.heightAnchor - constant:(self.scrollViewContentInsets.top + - self.scrollViewContentInsets.bottom)]; - scrollViewHeightConstraint.priority = UILayoutPriorityDefaultLow; - scrollViewHeightConstraint.active = YES; - self.scrollViewHeight = scrollViewHeightConstraint; + self.scrollViewHeight = VerticalConstraintsWithInset( + container, scrollView, + self.scrollViewContentInsets.top + self.scrollViewContentInsets.bottom); [NSLayoutConstraint activateConstraints:@[ [imageView.topAnchor constraintEqualToAnchor:container.topAnchor],
diff --git a/ios/chrome/common/ui/util/constraints_ui_util.h b/ios/chrome/common/ui/util/constraints_ui_util.h index ea93eff..42f0a634 100644 --- a/ios/chrome/common/ui/util/constraints_ui_util.h +++ b/ios/chrome/common/ui/util/constraints_ui_util.h
@@ -198,6 +198,12 @@ id<EdgeLayoutGuideProvider> bottomInnerView, CGFloat padding); +// Returns the vertical constraint of |innerView| and |outerView|. The height of +// |outerView| equals to the height of |innerView| plus |inset|. +NSLayoutConstraint* VerticalConstraintsWithInset(UIView* innerView, + UIView* outerView, + CGFloat inset); + #pragma mark - Safe Area. #endif // IOS_CHROME_COMMON_UI_UTIL_CONSTRAINTS_UI_UTIL_H_
diff --git a/ios/chrome/common/ui/util/constraints_ui_util.mm b/ios/chrome/common/ui/util/constraints_ui_util.mm index a0bec8d4..0cf0228 100644 --- a/ios/chrome/common/ui/util/constraints_ui_util.mm +++ b/ios/chrome/common/ui/util/constraints_ui_util.mm
@@ -190,3 +190,14 @@ [NSLayoutConstraint activateConstraints:@[ topPaddingConstraint, bottomPaddingConstraint ]]; } + +NSLayoutConstraint* VerticalConstraintsWithInset(UIView* innerView, + UIView* outerView, + CGFloat inset) { + NSLayoutConstraint* heightConstraint = + [outerView.heightAnchor constraintEqualToAnchor:innerView.heightAnchor + constant:inset]; + heightConstraint.priority = UILayoutPriorityDefaultLow; + heightConstraint.active = YES; + return heightConstraint; +}
diff --git a/media/gpu/vaapi/h264_vaapi_video_decoder_delegate.cc b/media/gpu/vaapi/h264_vaapi_video_decoder_delegate.cc index aa5e9bde..196eab3 100644 --- a/media/gpu/vaapi/h264_vaapi_video_decoder_delegate.cc +++ b/media/gpu/vaapi/h264_vaapi_video_decoder_delegate.cc
@@ -45,6 +45,28 @@ } // namespace +// This is the size of the data block which the AMD_SLICE_PARAMS is stored in. +constexpr size_t kAmdEncryptedSliceHeaderSize = 1024; +#if BUILDFLAG(IS_CHROMEOS_ASH) +// These structures match what AMD uses to pass back the extra slice header +// parameters we need for CENCv1. This is stored in the first 1KB of the +// encrypted subsample returned by the cdm-oemcrypto daemon on ChromeOS. +typedef struct AMD_EXTRA_SLICE_PARAMS { + uint8_t bottom_field_flag; + uint8_t num_ref_idx_l0_active_minus1; + uint8_t num_ref_idx_l1_active_minus1; +} AMD_EXTRA_SLICE_PARAMS; + +typedef struct AMD_SLICE_PARAMS { + AMD_EXTRA_SLICE_PARAMS va_param; + uint8_t reserved[64 - sizeof(AMD_EXTRA_SLICE_PARAMS)]; + VACencSliceParameterBufferH264 cenc_param; +} AMD_SLICE_PARAMS; + +static_assert(sizeof(AMD_SLICE_PARAMS) <= kAmdEncryptedSliceHeaderSize, + "Invalid size for AMD_SLICE_PARAMS"); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + H264VaapiVideoDecoderDelegate::H264VaapiVideoDecoderDelegate( DecodeSurfaceHandler<VASurface>* const vaapi_dec, scoped_refptr<VaapiWrapper> vaapi_wrapper, @@ -204,112 +226,146 @@ DCHECK(!subsamples.empty()); DCHECK(!data.empty()); - // This is done by sending in the encryption parameters and the encrypted - // slice header. Then the vaEndPicture call is blocking while it decrypts and - // parses the header parameters. We use VACencStatusBuf which allows us to - // extract the slice header parameters of interest and return them to the - // caller. - #if BUILDFLAG(IS_CHROMEOS_ASH) - VAEncryptionParameters crypto_params = {}; - // Don't use the VAEncryptionSegmentInfo vector in the class since we do not - // need to hold this data across calls. - std::vector<VAEncryptionSegmentInfo> segment_info; - ProtectedSessionState state = - SetupDecryptDecode(true /* full sample */, data[0].size(), &crypto_params, - &segment_info, subsamples); - if (state == ProtectedSessionState::kFailed) { - LOG(ERROR) << "ParseEncryptedSliceHeader fails because we couldn't setup " - "the protected session"; - return DecodeStatus::kFail; - } else if (state != ProtectedSessionState::kCreated) { - return DecodeStatus::kTryAgain; - } - - // For encrypted header parsing, we need to also send the SPS and PPS. Both of - // those and the slice NALU need to be prefixed with the 0x000001 start code. - constexpr size_t kStartCodeSize = 3; - constexpr size_t kExtraDataBytes = 3 * kStartCodeSize; - - // Adjust the first segment length and init length to compensate for inserting - // the SPS, PPS and 3 start codes. - size_t size_adjustment = - sps_nalu_data.size() + pps_nalu_data.size() + kExtraDataBytes; - size_t total_size = 0; - size_t offset_adjustment = 0; - for (auto& segment : segment_info) { - segment.segment_length += size_adjustment; - segment.init_byte_length += size_adjustment; - segment.segment_start_offset += offset_adjustment; - offset_adjustment += size_adjustment; - // Any additional segments are only adjusted by the start code size; - size_adjustment = kStartCodeSize; - total_size += segment.segment_length; - } - - crypto_params.status_report_index = GetSliceHeaderCounter(); - - // This is based on a sample from Intel for how to use this API. - constexpr size_t kDecryptQuerySizeAndAlignment = 4096; - std::unique_ptr<void, base::AlignedFreeDeleter> surface_memory( - base::AlignedAlloc(kDecryptQuerySizeAndAlignment, - kDecryptQuerySizeAndAlignment)); - constexpr size_t kVaQueryCencBufferSize = 2048; - auto back_buffer_mem = std::make_unique<uint8_t[]>(kVaQueryCencBufferSize); - VACencStatusBuf* status_buf = - reinterpret_cast<VACencStatusBuf*>(surface_memory.get()); - status_buf->status = VA_ENCRYPTION_STATUS_INCOMPLETE; - status_buf->buf = back_buffer_mem.get(); - status_buf->buf_size = kVaQueryCencBufferSize; - auto slice_param_buf = std::make_unique<VACencSliceParameterBufferH264>(); - status_buf->slice_buf_type = VaCencSliceBufParamter; - status_buf->slice_buf_size = sizeof(VACencSliceParameterBufferH264); - status_buf->slice_buf = slice_param_buf.get(); + // For AMD, we get the slice parameters as structures in the first encrypted + // range. + if (IsTranscrypted()) { + if (data.size() != 1) { + DLOG(ERROR) << "Incorrect number of spans for AMD encrypted slice header"; + return DecodeStatus::kFail; + } + if (subsamples[0].cypher_bytes < kAmdEncryptedSliceHeaderSize) { + DLOG(ERROR) << "AMD CENCv1 data is wrong size: " + << subsamples[0].cypher_bytes; + return DecodeStatus::kFail; + } + const AMD_SLICE_PARAMS* amd_slice_params = + reinterpret_cast<const AMD_SLICE_PARAMS*>(data[0].data() + + subsamples[0].clear_bytes); + // Fill in the AMD specific params. + slice_header_out->bottom_field_flag = + amd_slice_params->va_param.bottom_field_flag; + slice_header_out->num_ref_idx_l0_active_minus1 = + amd_slice_params->va_param.num_ref_idx_l0_active_minus1; + slice_header_out->num_ref_idx_l1_active_minus1 = + amd_slice_params->va_param.num_ref_idx_l1_active_minus1; + // Copy the common parameters that we will fill in below. + memcpy(slice_param_buf.get(), &amd_slice_params->cenc_param, + sizeof(VACencSliceParameterBufferH264)); + } else { + // For Intel, this is done by sending in the encryption parameters and the + // encrypted slice header. Then the vaEndPicture call is blocking while it + // decrypts and parses the header parameters. We use VACencStatusBuf which + // allows us to extract the slice header parameters of interest and return + // them to the caller. - constexpr int kCencStatusSurfaceDimension = 64; - auto buffer_ptr_alloc = std::make_unique<uintptr_t>(); - uintptr_t* buffer_ptr = reinterpret_cast<uintptr_t*>(buffer_ptr_alloc.get()); - buffer_ptr[0] = reinterpret_cast<uintptr_t>(surface_memory.get()); + VAEncryptionParameters crypto_params = {}; + // Don't use the VAEncryptionSegmentInfo vector in the class since we do not + // need to hold this data across calls. + std::vector<VAEncryptionSegmentInfo> segment_info; + ProtectedSessionState state = + SetupDecryptDecode(true /* full sample */, data[0].size(), + &crypto_params, &segment_info, subsamples); + if (state == ProtectedSessionState::kFailed) { + LOG(ERROR) << "ParseEncryptedSliceHeader fails because we couldn't setup " + "the protected session"; + return DecodeStatus::kFail; + } else if (state != ProtectedSessionState::kCreated) { + return DecodeStatus::kTryAgain; + } - auto surface = vaapi_wrapper_->CreateVASurfaceForUserPtr( - gfx::Size(kCencStatusSurfaceDimension, kCencStatusSurfaceDimension), - buffer_ptr, - 3 * kCencStatusSurfaceDimension * kCencStatusSurfaceDimension); - if (!surface) { - DVLOG(1) << "Failed allocating surface for decrypt status"; - return DecodeStatus::kFail; - } + // For encrypted header parsing, we need to also send the SPS and PPS. Both + // of those and the slice NALU need to be prefixed with the 0x000001 start + // code. + constexpr size_t kStartCodeSize = 3; + constexpr size_t kExtraDataBytes = 3 * kStartCodeSize; - // Assembles the 'slice data' which is the SPS, PPS, encrypted SEIS and - // encrypted slice data, each of which is also prefixed by the 0x000001 start - // code. - std::vector<uint8_t> full_data; - const std::vector<uint8_t> start_code = {0u, 0u, 1u}; - full_data.reserve(total_size); - full_data.insert(full_data.end(), start_code.begin(), start_code.end()); - full_data.insert(full_data.end(), sps_nalu_data.begin(), sps_nalu_data.end()); - full_data.insert(full_data.end(), start_code.begin(), start_code.end()); - full_data.insert(full_data.end(), pps_nalu_data.begin(), pps_nalu_data.end()); - for (auto& nalu : data) { + // Adjust the first segment length and init length to compensate for + // inserting the SPS, PPS and 3 start codes. + size_t size_adjustment = + sps_nalu_data.size() + pps_nalu_data.size() + kExtraDataBytes; + size_t total_size = 0; + size_t offset_adjustment = 0; + for (auto& segment : segment_info) { + segment.segment_length += size_adjustment; + segment.init_byte_length += size_adjustment; + segment.segment_start_offset += offset_adjustment; + offset_adjustment += size_adjustment; + // Any additional segments are only adjusted by the start code size; + size_adjustment = kStartCodeSize; + total_size += segment.segment_length; + } + + crypto_params.status_report_index = GetSliceHeaderCounter(); + + // This is based on a sample from Intel for how to use this API. + constexpr size_t kDecryptQuerySizeAndAlignment = 4096; + std::unique_ptr<void, base::AlignedFreeDeleter> surface_memory( + base::AlignedAlloc(kDecryptQuerySizeAndAlignment, + kDecryptQuerySizeAndAlignment)); + constexpr size_t kVaQueryCencBufferSize = 2048; + auto back_buffer_mem = std::make_unique<uint8_t[]>(kVaQueryCencBufferSize); + VACencStatusBuf* status_buf = + reinterpret_cast<VACencStatusBuf*>(surface_memory.get()); + status_buf->status = VA_ENCRYPTION_STATUS_INCOMPLETE; + status_buf->buf = back_buffer_mem.get(); + status_buf->buf_size = kVaQueryCencBufferSize; + + status_buf->slice_buf_type = VaCencSliceBufParamter; + status_buf->slice_buf_size = sizeof(VACencSliceParameterBufferH264); + status_buf->slice_buf = slice_param_buf.get(); + + constexpr int kCencStatusSurfaceDimension = 64; + auto buffer_ptr_alloc = std::make_unique<uintptr_t>(); + uintptr_t* buffer_ptr = + reinterpret_cast<uintptr_t*>(buffer_ptr_alloc.get()); + buffer_ptr[0] = reinterpret_cast<uintptr_t>(surface_memory.get()); + + auto surface = vaapi_wrapper_->CreateVASurfaceForUserPtr( + gfx::Size(kCencStatusSurfaceDimension, kCencStatusSurfaceDimension), + buffer_ptr, + 3 * kCencStatusSurfaceDimension * kCencStatusSurfaceDimension); + if (!surface) { + DVLOG(1) << "Failed allocating surface for decrypt status"; + return DecodeStatus::kFail; + } + + // Assembles the 'slice data' which is the SPS, PPS, encrypted SEIS and + // encrypted slice data, each of which is also prefixed by the 0x000001 + // start code. + std::vector<uint8_t> full_data; + const std::vector<uint8_t> start_code = {0u, 0u, 1u}; + full_data.reserve(total_size); full_data.insert(full_data.end(), start_code.begin(), start_code.end()); - full_data.insert(full_data.end(), nalu.begin(), nalu.end()); - } - if (!vaapi_wrapper_->SubmitBuffers({{VAEncryptionParameterBufferType, - sizeof(crypto_params), &crypto_params}, - {VAProtectedSliceDataBufferType, - full_data.size(), full_data.data()}})) { - DVLOG(1) << "Failure submitting encrypted slice header buffers"; - return DecodeStatus::kFail; - } - if (!vaapi_wrapper_->ExecuteAndDestroyPendingBuffers(surface->id())) { - LOG(ERROR) << "Failed executing for slice header decrypt"; - return DecodeStatus::kFail; - } - if (status_buf->status != VA_ENCRYPTION_STATUS_SUCCESSFUL) { - LOG(ERROR) << "Failure status in encrypted header parsing: " - << static_cast<int>(status_buf->status); - return DecodeStatus::kFail; + full_data.insert(full_data.end(), sps_nalu_data.begin(), + sps_nalu_data.end()); + full_data.insert(full_data.end(), start_code.begin(), start_code.end()); + full_data.insert(full_data.end(), pps_nalu_data.begin(), + pps_nalu_data.end()); + for (auto& nalu : data) { + full_data.insert(full_data.end(), start_code.begin(), start_code.end()); + full_data.insert(full_data.end(), nalu.begin(), nalu.end()); + } + if (!vaapi_wrapper_->SubmitBuffers( + {{VAEncryptionParameterBufferType, sizeof(crypto_params), + &crypto_params}, + {VAProtectedSliceDataBufferType, full_data.size(), + full_data.data()}})) { + DVLOG(1) << "Failure submitting encrypted slice header buffers"; + return DecodeStatus::kFail; + } + if (!vaapi_wrapper_->ExecuteAndDestroyPendingBuffers(surface->id())) { + LOG(ERROR) << "Failed executing for slice header decrypt"; + return DecodeStatus::kFail; + } + if (status_buf->status != VA_ENCRYPTION_STATUS_SUCCESSFUL) { + LOG(ERROR) << "Failure status in encrypted header parsing: " + << static_cast<int>(status_buf->status); + return DecodeStatus::kFail; + } + slice_header_out->full_sample_index = + status_buf->status_report_index_feedback; } // Read the parsed slice header data back and populate the structure with it. @@ -353,8 +409,6 @@ slice_param_buf->max_long_term_frame_idx_plus1[i]; } slice_header_out->full_sample_encryption = true; - slice_header_out->full_sample_index = - status_buf->status_report_index_feedback; return DecodeStatus::kOk; #else // BUILDFLAG(IS_CHROMEOS_ASH) return DecodeStatus::kFail; @@ -372,10 +426,10 @@ const std::vector<SubsampleEntry>& subsamples) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); TRACE_EVENT0("media,gpu", "H264VaapiVideoDecoderDelegate::SubmitSlice"); - if (slice_hdr->full_sample_encryption) { + if (slice_hdr->full_sample_encryption && !IsTranscrypted()) { // We do not need to submit all the slice data, instead we just submit the // index for what was already sent for parsing. The HW decoder already has - // the full slice data from when we decrypted the header. + // the full slice data from when we decrypted the header on Intel. full_sample_ = true; VACencStatusParameters cenc_status = {}; cenc_status.status_report_index_feedback = slice_hdr->full_sample_index; @@ -489,12 +543,15 @@ } if (IsTranscrypted()) { CHECK_EQ(subsamples.size(), 1u); + uint32_t cypher_skip = + slice_hdr->full_sample_encryption ? kAmdEncryptedSliceHeaderSize : 0; return vaapi_wrapper_->SubmitBuffers( {{VAProtectedSliceDataBufferType, GetDecryptKeyId().length(), GetDecryptKeyId().data()}, {VASliceParameterBufferType, sizeof(slice_param), &slice_param}, - {VASliceDataBufferType, subsamples[0].cypher_bytes, - data + subsamples[0].clear_bytes}}) + {VASliceDataBufferType, + subsamples[0].cypher_bytes - cypher_skip, + data + subsamples[0].clear_bytes + cypher_skip}}) ? DecodeStatus::kOk : DecodeStatus::kFail; }
diff --git a/native_client_sdk/src/doc/images/NaClExecution.png b/native_client_sdk/src/doc/images/NaClExecution.png deleted file mode 100644 index fa5ca01..0000000 --- a/native_client_sdk/src/doc/images/NaClExecution.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/doc/images/ProgramStructure.png b/native_client_sdk/src/doc/images/ProgramStructure.png deleted file mode 100644 index 15193c91f..0000000 --- a/native_client_sdk/src/doc/images/ProgramStructure.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/doc/images/bradchen.png b/native_client_sdk/src/doc/images/bradchen.png deleted file mode 100644 index 0df9b01..0000000 --- a/native_client_sdk/src/doc/images/bradchen.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/doc/images/pepper-fileiocreate.png b/native_client_sdk/src/doc/images/pepper-fileiocreate.png deleted file mode 100644 index df72bb2..0000000 --- a/native_client_sdk/src/doc/images/pepper-fileiocreate.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/doc/images/pepper-fileioread.png b/native_client_sdk/src/doc/images/pepper-fileioread.png deleted file mode 100644 index 0ee304b..0000000 --- a/native_client_sdk/src/doc/images/pepper-fileioread.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/doc/images/wrenchTool.png b/native_client_sdk/src/doc/images/wrenchTool.png deleted file mode 100644 index b70d375..0000000 --- a/native_client_sdk/src/doc/images/wrenchTool.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/dial_background.png b/native_client_sdk/src/examples/demo/flock/images/dial_background.png deleted file mode 100644 index 39e5fc1..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/dial_background.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/dial_face.png b/native_client_sdk/src/examples/demo/flock/images/dial_face.png deleted file mode 100644 index d62d3c8..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/dial_face.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/flock_green.png b/native_client_sdk/src/examples/demo/flock/images/flock_green.png deleted file mode 100644 index c743a12..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/flock_green.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/flock_red.png b/native_client_sdk/src/examples/demo/flock/images/flock_red.png deleted file mode 100644 index bbcf16e..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/flock_red.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/flock_size_ruler.png b/native_client_sdk/src/examples/demo/flock/images/flock_size_ruler.png deleted file mode 100644 index acba683..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/flock_size_ruler.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/flocking_geese_icon.png b/native_client_sdk/src/examples/demo/flock/images/flocking_geese_icon.png deleted file mode 100644 index d0638cbb..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/flocking_geese_icon.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/flocking_geese_icon16.png b/native_client_sdk/src/examples/demo/flock/images/flocking_geese_icon16.png deleted file mode 100644 index b30d582..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/flocking_geese_icon16.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/hub.png b/native_client_sdk/src/examples/demo/flock/images/hub.png deleted file mode 100644 index 1c084805..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/hub.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/numbers_black.png b/native_client_sdk/src/examples/demo/flock/images/numbers_black.png deleted file mode 100644 index e1dc00b..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/numbers_black.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/numbers_grey.png b/native_client_sdk/src/examples/demo/flock/images/numbers_grey.png deleted file mode 100644 index 36506438..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/numbers_grey.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/numbers_red.png b/native_client_sdk/src/examples/demo/flock/images/numbers_red.png deleted file mode 100644 index b4704ff..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/numbers_red.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/odometer.png b/native_client_sdk/src/examples/demo/flock/images/odometer.png deleted file mode 100644 index 09dbb50..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/odometer.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/pointer_green.png b/native_client_sdk/src/examples/demo/flock/images/pointer_green.png deleted file mode 100644 index 2f9a149..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/pointer_green.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/pointer_grey.png b/native_client_sdk/src/examples/demo/flock/images/pointer_grey.png deleted file mode 100644 index 9631512..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/pointer_grey.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/pointer_red.png b/native_client_sdk/src/examples/demo/flock/images/pointer_red.png deleted file mode 100644 index 8a07d0c9..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/pointer_red.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/sim_select_ruler.png b/native_client_sdk/src/examples/demo/flock/images/sim_select_ruler.png deleted file mode 100644 index ce2c9d74..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/sim_select_ruler.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/examples/demo/flock/images/slider_thumb.png b/native_client_sdk/src/examples/demo/flock/images/slider_thumb.png deleted file mode 100644 index 193ebb3..0000000 --- a/native_client_sdk/src/examples/demo/flock/images/slider_thumb.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/resources/promo440.png b/native_client_sdk/src/resources/promo440.png deleted file mode 100644 index 2d9b521..0000000 --- a/native_client_sdk/src/resources/promo440.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/resources/screenshot_earth_1280.png b/native_client_sdk/src/resources/screenshot_earth_1280.png deleted file mode 100644 index 912c0b3..0000000 --- a/native_client_sdk/src/resources/screenshot_earth_1280.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/resources/screenshot_graphics2d_1280.png b/native_client_sdk/src/resources/screenshot_graphics2d_1280.png deleted file mode 100644 index 44ac44f..0000000 --- a/native_client_sdk/src/resources/screenshot_graphics2d_1280.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/resources/screenshot_graphics3d_1280.png b/native_client_sdk/src/resources/screenshot_graphics3d_1280.png deleted file mode 100644 index ee03087..0000000 --- a/native_client_sdk/src/resources/screenshot_graphics3d_1280.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/resources/screenshot_life_1280.png b/native_client_sdk/src/resources/screenshot_life_1280.png deleted file mode 100644 index 4a14e9b..0000000 --- a/native_client_sdk/src/resources/screenshot_life_1280.png +++ /dev/null Binary files differ
diff --git a/native_client_sdk/src/resources/screenshot_voronoi_1280.png b/native_client_sdk/src/resources/screenshot_voronoi_1280.png deleted file mode 100644 index 1638ac7..0000000 --- a/native_client_sdk/src/resources/screenshot_voronoi_1280.png +++ /dev/null Binary files differ
diff --git a/net/cert/ct_log_response_parser.cc b/net/cert/ct_log_response_parser.cc index 896fd71..90a8a9a 100644 --- a/net/cert/ct_log_response_parser.cc +++ b/net/cert/ct_log_response_parser.cc
@@ -34,33 +34,17 @@ }; bool ConvertSHA256RootHash(base::StringPiece s, std::string* result) { - if (!base::Base64Decode(s, result)) { - DVLOG(1) << "Failed decoding sha256_root_hash"; - return false; - } - - if (result->length() != kSthRootHashLength) { - DVLOG(1) << "sha256_root_hash is expected to be 32 bytes, but is " - << result->length() << " bytes."; - return false; - } - - return true; + return base::Base64Decode(s, result) && result->size() == kSthRootHashLength; } bool ConvertTreeHeadSignature(base::StringPiece s, DigitallySigned* result) { std::string tree_head_signature; if (!base::Base64Decode(s, &tree_head_signature)) { - DVLOG(1) << "Failed decoding tree_head_signature"; return false; } base::StringPiece sp(tree_head_signature); - if (!DecodeDigitallySigned(&sp, result)) { - DVLOG(1) << "Failed decoding signature to DigitallySigned"; - return false; - } - return true; + return DecodeDigitallySigned(&sp, result); } void JsonSignedTreeHead::RegisterJSONConverter( @@ -77,29 +61,8 @@ } bool IsJsonSTHStructurallyValid(const JsonSignedTreeHead& sth) { - if (sth.tree_size < 0) { - DVLOG(1) << "Tree size in Signed Tree Head JSON is negative: " - << sth.tree_size; - return false; - } - - if (sth.timestamp < 0) { - DVLOG(1) << "Timestamp in Signed Tree Head JSON is negative: " - << sth.timestamp; - return false; - } - - if (sth.sha256_root_hash.empty()) { - DVLOG(1) << "Missing SHA256 root hash from Signed Tree Head JSON."; - return false; - } - - if (sth.signature.signature_data.empty()) { - DVLOG(1) << "Missing signature from Signed Tree Head JSON."; - return false; - } - - return true; + return sth.tree_size >= 0 && sth.timestamp >= 0 && + !sth.sha256_root_hash.empty() && !sth.signature.signature_data.empty(); } // Structure for making JSON decoding easier. The string fields @@ -113,13 +76,7 @@ bool ConvertIndividualProofNode(const base::Value* value, std::string* result) { const std::string* b64_encoded_node = value->GetIfString(); - if (!b64_encoded_node) - return false; - - if (!ConvertSHA256RootHash(*b64_encoded_node, result)) - return false; - - return true; + return b64_encoded_node && ConvertSHA256RootHash(*b64_encoded_node, result); } void JsonConsistencyProof::RegisterJSONConverter( @@ -135,14 +92,11 @@ SignedTreeHead* signed_tree_head) { JsonSignedTreeHead parsed_sth; base::JSONValueConverter<JsonSignedTreeHead> converter; - if (!converter.Convert(json_signed_tree_head, &parsed_sth)) { - DVLOG(1) << "Invalid Signed Tree Head JSON."; + if (!converter.Convert(json_signed_tree_head, &parsed_sth) || + !IsJsonSTHStructurallyValid(parsed_sth)) { return false; } - if (!IsJsonSTHStructurallyValid(parsed_sth)) - return false; - signed_tree_head->version = SignedTreeHead::V1; signed_tree_head->tree_size = parsed_sth.tree_size; signed_tree_head->timestamp = base::Time::FromJsTime(parsed_sth.timestamp); @@ -158,14 +112,12 @@ JsonConsistencyProof parsed_proof; base::JSONValueConverter<JsonConsistencyProof> converter; if (!converter.Convert(json_consistency_proof, &parsed_proof)) { - DVLOG(1) << "Invalid consistency proof."; return false; } const base::DictionaryValue* dict_value = nullptr; if (!json_consistency_proof.GetAsDictionary(&dict_value) || - !dict_value->HasKey("consistency")) { - DVLOG(1) << "Missing consistency field."; + !dict_value->FindKey("consistency")) { return false; }
diff --git a/net/cert/ct_log_verifier.cc b/net/cert/ct_log_verifier.cc index d2801929..5c46e05 100644 --- a/net/cert/ct_log_verifier.cc +++ b/net/cert/ct_log_verifier.cc
@@ -74,62 +74,39 @@ bool CTLogVerifier::Verify(const ct::SignedEntryData& entry, const ct::SignedCertificateTimestamp& sct) const { - if (sct.log_id != key_id()) { - DVLOG(1) << "SCT is not signed by this log."; - return false; - } - - if (!SignatureParametersMatch(sct.signature)) - return false; - std::string serialized_log_entry; - if (!ct::EncodeSignedEntry(entry, &serialized_log_entry)) { - DVLOG(1) << "Unable to serialize entry."; - return false; - } std::string serialized_data; - if (!ct::EncodeV1SCTSignedData(sct.timestamp, serialized_log_entry, - sct.extensions, &serialized_data)) { - DVLOG(1) << "Unable to create SCT to verify."; - return false; - } - return VerifySignature(serialized_data, sct.signature.signature_data); + return sct.log_id == key_id_ && SignatureParametersMatch(sct.signature) && + ct::EncodeSignedEntry(entry, &serialized_log_entry) && + ct::EncodeV1SCTSignedData(sct.timestamp, serialized_log_entry, + sct.extensions, &serialized_data) && + VerifySignature(serialized_data, sct.signature.signature_data); } bool CTLogVerifier::VerifySignedTreeHead( const ct::SignedTreeHead& signed_tree_head) const { - if (!SignatureParametersMatch(signed_tree_head.signature)) - return false; - std::string serialized_data; - if (!ct::EncodeTreeHeadSignature(signed_tree_head, &serialized_data)) + if (!SignatureParametersMatch(signed_tree_head.signature) || + !ct::EncodeTreeHeadSignature(signed_tree_head, &serialized_data) || + !VerifySignature(serialized_data, + signed_tree_head.signature.signature_data)) { return false; - - if (VerifySignature(serialized_data, - signed_tree_head.signature.signature_data)) { - if (signed_tree_head.tree_size == 0) { - // Root hash must equate SHA256 hash of the empty string. - return (memcmp(signed_tree_head.sha256_root_hash, kSHA256EmptyStringHash, - ct::kSthRootHashLength) == 0); - } - return true; } - return false; + + if (signed_tree_head.tree_size == 0) { + // Root hash must equate SHA256 hash of the empty string. + return memcmp(signed_tree_head.sha256_root_hash, kSHA256EmptyStringHash, + ct::kSthRootHashLength) == 0; + } + + return true; } bool CTLogVerifier::SignatureParametersMatch( const ct::DigitallySigned& signature) const { - if (!signature.SignatureParametersMatch(hash_algorithm_, - signature_algorithm_)) { - DVLOG(1) << "Mismatched hash or signature algorithm. Hash: " - << hash_algorithm_ << " vs " << signature.hash_algorithm - << " Signature: " << signature_algorithm_ << " vs " - << signature.signature_algorithm << "."; - return false; - } - - return true; + return signature.SignatureParametersMatch(hash_algorithm_, + signature_algorithm_); } bool CTLogVerifier::VerifyConsistencyProof( @@ -320,15 +297,13 @@ signature_algorithm_ = ct::DigitallySigned::SIG_ALGO_ECDSA; break; default: - DVLOG(1) << "Unsupported key type: " << EVP_PKEY_type(public_key_->type); return false; } - // Extra sanity check: Require RSA keys of at least 2048 bits. + // Extra safety check: Require RSA keys of at least 2048 bits. // EVP_PKEY_size returns the size in bytes. 256 = 2048-bit RSA key. if (signature_algorithm_ == ct::DigitallySigned::SIG_ALGO_RSA && EVP_PKEY_size(public_key_) < 256) { - DVLOG(1) << "Too small a public key."; return false; } @@ -340,11 +315,9 @@ crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); const EVP_MD* hash_alg = GetEvpAlg(hash_algorithm_); - if (hash_alg == nullptr) - return false; - bssl::ScopedEVP_MD_CTX ctx; - return EVP_DigestVerifyInit(ctx.get(), nullptr, hash_alg, nullptr, + return hash_alg && + EVP_DigestVerifyInit(ctx.get(), nullptr, hash_alg, nullptr, public_key_) && EVP_DigestVerifyUpdate(ctx.get(), data_to_sign.data(), data_to_sign.size()) &&
diff --git a/net/cert/ct_serialization.cc b/net/cert/ct_serialization.cc index 07fb954..ce8fb69 100644 --- a/net/cert/ct_serialization.cc +++ b/net/cert/ct_serialization.cc
@@ -39,12 +39,8 @@ while (CBS_len(&sct_list_data) != 0) { CBS sct_list_item; - if (!CBS_get_u16_length_prefixed(&sct_list_data, &sct_list_item)) { - DVLOG(1) << "Failed to read item in list."; - return false; - } - if (CBS_len(&sct_list_item) == 0) { - DVLOG(1) << "Empty item in list"; + if (!CBS_get_u16_length_prefixed(&sct_list_data, &sct_list_item) || + CBS_len(&sct_list_item) == 0) { return false; } @@ -168,14 +164,11 @@ } DigitallySigned result; - if (!ConvertHashAlgorithm(hash_algo, &result.hash_algorithm)) { - DVLOG(1) << "Invalid hash algorithm " << hash_algo; + if (!ConvertHashAlgorithm(hash_algo, &result.hash_algorithm) || + !ConvertSignatureAlgorithm(sig_algo, &result.signature_algorithm)) { return false; } - if (!ConvertSignatureAlgorithm(sig_algo, &result.signature_algorithm)) { - DVLOG(1) << "Invalid signature algorithm " << sig_algo; - return false; - } + result.signature_data.assign( reinterpret_cast<const char*>(CBS_data(&sig_data)), CBS_len(&sig_data)); @@ -227,8 +220,6 @@ base::CheckedNumeric<int64_t> time_since_epoch_signed = time_since_epoch; if (!time_since_epoch_signed.IsValid()) { - DVLOG(1) << "Timestamp value too big to cast to int64_t: " - << time_since_epoch; return false; } @@ -334,10 +325,8 @@ CBS input_cbs; CBS_init(&input_cbs, reinterpret_cast<const uint8_t*>(input->data()), input->size()); - if (!CBS_get_u8(&input_cbs, &version)) - return false; - if (version != SignedCertificateTimestamp::V1) { - DVLOG(1) << "Unsupported/invalid version " << version; + if (!CBS_get_u8(&input_cbs, &version) || + version != SignedCertificateTimestamp::V1) { return false; }
diff --git a/net/cert/multi_log_ct_verifier.cc b/net/cert/multi_log_ct_verifier.cc index dee8965e..97bbbfd 100644 --- a/net/cert/multi_log_ct_verifier.cc +++ b/net/cert/multi_log_ct_verifier.cc
@@ -82,7 +82,6 @@ const std::vector<scoped_refptr<const CTLogVerifier>>& log_verifiers) { logs_.clear(); for (const auto& log_verifier : log_verifiers) { - VLOG(1) << "Adding CT log: " << log_verifier->description(); std::string key_id = log_verifier->key_id(); logs_[key_id] = log_verifier; } @@ -200,7 +199,6 @@ // Assume this SCT is untrusted until proven otherwise. const auto& it = logs_.find(sct->log_id); if (it == logs_.end()) { - DVLOG(1) << "SCT does not match any known log."; AddSCTAndLogStatus(sct, ct::SCT_STATUS_LOG_UNKNOWN, output_scts); return false; } @@ -208,14 +206,12 @@ sct->log_description = it->second->description(); if (!it->second->Verify(expected_entry, *sct.get())) { - DVLOG(1) << "Unable to verify SCT signature."; AddSCTAndLogStatus(sct, ct::SCT_STATUS_INVALID_SIGNATURE, output_scts); return false; } // SCT verified ok, just make sure the timestamp is legitimate. if (sct->timestamp > base::Time::Now()) { - DVLOG(1) << "SCT is from the future!"; AddSCTAndLogStatus(sct, ct::SCT_STATUS_INVALID_TIMESTAMP, output_scts); return false; }
diff --git a/net/cert/nss_cert_database.cc b/net/cert/nss_cert_database.cc index 08c1ab8..65a38f0 100644 --- a/net/cert/nss_cert_database.cc +++ b/net/cert/nss_cert_database.cc
@@ -198,9 +198,6 @@ const std::u16string& password, bool is_extractable, ScopedCERTCertificateList* imported_certs) { - DVLOG(1) << __func__ << " " - << PK11_GetModuleID(slot_info) << ":" - << PK11_GetSlotID(slot_info); int result = psm::nsPKCS12Blob_Import(slot_info, data.data(), data.size(), password,
diff --git a/net/cert/nss_cert_database_chromeos.cc b/net/cert/nss_cert_database_chromeos.cc index 1f11bbd2..7a6da26 100644 --- a/net/cert/nss_cert_database_chromeos.cc +++ b/net/cert/nss_cert_database_chromeos.cc
@@ -71,13 +71,10 @@ bool need_rw) const { NSSCertDatabase::ListModules(modules, need_rw); - size_t pre_size = modules->size(); const NSSProfileFilterChromeOS& profile_filter = profile_filter_; base::EraseIf(*modules, [&profile_filter](crypto::ScopedPK11Slot& module) { return !profile_filter.IsModuleAllowed(module.get()); }); - DVLOG(1) << "filtered " << pre_size - modules->size() << " of " << pre_size - << " modules"; } bool NSSCertDatabaseChromeOS::SetCertTrust(CERTCertificate* cert, @@ -130,12 +127,9 @@ crypto::ScopedPK11Slot(), add_certs_info)); // Filter certificate information according to user profile. - size_t pre_size = certs_info.size(); base::EraseIf(certs_info, [&profile_filter](CertInfo& cert_info) { return !profile_filter.IsCertAllowed(cert_info.cert.get()); }); - DVLOG(1) << "filtered " << pre_size - certs_info.size() << " of " << pre_size - << " certs"; if (add_certs_info) { // Add Chrome OS specific information.
diff --git a/net/cert/nss_profile_filter_chromeos.cc b/net/cert/nss_profile_filter_chromeos.cc index 2b9913a..85dc7b6 100644 --- a/net/cert/nss_profile_filter_chromeos.cc +++ b/net/cert/nss_profile_filter_chromeos.cc
@@ -14,29 +14,6 @@ namespace net { -namespace { - -std::string CertSlotsString(CERTCertificate* cert) { - std::string result; - crypto::ScopedPK11SlotList slots_for_cert( - PK11_GetAllSlotsForCert(cert, NULL)); - for (PK11SlotListElement* slot_element = - PK11_GetFirstSafe(slots_for_cert.get()); - slot_element; - slot_element = - PK11_GetNextSafe(slots_for_cert.get(), slot_element, PR_FALSE)) { - if (!result.empty()) - result += ','; - base::StringAppendF(&result, - "%lu:%lu", - PK11_GetModuleID(slot_element->slot), - PK11_GetSlotID(slot_element->slot)); - } - return result; -} - -} // namespace - NSSProfileFilterChromeOS::NSSProfileFilterChromeOS() = default; NSSProfileFilterChromeOS::NSSProfileFilterChromeOS( @@ -118,10 +95,8 @@ bool NSSProfileFilterChromeOS::IsCertAllowed(CERTCertificate* cert) const { crypto::ScopedPK11SlotList slots_for_cert( PK11_GetAllSlotsForCert(cert, NULL)); - if (!slots_for_cert) { - DVLOG(2) << "cert no slots: " << base::StringPiece(cert->nickname); + if (!slots_for_cert) return false; - } for (PK11SlotListElement* slot_element = PK11_GetFirstSafe(slots_for_cert.get()); @@ -129,14 +104,11 @@ slot_element = PK11_GetNextSafe(slots_for_cert.get(), slot_element, PR_FALSE)) { if (IsModuleAllowed(slot_element->slot)) { - DVLOG(3) << "cert from " << CertSlotsString(cert) - << " allowed: " << base::StringPiece(cert->nickname); PK11_FreeSlotListElement(slots_for_cert.get(), slot_element); return true; } } - DVLOG(2) << "cert from " << CertSlotsString(cert) - << " filtered: " << base::StringPiece(cert->nickname); + return false; }
diff --git a/net/cert/x509_certificate.cc b/net/cert/x509_certificate.cc index 9a4cd2a2..00432c8c 100644 --- a/net/cert/x509_certificate.cc +++ b/net/cert/x509_certificate.cc
@@ -552,7 +552,6 @@ // Catch badly corrupt cert names up front. if (cert_san_dns_name.empty() || cert_san_dns_name.find('\0') != std::string::npos) { - DVLOG(1) << "Bad name in cert: " << cert_san_dns_name; continue; } std::string presented_name(base::ToLowerASCII(cert_san_dns_name));
diff --git a/services/tracing/perfetto/consumer_host_unittest.cc b/services/tracing/perfetto/consumer_host_unittest.cc index b760d3f..82936be 100644 --- a/services/tracing/perfetto/consumer_host_unittest.cc +++ b/services/tracing/perfetto/consumer_host_unittest.cc
@@ -302,6 +302,7 @@ public mojo::DataPipeDrainer::Client { public: void SetUp() override { + task_environment_ = std::make_unique<base::test::TaskEnvironment>(); PerfettoTracedProcess::ResetTaskRunnerForTesting(); PerfettoTracedProcess::Get()->ClearDataSourcesForTesting(); threaded_service_ = std::make_unique<ThreadedPerfettoService>(); @@ -310,7 +311,12 @@ total_bytes_received_ = 0; } - void TearDown() override { threaded_service_.reset(); } + void TearDown() override { + threaded_service_.reset(); + task_environment_->RunUntilIdle(); + PerfettoTracedProcess::TearDownForTesting(); + task_environment_.reset(); + } // mojo::DataPipeDrainer::Client void OnDataAvailable(const void* data, size_t num_bytes) override { @@ -420,7 +426,7 @@ bool IsTracingEnabled() { // Flush any other pending tasks on the perfetto task runner to ensure that // any pending data source start callbacks have propagated. - task_environment_.RunUntilIdle(); + task_environment_->RunUntilIdle(); return threaded_service_->IsTracingEnabled(); } @@ -433,7 +439,7 @@ private: std::unique_ptr<ThreadedPerfettoService> threaded_service_; - base::test::TaskEnvironment task_environment_; + std::unique_ptr<base::test::TaskEnvironment> task_environment_; base::OnceClosure on_data_complete_; std::unique_ptr<mojo::DataPipeDrainer> drainer_; std::vector<uint8_t> received_data_;
diff --git a/services/tracing/perfetto/perfetto_integration_unittest.cc b/services/tracing/perfetto/perfetto_integration_unittest.cc index f3538d9..aa0b348 100644 --- a/services/tracing/perfetto/perfetto_integration_unittest.cc +++ b/services/tracing/perfetto/perfetto_integration_unittest.cc
@@ -385,12 +385,9 @@ } TEST_F(PerfettoIntegrationTest, PerfettoClientLibraryTest) { - // Create a dummy tracing session without a real backend to check that - // the client library was initialized. - constexpr perfetto::BackendType kInvalidBackend( - static_cast<perfetto::BackendType>(1u << 31)); - auto tracing_session = perfetto::Tracing::NewTrace(kInvalidBackend); - EXPECT_TRUE(tracing_session); + // Check that PerfettoTracedProcess initialized the client library. Functional + // client library tests are in TracingServiceTest. + EXPECT_TRUE(perfetto::Tracing::IsInitialized()); } } // namespace
diff --git a/services/tracing/perfetto/test_utils.cc b/services/tracing/perfetto/test_utils.cc index b3fc2bd8..9f2e87b 100644 --- a/services/tracing/perfetto/test_utils.cc +++ b/services/tracing/perfetto/test_utils.cc
@@ -444,6 +444,7 @@ PerfettoTracedProcess::ResetTaskRunnerForTesting( base::ThreadTaskRunnerHandle::Get()); PerfettoTracedProcess::Get()->ClearDataSourcesForTesting(); + PerfettoTracedProcess::Get()->OnThreadPoolAvailable(); // Wait for any posted construction tasks to execute. RunUntilIdle(); @@ -463,6 +464,7 @@ PerfettoTracedProcess::Get()->GetTaskRunner()->ResetTaskRunnerForTesting( nullptr); PerfettoTracedProcess::Get()->ClearDataSourcesForTesting(); + PerfettoTracedProcess::TearDownForTesting(); } } // namespace tracing
diff --git a/services/tracing/public/cpp/perfetto/perfetto_traced_process.cc b/services/tracing/public/cpp/perfetto/perfetto_traced_process.cc index 3a1ceae..763fc53d 100644 --- a/services/tracing/public/cpp/perfetto/perfetto_traced_process.cc +++ b/services/tracing/public/cpp/perfetto/perfetto_traced_process.cc
@@ -186,42 +186,59 @@ return old_for_testing; } -// static -void PerfettoTracedProcess::DeleteSoonForTesting( - std::unique_ptr<PerfettoTracedProcess> perfetto_traced_process) { - GetTaskRunner()->GetOrCreateTaskRunner()->DeleteSoon( - FROM_HERE, std::move(perfetto_traced_process)); -} - void PerfettoTracedProcess::CreateProducerConnection( base::OnceCallback<void(mojo::PendingRemote<mojom::PerfettoService>)> callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // Perfetto will attempt to create the producer connection as soon as the - // client library is initialized, which is before we have a a connection to - // the tracing service. Store the connection callback until ConnectProducer() - // is called. - DCHECK(!pending_producer_callback_); - pending_producer_callback_ = std::move(callback); + // This is called on Perfetto's internal TracingMuxerImpl thread, so we need + // to hop over to the tracing sequence. + GetTaskRunner()->GetOrCreateTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce( + [](base::OnceCallback<void( + mojo::PendingRemote<mojom::PerfettoService>)> callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE( + PerfettoTracedProcess::Get()->sequence_checker_); + // Perfetto will attempt to create the producer connection as soon + // as the client library is initialized, which is before we have a a + // connection to the tracing service. Store the connection callback + // until ConnectProducer() is called. + // DCHECK(!pending_producer_callback_); + PerfettoTracedProcess::Get()->pending_producer_callback_ = + std::move(callback); + }, + std::move(callback))); } void PerfettoTracedProcess::CreateConsumerConnection( base::OnceCallback<void(mojo::PendingRemote<mojom::ConsumerHost>)> callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - consumer_connection_task_runner_->PostTask( + // This is called on Perfetto's internal TracingMuxerImpl thread, so we need + // to hop over to the tracing sequence. + GetTaskRunner()->GetOrCreateTaskRunner()->PostTask( FROM_HERE, base::BindOnce( - [](ConsumerConnectionFactory factory, - base::OnceCallback<void(mojo::PendingRemote<mojom::ConsumerHost>)> + [](base::OnceCallback<void(mojo::PendingRemote<mojom::ConsumerHost>)> callback) { - auto& tracing_service = factory(); - mojo::PendingRemote<mojom::ConsumerHost> consumer_host_remote; - tracing_service.BindConsumerHost( - consumer_host_remote.InitWithNewPipeAndPassReceiver()); - std::move(callback).Run(std::move(consumer_host_remote)); + auto* self = PerfettoTracedProcess::Get(); + DCHECK_CALLED_ON_VALID_SEQUENCE(self->sequence_checker_); + self->consumer_connection_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + [](ConsumerConnectionFactory factory, + base::OnceCallback<void( + mojo::PendingRemote<mojom::ConsumerHost>)> + callback) { + auto& tracing_service = factory(); + mojo::PendingRemote<mojom::ConsumerHost> + consumer_host_remote; + tracing_service.BindConsumerHost( + consumer_host_remote + .InitWithNewPipeAndPassReceiver()); + std::move(callback).Run(std::move(consumer_host_remote)); + }, + self->consumer_connection_factory_, std::move(callback))); }, - consumer_connection_factory_, std::move(callback))); + std::move(callback))); } // We never destroy the taskrunner as we may need it for cleanup @@ -237,6 +254,8 @@ // static void PerfettoTracedProcess::ResetTaskRunnerForTesting( scoped_refptr<base::SequencedTaskRunner> task_runner) { + // Make sure Perfetto was properly torn down in any prior tests. + DCHECK(!perfetto::Tracing::IsInitialized()); GetTaskRunner()->ResetTaskRunnerForTesting(task_runner); // On the first call within the process's lifetime, this will call // PerfettoTracedProcess::Get(), ensuring PerfettoTracedProcess is created. @@ -245,6 +264,9 @@ DETACH_FROM_SEQUENCE(PerfettoTracedProcess::Get()->sequence_checker_); PerfettoTracedProcess::GetTaskRunner()->GetOrCreateTaskRunner()->PostTask( FROM_HERE, base::BindOnce([]() { + // Lock the sequence checker onto the new task runner. + DCHECK_CALLED_ON_VALID_SEQUENCE( + PerfettoTracedProcess::Get()->sequence_checker_); PerfettoTracedProcess::Get() ->producer_client() ->ResetSequenceForTesting(); @@ -256,6 +278,13 @@ })); } +// static +void PerfettoTracedProcess::TearDownForTesting() { + // TODO(skyostil): We only uninitialize Perfetto for now, but there may also + // be other tracing-related state which should not leak between tests. + perfetto::Tracing::ResetForTesting(); +} + void PerfettoTracedProcess::AddDataSource(DataSourceBase* data_source) { bool inserted; {
diff --git a/services/tracing/public/cpp/perfetto/perfetto_traced_process.h b/services/tracing/public/cpp/perfetto/perfetto_traced_process.h index fb178f6..a97d015 100644 --- a/services/tracing/public/cpp/perfetto/perfetto_traced_process.h +++ b/services/tracing/public/cpp/perfetto/perfetto_traced_process.h
@@ -235,12 +235,18 @@ // Can be called on any thread, but only after OnThreadPoolAvailable(). void ActivateSystemTriggers(const std::vector<std::string>& triggers); + // Sets the task runner used by the tracing infrastructure in this process. Be + // sure to call TearDownForTesting to clean up at the end of the test. + // // Be careful when using ResetTaskRunnerForTesting. There is a PostTask in the // constructor of PerfettoTracedProcess, so before this class is constructed // is the only safe time to call this. static void ResetTaskRunnerForTesting( scoped_refptr<base::SequencedTaskRunner> task_runner = nullptr); + // Clean up tracing state at the end of a test. + static void TearDownForTesting(); + // Sets the ProducerClient (or SystemProducer) and returns the old pointer. If // tests want to restore the state of the world they should store the pointer // and call this method again with it as the parameter when finished. @@ -250,7 +256,6 @@ std::unique_ptr<SystemProducer> producer); void ClearDataSourcesForTesting(); - static void DeleteSoonForTesting(std::unique_ptr<PerfettoTracedProcess>); base::tracing::PerfettoPlatform* perfetto_platform_for_testing() const { return platform_.get();
diff --git a/services/tracing/public/cpp/perfetto/perfetto_tracing_backend.cc b/services/tracing/public/cpp/perfetto/perfetto_tracing_backend.cc index 6996509c..9eecf59 100644 --- a/services/tracing/public/cpp/perfetto/perfetto_tracing_backend.cc +++ b/services/tracing/public/cpp/perfetto/perfetto_tracing_backend.cc
@@ -84,8 +84,9 @@ void UnregisterDataSource(const std::string& name) override { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // TODO(skyostil): Implement data source unregistering. - NOTREACHED(); + // TODO(skyostil): Implement data source unregistering. Data sources are + // currently only unregistered in tests, and because the tracing service is + // also torn down at the same time, we can ignore unregistrations here. } void RegisterTraceWriter(uint32_t writer_id,
diff --git a/services/tracing/public/cpp/perfetto/producer_test_utils.cc b/services/tracing/public/cpp/perfetto/producer_test_utils.cc index 776ad78b..fa4e09f 100644 --- a/services/tracing/public/cpp/perfetto/producer_test_utils.cc +++ b/services/tracing/public/cpp/perfetto/producer_test_utils.cc
@@ -170,7 +170,6 @@ { features_.InitAndDisableFeature(features::kEnablePerfettoSystemTracing); #if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) - tracing::PerfettoTracedProcess::ResetTaskRunnerForTesting(); auto perfetto_wrapper = std::make_unique<base::tracing::PerfettoTaskRunner>( base::ThreadTaskRunnerHandle::Get()); @@ -179,11 +178,7 @@ #endif // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) } -DataSourceTester::~DataSourceTester() { -#if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) - tracing::PerfettoTracedProcess::ResetTaskRunnerForTesting(); -#endif // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY) -} +DataSourceTester::~DataSourceTester() = default; void DataSourceTester::BeginTrace( const base::trace_event::TraceConfig& trace_config) {
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc index 859fb42..4b72193 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
@@ -2007,8 +2007,6 @@ #define MAYBE_StartupTracingTimeout StartupTracingTimeout #endif TEST_F(TraceEventDataSourceTest, MAYBE_StartupTracingTimeout) { - PerfettoTracedProcess::ResetTaskRunnerForTesting( - base::SequencedTaskRunnerHandle::Get()); constexpr char kStartupTestEvent1[] = "startup_registry"; auto* data_source = TraceEventDataSource::GetInstance(); PerfettoTracedProcess::Get()->AddDataSource(data_source);
diff --git a/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android_unittest.cc b/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android_unittest.cc index 7f82abd..0dd64be 100644 --- a/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android_unittest.cc +++ b/services/tracing/public/cpp/stack_sampling/reached_code_data_source_android_unittest.cc
@@ -53,6 +53,7 @@ void TearDown() override { // Be sure there is no pending/running tasks. task_environment_.RunUntilIdle(); + PerfettoTracedProcess::TearDownForTesting(); } void BeginTrace() {
diff --git a/services/tracing/public/cpp/system_tracing_service_unittest.cc b/services/tracing/public/cpp/system_tracing_service_unittest.cc index 7124dee..cf2ebcc 100644 --- a/services/tracing/public/cpp/system_tracing_service_unittest.cc +++ b/services/tracing/public/cpp/system_tracing_service_unittest.cc
@@ -52,6 +52,8 @@ } else { ASSERT_EQ(0, unsetenv(kProducerSockEnvName)); } + task_environment_.RunUntilIdle(); + PerfettoTracedProcess::TearDownForTesting(); } protected:
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 0c86cc9..70e5e986 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5869,21 +5869,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.9/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.13/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4664.9", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4664.13", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v96.0.4664.9", - "revision": "version:96.0.4664.9" + "location": "lacros_version_skew_tests_v96.0.4664.13", + "revision": "version:96.0.4664.13" } ], "dimension_sets": [ @@ -5977,21 +5977,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.9/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.13/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4664.9", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4664.13", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v96.0.4664.9", - "revision": "version:96.0.4664.9" + "location": "lacros_version_skew_tests_v96.0.4664.13", + "revision": "version:96.0.4664.13" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 6fa017469..a037b1fa 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -83713,7 +83713,7 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.9/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.13/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "isolate_profile_data": true, @@ -83721,14 +83721,14 @@ "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4664.9", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4664.13", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v96.0.4664.9", - "revision": "version:96.0.4664.9" + "location": "lacros_version_skew_tests_v96.0.4664.13", + "revision": "version:96.0.4664.13" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -83805,7 +83805,7 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.9/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.13/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "isolate_profile_data": true, @@ -83813,14 +83813,14 @@ "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4664.9", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4664.13", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v96.0.4664.9", - "revision": "version:96.0.4664.9" + "location": "lacros_version_skew_tests_v96.0.4664.13", + "revision": "version:96.0.4664.13" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -85193,21 +85193,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.9/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.13/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4664.9", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4664.13", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v96.0.4664.9", - "revision": "version:96.0.4664.9" + "location": "lacros_version_skew_tests_v96.0.4664.13", + "revision": "version:96.0.4664.13" } ], "dimension_sets": [ @@ -85305,21 +85305,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.9/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.13/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4664.9", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4664.13", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v96.0.4664.9", - "revision": "version:96.0.4664.9" + "location": "lacros_version_skew_tests_v96.0.4664.13", + "revision": "version:96.0.4664.13" } ], "dimension_sets": [ @@ -86866,21 +86866,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.9/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.13/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4664.9", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4664.13", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v96.0.4664.9", - "revision": "version:96.0.4664.9" + "location": "lacros_version_skew_tests_v96.0.4664.13", + "revision": "version:96.0.4664.13" } ], "dimension_sets": [ @@ -86978,21 +86978,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.9/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.13/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4664.9", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4664.13", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v96.0.4664.9", - "revision": "version:96.0.4664.9" + "location": "lacros_version_skew_tests_v96.0.4664.13", + "revision": "version:96.0.4664.13" } ], "dimension_sets": [ @@ -87741,21 +87741,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.9/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.13/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4664.9", + "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4664.13", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v96.0.4664.9", - "revision": "version:96.0.4664.9" + "location": "lacros_version_skew_tests_v96.0.4664.13", + "revision": "version:96.0.4664.13" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -87837,21 +87837,21 @@ }, { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.9/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.13/test_ash_chrome", "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter" ], "merge": { "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, - "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4664.9", + "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4664.13", "swarming": { "can_use_on_swarming_builders": true, "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v96.0.4664.9", - "revision": "version:96.0.4664.9" + "location": "lacros_version_skew_tests_v96.0.4664.13", + "revision": "version:96.0.4664.13" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/testing/buildbot/chromium.webrtc.fyi.json b/testing/buildbot/chromium.webrtc.fyi.json index 83bd865e..9cb0b56 100644 --- a/testing/buildbot/chromium.webrtc.fyi.json +++ b/testing/buildbot/chromium.webrtc.fyi.json
@@ -12,58 +12,6 @@ }, "WebRTC Chromium FYI Android Builder (dbg)": {}, "WebRTC Chromium FYI Android Builder ARM64 (dbg)": {}, - "WebRTC Chromium FYI Android Tests (dbg) (L Nexus5)": { - "gtest_tests": [ - { - "args": [ - "--gtest_filter=WebRtc*", - "--gs-results-bucket=chromium-result-details", - "--recover-devices", - "--test-launcher-filter-file=../../testing/buildbot/filters/chromium.webrtc.fyi.android.tests.dbg.content_browsertests.filter" - ], - "merge": { - "args": [ - "--bucket", - "chromium-result-details", - "--test-name", - "content_browsertests" - ], - "script": "//build/android/pylib/results/presentation/test_results_presentation.py" - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/luci/logdog/butler/${platform}", - "location": "bin", - "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" - } - ], - "dimension_sets": [ - { - "device_os": "L", - "device_os_type": "userdebug", - "device_type": "hammerhead", - "os": "Android" - } - ], - "output_links": [ - { - "link": [ - "https://luci-logdog.appspot.com/v/?s", - "=android%2Fswarming%2Flogcats%2F", - "${TASK_ID}%2F%2B%2Funified_logcats" - ], - "name": "shard #${SHARD_INDEX} logcats" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test": "content_browsertests", - "test_id_prefix": "ninja://content/test:content_browsertests/" - } - ] - }, "WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)": { "gtest_tests": [ { @@ -116,6 +64,58 @@ } ] }, + "WebRTC Chromium FYI Android Tests (dbg) (N Nexus5X)": { + "gtest_tests": [ + { + "args": [ + "--gtest_filter=WebRtc*", + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--test-launcher-filter-file=../../testing/buildbot/filters/chromium.webrtc.fyi.android.tests.dbg.content_browsertests.filter" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "content_browsertests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "N", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "content_browsertests", + "test_id_prefix": "ninja://content/test:content_browsertests/" + } + ] + }, "WebRTC Chromium FYI Linux Builder (dbg)": { "additional_compile_targets": [ "browser_tests",
diff --git a/testing/buildbot/filters/fuchsia.content_browsertests.filter b/testing/buildbot/filters/fuchsia.content_browsertests.filter index 70e7fbb..8f32ef0 100644 --- a/testing/buildbot/filters/fuchsia.content_browsertests.filter +++ b/testing/buildbot/filters/fuchsia.content_browsertests.filter
@@ -68,8 +68,6 @@ -CaptureStreamRenderProcessHostTest.KillProcessZerosAudioCaptureStreams -ContentBrowserTest.BrowserCrashCallStack -ContentBrowserTest.RendererCrashCallStack --CrossOriginOpenerPolicyReportingBrowserTest.ParseReportingEndpointsDuringNavigation --CrossOriginOpenerPolicyReportingBrowserTest.ParseReportingEndpointsDuringRedirect -CrossPlatformAccessibilityBrowserTest.ControlsIdsForDateTimePopup -DataDecoderBrowserTest.DecodeImage -DataDecoderBrowserTest.DecodeImageIsolated
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 75b0a29..8d1c9bb 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1209,17 +1209,16 @@ 'shards': 15, }, }, - 'WebRTC Chromium FYI Android Tests (dbg) (L Nexus5)': { - 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/chromium.webrtc.fyi.android.tests.dbg.content_browsertests.filter', - ], - }, 'WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)': { 'args': [ '--test-launcher-filter-file=../../testing/buildbot/filters/chromium.webrtc.fyi.android.tests.dbg.content_browsertests.filter', ], - } - , + }, + 'WebRTC Chromium FYI Android Tests (dbg) (N Nexus5X)': { + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/chromium.webrtc.fyi.android.tests.dbg.content_browsertests.filter', + ], + }, 'Win10 Tests x64': { # crbug.com/868082 'args': [
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index c83a3d81a..3f9d415f 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -44,16 +44,16 @@ }, 'LACROS_VERSION_SKEW_DEV': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.9/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4664.13/test_ash_chrome', '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter', ], - 'identifier': 'Lacros version skew testing ash 96.0.4664.9', + 'identifier': 'Lacros version skew testing ash 96.0.4664.13', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v96.0.4664.9', - 'revision': 'version:96.0.4664.9', + 'location': 'lacros_version_skew_tests_v96.0.4664.13', + 'revision': 'version:96.0.4664.13', }, ], },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 4b740dc..22b0d50c 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -6086,20 +6086,20 @@ }, 'WebRTC Chromium FYI Android Builder (dbg)': {}, 'WebRTC Chromium FYI Android Builder ARM64 (dbg)': {}, - 'WebRTC Chromium FYI Android Tests (dbg) (L Nexus5)': { + 'WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)': { 'os_type': 'android', 'mixins': [ - 'lollipop_generic', - 'hammerhead', + 'marshmallow', + 'bullhead', ], 'test_suites': { 'gtest_tests': 'webrtc_chromium_simple_gtests', }, }, - 'WebRTC Chromium FYI Android Tests (dbg) (M Nexus5X)': { + 'WebRTC Chromium FYI Android Tests (dbg) (N Nexus5X)': { 'os_type': 'android', 'mixins': [ - 'marshmallow', + 'nougat_generic', 'bullhead', ], 'test_suites': {
diff --git a/testing/test.gni b/testing/test.gni index 47f01a30..ec9317e 100644 --- a/testing/test.gni +++ b/testing/test.gni
@@ -427,6 +427,11 @@ if (!defined(data_deps)) { data_deps = [] } + data_deps += [ + "//testing:test_scripts_shared", + "//testing/buildbot/filters:fuchsia_filters", + ] + if (use_rts) { data_deps += [ ":${target_name}__rts_filters" ] }
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 07d3a23..46492f3 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2322,21 +2322,6 @@ ] } ], - "CompositingBasedThrottling": [ - { - "platforms": [ - "chromeos" - ], - "experiments": [ - { - "name": "CompositingBasedThrottling", - "enable_features": [ - "CompositingBasedThrottling" - ] - } - ] - } - ], "ConsumeCodeCacheOffThread": [ { "platforms": [ @@ -5038,6 +5023,27 @@ ] } ], + "NavigationNetworkResponseQueue": [ + { + "platforms": [ + "android", + "android_weblayer", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "NavigationNetworkResponseQueue" + ] + } + ] + } + ], "NavigationPredictor": [ { "platforms": [
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index ba671ae..de692dc9 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -440,10 +440,10 @@ "BlockingFocusWithoutUserActivation", base::FEATURE_DISABLED_BY_DEFAULT}; // A server-side switch for the REALTIME_AUDIO thread priority of -// RealtimeAudioWorkletThread object. When disabled, it will use the NORMAL -// priority thread. +// RealtimeAudioWorkletThread object. This can be controlled by a field trial, +// it will use the NORMAL priority thread when disabled. const base::Feature kAudioWorkletThreadRealtimePriority{ - "AudioWorkletThreadRealtimePriority", base::FEATURE_DISABLED_BY_DEFAULT}; + "AudioWorkletThreadRealtimePriority", base::FEATURE_ENABLED_BY_DEFAULT}; // A feature to reduce the set of resources fetched by No-State Prefetch. const base::Feature kLightweightNoStatePrefetch {
diff --git a/third_party/blink/renderer/core/OWNERS b/third_party/blink/renderer/core/OWNERS index ede99cd..042050c4 100644 --- a/third_party/blink/renderer/core/OWNERS +++ b/third_party/blink/renderer/core/OWNERS
@@ -23,7 +23,7 @@ # dtapuska reviews input-related changes dtapuska@chromium.org enne@chromium.org -# flackr reviews animation- and scrolling-related changes. +# flackr reviews animation, input-related and scrolling-related changes. flackr@chromium.org fmalita@chromium.org # foolip reviews <video>, <track>, WebVTT and Fullscreen.
diff --git a/third_party/blink/renderer/core/animation/animation.cc b/third_party/blink/renderer/core/animation/animation.cc index 724cd42..3a86181 100644 --- a/third_party/blink/renderer/core/animation/animation.cc +++ b/third_party/blink/renderer/core/animation/animation.cc
@@ -344,8 +344,8 @@ return document_; } -absl::optional<double> Animation::TimelineTime() const { - return timeline_ ? timeline_->CurrentTimeMilliseconds() : absl::nullopt; +absl::optional<AnimationTimeDelta> Animation::TimelineTime() const { + return timeline_ ? timeline_->CurrentTime() : absl::nullopt; } bool Animation::ConvertCSSNumberishToTime( @@ -520,11 +520,14 @@ } V8CSSNumberish* Animation::ConvertTimeToCSSNumberish( - AnimationTimeDelta time) const { - if (timeline_ && timeline_->IsScrollTimeline()) { - return To<ScrollTimeline>(*timeline_).ConvertTimeToProgress(time); + absl::optional<AnimationTimeDelta> time) const { + if (time) { + if (timeline_ && timeline_->IsScrollTimeline()) { + return To<ScrollTimeline>(*timeline_).ConvertTimeToProgress(time.value()); + } + return MakeGarbageCollected<V8CSSNumberish>(time.value().InMillisecondsF()); } - return MakeGarbageCollected<V8CSSNumberish>(time.InMillisecondsF()); + return nullptr; } // https://drafts.csswg.org/web-animations/#the-current-time-of-an-animation @@ -2297,14 +2300,8 @@ void Animation::QueueFinishedEvent() { const AtomicString& event_type = event_type_names::kFinish; if (GetExecutionContext() && HasEventListeners(event_type)) { - absl::optional<AnimationTimeDelta> event_current_time = - CurrentTimeInternal(); - absl::optional<double> event_current_time_ms; - if (event_current_time) - event_current_time_ms = event_current_time.value().InMillisecondsF(); - // TODO(crbug.com/916117): Handle NaN values for scroll-linked animations. pending_finished_event_ = MakeGarbageCollected<AnimationPlaybackEvent>( - event_type, event_current_time_ms, TimelineTime()); + event_type, currentTime(), ConvertTimeToCSSNumberish(TimelineTime())); pending_finished_event_->SetTarget(this); pending_finished_event_->SetCurrentTarget(this); document_->EnqueueAnimationFrameEvent(pending_finished_event_); @@ -2366,11 +2363,8 @@ const AtomicString& event_type = event_type_names::kCancel; if (GetExecutionContext() && HasEventListeners(event_type)) { - absl::optional<double> event_current_time = absl::nullopt; - // TODO(crbug.com/916117): Handle NaN values for scroll-linked - // animations. pending_cancelled_event_ = MakeGarbageCollected<AnimationPlaybackEvent>( - event_type, event_current_time, TimelineTime()); + event_type, nullptr, ConvertTimeToCSSNumberish(TimelineTime())); pending_cancelled_event_->SetTarget(this); pending_cancelled_event_->SetCurrentTarget(this); document_->EnqueueAnimationFrameEvent(pending_cancelled_event_); @@ -2679,13 +2673,8 @@ replace_state_ = kRemoved; const AtomicString& event_type = event_type_names::kRemove; if (GetExecutionContext() && HasEventListeners(event_type)) { - absl::optional<AnimationTimeDelta> event_current_time = - CurrentTimeInternal(); - absl::optional<double> event_current_time_ms; - if (event_current_time) - event_current_time_ms = event_current_time.value().InMillisecondsF(); pending_remove_event_ = MakeGarbageCollected<AnimationPlaybackEvent>( - event_type, event_current_time_ms, TimelineTime()); + event_type, currentTime(), ConvertTimeToCSSNumberish(TimelineTime())); pending_remove_event_->SetTarget(this); pending_remove_event_->SetCurrentTarget(this); document_->EnqueueAnimationFrameEvent(pending_remove_event_);
diff --git a/third_party/blink/renderer/core/animation/animation.h b/third_party/blink/renderer/core/animation/animation.h index 3c9bcba0..4bb87a1 100644 --- a/third_party/blink/renderer/core/animation/animation.h +++ b/third_party/blink/renderer/core/animation/animation.h
@@ -348,7 +348,8 @@ absl::optional<AnimationTimeDelta> CalculateCurrentTime() const; TimelinePhase CalculateCurrentPhase() const; - V8CSSNumberish* ConvertTimeToCSSNumberish(AnimationTimeDelta) const; + V8CSSNumberish* ConvertTimeToCSSNumberish( + absl::optional<AnimationTimeDelta>) const; // Failure to convert results in a thrown exception and returning false. bool ConvertCSSNumberishToTime(const V8CSSNumberish* numberish, absl::optional<AnimationTimeDelta>& time, @@ -398,7 +399,7 @@ void PlayInternal(AutoRewind auto_rewind, ExceptionState& exception_state); void ResetPendingTasks(); - absl::optional<double> TimelineTime() const; + absl::optional<AnimationTimeDelta> TimelineTime() const; void ScheduleAsyncFinish(); void AsyncFinishMicrotask();
diff --git a/third_party/blink/renderer/core/dom/element-hot.cc b/third_party/blink/renderer/core/dom/element-hot.cc index 1ea15e2..ba3dde1f 100644 --- a/third_party/blink/renderer/core/dom/element-hot.cc +++ b/third_party/blink/renderer/core/dom/element-hot.cc
@@ -84,7 +84,7 @@ } std::pair<wtf_size_t, const QualifiedName> Element::LookupAttributeQNameHinted( - const AtomicString& name, + AtomicString name, WTF::AtomicStringTable::WeakResult hint) const { if (!GetElementData()) { return std::make_pair( @@ -137,7 +137,7 @@ SetAttributeInternal(index, name, value, kInSynchronizationOfLazyAttribute); } -void Element::SetAttributeHinted(const AtomicString& local_name, +void Element::SetAttributeHinted(AtomicString local_name, WTF::AtomicStringTable::WeakResult hint, const AtomicString& value, ExceptionState& exception_state) { @@ -151,7 +151,8 @@ SynchronizeAttributeHinted(local_name, hint); wtf_size_t index; QualifiedName q_name = QualifiedName::Null(); - std::tie(index, q_name) = LookupAttributeQNameHinted(local_name, hint); + std::tie(index, q_name) = + LookupAttributeQNameHinted(std::move(local_name), hint); AtomicString trusted_value(TrustedTypesCheckFor( ExpectedTrustedTypeForAttribute(q_name), std::move(value), @@ -163,7 +164,7 @@ kNotInSynchronizationOfLazyAttribute); } -void Element::SetAttributeHinted(const AtomicString& local_name, +void Element::SetAttributeHinted(AtomicString local_name, WTF::AtomicStringTable::WeakResult hint, const V8TrustedString* trusted_string, ExceptionState& exception_state) { @@ -177,7 +178,8 @@ SynchronizeAttributeHinted(local_name, hint); wtf_size_t index; QualifiedName q_name = QualifiedName::Null(); - std::tie(index, q_name) = LookupAttributeQNameHinted(local_name, hint); + std::tie(index, q_name) = + LookupAttributeQNameHinted(std::move(local_name), hint); AtomicString value(TrustedTypesCheckFor( ExpectedTrustedTypeForAttribute(q_name), trusted_string, GetExecutionContext(), exception_state));
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index b327004..1e431f5 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -242,18 +242,22 @@ const AtomicString& getAttributeNS(const AtomicString& namespace_uri, const AtomicString& local_name) const; - void setAttribute(const AtomicString& name, + void setAttribute(AtomicString name, AtomicString value, ExceptionState& exception_state = ASSERT_NO_EXCEPTION) { - SetAttributeHinted(name, WeakLowercaseIfNecessary(name), value, + WTF::AtomicStringTable::WeakResult weak_lowercase_name = + WeakLowercaseIfNecessary(name); + SetAttributeHinted(std::move(name), weak_lowercase_name, value, exception_state); } // Trusted Types variant for explicit setAttribute() use. - void setAttribute(const AtomicString& name, + void setAttribute(AtomicString name, const V8TrustedString* trusted_string, ExceptionState& exception_state) { - SetAttributeHinted(name, WeakLowercaseIfNecessary(name), trusted_string, + WTF::AtomicStringTable::WeakResult weak_lowercase_name = + WeakLowercaseIfNecessary(name); + SetAttributeHinted(std::move(name), weak_lowercase_name, trusted_string, exception_state); } @@ -1237,16 +1241,16 @@ void SynchronizeAttributeHinted( const AtomicString& name, WTF::AtomicStringTable::WeakResult hint) const; - void SetAttributeHinted(const AtomicString& name, + void SetAttributeHinted(AtomicString name, WTF::AtomicStringTable::WeakResult hint, const AtomicString& value, ExceptionState& = ASSERT_NO_EXCEPTION); - void SetAttributeHinted(const AtomicString& name, + void SetAttributeHinted(AtomicString name, WTF::AtomicStringTable::WeakResult hint, const V8TrustedString* trusted_string, ExceptionState& exception_state); std::pair<wtf_size_t, const QualifiedName> LookupAttributeQNameHinted( - const AtomicString& name, + AtomicString name, WTF::AtomicStringTable::WeakResult hint) const; void CancelFocusAppearanceUpdate();
diff --git a/third_party/blink/renderer/core/events/animation_playback_event.cc b/third_party/blink/renderer/core/events/animation_playback_event.cc index 33940c40..954a31aa 100644 --- a/third_party/blink/renderer/core/events/animation_playback_event.cc +++ b/third_party/blink/renderer/core/events/animation_playback_event.cc
@@ -6,34 +6,24 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_animation_playback_event_init.h" #include "third_party/blink/renderer/core/animation/timing.h" +#include "third_party/blink/renderer/core/css/cssom/css_unit_values.h" #include "third_party/blink/renderer/core/event_interface_names.h" namespace blink { -AnimationPlaybackEvent::AnimationPlaybackEvent( - const AtomicString& type, - absl::optional<double> current_time, - absl::optional<double> timeline_time) +AnimationPlaybackEvent::AnimationPlaybackEvent(const AtomicString& type, + V8CSSNumberish* current_time, + V8CSSNumberish* timeline_time) : Event(type, Bubbles::kNo, Cancelable::kNo), current_time_(current_time), - timeline_time_(timeline_time) { - DCHECK(!current_time_ || !std::isnan(current_time_.value())); - DCHECK(!timeline_time_ || !std::isnan(timeline_time_.value())); -} + timeline_time_(timeline_time) {} AnimationPlaybackEvent::AnimationPlaybackEvent( const AtomicString& type, const AnimationPlaybackEventInit* initializer) - : Event(type, initializer) { - if (initializer->hasCurrentTimeNonNull()) { - current_time_ = initializer->currentTimeNonNull(); - } - if (initializer->hasTimelineTimeNonNull()) { - timeline_time_ = initializer->timelineTime(); - } - DCHECK(!current_time_ || !std::isnan(current_time_.value())); - DCHECK(!timeline_time_ || !std::isnan(timeline_time_.value())); -} + : Event(type, initializer), + current_time_(initializer->currentTime()), + timeline_time_(initializer->timelineTime()) {} AnimationPlaybackEvent::~AnimationPlaybackEvent() = default; @@ -42,6 +32,8 @@ } void AnimationPlaybackEvent::Trace(Visitor* visitor) const { + TraceIfNeeded<Member<V8CSSNumberish>>::Trace(visitor, current_time_); + TraceIfNeeded<Member<V8CSSNumberish>>::Trace(visitor, timeline_time_); Event::Trace(visitor); }
diff --git a/third_party/blink/renderer/core/events/animation_playback_event.h b/third_party/blink/renderer/core/events/animation_playback_event.h index eeab815..65726ff5 100644 --- a/third_party/blink/renderer/core/events/animation_playback_event.h +++ b/third_party/blink/renderer/core/events/animation_playback_event.h
@@ -6,6 +6,8 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_ANIMATION_PLAYBACK_EVENT_H_ #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h" #include "third_party/blink/renderer/core/dom/events/event.h" namespace blink { @@ -23,22 +25,22 @@ } AnimationPlaybackEvent(const AtomicString& type, - absl::optional<double> current_time, - absl::optional<double> timeline_time); + V8CSSNumberish* current_time, + V8CSSNumberish* timeline_time); AnimationPlaybackEvent(const AtomicString&, const AnimationPlaybackEventInit*); ~AnimationPlaybackEvent() override; - absl::optional<double> currentTime() const { return current_time_; } - absl::optional<double> timelineTime() const { return timeline_time_; } + V8CSSNumberish* currentTime() const { return current_time_; } + V8CSSNumberish* timelineTime() const { return timeline_time_; } const AtomicString& InterfaceName() const override; void Trace(Visitor*) const override; private: - absl::optional<double> current_time_; - absl::optional<double> timeline_time_; + Member<V8CSSNumberish> current_time_; + Member<V8CSSNumberish> timeline_time_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/events/animation_playback_event.idl b/third_party/blink/renderer/core/events/animation_playback_event.idl index 00e5e91..032ebb28 100644 --- a/third_party/blink/renderer/core/events/animation_playback_event.idl +++ b/third_party/blink/renderer/core/events/animation_playback_event.idl
@@ -9,6 +9,6 @@ Exposed=Window ] interface AnimationPlaybackEvent : Event { constructor(DOMString type, optional AnimationPlaybackEventInit eventInitDict = {}); - readonly attribute double? currentTime; - readonly attribute double? timelineTime; + readonly attribute CSSNumberish? currentTime; + readonly attribute CSSNumberish? timelineTime; };
diff --git a/third_party/blink/renderer/core/events/animation_playback_event_init.idl b/third_party/blink/renderer/core/events/animation_playback_event_init.idl index bce162f..e591ee00 100644 --- a/third_party/blink/renderer/core/events/animation_playback_event_init.idl +++ b/third_party/blink/renderer/core/events/animation_playback_event_init.idl
@@ -5,6 +5,6 @@ // https://drafts.csswg.org/web-animations/#the-animationplaybackevent-interface dictionary AnimationPlaybackEventInit : EventInit { - double? currentTime = null; - double? timelineTime = null; + CSSNumberish? currentTime = null; + CSSNumberish? timelineTime = null; };
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 c210f69..46f905747 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
@@ -2050,13 +2050,14 @@ ->GetEventHandler() .RecomputeMouseHoverStateIfNeeded(); - // Adjusting frame anchor only happens on the main frame. - if (ForMainFrame()) { - if (LocalFrameView* view = LocalRootImpl()->GetFrameView()) { - if (FragmentAnchor* anchor = view->GetFragmentAnchor()) - anchor->PerformPreRafActions(); - } - } + ForEachLocalFrameControlledByWidget( + LocalRootImpl()->GetFrame(), + WTF::BindRepeating([](WebLocalFrameImpl* local_frame) { + if (LocalFrameView* view = local_frame->GetFrameView()) { + if (FragmentAnchor* anchor = view->GetFragmentAnchor()) + anchor->PerformPreRafActions(); + } + })); absl::optional<LocalFrameUkmAggregator::ScopedUkmHierarchicalTimer> ukm_timer; if (WidgetBase::ShouldRecordBeginMainFrameMetrics()) {
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_image_source.cc b/third_party/blink/renderer/core/html/canvas/canvas_image_source.cc index d0478b5..8703369 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_image_source.cc +++ b/third_party/blink/renderer/core/html/canvas/canvas_image_source.cc
@@ -16,21 +16,17 @@ const SkImageInfo& info, const scoped_refptr<StaticBitmapImage>& source_image, bool fallback_to_software) { - IntSize size(info.width(), info.height()); - const cc::PaintFlags::FilterQuality filter_quality = cc::PaintFlags::FilterQuality::kLow; - const CanvasResourceParams resource_params(info); - if (context_provider) { uint32_t usage_flags = context_provider->ContextProvider() ->SharedImageInterface() ->UsageForMailbox(source_image->GetMailboxHolder().mailbox); auto resource_provider = CanvasResourceProvider::CreateSharedImageProvider( - size, filter_quality, resource_params, - CanvasResourceProvider::ShouldInitialize::kNo, context_provider, - RasterMode::kGPU, source_image->IsOriginTopLeft(), usage_flags); + info, filter_quality, CanvasResourceProvider::ShouldInitialize::kNo, + context_provider, RasterMode::kGPU, source_image->IsOriginTopLeft(), + usage_flags); if (resource_provider) return resource_provider; @@ -39,8 +35,7 @@ } return CanvasResourceProvider::CreateBitmapProvider( - size, filter_quality, resource_params, - CanvasResourceProvider::ShouldInitialize::kNo); + info, filter_quality, CanvasResourceProvider::ShouldInitialize::kNo); } } // anonymous namespace
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc index 5debb277f..d818be7 100644 --- a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc +++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
@@ -217,21 +217,17 @@ const SkImageInfo& info, const scoped_refptr<StaticBitmapImage>& source_image, bool fallback_to_software) { - IntSize size(info.width(), info.height()); - const cc::PaintFlags::FilterQuality filter_quality = cc::PaintFlags::FilterQuality::kLow; - const CanvasResourceParams resource_params(info); - if (context_provider) { uint32_t usage_flags = context_provider->ContextProvider() ->SharedImageInterface() ->UsageForMailbox(source_image->GetMailboxHolder().mailbox); auto resource_provider = CanvasResourceProvider::CreateSharedImageProvider( - size, filter_quality, resource_params, - CanvasResourceProvider::ShouldInitialize::kNo, context_provider, - RasterMode::kGPU, source_image->IsOriginTopLeft(), usage_flags); + info, filter_quality, CanvasResourceProvider::ShouldInitialize::kNo, + context_provider, RasterMode::kGPU, source_image->IsOriginTopLeft(), + usage_flags); if (resource_provider) return resource_provider; @@ -240,8 +236,7 @@ } return CanvasResourceProvider::CreateBitmapProvider( - size, filter_quality, resource_params, - CanvasResourceProvider::ShouldInitialize::kNo); + info, filter_quality, CanvasResourceProvider::ShouldInitialize::kNo); } scoped_refptr<StaticBitmapImage> FlipImageVertically(
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap_test.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap_test.cc index c53f9f1c..a3b28a187 100644 --- a/third_party/blink/renderer/core/imagebitmap/image_bitmap_test.cc +++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap_test.cc
@@ -253,9 +253,8 @@ TEST_F(ImageBitmapTest, AvoidGPUReadback) { base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper = SharedGpuContext::ContextProviderWrapper(); - CanvasResourceParams resource_params; auto resource_provider = CanvasResourceProvider::CreateSharedImageProvider( - IntSize(100, 100), cc::PaintFlags::FilterQuality::kLow, resource_params, + SkImageInfo::MakeN32Premul(100, 100), cc::PaintFlags::FilterQuality::kLow, CanvasResourceProvider::ShouldInitialize::kNo, context_provider_wrapper, RasterMode::kGPU, true /*is_origin_top_left*/, 0u /*shared_image_usage_flags*/);
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index ac3b10c..8b985ee 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -316,6 +316,10 @@ #endif #define NOT_DESTROYED() CheckIsNotDestroyed() +#if DCHECK_IS_ON() + bool IsDestroyed() const { return is_destroyed_; } +#endif + // Returns the name of the layout object. virtual const char* GetName() const = 0;
diff --git a/third_party/blink/renderer/core/layout/subtree_layout_scope.cc b/third_party/blink/renderer/core/layout/subtree_layout_scope.cc index f71fecc..8af6504e 100644 --- a/third_party/blink/renderer/core/layout/subtree_layout_scope.cc +++ b/third_party/blink/renderer/core/layout/subtree_layout_scope.cc
@@ -46,6 +46,15 @@ #if DCHECK_IS_ON() for (const auto& layout_object : layout_objects_to_layout_) { + // When CSS Container Queries are enabled, style recalc and layout tree + // rebuild for a container during layout may detach LayoutObjects which + // have been marked for layout. Skip such LayoutObject to avoid that + // NOT_DESTROYED() triggers a DCHECK failure in AssertLaidOut() or + // AssertFragmentTree(). + if (layout_object->IsDestroyed()) { + DCHECK(RuntimeEnabledFeatures::CSSContainerQueriesEnabled()); + continue; + } // There are situations where the object to layout was never laid out, such // as if there was a display-locked descendant of the root and ancestor of // the object which prevented layout. This can happen in quirks mode, where
diff --git a/third_party/blink/renderer/core/page/drag_image.cc b/third_party/blink/renderer/core/page/drag_image.cc index c5b381e..0be311a 100644 --- a/third_party/blink/renderer/core/page/drag_image.cc +++ b/third_party/blink/renderer/core/page/drag_image.cc
@@ -203,8 +203,9 @@ // TODO(fserb): are we sure this should be software? std::unique_ptr<CanvasResourceProvider> resource_provider( CanvasResourceProvider::CreateBitmapProvider( - scaled_image_size, cc::PaintFlags::FilterQuality::kLow, - CanvasResourceParams(), + SkImageInfo::MakeN32Premul(scaled_image_size.width(), + scaled_image_size.height()), + cc::PaintFlags::FilterQuality::kLow, CanvasResourceProvider::ShouldInitialize::kNo)); if (!resource_provider) return nullptr;
diff --git a/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc b/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc index 9b8b2b6..fc03c53 100644 --- a/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc +++ b/third_party/blink/renderer/core/page/scrolling/element_fragment_anchor.cc
@@ -22,6 +22,18 @@ namespace blink { +namespace { +// TODO(bokan): Move this into FragmentDirective after +// https://crrev.com/c/3216206 lands. +String RemoveFragmentDirectives(const String& url_fragment) { + wtf_size_t directive_delimiter_ix = url_fragment.Find(":~:"); + if (directive_delimiter_ix == kNotFound) + return url_fragment; + + return url_fragment.Substring(0, directive_delimiter_ix); +} +} // namespace + ElementFragmentAnchor* ElementFragmentAnchor::TryCreate(const KURL& url, LocalFrame& frame, bool should_scroll) { @@ -37,7 +49,7 @@ if (!url.HasFragmentIdentifier() && !doc.CssTarget() && !doc.IsSVGDocument()) return nullptr; - String fragment = url.FragmentIdentifier(); + String fragment = RemoveFragmentDirectives(url.FragmentIdentifier()); Node* anchor_node = doc.FindAnchor(fragment); // Setting to null will clear the current target.
diff --git a/third_party/blink/renderer/core/scroll/OWNERS b/third_party/blink/renderer/core/scroll/OWNERS index a166098..e2b9820 100644 --- a/third_party/blink/renderer/core/scroll/OWNERS +++ b/third_party/blink/renderer/core/scroll/OWNERS
@@ -1,2 +1,5 @@ +bokan@chromium.org +flackr@chromium.org + per-file *_type_converter*.*=set noparent per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS
diff --git a/third_party/blink/renderer/core/timing/responsiveness_metrics.cc b/third_party/blink/renderer/core/timing/responsiveness_metrics.cc index 38b151e..deea457 100644 --- a/third_party/blink/renderer/core/timing/responsiveness_metrics.cc +++ b/third_party/blink/renderer/core/timing/responsiveness_metrics.cc
@@ -10,10 +10,14 @@ #include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_recorder.h" #include "third_party/blink/public/common/responsiveness_metrics/user_interaction_latency.h" +#include "third_party/blink/renderer/core/dom/dom_high_res_time_stamp.h" #include "third_party/blink/renderer/core/event_type_names.h" #include "third_party/blink/renderer/core/frame/frame.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" +#include "third_party/blink/renderer/core/timing/performance_event_timing.h" +#include "third_party/blink/renderer/core/timing/window_performance.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h" namespace blink { @@ -25,6 +29,20 @@ constexpr int kMaxValueForSampling = 100; // UKM sampling rate. The sampling strategy is 1/N. constexpr int kUkmSamplingRate = 10; +// Minimum potential value for the first Interaction ID. +constexpr uint32_t kMinFirstInteractionID = 100; +// Maximum potential value for the first Interaction ID. +constexpr uint32_t kMaxFirstInteractionID = 10000; +// Interaction ID increment. We increase this value by an integer greater than 1 +// to discourage developers from using the value to 'count' the number of user +// interactions. This is consistent with the spec, which allows the increasing +// the user interaction value by a small number chosen by the user agent. +constexpr uint32_t kInteractionIdIncrement = 7; +// The maximum tap delay we can handle for assigning interaction id. +constexpr blink::DOMHighResTimeStamp kMaxDelayForEntries = + blink::DOMHighResTimeStamp(500); +// The length of the timer to flush entries from the time pointerup occurs. +constexpr base::TimeDelta kFlushTimerLength = base::Seconds(1); base::TimeDelta MaxEventDuration( const WTF::Vector<ResponsivenessMetrics::EventTimestamps>& timestamps) { @@ -88,17 +106,29 @@ } // namespace -ResponsivenessMetrics::ResponsivenessMetrics() = default; +ResponsivenessMetrics::ResponsivenessMetrics( + WindowPerformance* window_performance) + : window_performance_(window_performance), + pointer_flush_timer_(window_performance_->task_runner_, + this, + &ResponsivenessMetrics::FlushPointerTimerFired), + current_interaction_id_for_event_timing_( + // Follow the spec by choosing a random integer as the initial value + // to discourage developers from using interactionId to count the + // number of interactions. See + // https://wicg.github.io/event-timing/#user-interaction-value. + base::RandInt(kMinFirstInteractionID, kMaxFirstInteractionID)) {} + ResponsivenessMetrics::~ResponsivenessMetrics() = default; void ResponsivenessMetrics::RecordUserInteractionUKM( LocalDOMWindow* window, UserInteractionType interaction_type, - const WTF::Vector<ResponsivenessMetrics::EventTimestamps>& timestamps) { + const WTF::Vector<EventTimestamps>& timestamps) { if (!window) return; - for (ResponsivenessMetrics::EventTimestamps timestamp : timestamps) { + for (EventTimestamps timestamp : timestamps) { if (timestamp.start_time == base::TimeTicks()) { return; } @@ -132,73 +162,259 @@ } } -void ResponsivenessMetrics::NotifyPotentialDrag() { - is_drag_ = pending_pointer_down_timestamps_.has_value() && - !pending_pointer_up_timestamps_.has_value(); +void ResponsivenessMetrics::NotifyPotentialDrag(PointerId pointer_id) { + if (pointer_id_entry_map_.Contains(pointer_id)) + pointer_id_entry_map_.at(pointer_id)->SetIsDrag(); } -void ResponsivenessMetrics::FlushPendingInteraction(LocalDOMWindow* window) { - // For tap delay, the click can be dropped. We will measure the latency - // without any click data. - if (pending_pointer_down_timestamps_.has_value() && - pending_pointer_up_timestamps_.has_value()) { - WTF::Vector<EventTimestamps> timestamps; - // Insertion order matters for latency computation. - timestamps.push_back(pending_pointer_down_timestamps_.value()); - timestamps.push_back(pending_pointer_up_timestamps_.value()); - RecordUserInteractionUKM(window, - is_drag_ ? UserInteractionType::kDrag - : UserInteractionType::kTapOrClick, - timestamps); - } - ResetPendingPointers(); -} - -void ResponsivenessMetrics::ResetPendingPointers() { - is_drag_ = false; - pending_pointer_down_timestamps_.reset(); - pending_pointer_up_timestamps_.reset(); -} - -// For multi-finger touch, we record the innermost pair of pointerdown and -// pointerup. -// TODO(hbsong): Record one interaction per pointer id. -void ResponsivenessMetrics::RecordTapOrClickOrDrag( +void ResponsivenessMetrics::RecordDragTapOrClickUKM( LocalDOMWindow* window, - const AtomicString& event_type, - EventTimestamps event_timestamps) { - if (event_type == event_type_names::kPointercancel) { - pending_pointer_down_timestamps_.reset(); - } else if (event_type == event_type_names::kPointerdown) { - FlushPendingInteraction(window); - pending_pointer_down_timestamps_ = event_timestamps; - } else if (event_type == event_type_names::kPointerup && - pending_pointer_down_timestamps_.has_value() && - !pending_pointer_up_timestamps_.has_value()) { - pending_pointer_up_timestamps_ = event_timestamps; - } else if (event_type == event_type_names::kClick) { - WTF::Vector<EventTimestamps> timestamps; - // Insertion order matters for latency computation. - if (pending_pointer_down_timestamps_.has_value()) { - timestamps.push_back(pending_pointer_down_timestamps_.value()); - } - if (pending_pointer_up_timestamps_.has_value()) { - timestamps.push_back(pending_pointer_up_timestamps_.value()); - } - timestamps.push_back(event_timestamps); - RecordUserInteractionUKM(window, - is_drag_ ? UserInteractionType::kDrag - : UserInteractionType::kTapOrClick, - timestamps); - ResetPendingPointers(); + PointerEntryAndInfo& pointer_info) { + DCHECK(pointer_info.GetEntry()); + // Early return if all we got was a pointerdown. + if (pointer_info.GetEntry()->name() == event_type_names::kPointerdown && + pointer_info.GetTimeStamps().size() == 1u) { + return; } + RecordUserInteractionUKM(window, + pointer_info.IsDrag() + ? UserInteractionType::kDrag + : UserInteractionType::kTapOrClick, + pointer_info.GetTimeStamps()); } -void ResponsivenessMetrics::RecordKeyboardInteractions( +bool ResponsivenessMetrics::SetPointerIdAndRecordLatency( + PerformanceEventTiming* entry, + PointerId pointer_id, + EventTimestamps event_timestamps) { + const AtomicString& event_type = entry->name(); + auto* pointer_info = pointer_id_entry_map_.Contains(pointer_id) + ? pointer_id_entry_map_.at(pointer_id) + : nullptr; + LocalDOMWindow* window = window_performance_->DomWindow(); + if (event_type == event_type_names::kPointercancel && pointer_info) { + MaybeNotifyPointerdown(pointer_info->GetEntry()); + // The pointer id of the pointerdown is no longer needed. + pointer_id_entry_map_.erase(pointer_id); + } else if (event_type == event_type_names::kPointerdown) { + if (pointer_info) { + // Flush the existing entry. We are starting a new interaction. + RecordDragTapOrClickUKM(window, *pointer_info); + MaybeNotifyPointerdown(pointer_info->GetEntry()); + pointer_id_entry_map_.erase(pointer_id); + } + // Any existing entry in the map cannot fire a click. + FlushPointerMap(); + if (pointer_flush_timer_.IsActive()) { + pointer_flush_timer_.Stop(); + } + pointer_id_entry_map_.Set( + pointer_id, PointerEntryAndInfo::Create(entry, event_timestamps)); + + // Waiting to see if we get a pointercancel or pointerup. + return false; + } else if (event_type == event_type_names::kPointerup) { + // Generate a new interaction id. + UpdateInteractionId(); + entry->SetInteractionId(GetCurrentInteractionId()); + if (pointer_info && + pointer_info->GetEntry()->name() == event_type_names::kPointerdown) { + // Set interaction id and notify the pointer down entry. + PerformanceEventTiming* pointer_down_entry = pointer_info->GetEntry(); + pointer_down_entry->SetInteractionId(GetCurrentInteractionId()); + MaybeNotifyPointerdown(pointer_down_entry); + pointer_info->GetTimeStamps().push_back(event_timestamps); + } else { + // There is no matching pointerdown: Set the map using pointerup, in + // case a click event shows up. + pointer_id_entry_map_.Set( + pointer_id, PointerEntryAndInfo::Create(entry, event_timestamps)); + } + // Start the timer to flush the entry just created later, if needed. + if (!pointer_flush_timer_.IsActive()) { + pointer_flush_timer_.StartOneShot(kFlushTimerLength, FROM_HERE); + } + } else if (event_type == event_type_names::kClick) { + if (pointer_info) { + // There is a previous pointerdown or pointerup entry. Use its + // interactionId. + PerformanceEventTiming* previous_entry = pointer_info->GetEntry(); + // There are cases where we only see pointerdown and click, for instance + // with contextmenu. + if (previous_entry->interactionId() == 0u) { + UpdateInteractionId(); + previous_entry->SetInteractionId(GetCurrentInteractionId()); + } + entry->SetInteractionId(previous_entry->interactionId()); + pointer_info->GetTimeStamps().push_back(event_timestamps); + RecordDragTapOrClickUKM(window, *pointer_info); + // The pointer id of the pointerdown is no longer needed. + pointer_id_entry_map_.erase(pointer_id); + } else { + // There is no previous pointerdown or pointerup entry. This can happen + // when the user clicks using a non-pointer device. Generate a new + // interactionId. No need to add to the map since this is the last event + // in the interaction. + UpdateInteractionId(); + entry->SetInteractionId(GetCurrentInteractionId()); + RecordDragTapOrClickUKM( + window, *PointerEntryAndInfo::Create(entry, event_timestamps)); + } + } + return true; +} + +void ResponsivenessMetrics::RecordKeyboardUKM( LocalDOMWindow* window, const WTF::Vector<EventTimestamps>& event_timestamps) { RecordUserInteractionUKM(window, UserInteractionType::kKeyboard, event_timestamps); } +bool ResponsivenessMetrics::SetKeyIdAndRecordLatency( + PerformanceEventTiming* entry, + absl::optional<int> key_code, + EventTimestamps event_timestamps) { + auto event_type = entry->name(); + if (event_type == event_type_names::kKeydown) { + DCHECK(key_code.has_value()); + // During compositions, we ignore keydowns/keyups and look at input events. + if (composition_started_) + return true; + + if (key_code_entry_map_.Contains(*key_code)) { + auto* previous_entry = key_code_entry_map_.at(*key_code); + // Ignore repeat IME keydowns. See + // https://w3c.github.io/uievents/#determine-keydown-keyup-keyCode. + // Reasoning: we cannot ignore all IME keydowns because on Android in some + // languages the events received are 'keydown', 'input', 'keyup', and + // since we are not composing then the 'input' event is ignored, so we + // must consider the key events with 229 keyCode as the user interaction. + // Besides this, we cannot consider repeat 229 keydowns because we may get + // those on ChromeOS when we should ignore them. This may be related to + // crbug.com/1252856. + if (*key_code != 229) { + // Generate a new interaction id for |previous_entry|. This case could + // be caused by keeping a key pressed for a while. + UpdateInteractionId(); + previous_entry->GetEntry()->SetInteractionId(GetCurrentInteractionId()); + RecordKeyboardUKM(window_performance_->DomWindow(), + {previous_entry->GetTimeStamps()}); + } + window_performance_->MaybeNotifyInteractionAndAddEventTimingBuffer( + previous_entry->GetEntry()); + } + key_code_entry_map_.Set( + *key_code, KeyboardEntryAndTimestamps::Create(entry, event_timestamps)); + // Similar to pointerdown, we need to wait a bit before knowing the + // interactionId of keydowns. + return false; + } else if (event_type == event_type_names::kKeyup) { + DCHECK(key_code.has_value()); + if (composition_started_ || !key_code_entry_map_.Contains(*key_code)) + return true; + + auto* previous_entry = key_code_entry_map_.at(*key_code); + // Generate a new interaction id for the keydown-keyup pair. + UpdateInteractionId(); + previous_entry->GetEntry()->SetInteractionId(GetCurrentInteractionId()); + window_performance_->MaybeNotifyInteractionAndAddEventTimingBuffer( + previous_entry->GetEntry()); + entry->SetInteractionId(GetCurrentInteractionId()); + RecordKeyboardUKM(window_performance_->DomWindow(), + {previous_entry->GetTimeStamps(), event_timestamps}); + key_code_entry_map_.erase(*key_code); + } else if (event_type == event_type_names::kCompositionstart) { + composition_started_ = true; + for (auto key_entry : key_code_entry_map_.Values()) { + window_performance_->MaybeNotifyInteractionAndAddEventTimingBuffer( + key_entry->GetEntry()); + } + key_code_entry_map_.clear(); + } else if (event_type == event_type_names::kCompositionend) { + composition_started_ = false; + } else if (event_type == event_type_names::kInput) { + if (!composition_started_) { + return true; + } + // We are in the case of a text input event while compositing with + // non-trivial data, so we want to increase interactionId. + // TODO(crbug.com/1252856): fix counts in ChromeOS due to duplicate events. + UpdateInteractionId(); + entry->SetInteractionId(GetCurrentInteractionId()); + RecordKeyboardUKM(window_performance_->DomWindow(), {event_timestamps}); + } + return true; +} + +void ResponsivenessMetrics::MaybeFlushKeyboardEntries( + DOMHighResTimeStamp current_time) { + // We cannot delete from a HashMap while iterating. + Vector<int> key_codes_to_remove; + for (const auto& entry : key_code_entry_map_) { + PerformanceEventTiming* key_down = entry.value->GetEntry(); + if (current_time - key_down->processingEnd() > kMaxDelayForEntries) { + window_performance_->NotifyAndAddEventTimingBuffer(key_down); + key_codes_to_remove.push_back(entry.key); + } + } + key_code_entry_map_.RemoveAll(key_codes_to_remove); +} + +void ResponsivenessMetrics::UpdateInteractionId() { + current_interaction_id_for_event_timing_ += kInteractionIdIncrement; +} + +uint32_t ResponsivenessMetrics::GetCurrentInteractionId() const { + return current_interaction_id_for_event_timing_; +} + +void ResponsivenessMetrics::FlushPointerTimerFired(TimerBase*) { + FlushPointerMap(); +} + +void ResponsivenessMetrics::FlushPointerMap() { + LocalDOMWindow* window = window_performance_->DomWindow(); + if (!window) + return; + Vector<PointerId> pointer_ids_to_remove; + for (const auto& item : pointer_id_entry_map_) { + PerformanceEventTiming* entry = item.value->GetEntry(); + // Report entries that are currently waiting for a click. This could be the + // case when the entry's name() is pointerup or when we have more than one + // event for this |item|, which means we have pointerdown and pointerup. + if (entry->name() == event_type_names::kPointerup || + item.value->GetTimeStamps().size() > 1u) { + MaybeNotifyPointerdown(entry); + RecordDragTapOrClickUKM(window, *item.value); + pointer_ids_to_remove.push_back(item.key); + } + } + pointer_id_entry_map_.RemoveAll(pointer_ids_to_remove); +} + +void ResponsivenessMetrics::MaybeNotifyPointerdown( + PerformanceEventTiming* entry) const { + // We only delay dispatching entries when they are pointerdown. + if (entry->name() != event_type_names::kPointerdown) + return; + window_performance_->MaybeNotifyInteractionAndAddEventTimingBuffer(entry); +} + +void ResponsivenessMetrics::KeyboardEntryAndTimestamps::Trace( + Visitor* visitor) const { + visitor->Trace(entry_); +} + +void ResponsivenessMetrics::PointerEntryAndInfo::Trace(Visitor* visitor) const { + visitor->Trace(entry_); +} + +void ResponsivenessMetrics::Trace(Visitor* visitor) const { + visitor->Trace(window_performance_); + visitor->Trace(pointer_id_entry_map_); + visitor->Trace(key_code_entry_map_); + visitor->Trace(pointer_flush_timer_); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/timing/responsiveness_metrics.h b/third_party/blink/renderer/core/timing/responsiveness_metrics.h index b04b5f1..4238d0a 100644 --- a/third_party/blink/renderer/core/timing/responsiveness_metrics.h +++ b/third_party/blink/renderer/core/timing/responsiveness_metrics.h
@@ -12,7 +12,10 @@ namespace blink { -class ResponsivenessMetrics { +class PerformanceEventTiming; +class WindowPerformance; + +class ResponsivenessMetrics : public GarbageCollected<ResponsivenessMetrics> { public: // Timestamps for input events. struct EventTimestamps { @@ -23,7 +26,69 @@ base::TimeTicks end_time; }; - ResponsivenessMetrics(); + // Wrapper class to store PerformanceEventTiming and timestamps + // on a HeapHashMap. + class KeyboardEntryAndTimestamps + : public GarbageCollected<KeyboardEntryAndTimestamps> { + public: + KeyboardEntryAndTimestamps(PerformanceEventTiming* entry, + EventTimestamps timestamps) + : entry_(entry), timestamps_({timestamps}) {} + + static KeyboardEntryAndTimestamps* Create(PerformanceEventTiming* entry, + EventTimestamps timestamps) { + return MakeGarbageCollected<KeyboardEntryAndTimestamps>(entry, + timestamps); + } + ~KeyboardEntryAndTimestamps() = default; + void Trace(Visitor*) const; + PerformanceEventTiming* GetEntry() const { return entry_; } + EventTimestamps GetTimeStamps() { return timestamps_; } + + private: + // The PerformanceEventTiming entry that has not been sent to observers + // yet: the event dispatch has been completed but the presentation promise + // used to determine |duration| has not yet been resolved, or the + // interactionId has not yet been computed yet. + Member<PerformanceEventTiming> entry_; + // Timestamps associated with the entry. + EventTimestamps timestamps_; + }; + + // Wrapper class to store PerformanceEventTiming, pointerdown and pointerup + // timestamps, and whether drag has been detected on a HeapHashMap. + class PointerEntryAndInfo : public GarbageCollected<PointerEntryAndInfo> { + public: + PointerEntryAndInfo(PerformanceEventTiming* entry, + EventTimestamps timestamps) + : entry_(entry), timestamps_({timestamps}) {} + + static PointerEntryAndInfo* Create(PerformanceEventTiming* entry, + EventTimestamps timestamps) { + return MakeGarbageCollected<PointerEntryAndInfo>(entry, timestamps); + } + ~PointerEntryAndInfo() = default; + void Trace(Visitor*) const; + PerformanceEventTiming* GetEntry() const { return entry_; } + Vector<EventTimestamps>& GetTimeStamps() { return timestamps_; } + void SetIsDrag() { is_drag_ = true; } + bool IsDrag() const { return is_drag_; } + + private: + // The PerformanceEventTiming entry that has not been sent to observers + // yet: the event dispatch has been completed but the presentation promise + // used to determine |duration| has not yet been resolved, , or the + // interactionId has not yet been computed yet. + Member<PerformanceEventTiming> entry_; + // Timestamps associated with the entry. The first should always be + // for a pointerdown, the second for a pointerup, and optionally the third + // for a click. + Vector<EventTimestamps> timestamps_; + // Whether drag has been detected. + bool is_drag_; + }; + + explicit ResponsivenessMetrics(WindowPerformance*); ~ResponsivenessMetrics(); // Stop UKM sampling for testing. @@ -31,16 +96,29 @@ // The use might be dragging. The function will be called whenever we have a // pointermove. - void NotifyPotentialDrag(); + void NotifyPotentialDrag(PointerId pointer_id); - void RecordKeyboardInteractions( - LocalDOMWindow* window, - const WTF::Vector<EventTimestamps>& event_timestamps); + // Assigns an interactionId and records interaction latency for pointer + // events. Returns true if the entry is ready to be surfaced in + // PerformanceObservers and the Performance Timeline. + bool SetPointerIdAndRecordLatency(PerformanceEventTiming* entry, + PointerId pointer_id, + EventTimestamps event_timestamps); - // Might not be accurate for multi-fingers touch. - void RecordTapOrClickOrDrag(LocalDOMWindow* window, - const AtomicString& event_type, - EventTimestamps event_timestamps); + // Assigns interactionId and records interaction latency for keyboard events. + // We care about input, compositionstart, and compositionend events, so + // |key_code| will be absl::nullopt in those cases. Returns true if the entry + // would be ready to be surfaced in PerformanceObservers and the Performance + // Timeline. + bool SetKeyIdAndRecordLatency(PerformanceEventTiming* entry, + absl::optional<int> key_code, + EventTimestamps event_timestamps); + + // Clears some entries in |key_codes_to_remove| if we have stored them for a + // while. + void MaybeFlushKeyboardEntries(DOMHighResTimeStamp current_time); + + void Trace(Visitor*) const; private: // Record UKM for user interaction latencies. @@ -49,15 +127,51 @@ UserInteractionType interaction_type, const WTF::Vector<ResponsivenessMetrics::EventTimestamps>& timestamps); - // Flush the latency data for pending tap or drag. - void FlushPendingInteraction(LocalDOMWindow* window); + void RecordDragTapOrClickUKM(LocalDOMWindow*, PointerEntryAndInfo&); - // Reset the latency data for pointer events. - void ResetPendingPointers(); + void RecordKeyboardUKM(LocalDOMWindow* window, + const WTF::Vector<EventTimestamps>& event_timestamps); - absl::optional<EventTimestamps> pending_pointer_up_timestamps_; - absl::optional<EventTimestamps> pending_pointer_down_timestamps_; - bool is_drag_ = false; + // Updates the interactionId counter which is used by Event Timing. + void UpdateInteractionId(); + + uint32_t GetCurrentInteractionId() const; + + // Method called when |pointer_flush_timer_| fires. Ensures that the last + // interaction of any given pointerId is reported, even if it does not receive + // a click. + void FlushPointerTimerFired(TimerBase*); + + // Used to flush any entries in |pointer_id_entry_map_| which already have + // pointerup. We either know there is no click happening or waited long enough + // for a click to occur. + void FlushPointerMap(); + + void MaybeNotifyPointerdown(PerformanceEventTiming* entry) const; + + Member<WindowPerformance> window_performance_; + + // Map from keyCodes to keydown entries and keydown timestamps. + HeapHashMap<int, + Member<KeyboardEntryAndTimestamps>, + WTF::IntHash<int>, + WTF::UnsignedWithZeroKeyHashTraits<int>> + key_code_entry_map_; + // Whether we are composing or not. When we are not composing, we set + // interactionId for keydown and keyup events. When we are composing, we set + // interactionId for input events. + bool composition_started_ = false; + + // Map from pointerId to the first pointer event entry seen for the user + // interaction, and other information. + HeapHashMap<PointerId, + Member<PointerEntryAndInfo>, + WTF::IntHash<PointerId>, + WTF::UnsignedWithZeroKeyHashTraits<PointerId>> + pointer_id_entry_map_; + HeapTaskRunnerTimer<ResponsivenessMetrics> pointer_flush_timer_; + + uint32_t current_interaction_id_for_event_timing_; // Whether to perform UKM sampling. bool sampling_ = true;
diff --git a/third_party/blink/renderer/core/timing/window_performance.cc b/third_party/blink/renderer/core/timing/window_performance.cc index 605e2d80..1a227a2b4 100644 --- a/third_party/blink/renderer/core/timing/window_performance.cc +++ b/third_party/blink/renderer/core/timing/window_performance.cc
@@ -67,6 +67,7 @@ #include "third_party/blink/renderer/core/timing/responsiveness_metrics.h" #include "third_party/blink/renderer/core/timing/visibility_state_entry.h" #include "third_party/blink/renderer/platform/heap/forward.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h" @@ -81,17 +82,6 @@ namespace blink { namespace { -// Minimum potential value for the first Interaction ID. -constexpr uint32_t kMinFirstInteractionID = 100; -// Maximum potential value for the first Interaction ID. -constexpr uint32_t kMaxFirstInteractionID = 10000; -// Interaction ID increment. -constexpr uint32_t kInteractionIdIncrement = 7; -// The maximum number of pending pointer down. -constexpr WTF::wtf_size_t kMaxPendingPointerDownNumber = 20; -// The maximum tap delay we can handle for assigning interaction id. -constexpr blink::DOMHighResTimeStamp kMaxDelayForEntries = - blink::DOMHighResTimeStamp(500); AtomicString GetFrameAttribute(HTMLFrameOwnerElement* frame_owner, const QualifiedName& attr_name) { @@ -183,8 +173,8 @@ window), ExecutionContextClient(window), PageVisibilityObserver(window->GetFrame()->GetPage()), - current_interaction_id_for_event_timing_( - base::RandInt(kMinFirstInteractionID, kMaxFirstInteractionID)) { + responsiveness_metrics_( + MakeGarbageCollected<ResponsivenessMetrics>(this)) { DCHECK(window); DCHECK(window->GetFrame()->GetPerformanceMonitor()); window->GetFrame()->GetPerformanceMonitor()->Subscribe( @@ -199,11 +189,6 @@ visitor->Trace(event_timing_); } -void WindowPerformance::KeyboardEntryAndTimestamps::Trace( - Visitor* visitor) const { - visitor->Trace(entry_); -} - WindowPerformance::~WindowPerformance() = default; ExecutionContext* WindowPerformance::GetExecutionContext() const { @@ -277,9 +262,8 @@ visitor->Trace(event_counts_); visitor->Trace(navigation_); visitor->Trace(timing_); + visitor->Trace(responsiveness_metrics_); visitor->Trace(current_event_); - visitor->Trace(pointer_id_pointer_down_map_); - visitor->Trace(key_code_entry_map_); Performance::Trace(visitor); PerformanceMonitor::Client::Trace(visitor); ExecutionContextClient::Trace(visitor); @@ -392,14 +376,16 @@ return; const AtomicString& event_type = event.type(); + const PointerEvent* pointer_event = DynamicTo<PointerEvent>(event); if (event_type == event_type_names::kPointermove) { - NotifyPotentialDrag(); + // A trusted pointermove must be a PointerEvent. + DCHECK(event.IsPointerEvent()); + NotifyPotentialDrag(pointer_event->pointerId()); SetCurrentEventTimingEvent(nullptr); return; } eventCounts()->Add(event_type); absl::optional<PointerId> pointer_id; - const PointerEvent* pointer_event = DynamicTo<PointerEvent>(event); if (pointer_event) pointer_id = pointer_event->pointerId(); PerformanceEventTiming* entry = PerformanceEventTiming::Create( @@ -525,34 +511,10 @@ NotifyAndAddEventTimingBuffer(entry); } - if (!RuntimeEnabledFeatures::InteractionIdEnabled(GetExecutionContext())) - return; - // Clear the map if there are too many pending pointer down entries. - if (pointer_id_pointer_down_map_.size() > kMaxPendingPointerDownNumber) { - blink::DOMHighResTimeStamp current_time = - MonotonicTimeToDOMHighResTimeStamp(base::TimeTicks::Now()); - // We cannot delete from a HashMap while iterating. - Vector<PointerId> pointer_ids_to_remove; - for (const auto& pointer_id_pointer_down : pointer_id_pointer_down_map_) { - PerformanceEventTiming* pointer_down = pointer_id_pointer_down.value; - if ((current_time - pointer_down->startTime() - - pointer_down->duration()) > kMaxDelayForEntries) { - pointer_ids_to_remove.push_back(pointer_id_pointer_down.key); - } - } - pointer_id_pointer_down_map_.RemoveAll(pointer_ids_to_remove); + if (RuntimeEnabledFeatures::InteractionIdEnabled(GetExecutionContext())) { + // Use |end_time| as a proxy for the current time. + responsiveness_metrics_->MaybeFlushKeyboardEntries(end_time); } - // We cannot delete from a HashMap while iterating. - Vector<int> key_codes_to_remove; - for (const auto& entry : key_code_entry_map_) { - PerformanceEventTiming* key_down = entry.value->GetEntry(); - // Use |end_time| as a proxy for the current timestamp. - if (end_time - key_down->processingEnd() > kMaxDelayForEntries) { - NotifyAndAddEventTimingBuffer(key_down); - key_codes_to_remove.push_back(entry.key); - } - } - key_code_entry_map_.RemoveAll(key_codes_to_remove); } void WindowPerformance::NotifyAndAddEventTimingBuffer( @@ -579,151 +541,24 @@ NotifyAndAddEventTimingBuffer(entry); } -void WindowPerformance::UpdateInteractionId() { - current_interaction_id_for_event_timing_ += kInteractionIdIncrement; -} - -uint32_t WindowPerformance::GetCurrentInteractionId() const { - return current_interaction_id_for_event_timing_; -} - bool WindowPerformance::SetInteractionIdAndRecordLatency( PerformanceEventTiming* entry, absl::optional<int> key_code, absl::optional<PointerId> pointer_id, ResponsivenessMetrics::EventTimestamps event_timestamps) { - if (pointer_id.has_value()) { - return SetPointerIdAndRecordLatency(entry, *pointer_id, event_timestamps); - } - // For keyboard events, we set the interactionId and record the metric in the + // We set the interactionId and record the metric in the // same logic, so we need to ignore the return value when InteractionId is // disabled. - return SetKeyIdAndRecordLatency(entry, key_code, event_timestamps) || + if (pointer_id.has_value()) { + return responsiveness_metrics_->SetPointerIdAndRecordLatency( + entry, *pointer_id, event_timestamps) || + !RuntimeEnabledFeatures::InteractionIdEnabled(GetExecutionContext()); + } + return responsiveness_metrics_->SetKeyIdAndRecordLatency(entry, key_code, + event_timestamps) || !RuntimeEnabledFeatures::InteractionIdEnabled(GetExecutionContext()); } -bool WindowPerformance::SetPointerIdAndRecordLatency( - PerformanceEventTiming* entry, - PointerId pointer_id, - ResponsivenessMetrics::EventTimestamps event_timestamps) { - // TODO(npm): merge the logic on RecordTapOrClickOrDrag() with the logic - // computing interactionIds for pointer events once interactionId ships and is - // not behind a flag. - responsiveness_metrics_.RecordTapOrClickOrDrag(DomWindow(), entry->name(), - event_timestamps); - if (!RuntimeEnabledFeatures::InteractionIdEnabled(GetExecutionContext())) { - return true; - } - auto event_type = entry->name(); - if (event_type == event_type_names::kPointercancel && - pointer_id_pointer_down_map_.Contains(pointer_id)) { - // Flush the pointer down entry. - NotifyAndAddEventTimingBuffer(pointer_id_pointer_down_map_.at(pointer_id)); - // The pointer id of the pointerdown is no longer needed. - pointer_id_pointer_down_map_.erase(pointer_id); - } else if (event_type == event_type_names::kPointerdown) { - if (pointer_id_pointer_down_map_.Contains(pointer_id)) { - NotifyAndAddEventTimingBuffer( - pointer_id_pointer_down_map_.at(pointer_id)); - } - pointer_id_pointer_down_map_.Set(pointer_id, entry); - // Waiting to see if we get a pointercancel or pointerup. - return false; - } else if (event_type == event_type_names::kPointerup && - pointer_id_pointer_down_map_.Contains(pointer_id)) { - PerformanceEventTiming* pointer_down_entry = - pointer_id_pointer_down_map_.at(pointer_id); - // Generate a new interaction id. - UpdateInteractionId(); - pointer_down_entry->SetInteractionId(GetCurrentInteractionId()); - entry->SetInteractionId(pointer_down_entry->interactionId()); - // Flush the pointer down entry. - NotifyAndAddEventTimingBuffer(pointer_down_entry); - } else if (event_type == event_type_names::kClick && - pointer_id_pointer_down_map_.Contains(pointer_id)) { - PerformanceEventTiming* pointer_down_entry = - pointer_id_pointer_down_map_.at(pointer_id); - entry->SetInteractionId(pointer_down_entry->interactionId()); - // The pointer id of the pointerdown is no longer needed. - pointer_id_pointer_down_map_.erase(pointer_id); - } - return true; -} - -bool WindowPerformance::SetKeyIdAndRecordLatency( - PerformanceEventTiming* entry, - absl::optional<int> key_code, - ResponsivenessMetrics::EventTimestamps event_timestamps) { - auto event_type = entry->name(); - if (event_type == event_type_names::kKeydown) { - DCHECK(key_code.has_value()); - // During compositions, we ignore keydowns/keyups and look at input events. - if (composition_started_) - return true; - - if (key_code_entry_map_.Contains(*key_code)) { - auto* previous_entry = key_code_entry_map_.at(*key_code); - // Ignore repeat IME keydowns. See - // https://w3c.github.io/uievents/#determine-keydown-keyup-keyCode. - // Reasoning: we cannot ignore all IME keydowns because on Android in some - // languages the events received are 'keydown', 'input', 'keyup', and - // since we are not composing then the 'input' event is ignored, so we - // must consider the key events with 229 keyCode as the user interaction. - // Besides this, we cannot consider repeat 229 keydowns because we may get - // those on ChromeOS when we should ignore them. This may be related to - // crbug.com/1252856. - if (*key_code != 229) { - // Generate a new interaction id for |previous_entry|. This case could - // be caused by keeping a key pressed for a while. - UpdateInteractionId(); - previous_entry->GetEntry()->SetInteractionId(GetCurrentInteractionId()); - responsiveness_metrics_.RecordKeyboardInteractions( - DomWindow(), {previous_entry->GetTimeStamps()}); - } - MaybeNotifyInteractionAndAddEventTimingBuffer(previous_entry->GetEntry()); - } - key_code_entry_map_.Set( - *key_code, KeyboardEntryAndTimestamps::Create(entry, event_timestamps)); - // Similar to pointerdown, we need to wait a bit before knowing the - // interactionId of keydowns. - return false; - } else if (event_type == event_type_names::kKeyup) { - DCHECK(key_code.has_value()); - if (composition_started_ || !key_code_entry_map_.Contains(*key_code)) - return true; - - auto* previous_entry = key_code_entry_map_.at(*key_code); - // Generate a new interaction id for the keydown-keyup pair. - UpdateInteractionId(); - previous_entry->GetEntry()->SetInteractionId(GetCurrentInteractionId()); - MaybeNotifyInteractionAndAddEventTimingBuffer(previous_entry->GetEntry()); - key_code_entry_map_.erase(*key_code); - entry->SetInteractionId(GetCurrentInteractionId()); - responsiveness_metrics_.RecordKeyboardInteractions( - DomWindow(), {previous_entry->GetTimeStamps(), event_timestamps}); - } else if (event_type == event_type_names::kCompositionstart) { - composition_started_ = true; - for (auto key_entry : key_code_entry_map_.Values()) { - MaybeNotifyInteractionAndAddEventTimingBuffer(key_entry->GetEntry()); - } - key_code_entry_map_.clear(); - } else if (event_type == event_type_names::kCompositionend) { - composition_started_ = false; - } else if (event_type == event_type_names::kInput) { - if (!composition_started_) { - return true; - } - // We are in the case of a text input event while compositing with - // non-trivial data, so we want to increase interactionId. - // TODO(crbug.com/1252856): fix counts in ChromeOS due to duplicate events. - UpdateInteractionId(); - entry->SetInteractionId(GetCurrentInteractionId()); - responsiveness_metrics_.RecordKeyboardInteractions(DomWindow(), - {event_timestamps}); - } - return true; -} - void WindowPerformance::AddElementTiming(const AtomicString& name, const String& url, const FloatRect& rect, @@ -822,8 +657,8 @@ ++frame_index_; } -void WindowPerformance::NotifyPotentialDrag() { - responsiveness_metrics_.NotifyPotentialDrag(); +void WindowPerformance::NotifyPotentialDrag(PointerId pointer_id) { + responsiveness_metrics_->NotifyPotentialDrag(pointer_id); } } // namespace blink
diff --git a/third_party/blink/renderer/core/timing/window_performance.h b/third_party/blink/renderer/core/timing/window_performance.h index 62a13455..4362b11 100644 --- a/third_party/blink/renderer/core/timing/window_performance.h +++ b/third_party/blink/renderer/core/timing/window_performance.h
@@ -32,7 +32,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_WINDOW_PERFORMANCE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_WINDOW_PERFORMANCE_H_ -#include "base/rand_util.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/events/pointer_event.h" @@ -58,6 +57,7 @@ public ExecutionContextClient, public PageVisibilityObserver { friend class WindowPerformanceTest; + friend class ResponsivenessMetrics; class EventData : public GarbageCollected<EventData> { public: @@ -156,10 +156,10 @@ void Trace(Visitor*) const override; ResponsivenessMetrics& GetResponsivenessMetrics() { - return responsiveness_metrics_; + return *responsiveness_metrics_; } - void NotifyPotentialDrag(); + void NotifyPotentialDrag(PointerId pointer_id); void SetCurrentEventTimingEvent(const Event* event) { current_event_ = event; @@ -199,24 +199,6 @@ absl::optional<PointerId> pointer_id, ResponsivenessMetrics::EventTimestamps event_timestamps); - // Assigns an interactionId and records interaction latency for pointer - // events. Returns true if the entry is ready to be surfaced in - // PerformanceObservers and the Performance Timeline. - bool SetPointerIdAndRecordLatency( - PerformanceEventTiming* entry, - PointerId pointer_id, - ResponsivenessMetrics::EventTimestamps event_timestamps); - - // Assigns interactionId and records interaction latency for keyboard events. - // We care about input, compositionstart, and compositionend events, so - // |key_code| will be absl::nullopt in those cases. Returns true if the entry - // would be ready to be surfaced in PerformanceObservers and the Performance - // Timeline. - bool SetKeyIdAndRecordLatency( - PerformanceEventTiming* entry, - absl::optional<int> key_code, - ResponsivenessMetrics::EventTimestamps event_timestamps); - // Notify observer that an event timing entry is ready and add it to the event // timing buffer if needed. void NotifyAndAddEventTimingBuffer(PerformanceEventTiming* entry); @@ -225,9 +207,6 @@ void MaybeNotifyInteractionAndAddEventTimingBuffer( PerformanceEventTiming* entry); - void UpdateInteractionId(); - - uint32_t GetCurrentInteractionId() const; // The last time the page visibility was changed. base::TimeTicks last_visibility_change_timestamp_; @@ -251,58 +230,9 @@ absl::optional<base::TimeDelta> pending_pointer_down_time_to_next_paint_; // Calculate responsiveness metrics and record UKM for them. - ResponsivenessMetrics responsiveness_metrics_; + Member<ResponsivenessMetrics> responsiveness_metrics_; // The event we are currently processing. WeakMember<const Event> current_event_; - - // Wrapper class to store keyboard PerformanceEventTiming and other entry data - // on a HeapHashMap. - class KeyboardEntryAndTimestamps - : public GarbageCollected<KeyboardEntryAndTimestamps> { - public: - KeyboardEntryAndTimestamps( - PerformanceEventTiming* entry, - ResponsivenessMetrics::EventTimestamps timestamps) - : entry_(entry), timestamps_(timestamps) {} - - static KeyboardEntryAndTimestamps* Create( - PerformanceEventTiming* entry, - ResponsivenessMetrics::EventTimestamps timestamps) { - return MakeGarbageCollected<KeyboardEntryAndTimestamps>(entry, - timestamps); - } - ~KeyboardEntryAndTimestamps() = default; - void Trace(Visitor*) const; - PerformanceEventTiming* GetEntry() const { return entry_; } - ResponsivenessMetrics::EventTimestamps GetTimeStamps() const { - return timestamps_; - } - - private: - // Event PerformanceEventTiming entry that has not been sent to observers - // yet: the event dispatch has been completed but the presentation promise - // used to determine |duration| has not yet been resolved. - Member<PerformanceEventTiming> entry_; - // ResponsivenessMetrics::EventTimestamps - ResponsivenessMetrics::EventTimestamps timestamps_; - }; - - // Map used to map keyCodes to interactionId values. - HeapHashMap<int, - Member<KeyboardEntryAndTimestamps>, - WTF::IntHash<int>, - WTF::UnsignedWithZeroKeyHashTraits<int>> - key_code_entry_map_; - // Whether we are composing or not. When we are not composing, we set - // interactionId for keydown and keyup events. When we are composing, we set - // interactionId for input events. - bool composition_started_ = false; - HeapHashMap<PointerId, - Member<PerformanceEventTiming>, - WTF::IntHash<PointerId>, - WTF::UnsignedWithZeroKeyHashTraits<PointerId>> - pointer_id_pointer_down_map_; - uint32_t current_interaction_id_for_event_timing_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/timing/window_performance_test.cc b/third_party/blink/renderer/core/timing/window_performance_test.cc index 7b0254e..9c9fb4ec 100644 --- a/third_party/blink/renderer/core/timing/window_performance_test.cc +++ b/third_party/blink/renderer/core/timing/window_performance_test.cc
@@ -755,7 +755,7 @@ pointer_id); SimulateSwapPromise(swap_time_pointerdown); // Notify drag. - performance_->NotifyPotentialDrag(); + performance_->NotifyPotentialDrag(pointer_id); // Pointerup base::TimeTicks pointerup_timestamp = GetTimeStamp(3); base::TimeTicks processing_start_pointerup = GetTimeStamp(5); @@ -855,80 +855,6 @@ EXPECT_EQ(0u, entries.size()); } -// For multi-touch, we only record the innermost pair of pointerdown and -// pointerup. -// TODO(hbsong): Record each touch by pointer_id separately. -TEST_F(WindowPerformanceTest, MultiTouch) { - // First Pointerdown - base::TimeTicks pointerdown_timestamp = GetTimeOrigin(); - base::TimeTicks processing_start_pointerdown = GetTimeStamp(1); - base::TimeTicks processing_end_pointerdown = GetTimeStamp(2); - base::TimeTicks swap_time_pointerdown = GetTimeStamp(5); - PointerId pointer_id_1 = 4; - RegisterPointerEvent("pointerdown", pointerdown_timestamp, - processing_start_pointerdown, processing_end_pointerdown, - pointer_id_1); - SimulateSwapPromise(swap_time_pointerdown); - // Second Pointerdown - pointerdown_timestamp = GetTimeOrigin(); - processing_start_pointerdown = GetTimeStamp(1); - processing_end_pointerdown = GetTimeStamp(2); - swap_time_pointerdown = GetTimeStamp(6); - PointerId pointer_id_2 = 6; - RegisterPointerEvent("pointerdown", pointerdown_timestamp, - processing_start_pointerdown, processing_end_pointerdown, - pointer_id_2); - SimulateSwapPromise(swap_time_pointerdown); - - // First Pointerup - base::TimeTicks pointerup_timestamp = GetTimeStamp(3); - base::TimeTicks processing_start_pointerup = GetTimeStamp(5); - base::TimeTicks processing_end_pointerup = GetTimeStamp(6); - base::TimeTicks swap_time_pointerup = GetTimeStamp(9); - RegisterPointerEvent("pointerup", pointerup_timestamp, - processing_start_pointerup, processing_end_pointerup, - pointer_id_2); - SimulateSwapPromise(swap_time_pointerup); - - // Second Pointerup - pointerup_timestamp = GetTimeStamp(5); - processing_start_pointerup = GetTimeStamp(6); - processing_end_pointerup = GetTimeStamp(7); - swap_time_pointerup = GetTimeStamp(13); - RegisterPointerEvent("pointerup", pointerup_timestamp, - processing_start_pointerup, processing_end_pointerup, - pointer_id_1); - SimulateSwapPromise(swap_time_pointerup); - - // Click - base::TimeTicks click_timestamp = GetTimeStamp(13); - base::TimeTicks processing_start_click = GetTimeStamp(15); - base::TimeTicks processing_end_click = GetTimeStamp(16); - base::TimeTicks swap_time_click = GetTimeStamp(20); - RegisterPointerEvent("click", click_timestamp, processing_start_click, - processing_end_click, pointer_id_2); - SimulateSwapPromise(swap_time_click); - - // Flush UKM logging mojo request. - RunPendingTasks(); - - // Check UKM recording. - auto entries = GetUkmRecorder()->GetEntriesByName( - ukm::builders::Responsiveness_UserInteraction::kEntryName); - EXPECT_EQ(1u, entries.size()); - const ukm::mojom::UkmEntry* entry = entries[0]; - GetUkmRecorder()->ExpectEntryMetric( - entry, - ukm::builders::Responsiveness_UserInteraction::kMaxEventDurationName, 7); - GetUkmRecorder()->ExpectEntryMetric( - entry, - ukm::builders::Responsiveness_UserInteraction::kTotalEventDurationName, - 16); - GetUkmRecorder()->ExpectEntryMetric( - entry, - ukm::builders::Responsiveness_UserInteraction::kInteractionTypeName, 1); -} - TEST_F(WindowPerformanceTest, ElementTimingTraceEvent) { using trace_analyzer::Query; trace_analyzer::Start("*"); @@ -986,32 +912,34 @@ EXPECT_GT(keydown_entry->interactionId(), 0u); // Tap or Click with max duration 70, total duration 90. + PointerId pointer_id_1 = 10; PerformanceEventTiming* pointerdown_entry = CreatePerformanceEventTiming(event_type_names::kPointerdown); - SimulateInteractionId(pointerdown_entry, absl::nullopt, 10, GetTimeStamp(100), - GetTimeStamp(120)); + SimulateInteractionId(pointerdown_entry, absl::nullopt, pointer_id_1, + GetTimeStamp(100), GetTimeStamp(120)); PerformanceEventTiming* pointerup_entry = CreatePerformanceEventTiming(event_type_names::kPointerup); - SimulateInteractionId(pointerup_entry, absl::nullopt, 10, GetTimeStamp(130), - GetTimeStamp(150)); + SimulateInteractionId(pointerup_entry, absl::nullopt, pointer_id_1, + GetTimeStamp(130), GetTimeStamp(150)); PerformanceEventTiming* click_entry = CreatePerformanceEventTiming(event_type_names::kClick); - SimulateInteractionId(click_entry, absl::nullopt, 10, GetTimeStamp(130), - GetTimeStamp(200)); + SimulateInteractionId(click_entry, absl::nullopt, pointer_id_1, + GetTimeStamp(130), GetTimeStamp(200)); EXPECT_GT(pointerdown_entry->interactionId(), 0u); EXPECT_EQ(pointerdown_entry->interactionId(), pointerup_entry->interactionId()); EXPECT_EQ(pointerup_entry->interactionId(), click_entry->interactionId()); // Drag with max duration 50, total duration 80. + PointerId pointer_id_2 = 20; pointerdown_entry = CreatePerformanceEventTiming(event_type_names::kPointerdown); - SimulateInteractionId(pointerdown_entry, absl::nullopt, 20, GetTimeStamp(150), - GetTimeStamp(200)); - performance_->NotifyPotentialDrag(); + SimulateInteractionId(pointerdown_entry, absl::nullopt, pointer_id_2, + GetTimeStamp(150), GetTimeStamp(200)); + performance_->NotifyPotentialDrag(20); pointerup_entry = CreatePerformanceEventTiming(event_type_names::kPointerup); - SimulateInteractionId(pointerup_entry, absl::nullopt, 20, GetTimeStamp(200), - GetTimeStamp(230)); + SimulateInteractionId(pointerup_entry, absl::nullopt, pointer_id_2, + GetTimeStamp(200), GetTimeStamp(230)); EXPECT_GT(pointerdown_entry->interactionId(), 0u); EXPECT_EQ(pointerdown_entry->interactionId(), pointerup_entry->interactionId()); @@ -1019,11 +947,11 @@ // Scroll should not be reported in ukm. pointerdown_entry = CreatePerformanceEventTiming(event_type_names::kPointerdown); - SimulateInteractionId(pointerdown_entry, absl::nullopt, 5, GetTimeStamp(300), - GetTimeStamp(315)); + SimulateInteractionId(pointerdown_entry, absl::nullopt, pointer_id_2, + GetTimeStamp(300), GetTimeStamp(315)); PerformanceEventTiming* pointercancel_entry = CreatePerformanceEventTiming(event_type_names::kPointercancel); - SimulateInteractionId(pointercancel_entry, absl::nullopt, 5, + SimulateInteractionId(pointercancel_entry, absl::nullopt, pointer_id_2, GetTimeStamp(310), GetTimeStamp(330)); EXPECT_EQ(pointerdown_entry->interactionId(), 0u); EXPECT_EQ(pointercancel_entry->interactionId(), 0u); @@ -1362,4 +1290,91 @@ {43, 70, UserInteractionType::kKeyboard}}); } +TEST_F(InteractionIdTest, TapWithoutClick) { + std::vector<EventForInteraction> events = { + {event_type_names::kPointerdown, absl::nullopt, 1, GetTimeStamp(100), + GetTimeStamp(140)}, + {event_type_names::kPointerup, absl::nullopt, 1, GetTimeStamp(120), + GetTimeStamp(150)}}; + std::vector<uint32_t> ids = SimulateInteractionIds(events); + EXPECT_GT(ids[0], 0u) << "Nonzero interaction id"; + EXPECT_EQ(ids[0], ids[1]) + << "Pointerdown and pointerup have same interaction id"; + // No UKM value, since we are waiting for click. + RunPendingTasks(); + auto entries = GetUkmRecorder()->GetEntriesByName( + ukm::builders::Responsiveness_UserInteraction::kEntryName); + EXPECT_EQ(entries.size(), 0u); + + // After a wait, we should see the UKM. + test::RunDelayedTasks(base::Seconds(1)); + CheckUKMValues({{40, 50, UserInteractionType::kTapOrClick}}); +} + +TEST_F(InteractionIdTest, PointerupClick) { + std::vector<EventForInteraction> events = { + {event_type_names::kPointerup, absl::nullopt, 1, GetTimeStamp(100), + GetTimeStamp(140)}, + {event_type_names::kClick, absl::nullopt, 1, GetTimeStamp(120), + GetTimeStamp(150)}}; + std::vector<uint32_t> ids = SimulateInteractionIds(events); + EXPECT_GT(ids[0], 0u) << "Nonzero interaction id"; + EXPECT_EQ(ids[0], ids[1]) << "Pointerup and click have same interaction id"; + // Flush UKM logging mojo request. + RunPendingTasks(); + CheckUKMValues({{40, 50, UserInteractionType::kTapOrClick}}); +} + +TEST_F(InteractionIdTest, JustClick) { + // Hitting enter on a keyboard may cause just a trusted click event. + std::vector<EventForInteraction> events = { + {event_type_names::kClick, absl::nullopt, -1, GetTimeStamp(120), + GetTimeStamp(150)}}; + std::vector<uint32_t> ids = SimulateInteractionIds(events); + EXPECT_GT(ids[0], 0u) << "Nonzero interaction id"; + // Flush UKM logging mojo request. + RunPendingTasks(); + CheckUKMValues({{30, 30, UserInteractionType::kTapOrClick}}); +} + +TEST_F(InteractionIdTest, PointerdownClick) { + // Contextmenus may cause us to only see pointerdown and click (no pointerup). + std::vector<EventForInteraction> events = { + {event_type_names::kPointerdown, absl::nullopt, 1, GetTimeStamp(100), + GetTimeStamp(140)}, + {event_type_names::kClick, absl::nullopt, 1, GetTimeStamp(120), + GetTimeStamp(150)}}; + std::vector<uint32_t> ids = SimulateInteractionIds(events); + EXPECT_GT(ids[0], 0u) << "Nonzero interaction id"; + EXPECT_EQ(ids[0], ids[1]) << "Pointerdown and click have same interaction id"; + // Flush UKM logging mojo request. + RunPendingTasks(); + CheckUKMValues({{40, 50, UserInteractionType::kTapOrClick}}); +} + +TEST_F(InteractionIdTest, MultiTouch) { + // In multitouch, we report an interaction per pointerId. We do not see + // clicks. + std::vector<EventForInteraction> events = { + {event_type_names::kPointerdown, absl::nullopt, 1, GetTimeStamp(100), + GetTimeStamp(110)}, + {event_type_names::kPointerdown, absl::nullopt, 2, GetTimeStamp(120), + GetTimeStamp(140)}, + {event_type_names::kPointerup, absl::nullopt, 2, GetTimeStamp(200), + GetTimeStamp(230)}, + {event_type_names::kPointerup, absl::nullopt, 1, GetTimeStamp(200), + GetTimeStamp(250)}}; + std::vector<uint32_t> ids = SimulateInteractionIds(events); + for (uint32_t id : ids) { + EXPECT_GT(id, 0u); + } + // Interaction ids should match by PointerId. + EXPECT_EQ(ids[0], ids[3]); + EXPECT_EQ(ids[1], ids[2]); + // After a wait, flush UKM logging mojo request. + test::RunDelayedTasks(base::Seconds(1)); + CheckUKMValues({{50, 60, UserInteractionType::kTapOrClick}, + {30, 50, UserInteractionType::kTapOrClick}}); +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc index ef7052d..6dc1434c 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
@@ -13,6 +13,7 @@ #include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h" #include "third_party/blink/public/platform/modules/remoteplayback/web_remote_playback_client.h" #include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_pointer_event_init.h" #include "third_party/blink/renderer/core/css/css_property_value_set.h" #include "third_party/blink/renderer/core/css/document_style_environment_variables.h" #include "third_party/blink/renderer/core/css/style_engine.h" @@ -334,6 +335,11 @@ return true; } + PointerEvent* CreatePointerEvent(const AtomicString& name) { + PointerEventInit* init = PointerEventInit::Create(); + return PointerEvent::Create(name, init); + } + private: Persistent<MediaControlsImpl> media_controls_; HistogramTester histogram_tester_; @@ -970,7 +976,7 @@ MediaControls().DispatchEvent(*Event::Create("focusin")); MediaControls().MediaElement().SetFocused(true, mojom::blink::FocusType::kNone); - MediaControls().DispatchEvent(*Event::Create("pointermove")); + MediaControls().DispatchEvent(*CreatePointerEvent("pointermove")); // Controls should remain visible platform()->RunForPeriodSeconds(2); @@ -1021,7 +1027,7 @@ // If the mouse moves, the controls are shown and the cursor is no longer // hidden. - MediaControls().DispatchEvent(*Event::Create("pointermove")); + MediaControls().DispatchEvent(*CreatePointerEvent("pointermove")); EXPECT_FALSE(IsCursorHidden()); // Once the controls hide again, the cursor is hidden again. @@ -1282,9 +1288,11 @@ SimulateHideMediaControlsTimerFired(); EXPECT_FALSE(IsElementVisible(*cast_overlay_button)); - for (auto* const event_name : + for (const AtomicString event_name : {"gesturetap", "click", "pointerover", "pointermove"}) { - overlay_enclosure->DispatchEvent(*Event::Create(event_name)); + overlay_enclosure->DispatchEvent(event_name == "gesturetap" + ? *Event::Create(event_name) + : *CreatePointerEvent(event_name)); EXPECT_TRUE(IsElementVisible(*cast_overlay_button)); SimulateHideMediaControlsTimerFired();
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_audio_worklet_thread.cc b/third_party/blink/renderer/modules/webaudio/realtime_audio_worklet_thread.cc index 8b7afe0..ec8a1a7 100644 --- a/third_party/blink/renderer/modules/webaudio/realtime_audio_worklet_thread.cc +++ b/third_party/blink/renderer/modules/webaudio/realtime_audio_worklet_thread.cc
@@ -26,7 +26,8 @@ ThreadCreationParams params = ThreadCreationParams(ThreadType::kRealtimeAudioWorkletThread); - // Use a higher priority thread only when it is allowed by Finch. + // The real-time priority thread is enabled by default. A normal priority + // thread is used when it is blocked by a field trial. if (base::FeatureList::IsEnabled( features::kAudioWorkletThreadRealtimePriority)) { // TODO(crbug.com/1022888): The worklet thread priority is always NORMAL on
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc b/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc index 3315b24..41f7bb4 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc +++ b/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc
@@ -264,9 +264,8 @@ V8TestingScope scope; auto context_provider_wrapper = SharedGpuContext::ContextProviderWrapper(); - CanvasResourceParams resource_params; auto resource_provider = CanvasResourceProvider::CreateSharedImageProvider( - IntSize(100, 100), cc::PaintFlags::FilterQuality::kLow, resource_params, + SkImageInfo::MakeN32Premul(100, 100), cc::PaintFlags::FilterQuality::kLow, CanvasResourceProvider::ShouldInitialize::kNo, context_provider_wrapper, RasterMode::kGPU, true /*is_origin_top_left*/, 0u /*shared_image_usage_flags*/);
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc index 3a9976e..63be15f9 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -6074,7 +6074,7 @@ // TODO(crbug.com/1175907): Double check that the premultiply alpha settings // are all correct below. When we go through the CanvasResourceProvider for - // Image creation, CanvasResourceParams { kPremul_SkAlphaType } is used. + // Image creation, SkImageInfo { kPremul_SkAlphaType } is used. // // We probably need some stronger checks on the accelerated upload path if // unmultiply has been requested or we need to never premultiply for Image @@ -8697,7 +8697,8 @@ } else { // TODO(fserb): why is this a BITMAP? temp = CanvasResourceProvider::CreateBitmapProvider( - size, cc::PaintFlags::FilterQuality::kLow, CanvasResourceParams(), + SkImageInfo::MakeN32Premul(size.width(), size.height()), + cc::PaintFlags::FilterQuality::kLow, CanvasResourceProvider::ShouldInitialize::kNo); // TODO: should this // use the canvas's }
diff --git a/third_party/blink/renderer/platform/bindings/parkable_string.cc b/third_party/blink/renderer/platform/bindings/parkable_string.cc index 03736c57..0ccf433 100644 --- a/third_party/blink/renderer/platform/bindings/parkable_string.cc +++ b/third_party/blink/renderer/platform/bindings/parkable_string.cc
@@ -565,6 +565,7 @@ auto& manager = ParkableStringManager::Instance(); if (is_on_disk()) { + TRACE_EVENT("blink", "ParkableStringImpl::ReadFromDisk"); base::ElapsedTimer disk_read_timer; DCHECK(has_on_disk_data()); metadata_->compressed_ = std::make_unique<Vector<uint8_t>>(); @@ -579,6 +580,7 @@ manager.RecordDiskReadTime(elapsed); } + TRACE_EVENT("blink", "ParkableStringImpl::Decompress"); base::StringPiece compressed_string_piece( reinterpret_cast<const char*>(metadata_->compressed_->data()), metadata_->compressed_->size() * sizeof(uint8_t));
diff --git a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc index cba921b92..dab99b2 100644 --- a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc +++ b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
@@ -8,6 +8,7 @@ #include <utility> #include "components/viz/common/resources/release_callback.h" +#include "components/viz/common/resources/resource_format_utils.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/client/raster_interface.h" @@ -302,8 +303,8 @@ GrGLTextureInfo texture_info; texture_info.fTarget = texture_target_; texture_info.fID = shared_context_texture_id; - texture_info.fFormat = - CanvasResourceParams(sk_image_info_).GLSizedInternalFormat(); + texture_info.fFormat = viz::TextureStorageFormat( + viz::SkColorTypeToResourceFormat(sk_image_info_.colorType())); GrBackendTexture backend_texture(sk_image_info_.width(), sk_image_info_.height(), GrMipMapped::kNo, texture_info); @@ -390,16 +391,16 @@ color_type == image_info.colorType()) { return this; } - - image_info = image_info.makeColorSpace(color_space).makeColorType(color_type); + image_info = image_info.makeColorSpace(color_space) + .makeColorType(color_type) + .makeWH(Size().width(), Size().height()); auto usage_flags = ContextProviderWrapper() ->ContextProvider() ->SharedImageInterface() ->UsageForMailbox(mailbox_); auto provider = CanvasResourceProvider::CreateSharedImageProvider( - Size(), cc::PaintFlags::FilterQuality::kLow, - CanvasResourceParams(image_info), + image_info, cc::PaintFlags::FilterQuality::kLow, CanvasResourceProvider::ShouldInitialize::kNo, ContextProviderWrapper(), RasterMode::kGPU, IsOriginTopLeft(), usage_flags); if (!provider) {
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc index 70f571b90..1e47c53 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc
@@ -74,9 +74,7 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderAcceleratedOverlay) { const IntSize kSize(10, 10); - const CanvasResourceParams kColorParams( - CanvasColorSpace::kSRGB, kN32_SkColorType, kPremul_SkAlphaType); - const SkImageInfo kInfo = kColorParams.MakeSkImageInfo(kSize); + const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10); const uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT | @@ -93,16 +91,15 @@ EXPECT_TRUE(provider->IsAccelerated()); EXPECT_TRUE(provider->SupportsDirectCompositing()); EXPECT_TRUE(provider->SupportsSingleBuffering()); - EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace()); // As it is an CanvasResourceProviderSharedImage and an accelerated canvas, it // will internally force it to RGBA8, or BGRA8 on MacOS #if defined(OS_MAC) - EXPECT_EQ(provider->ColorParams().GetSkColorType(), kBGRA_8888_SkColorType); + EXPECT_TRUE(provider->GetSkImageInfo() == + kInfo.makeColorType(kBGRA_8888_SkColorType)); #else - EXPECT_EQ(provider->ColorParams().GetSkColorType(), kRGBA_8888_SkColorType); + EXPECT_TRUE(provider->GetSkImageInfo() == + kInfo.makeColorType(kRGBA_8888_SkColorType)); #endif - EXPECT_EQ(provider->ColorParams().GetSkAlphaType(), - kColorParams.GetSkAlphaType()); EXPECT_FALSE(provider->IsSingleBuffered()); provider->TryEnableSingleBuffering(); @@ -111,9 +108,7 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderTexture) { const IntSize kSize(10, 10); - const CanvasResourceParams kColorParams( - CanvasColorSpace::kSRGB, kN32_SkColorType, kPremul_SkAlphaType); - const SkImageInfo kInfo = kColorParams.MakeSkImageInfo(kSize); + const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10); auto provider = CanvasResourceProvider::CreateSharedImageProvider( kInfo, cc::PaintFlags::FilterQuality::kLow, @@ -126,21 +121,17 @@ EXPECT_TRUE(provider->IsAccelerated()); EXPECT_TRUE(provider->SupportsDirectCompositing()); EXPECT_FALSE(provider->SupportsSingleBuffering()); - EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace()); // As it is an CanvasResourceProviderSharedImage and an accelerated canvas, it // will internally force it to kRGBA8 - EXPECT_EQ(provider->ColorParams().GetSkColorType(), kRGBA_8888_SkColorType); - EXPECT_EQ(provider->ColorParams().GetSkAlphaType(), - kColorParams.GetSkAlphaType()); + EXPECT_EQ(provider->GetSkImageInfo(), + kInfo.makeColorType(kRGBA_8888_SkColorType)); EXPECT_FALSE(provider->IsSingleBuffered()); } TEST_F(CanvasResourceProviderTest, CanvasResourceProviderUnacceleratedOverlay) { const IntSize kSize(10, 10); - const CanvasResourceParams kColorParams( - CanvasColorSpace::kSRGB, kN32_SkColorType, kPremul_SkAlphaType); - const SkImageInfo kInfo = kColorParams.MakeSkImageInfo(kSize); + const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10); const uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT; @@ -159,11 +150,7 @@ // We do not support single buffering for unaccelerated low latency canvas. EXPECT_FALSE(provider->SupportsSingleBuffering()); - EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace()); - EXPECT_EQ(provider->ColorParams().GetSkColorType(), - kColorParams.GetSkColorType()); - EXPECT_EQ(provider->ColorParams().GetSkAlphaType(), - kColorParams.GetSkAlphaType()); + EXPECT_EQ(provider->GetSkImageInfo(), kInfo); EXPECT_FALSE(provider->IsSingleBuffered()); } @@ -171,9 +158,7 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderSharedImageResourceRecycling) { const IntSize kSize(10, 10); - const CanvasResourceParams kColorParams( - CanvasColorSpace::kSRGB, kN32_SkColorType, kPremul_SkAlphaType); - const SkImageInfo kInfo = kColorParams.MakeSkImageInfo(kSize); + const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10); const uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT; @@ -189,16 +174,15 @@ EXPECT_TRUE(provider->IsAccelerated()); EXPECT_FALSE(provider->IsSingleBuffered()); EXPECT_FALSE(provider->SupportsSingleBuffering()); - EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace()); // As it is an CanvasResourceProviderSharedImage and an accelerated canvas, it // will internally force it to RGBA8, or BGRA8 on MacOS #if defined(OS_MAC) - EXPECT_EQ(provider->ColorParams().GetSkColorType(), kBGRA_8888_SkColorType); + EXPECT_TRUE(provider->GetSkImageInfo() == + kInfo.makeColorType(kBGRA_8888_SkColorType)); #else - EXPECT_EQ(provider->ColorParams().GetSkColorType(), kRGBA_8888_SkColorType); + EXPECT_TRUE(provider->GetSkImageInfo() == + kInfo.makeColorType(kRGBA_8888_SkColorType)); #endif - EXPECT_EQ(provider->ColorParams().GetSkAlphaType(), - kColorParams.GetSkAlphaType()); // Same resource and sync token if we query again without updating. auto resource = provider->ProduceCanvasResource(); @@ -230,10 +214,7 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderSharedImageStaticBitmapImage) { - const IntSize kSize(10, 10); - const CanvasResourceParams kColorParams( - CanvasColorSpace::kSRGB, kN32_SkColorType, kPremul_SkAlphaType); - const SkImageInfo kInfo = kColorParams.MakeSkImageInfo(kSize); + const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10); const uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT; @@ -279,10 +260,7 @@ caps.disable_2d_canvas_copy_on_write = true; fake_context->SetCapabilities(caps); - const IntSize kSize(10, 10); - const CanvasResourceParams kColorParams( - CanvasColorSpace::kSRGB, kN32_SkColorType, kPremul_SkAlphaType); - const SkImageInfo kInfo = kColorParams.MakeSkImageInfo(kSize); + const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10); const uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT; @@ -304,9 +282,7 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderBitmap) { const IntSize kSize(10, 10); - const CanvasResourceParams kColorParams( - CanvasColorSpace::kSRGB, kN32_SkColorType, kPremul_SkAlphaType); - const SkImageInfo kInfo = kColorParams.MakeSkImageInfo(kSize); + const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10); auto provider = CanvasResourceProvider::CreateBitmapProvider( kInfo, cc::PaintFlags::FilterQuality::kLow, @@ -317,20 +293,14 @@ EXPECT_FALSE(provider->IsAccelerated()); EXPECT_FALSE(provider->SupportsDirectCompositing()); EXPECT_FALSE(provider->SupportsSingleBuffering()); - EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace()); - EXPECT_EQ(provider->ColorParams().GetSkColorType(), - kColorParams.GetSkColorType()); - EXPECT_EQ(provider->ColorParams().GetSkAlphaType(), - kColorParams.GetSkAlphaType()); + EXPECT_TRUE(provider->GetSkImageInfo() == kInfo); EXPECT_FALSE(provider->IsSingleBuffered()); } TEST_F(CanvasResourceProviderTest, CanvasResourceProviderSharedBitmap) { const IntSize kSize(10, 10); - const CanvasResourceParams kColorParams( - CanvasColorSpace::kSRGB, kN32_SkColorType, kPremul_SkAlphaType); - const SkImageInfo kInfo = kColorParams.MakeSkImageInfo(kSize); + const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10); MockCanvasResourceDispatcherClient client; CanvasResourceDispatcher resource_dispatcher( @@ -347,11 +317,7 @@ EXPECT_FALSE(provider->IsAccelerated()); EXPECT_TRUE(provider->SupportsDirectCompositing()); EXPECT_FALSE(provider->SupportsSingleBuffering()); - EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace()); - EXPECT_EQ(provider->ColorParams().GetSkColorType(), - kColorParams.GetSkColorType()); - EXPECT_EQ(provider->ColorParams().GetSkAlphaType(), - kColorParams.GetSkAlphaType()); + EXPECT_TRUE(provider->GetSkImageInfo() == kInfo); EXPECT_FALSE(provider->IsSingleBuffered()); provider->TryEnableSingleBuffering(); @@ -361,9 +327,7 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect2DGpuMemoryBuffer) { const IntSize kSize(10, 10); - const CanvasResourceParams kColorParams( - CanvasColorSpace::kSRGB, kN32_SkColorType, kPremul_SkAlphaType); - const SkImageInfo kInfo = kColorParams.MakeSkImageInfo(kSize); + const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10); const uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT | @@ -380,16 +344,15 @@ EXPECT_TRUE(provider->IsAccelerated()); EXPECT_TRUE(provider->SupportsDirectCompositing()); EXPECT_TRUE(provider->SupportsSingleBuffering()); - EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace()); // As it is an CanvasResourceProviderSharedImage and an accelerated canvas, it // will internally force it to RGBA8, or BGRA8 on MacOS #if defined(OS_MAC) - EXPECT_EQ(provider->ColorParams().GetSkColorType(), kBGRA_8888_SkColorType); + EXPECT_TRUE(provider->GetSkImageInfo() == + kInfo.makeColorType(kBGRA_8888_SkColorType)); #else - EXPECT_EQ(provider->ColorParams().GetSkColorType(), kRGBA_8888_SkColorType); + EXPECT_TRUE(provider->GetSkImageInfo() == + kInfo.makeColorType(kRGBA_8888_SkColorType)); #endif - EXPECT_EQ(provider->ColorParams().GetSkAlphaType(), - kColorParams.GetSkAlphaType()); EXPECT_FALSE(provider->IsSingleBuffered()); provider->TryEnableSingleBuffering(); @@ -399,9 +362,7 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect3DGpuMemoryBuffer) { const IntSize kSize(10, 10); - const CanvasResourceParams kColorParams( - CanvasColorSpace::kSRGB, kN32_SkColorType, kPremul_SkAlphaType); - const SkImageInfo kInfo = kColorParams.MakeSkImageInfo(kSize); + const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10); auto provider = CanvasResourceProvider::CreatePassThroughProvider( kInfo, cc::PaintFlags::FilterQuality::kLow, context_provider_wrapper_, @@ -412,11 +373,7 @@ EXPECT_TRUE(provider->IsAccelerated()); EXPECT_TRUE(provider->SupportsDirectCompositing()); EXPECT_TRUE(provider->SupportsSingleBuffering()); - EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace()); - EXPECT_EQ(provider->ColorParams().GetSkColorType(), - kColorParams.GetSkColorType()); - EXPECT_EQ(provider->ColorParams().GetSkAlphaType(), - kColorParams.GetSkAlphaType()); + EXPECT_TRUE(provider->GetSkImageInfo() == kInfo); EXPECT_FALSE(provider->IsSingleBuffered()); provider->TryEnableSingleBuffering(); @@ -530,9 +487,7 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect2DSwapChain) { const IntSize kSize(10, 10); - const CanvasResourceParams kColorParams( - CanvasColorSpace::kSRGB, kN32_SkColorType, kPremul_SkAlphaType); - const SkImageInfo kInfo = kColorParams.MakeSkImageInfo(kSize); + const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10); auto provider = CanvasResourceProvider::CreateSwapChainProvider( kInfo, cc::PaintFlags::FilterQuality::kLow, @@ -547,18 +502,11 @@ EXPECT_TRUE(provider->SupportsDirectCompositing()); EXPECT_TRUE(provider->SupportsSingleBuffering()); EXPECT_TRUE(provider->IsSingleBuffered()); - EXPECT_EQ(provider->ColorParams().ColorSpace(), kColorParams.ColorSpace()); - EXPECT_EQ(provider->ColorParams().GetSkColorType(), - kColorParams.GetSkColorType()); - EXPECT_EQ(provider->ColorParams().GetSkAlphaType(), - kColorParams.GetSkAlphaType()); + EXPECT_EQ(provider->GetSkImageInfo(), kInfo); } TEST_F(CanvasResourceProviderTest, FlushForImage) { - const IntSize kSize(10, 10); - const CanvasResourceParams kColorParams( - CanvasColorSpace::kSRGB, kN32_SkColorType, kPremul_SkAlphaType); - const SkImageInfo kInfo = kColorParams.MakeSkImageInfo(kSize); + const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10); auto src_provider = CanvasResourceProvider::CreateSharedImageProvider( kInfo, cc::PaintFlags::FilterQuality::kMedium,
diff --git a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc index 49f7c01..2205f60 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
@@ -39,9 +39,10 @@ return source; auto paint_image = source->PaintImageForCurrentFrame(); + auto image_info = paint_image.GetSkImageInfo().makeWH( + source->Size().width(), source->Size().height()); auto provider = CanvasResourceProvider::CreateSharedImageProvider( - source->Size(), cc::PaintFlags::FilterQuality::kLow, - CanvasResourceParams(paint_image.GetSkImageInfo()), + image_info, cc::PaintFlags::FilterQuality::kLow, CanvasResourceProvider::ShouldInitialize::kNo, context_provider_wrapper, RasterMode::kGPU, source->IsOriginTopLeft(), gpu::SHARED_IMAGE_USAGE_DISPLAY);
diff --git a/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc b/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc index 36371bc1..1967fb5 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc
@@ -190,10 +190,10 @@ TEST_F(BadSharedGpuContextTest, AccelerateImageBufferSurfaceCreationFails) { // With a bad shared context, AccelerateImageBufferSurface should fail and // return a nullptr provider - IntSize size(10, 10); std::unique_ptr<CanvasResourceProvider> resource_provider = CanvasResourceProvider::CreateSharedImageProvider( - size, cc::PaintFlags::FilterQuality::kLow, CanvasResourceParams(), + SkImageInfo::MakeN32Premul(10, 10), + cc::PaintFlags::FilterQuality::kLow, CanvasResourceProvider::ShouldInitialize::kNo, SharedGpuContext::ContextProviderWrapper(), RasterMode::kGPU, true /*is_origin_top_left*/, 0u /*shared_image_usage_flags*/); @@ -217,10 +217,10 @@ // AcceleratedImageBufferSurface will restore the context and succeed test_context_provider_->TestContextGL()->set_context_lost(true); EXPECT_FALSE(SharedGpuContext::IsValidWithoutRestoring()); - IntSize size(10, 10); std::unique_ptr<CanvasResourceProvider> resource_provider = CanvasResourceProvider::CreateSharedImageProvider( - size, cc::PaintFlags::FilterQuality::kLow, CanvasResourceParams(), + SkImageInfo::MakeN32Premul(10, 10), + cc::PaintFlags::FilterQuality::kLow, CanvasResourceProvider::ShouldInitialize::kNo, SharedGpuContext::ContextProviderWrapper(), RasterMode::kGPU, true /*is_origin_top_left*/, 0u /*shared_image_usage_flags*/);
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_image_util.cc b/third_party/blink/renderer/platform/graphics/video_frame_image_util.cc index 04d4c0c..217e486 100644 --- a/third_party/blink/renderer/platform/graphics/video_frame_image_util.cc +++ b/third_party/blink/renderer/platform/graphics/video_frame_image_util.cc
@@ -322,12 +322,14 @@ viz::RasterContextProvider* raster_context_provider) { if (!ShouldCreateAcceleratedImages(raster_context_provider)) { return CanvasResourceProvider::CreateBitmapProvider( - size, cc::PaintFlags::FilterQuality::kLow, CanvasResourceParams(), + SkImageInfo::MakeN32Premul(size.width(), size.height()), + cc::PaintFlags::FilterQuality::kLow, CanvasResourceProvider::ShouldInitialize::kNo); } return CanvasResourceProvider::CreateSharedImageProvider( - size, cc::PaintFlags::FilterQuality::kLow, CanvasResourceParams(), + SkImageInfo::MakeN32Premul(size.width(), size.height()), + cc::PaintFlags::FilterQuality::kLow, CanvasResourceProvider::ShouldInitialize::kNo, SharedGpuContext::ContextProviderWrapper(), RasterMode::kGPU, false, // Origin of GL texture is bottom left on screen
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index bacd7ca..194908aa 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1714,7 +1714,6 @@ crbug.com/1145970 wpt_internal/css/css-conditional/container-queries/* [ Skip ] crbug.com/1146092 wpt_internal/css/css-contain/* [ Skip ] crbug.com/1145970 virtual/container-queries/* [ Pass ] -crbug.com/1245689 virtual/container-queries/wpt_internal/css/css-conditional/container-queries/svg-layout-root-crash.html [ Crash ] crbug.com/829028 virtual/container-queries/wpt_internal/css/css-contain/multicol-block-size.html [ Failure ] crbug.com/829028 virtual/container-queries/wpt_internal/css/css-contain/multicol-inline-size.html [ Failure ] @@ -2346,15 +2345,6 @@ crbug.com/1236768 external/wpt/html/browsers/browsing-the-web/overlapping-navigations-and-traversals/tentative/cross-document-traversal-same-document-nav.html [ Failure Timeout ] crbug.com/1236768 external/wpt/html/browsers/browsing-the-web/overlapping-navigations-and-traversals/tentative/same-document-traversal-same-document-nav.html [ Failure Timeout ] -# Disabling test to checkin associated frontend changes on DevTools -crbug.com/1252049 http/tests/devtools/forced-layout-in-microtask.js [ Failure Pass ] -crbug.com/1252049 [ Linux ] http/tests/devtools/tracing/timeline-js/timeline-script-id.js [ Failure Pass ] -crbug.com/1252049 [ Win ] http/tests/devtools/tracing/timeline-js/timeline-script-id.js [ Failure Pass ] -crbug.com/1252049 http/tests/devtools/tracing/timeline-layout/timeline-layout.js [ Failure Pass ] -crbug.com/1252049 http/tests/devtools/tracing/timeline-misc/timeline-animation-frame.js [ Failure Pass ] -crbug.com/1252049 http/tests/devtools/tracing/timeline-network/timeline-network-resource-details.js [ Failure Pass ] -crbug.com/1252049 http/tests/devtools/tracing/timeline-time/timeline-timer.js [ Failure Pass ] - crbug.com/876485 fast/performance/performance-measure-null-exception.html [ Failure ] crbug.com/713587 external/wpt/css/css-ui/caret-color-006.html [ Skip ] @@ -5110,22 +5100,6 @@ crbug.com/966345 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_normal_wrapped.html [ Failure ] crbug.com/966345 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-line_wrapped.html [ Failure ] -# Temporarily disabled to land https://crrev.com/c/3234177 -crbug.com/1073064 http/tests/devtools/console/console-format-classes.js [ Skip ] -crbug.com/1073064 http/tests/devtools/console/console-linkify-relative-links.js [ Skip ] -crbug.com/1073064 http/tests/devtools/console/console-log-linkify-stack-in-errors.js [ Skip ] -crbug.com/1073064 http/tests/devtools/console/console-message-from-inline-with-url.js [ Skip ] -crbug.com/1073064 http/tests/devtools/console/console-repeat-count.js [ Skip ] -crbug.com/1073064 http/tests/devtools/console/console-stack-overflow.js [ Skip ] -crbug.com/1073064 http/tests/devtools/console/console-uncaught-exception-in-eval.js [ Skip ] -crbug.com/1073064 http/tests/devtools/console/console-uncaught-exception.js [ Skip ] -crbug.com/1073064 http/tests/devtools/console/console-worker-nested-imports-syntax-error.js [ Skip ] -crbug.com/1073064 http/tests/devtools/console/exception-objects.js [ Skip ] -crbug.com/1073064 http/tests/devtools/sources/debugger/rethrow-error-from-bindings-crash.js [ Skip ] -crbug.com/1073064 http/tests/devtools/sources/debugger-async/async-callstack-in-console.js [ Skip ] -crbug.com/1073064 http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.js [ Skip ] -crbug.com/1073064 http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused-throws.js [ Skip ] - # Sheriff 2019-06-04 crbug.com/970135 [ Mac ] virtual/focusless-spat-nav/fast/spatial-navigation/focusless/snav-focusless-interested-element-indicated.html [ Failure ] crbug.com/970334 [ Mac ] fast/spatial-navigation/snav-tiny-table-traversal.html [ Failure ] @@ -7290,3 +7264,4 @@ crbug.com/1261744 [ Mac11-arm64 ] external/wpt/url/a-element-origin.html [ Failure Pass ] crbug.com/1261770 crbug.com/1245166 [ Linux ] external/wpt/web-bundle/subresource-loading/script-relative-url-in-web-bundle-cors.https.tentative.sub.html [ Failure Pass ] crbug.com/1261770 crbug.com/1245166 [ Linux ] virtual/wbn-from-network/external/wpt/web-bundle/subresource-loading/script-relative-url-in-web-bundle-cors.https.tentative.sub.html [ Failure Pass ] +crbug.com/1261889 http/tests/inspector-protocol/network/extra-info-emitted.js [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 7bf04fc..4c267ea 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -844,7 +844,10 @@ }, { "prefix": "third-party-storage-partitioning", - "bases":[ "external/wpt/service-workers/service-worker/partitioned-service-worker.tentative.https.html" ], + "bases": [ + "external/wpt/service-workers/service-worker/partitioned-service-worker.tentative.https.html", + "external/wpt/webstorage/localstorage-basic-partitioned.tentative.sub.html" + ], "args": [ "--enable-features=ThirdPartyStoragePartitioning" ] }, {
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/finish-animation.html b/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/finish-animation.html index ca46d15..1367abf9 100644 --- a/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/finish-animation.html +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/scroll-timelines/finish-animation.html
@@ -260,9 +260,9 @@ 'The current time is the end of the active duration in finished state.'); assert_percents_equal(animation.startTime, -75, 'The start time is calculated to match the current time.'); - assert_times_equal(finishEvent.currentTime / 1000, 100, + assert_percents_equal(finishEvent.currentTime, 100, 'event.currentTime is the animation current time.'); - assert_times_equal(finishEvent.timelineTime / 1000, 25, + assert_percents_equal(finishEvent.timelineTime, 25, 'event.timelineTime is timeline.currentTime'); }, 'Finishing idle animation produces correct state and fires finish event.'); @@ -300,9 +300,9 @@ 'The current time is the end of active duration in finished state.'); assert_percents_equal(animation.startTime, -75, 'The start time is calculated to match animation current time.'); - assert_times_equal(finishEvent.currentTime / 1000, 100, + assert_percents_equal(finishEvent.currentTime, 100, 'event.currentTime is the animation current time.'); - assert_times_equal(finishEvent.timelineTime / 1000, 25, + assert_percents_equal(finishEvent.timelineTime, 25, 'event.timelineTime is timeline.currentTime'); }, 'Finishing running animation produces correct state and fires finish event.');
diff --git a/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/iframe-target.html b/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/iframe-target.html index 92dff39..e1a6c85 100644 --- a/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/iframe-target.html +++ b/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/iframe-target.html
@@ -13,6 +13,8 @@ position = 'top'; else if (isInView(document.getElementById('target'))) position = 'target'; + else if (isInView(document.getElementById('elementid'))) + position = 'elementid'; let results = { scrollPosition: position, @@ -29,6 +31,10 @@ window.requestAnimationFrame(() => { window.requestAnimationFrame(postResult); }) + } else if (e.data == 'reset') { + window.location.hash = ''; + window.scrollTo(0, 0); + window.top.postMessage('', "*"); } }); </script> @@ -40,4 +46,5 @@ </style> <body> <p id="target">Target Text</p> + <div id="elementid">DIV</div> </body>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/iframes.sub.html b/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/iframes.sub.html index ea7ee75..6b3e83f 100644 --- a/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/iframes.sub.html +++ b/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/iframes.sub.html
@@ -14,6 +14,15 @@ }); } + function reset(iframe) { + return new Promise((resolve) => { + window.addEventListener('message', (e) => { + resolve(); + }, {once: true}); + iframe.contentWindow.postMessage('reset', '*'); + }); + } + function runTests() { const attribute_iframe = document.getElementById('srcattrib'); const sameorigin_iframe = document.getElementById('sameorigin'); @@ -22,6 +31,7 @@ // Check behavior that occurs when a text fragment is specified directly in // an iframe's src attribute. We expect the text fragment to be blocked. promise_test(t => new Promise(async resolve => { + // No reset since we're checking the hash specified in the `src` attribute. const data = await getResult(attribute_iframe); resolve(data); }).then( data => { @@ -34,6 +44,7 @@ // a same-document navigation initiated by an origin that's same-origin // with the current document. promise_test(t => new Promise(async resolve => { + await reset(sameorigin_iframe); sameorigin_iframe.contentWindow.location = `${sameorigin_iframe.src}#:~:text=Target`; const data = await getResult(sameorigin_iframe); resolve(data); @@ -46,6 +57,7 @@ // cross-origin parent. The text fragment should be blocked because the // initiating origin is not same-origin with the current document. promise_test(t => new Promise(async resolve => { + await reset(crossorigin_iframe); crossorigin_iframe.contentWindow.location = `${crossorigin_iframe.src}#:~:text=Target`; const data = await getResult(crossorigin_iframe); resolve(data); @@ -53,6 +65,29 @@ assert_equals(data.href.indexOf(':~:'), -1, 'Expected fragment directive to be stripped from the URL.'); assert_equals(data.scrollPosition, 'top', 'Should not to scroll to text fragment.'); }), 'Navigate cross-origin iframe via window.location'); + + // Check the element-id fallback behavior when the text is not found. We + // should fallback to a regular element-id hash navigation. + promise_test(t => new Promise(async resolve => { + await reset(sameorigin_iframe); + sameorigin_iframe.contentWindow.location = `${sameorigin_iframe.src}#elementid:~:text=NonExistentText`; + const data = await getResult(sameorigin_iframe); + resolve(data); + }).then( data => { + assert_equals(data.scrollPosition, 'elementid', 'Should scroll to the element-id anchor.'); + }), 'Non-matching text with element-id fallback'); + + // Check the element-id fallback behaviour when used across origins. The + // text fragment should be blocked across origins but the element id hash + // should not. + promise_test(t => new Promise(async resolve => { + await reset(crossorigin_iframe); + crossorigin_iframe.contentWindow.location = `${crossorigin_iframe.src}#elementid:~:text=Target%20Text`; + const data = await getResult(crossorigin_iframe); + resolve(data); + }).then( data => { + assert_equals(data.scrollPosition, 'elementid', 'Should scroll to the element-id anchor.'); + }), 'Cross-origin with element-id fallback'); } </script> <style>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/same-document-tests.html b/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/same-document-tests.html new file mode 100644 index 0000000..be9bed9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/same-document-tests.html
@@ -0,0 +1,80 @@ +<!doctype html> +<title>Same document navigation to text fragment directives</title> +<meta charset=utf-8> +<link rel="help" href="https://wicg.github.io/ScrollToTextFragment/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + function reset() { + location.hash = ''; + window.scrollTo(0, 0); + } + + function isInViewport(element) { + const viewportRect = { + left: visualViewport.offsetLeft, + top: visualViewport.offsetTop, + right: visualViewport.offsetLeft + visualViewport.width, + bottom: visualViewport.offsetTop + visualViewport.height + }; + + const elementRect = element.getBoundingClientRect(); + const elementCenter = { + x: elementRect.left + elementRect.width / 2, + y: elementRect.top + elementRect.height / 2 + }; + + return elementCenter.x > viewportRect.left && + elementCenter.x < viewportRect.right && + elementCenter.y > viewportRect.top && + elementCenter.y < viewportRect.bottom; + } + + function runTests() { + // Ensure a simple text directive works correctly when navigated to the + // same document using `location.hash`. + promise_test(async t => { + assert_implements(document.fragmentDirective, 'Text directive not implemented'); + reset(); + + location.hash = ':~:text=line%20of%20text'; + await t.step_wait(() => window.scrollY > 0, "Wait for scroll"); + assert_true(isInViewport(document.getElementById('text')), 'Scrolled to text'); + }, 'Basic text directive navigation'); + + // Test that we correctly fallback to the element id when we have a text + // directive that doesn't match any text in the page. + promise_test(async t => { + assert_implements(document.fragmentDirective, 'Text directive not implemented'); + reset(); + + location.hash = 'elementid:~:text=textDoesntExist'; + await t.step_wait(() => window.scrollY > 0, "Wait for scroll"); + assert_true(isInViewport(document.getElementById('elementid')), 'Scrolled to `elementid`'); + }, 'Basic element id fallback'); + + // Test that we correctly fallback to the element id when we have a text + // directive that's malformed and won't be parsed. + promise_test(async t => { + assert_implements(document.fragmentDirective, 'Text directive not implemented'); + reset(); + + location.hash = 'elementid:~:text=,,,,,'; + await t.step_wait(() => window.scrollY > 0, "Wait for scroll"); + assert_true(isInViewport(document.getElementById('elementid')), 'Scrolled to `elementid`'); + }, 'Malformed text directive element id fallback'); + } +</script> +<style> + div { + margin: 200vh 0 200vh 0; + } +</style> +<body onload="runTests()"> + <div id="text"> + This is a line of text. + </div> + <div id="elementid"> + This div has an id: 'elementid'. + </div> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/timing-model/timelines/update-and-send-events-replacement.html b/third_party/blink/web_tests/external/wpt/web-animations/timing-model/timelines/update-and-send-events-replacement.html index 04389a9..d6ed734 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/timing-model/timelines/update-and-send-events-replacement.html +++ b/third_party/blink/web_tests/external/wpt/web-animations/timing-model/timelines/update-and-send-events-replacement.html
@@ -725,8 +725,8 @@ const event = await eventWatcher.wait_for('remove'); - assert_equals(event.timelineTime, document.timeline.currentTime); - assert_equals(event.currentTime, 1); + assert_times_equal(event.timelineTime, document.timeline.currentTime); + assert_times_equal(event.currentTime, 1); }, 'Dispatches an event when removing'); promise_test(async t => {
diff --git a/third_party/blink/web_tests/external/wpt/webstorage/localstorage-basic-partitioned.tentative.sub-expected.txt b/third_party/blink/web_tests/external/wpt/webstorage/localstorage-basic-partitioned.tentative.sub-expected.txt new file mode 100644 index 0000000..6cdbef6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webstorage/localstorage-basic-partitioned.tentative.sub-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Simple test for partitioned localStorage assert_true: IDs pulled from two partitioned iframes are different. expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/webstorage/localstorage-basic-partitioned.tentative.sub.html b/third_party/blink/web_tests/external/wpt/webstorage/localstorage-basic-partitioned.tentative.sub.html new file mode 100644 index 0000000..39209eae --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webstorage/localstorage-basic-partitioned.tentative.sub.html
@@ -0,0 +1,61 @@ +<!doctype html> +<meta charset=utf-8> +<title>localStorage: partitioned storage test</title> +<meta name=help href="https://privacycg.github.io/storage-partitioning/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<iframe id="shared-iframe" src="http://{{host}}:{{ports[http][0]}}/webstorage/resources/localstorage-basic-partitioned-iframe.html"></iframe> +<body> +<script> +// Here's the set-up for this test: +// Step 1. (window) set up listeners for main window. +// Step 2. (window) set up load listener for same-site iframe. +// Step 3. (same-site iframe) loads, send it a message to createOrGet a "userID". +// Step 4. (same-site iframe) receives the message, creates the "userID". +// Step 5. (window) receives "storage got set" message from same-site iframe. +// Step 6. (window) opens cross-site window w/ shared (same-site to us currently) iframe. +// Step 7. (cross-site iframe) loads, sends back the userID key from the iframe. +// Step 8. (window) asserts that the IDs should be different, as they should have a different StorageKey. +const altOrigin = "http://{{hosts[alt][]}}:{{ports[http][0]}}"; + +async_test(t => { + let crossSiteWindow; + let crossSiteID; + let sameSiteID; + const iframe = document.getElementById("shared-iframe"); + + iframe.addEventListener("load", t.step_func(e => { + const payload = { + command: "create ID", + key: "userID", + }; + iframe.contentWindow.postMessage(payload, iframe.origin); + }), {once: true}); + + window.addEventListener("message", t.step_func(e => { + if (e.data.message === "ID created") { + sameSiteID = e.data.userID; + assert_true(typeof sameSiteID === "string"); + + if (location.origin !== altOrigin) { + crossSiteWindow = window.open(`${altOrigin}/webstorage/localstorage-basic-partitioned.tentative.sub.html`, "", "noopener=false"); + t.add_cleanup(() => crossSiteWindow.close()); + } + } + + if (e.data.message === "cross-site window iframe loaded") { + crossSiteID = e.data.userID; + t.step(() => { + assert_true(typeof crossSiteID === "string"); + assert_true(sameSiteID !== crossSiteID, "IDs pulled from two partitioned iframes are different.") + }); + + // clean up after ourselves. + iframe.contentWindow.localStorage.clear(); + crossSiteWindow.postMessage({command: "clearStorage"}, altOrigin); + t.done(); + }; + })); +}, "Simple test for partitioned localStorage"); +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/webstorage/resources/localstorage-basic-partitioned-iframe.html b/third_party/blink/web_tests/external/wpt/webstorage/resources/localstorage-basic-partitioned-iframe.html new file mode 100644 index 0000000..5cb2c4f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webstorage/resources/localstorage-basic-partitioned-iframe.html
@@ -0,0 +1,41 @@ +<!doctype html> +<meta charset="utf-8"> +<script> +function getOrCreateID(key) { + if (!localStorage.getItem(key)) { + const newID = +new Date() + "-" + Math.random(); + localStorage.setItem(key, newID); + } + return localStorage.getItem(key); +} + +window.addEventListener("load", () => { + // if we have an opener, we know that we are loaded inside a cross-site + // iframe (because we opened it ourselves). + if (parent.opener) { + const payload = { + message: "cross-site window iframe loaded", + userID: getOrCreateID("userID"), + } + parent.opener.postMessage(payload, parent.opener.origin); + } +}); + +window.addEventListener("message", (e) => { + if (e.data.command == "create ID") { + getOrCreateID(e.data.key); + + // storage is set, call back to window. + const payload = { + message: "ID created", + userID: localStorage.getItem("userID"), + } + + e.source.postMessage(payload, e.source.origin); + } + + if (e.data.command == "clearStorage") { + localStorage.clear(); + } +}); +</script>
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-format-classes-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-format-classes-expected.txt index 18587c6..4ceec07 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-format-classes-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-format-classes-expected.txt
@@ -1,7 +1,7 @@ Tests that console produces instant previews for arrays and objects. console-format-classes.js:30 Error: custom error with link www.chromium.org - at console-format-classes.js:20 + at console-format-classes.js:20:9 console-message source-code console-message-anchor
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-linkify-relative-links-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-linkify-relative-links-expected.txt index c5b7e7ee..3558765 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-linkify-relative-links-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-linkify-relative-links-expected.txt
@@ -1,16 +1,16 @@ Test that logging an error in console would linkify relative URLs console-linkify-relative-links.js:10 Error with relative links - at (foo1.js:10) - at (foo2.js:10) - at (:8000/foo3.js:10) - at (:8000/devtools/foo4.js:10) - at (foo5.js:10) - at (bar/foo6.js:10) -Link: foo1.js:10, href: http://127.0.0.1:8000/devtools/resources/foo1.js -Link: foo2.js:10, href: http://foo2.js -Link: :8000/foo3.js:10, href: http://127.0.0.1:8000/foo3.js -Link: :8000/devtools/foo4.js:10, href: http://127.0.0.1:8000/devtools/foo4.js -Link: foo5.js:10, href: http://127.0.0.1:8000/devtools/resources/foo5.js -Link: bar/foo6.js:10, href: http://127.0.0.1:8000/devtools/resources/bar/foo6.js + at (foo1.js:10:50) + at (foo2.js:10:50) + at (:8000/foo3.js:10:50) + at (:8000/devtools/foo4.js:10:50) + at (foo5.js:10:50) + at (bar/foo6.js:10:50) +Link: foo1.js:10:50, href: http://127.0.0.1:8000/devtools/resources/foo1.js +Link: foo2.js:10:50, href: http://foo2.js +Link: :8000/foo3.js:10:50, href: http://127.0.0.1:8000/foo3.js +Link: :8000/devtools/foo4.js:10:50, href: http://127.0.0.1:8000/devtools/foo4.js +Link: foo5.js:10:50, href: http://127.0.0.1:8000/devtools/resources/foo5.js +Link: bar/foo6.js:10:50, href: http://127.0.0.1:8000/devtools/resources/bar/foo6.js
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-log-linkify-stack-in-errors-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-log-linkify-stack-in-errors-expected.txt index 7099a966..9569b54 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-log-linkify-stack-in-errors-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-log-linkify-stack-in-errors-expected.txt
@@ -1,57 +1,57 @@ Test that console.log(new Error().stack) would linkify links in stacks for sourceUrls and sourceMaps Bug 424001. foob.js:5 Error: Some test - at namedFunction (foob.js:5) - at foob.js:8 + at namedFunction (foob.js:5:17) + at foob.js:8:1 console-log-linkify-…ack-in-errors.js:15 Error: line break - at forStack (console-log-linkify-…ack-in-errors.js:15) - at console-log-linkify-…ack-in-errors.js:18 + at forStack (console-log-linkify-…-in-errors.js:15:23) + at console-log-linkify-…k-in-errors.js:18:7 console-log-linkify-…ack-in-errors.js:34 Error: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node. - at domError (console-log-linkify-…ack-in-errors.js:32) - at console-log-linkify-…ack-in-errors.js:38 + at domError (console-log-linkify-…-in-errors.js:32:29) + at console-log-linkify-…k-in-errors.js:38:7 console-log-linkify-…ack-in-errors.js:45 Error: some error - at logError (console-log-linkify-…ack-in-errors.js:43) - at console-log-linkify-…ack-in-errors.js:49 + at logError (console-log-linkify-…-in-errors.js:43:21) + at console-log-linkify-…k-in-errors.js:49:7 console-log-linkify-…ack-in-errors.js:51 Error message without stacks http://www.chromium.org/ console-log-linkify-…ack-in-errors.js:53 Error valid stack #2 - at www.chromium.org/boo.js:40 - at foo(www.chromium.org/foo.js:10) + at www.chromium.org/boo.js:40:70 + at foo(www.chromium.org/foo.js:10:50) console-log-linkify-…ack-in-errors.js:54 Error valid stack #3 at www.chromium.org/foo.js:40 console-log-linkify-…ack-in-errors.js:55 Error: MyError at throwError (www.chromium.org/foo.js:40) - at eval (eval at <anonymous> (www.chromium.org/foo.js:42), <anonymous>:1:1) + at eval (eval at <anonymous> (www.chromium.org/foo.js:42:1), <anonymous>:1:1) at www.chromium.org/foo.js:239 console-log-linkify-…ack-in-errors.js:24 ReferenceError: valid stack - at stack2 (console-log-linkify-…ack-in-errors.js:24) - at stack1 (console-log-linkify-…ack-in-errors.js:26) - at console-log-linkify-…ack-in-errors.js:57 + at stack2 (console-log-linkify-…-in-errors.js:24:27) + at stack1 (console-log-linkify-…-in-errors.js:26:11) + at console-log-linkify-…k-in-errors.js:57:7 console-log-linkify-…ack-in-errors.js:24 EvalError: valid stack - at stack2 (console-log-linkify-…ack-in-errors.js:24) - at stack1 (console-log-linkify-…ack-in-errors.js:26) - at console-log-linkify-…ack-in-errors.js:58 + at stack2 (console-log-linkify-…-in-errors.js:24:27) + at stack1 (console-log-linkify-…-in-errors.js:26:11) + at console-log-linkify-…k-in-errors.js:58:7 console-log-linkify-…ack-in-errors.js:24 SyntaxError: valid stack - at stack2 (console-log-linkify-…ack-in-errors.js:24) - at stack1 (console-log-linkify-…ack-in-errors.js:26) - at console-log-linkify-…ack-in-errors.js:59 + at stack2 (console-log-linkify-…-in-errors.js:24:27) + at stack1 (console-log-linkify-…-in-errors.js:26:11) + at console-log-linkify-…k-in-errors.js:59:7 console-log-linkify-…ack-in-errors.js:24 RangeError: valid stack - at stack2 (console-log-linkify-…ack-in-errors.js:24) - at stack1 (console-log-linkify-…ack-in-errors.js:26) - at console-log-linkify-…ack-in-errors.js:60 + at stack2 (console-log-linkify-…-in-errors.js:24:27) + at stack1 (console-log-linkify-…-in-errors.js:26:11) + at console-log-linkify-…k-in-errors.js:60:7 console-log-linkify-…ack-in-errors.js:24 TypeError: valid stack - at stack2 (console-log-linkify-…ack-in-errors.js:24) - at stack1 (console-log-linkify-…ack-in-errors.js:26) - at console-log-linkify-…ack-in-errors.js:61 + at stack2 (console-log-linkify-…-in-errors.js:24:27) + at stack1 (console-log-linkify-…-in-errors.js:26:11) + at console-log-linkify-…k-in-errors.js:61:7 console-log-linkify-…ack-in-errors.js:24 URIError: valid stack - at stack2 (console-log-linkify-…ack-in-errors.js:24) - at stack1 (console-log-linkify-…ack-in-errors.js:26) - at console-log-linkify-…ack-in-errors.js:62 + at stack2 (console-log-linkify-…-in-errors.js:24:27) + at stack1 (console-log-linkify-…-in-errors.js:26:11) + at console-log-linkify-…k-in-errors.js:62:7 console-log-linkify-…ack-in-errors.js:64 Error broken stack - at function_name(foob.js foob.js:30) - at foob.js:40 + at function_name(foob.js foob.js:30:1) + at foob.js:40:70 console-log-linkify-…ack-in-errors.js:65 Error broken stack #2 - at function_name(foob.js:20 + at function_name(foob.js:20:30 console-log-linkify-…ack-in-errors.js:66 Error broken stack #3 at function_name(foob:20.js:30 bla console-log-linkify-…ack-in-errors.js:67 Error broken stack #4 @@ -59,11 +59,11 @@ console-log-linkify-…ack-in-errors.js:68 Error broken stack #5 at function_name foob.js:20:30) console-log-linkify-…ack-in-errors.js:69 Error broken stack #6 - at foob.js foob.js:40 + at foob.js foob.js:40:70 stack-with-sourceMap.coffee:2 Error - at window.letsFailWithStack (stack-with-sourceMap.coffee:2) - at eval (eval at letsFailWithStackInEval (stack-with-sourceMap.coffee:8), <anonymous>:1:1) - at Failure.letsFailWithStackInEval (stack-with-sourceMap.coffee:8) - at window.failure (stack-with-sourceMap.coffee:13) + at window.letsFailWithStack (stack-with-sourceMap.coffee:2:18) + at eval (eval at letsFailWithStackInEval (stack-with-sourceMap.coffee:8:9), <anonymous>:1:1) + at Failure.letsFailWithStackInEval (stack-with-sourceMap.coffee:8:9) + at window.failure (stack-with-sourceMap.coffee:13:13) at <anonymous>:1:1
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-message-from-inline-with-url-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-message-from-inline-with-url-expected.txt index 468142d..d33c23f 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-message-from-inline-with-url-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-message-from-inline-with-url-expected.txt
@@ -2,7 +2,7 @@ foo.js:13 foo boo.js:1 Uncaught SyntaxError: Unexpected token '}' - at addInlineWithSyntaxError (foo.js:21) + at addInlineWithSyntaxError (foo.js:21:30) addInlineWithSyntaxError @ foo.js:21 setTimeout (async) (anonymous) @ console-message-from…line-with-url.js:29
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-repeat-count-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-repeat-count-expected.txt index 1cbe3bd3..b64e8aa5 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-repeat-count-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-repeat-count-expected.txt
@@ -9,8 +9,8 @@ undefined 2console-repeat-count.js:15 Message 2console-repeat-count.js:18 Error: Message with error - at dumpMessages (console-repeat-count.js:18) - at console-repeat-count.js:49 + at dumpMessages (console-repeat-count.js:18:21) + at console-repeat-count.js:49:1 console-repeat-count.js:21 {a: 1} dumpMessages @ console-repeat-count.js:21 (anonymous) @ console-repeat-count.js:49
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-stack-overflow-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-stack-overflow-expected.txt index 7833edb..c435b9d 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-stack-overflow-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-stack-overflow-expected.txt
@@ -1,16 +1,16 @@ Tests that when stack overflow exception happens when inspector is open the stack trace is correctly shown in console. console-stack-overflow.js:15 Uncaught RangeError: Maximum call stack size exceeded - at overflow (console-stack-overflow.js:15) - at overflow (console-stack-overflow.js:15) - at overflow (console-stack-overflow.js:15) - at overflow (console-stack-overflow.js:15) - at overflow (console-stack-overflow.js:15) - at overflow (console-stack-overflow.js:15) - at overflow (console-stack-overflow.js:15) - at overflow (console-stack-overflow.js:15) - at overflow (console-stack-overflow.js:15) - at overflow (console-stack-overflow.js:15) + at overflow (console-stack-overflow.js:15:27) + at overflow (console-stack-overflow.js:15:27) + at overflow (console-stack-overflow.js:15:27) + at overflow (console-stack-overflow.js:15:27) + at overflow (console-stack-overflow.js:15:27) + at overflow (console-stack-overflow.js:15:27) + at overflow (console-stack-overflow.js:15:27) + at overflow (console-stack-overflow.js:15:27) + at overflow (console-stack-overflow.js:15:27) + at overflow (console-stack-overflow.js:15:27) overflow @ console-stack-overflow.js:15 overflow @ console-stack-overflow.js:15 overflow @ console-stack-overflow.js:15 @@ -22,5 +22,5 @@ overflow @ console-stack-overflow.js:15 overflow @ console-stack-overflow.js:15 overflow @ console-stack-overflow.js:15 -overflow @ console-stack-overfl +o
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-uncaught-exception-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-uncaught-exception-expected.txt index 77ce2ef0..62cd3b92 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-uncaught-exception-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-uncaught-exception-expected.txt
@@ -1,22 +1,22 @@ Tests that uncaught exceptions are logged into console.Bug 47250. uncaught-in-iframe.html:18 Uncaught Error: Exception in inline script. - at a (uncaught-in-iframe.html:18) - at b (uncaught-in-iframe.html:23) - at uncaught-in-iframe.html:26 + at a (uncaught-in-iframe.html:18:11) + at b (uncaught-in-iframe.html:23:5) + at uncaught-in-iframe.html:26:1 a @ uncaught-in-iframe.html:18 b @ uncaught-in-iframe.html:23 (anonymous) @ uncaught-in-iframe.html:26 uncaught-in-iframe.html:11 Uncaught Error: Exception in 'load' event listener. - at f (uncaught-in-iframe.html:11) - at uncaught-in-iframe.html:13 + at f (uncaught-in-iframe.html:11:15) + at uncaught-in-iframe.html:13:5 f @ uncaught-in-iframe.html:11 (anonymous) @ uncaught-in-iframe.html:13 load (async) (anonymous) @ uncaught-in-iframe.html:2 uncaught-in-iframe.html:6 Uncaught Error: Exception in setTimeout callback. - at bar (uncaught-in-iframe.html:6) - at uncaught-in-iframe.html:8 + at bar (uncaught-in-iframe.html:6:23) + at uncaught-in-iframe.html:8:13 bar @ uncaught-in-iframe.html:6 (anonymous) @ uncaught-in-iframe.html:8 setTimeout (async)
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-uncaught-exception-in-eval-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-uncaught-exception-in-eval-expected.txt index 7c9d808..ea45d38 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-uncaught-exception-in-eval-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-uncaught-exception-in-eval-expected.txt
@@ -1,10 +1,10 @@ Tests that when uncaught exception in eval'ed script ending with //# sourceURL=url is logged into console, its stack trace will have the url as the script source. Bug 47252. evalURL.js:5 Uncaught Error: Exception in eval:with sourceURL - at b (evalURL.js:5) - at a (evalURL.js:10) - at evalSource (evalURL.js:13) - at eval (evalURL.js:14) + at b (evalURL.js:5:21) + at a (evalURL.js:10:15) + at evalSource (evalURL.js:13:11) + at eval (evalURL.js:14:9) at eval (<anonymous>) b @ evalURL.js:5 a @ evalURL.js:10
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-worker-nested-imports-syntax-error-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-worker-nested-imports-syntax-error-expected.txt index 8f0fd2b..77a2064 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-worker-nested-imports-syntax-error-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-worker-nested-imports-syntax-error-expected.txt
@@ -2,10 +2,10 @@ Message count: 1 invalidScript.js:1 Uncaught SyntaxError: Unexpected identifier - at importScripts-3.js:1 - at foo (importScripts-2.js:3) - at importScripts-2.js:5 - at importScripts-1.js:1 + at importScripts-3.js:1:1 + at foo (importScripts-2.js:3:5) + at importScripts-2.js:5:1 + at importScripts-1.js:1:1 (anonymous) @ importScripts-3.js:1 foo @ importScripts-2.js:3 (anonymous) @ importScripts-2.js:5
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/exception-objects-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/exception-objects-expected.txt index a297881..bc5a368 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/exception-objects-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/exception-objects-expected.txt
@@ -3,13 +3,13 @@ setTimeout(throwError, 0); undefined undefined foo.js:12 Uncaught Error: error_text - at throwError (foo.js:12) + at throwError (foo.js:12:17) throwError @ foo.js:12 setTimeout (async) (anonymous) @ VM:1 throwError(); foo.js:12 Uncaught Error: error_text - at throwError (foo.js:12) + at throwError (foo.js:12:17) at <anonymous>:1:1 throwError @ foo.js:12 (anonymous) @ VM:1 @@ -36,14 +36,14 @@ setTimeout(rejectWithError, 0); undefined undefined foo.js:27 Uncaught (in promise) Error: promise_error - at rejectWithError (foo.js:27) + at rejectWithError (foo.js:27:26) rejectWithError @ foo.js:27 setTimeout (async) (anonymous) @ VM:1 rejectWithError(); undefined foo.js:27 Uncaught (in promise) Error: promise_error - at rejectWithError (foo.js:27) + at rejectWithError (foo.js:27:26) at <anonymous>:1:1 rejectWithError @ foo.js:27 (anonymous) @ VM:1
diff --git a/third_party/blink/web_tests/http/tests/devtools/forced-layout-in-microtask-expected.txt b/third_party/blink/web_tests/http/tests/devtools/forced-layout-in-microtask-expected.txt index aafcc43a..6676ce98 100644 --- a/third_party/blink/web_tests/http/tests/devtools/forced-layout-in-microtask-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/forced-layout-in-microtask-expected.txt
@@ -37,5 +37,5 @@ startTime : <number> type : "Layout" } -Text details for Layout: test://evaluations/0/forced-layout-in-microtask.js:21 +Text details for Layout: test://evaluations/0/forced-layout-in-microtask.js:21:36
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-in-console-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-in-console-expected.txt index f049d11..375ec463 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-in-console-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-async/async-callstack-in-console-expected.txt
@@ -10,7 +10,7 @@ testFunction @ async-callstack-in-console.js:19 async-callstack-in-console.js:31 Uncaught Error: foo - at timeout2 (async-callstack-in-console.js:31) + at timeout2 (async-callstack-in-console.js:31:17) timeout2 @ async-callstack-in-console.js:31
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe-expected.txt index 556994b..79db589 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe-expected.txt
@@ -12,7 +12,7 @@ clear = x: = VM:1 Uncaught SyntaxError: Unexpected end of input at Object.pauseInsideIframe (<anonymous>:6:5) - at testFunction (debugger-eval-on-cal…inside-iframe.js:35) + at testFunction (debugger-eval-on-cal…ide-iframe.js:35:50) pauseInsideIframe @ VM:6 testFunction @ debugger-eval-on-cal…inside-iframe.js:35 setTimeout (async) @@ -26,7 +26,7 @@ clear = 'local in top frame' x: = VM:1 Uncaught SyntaxError: Unexpected end of input at Object.pauseInsideIframe (<anonymous>:6:5) - at testFunction (debugger-eval-on-cal…inside-iframe.js:35) + at testFunction (debugger-eval-on-cal…ide-iframe.js:35:50) pauseInsideIframe @ VM:6 testFunction @ debugger-eval-on-cal…inside-iframe.js:35 setTimeout (async)
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused-throws-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused-throws-expected.txt index a8b1ca6d..f76372f 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused-throws-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused-throws-expected.txt
@@ -5,10 +5,10 @@ injectedFunction() debugger-eval-while-paused-throws.js:51 Uncaught Error: injectedObj.func - at Object.func (debugger-eval-while-paused-throws.js:51) - at injectedFunction (debugger-eval-while-paused-throws.js:54) - at eval (eval at testFunction (inspected-page.html:27), <anonymous>:1:1) - at testFunction (test.js:27) + at Object.func (debugger-eval-while-…sed-throws.js:51:15) + at injectedFunction (debugger-eval-while-…sed-throws.js:54:24) + at eval (eval at testFunction (inspected-page.html:27:11), <anonymous>:1:1) + at testFunction (test.js:27:11) func @ debugger-eval-while-paused-throws.js:51 injectedFunction @ debugger-eval-while-paused-throws.js:54 eval @ VM:1 @@ -18,9 +18,9 @@ (anonymous) @ VM:1 localObj.func() test.js:24 Uncaught Error: localObj.func - at Object.func (test.js:24) - at eval (eval at testFunction (inspected-page.html:27), <anonymous>:1:10) - at testFunction (test.js:27) + at Object.func (test.js:24:25) + at eval (eval at testFunction (inspected-page.html:27:11), <anonymous>:1:10) + at testFunction (test.js:27:11) func @ test.js:24 eval @ VM:1 testFunction @ test.js:27 @@ -29,9 +29,9 @@ (anonymous) @ VM:1 globalObj.func() test.js:15 Uncaught Error: globalObj.func - at Object.func (test.js:15) - at eval (eval at testFunction (inspected-page.html:27), <anonymous>:1:11) - at testFunction (test.js:27) + at Object.func (test.js:15:21) + at eval (eval at testFunction (inspected-page.html:27:11), <anonymous>:1:11) + at testFunction (test.js:27:11) func @ test.js:15 eval @ VM:1 testFunction @ test.js:27
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/rethrow-error-from-bindings-crash-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger/rethrow-error-from-bindings-crash-expected.txt index e99a7ee..af9e799 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/rethrow-error-from-bindings-crash-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger/rethrow-error-from-bindings-crash-expected.txt
@@ -3,15 +3,15 @@ Set timer for test function. rethrow-error-from-bindings-crash.js:15 Console was cleared rethrow-error-from-bindings-crash.js:29 Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'. - at f2 (rethrow-error-from-bindings-crash.js:29) - at testFunction (rethrow-error-from-bindings-crash.js:19) + at f2 (rethrow-error-from-b…ings-crash.js:29:23) + at testFunction (rethrow-error-from-b…ings-crash.js:19:28) f2 @ rethrow-error-from-bindings-crash.js:29 testFunction @ rethrow-error-from-bindings-crash.js:19 setTimeout (async) scheduleTestFunction @ VM:3 (anonymous) @ VM:1 rethrow-error-from-bindings-crash.js:24 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. - at f1 (rethrow-error-from-bindings-crash.js:24) + at f1 (rethrow-error-from-b…ings-crash.js:24:25) f1 @ rethrow-error-from-bindings-crash.js:24 setTimeout (async) f2 @ rethrow-error-from-bindings-crash.js:28 @@ -20,7 +20,7 @@ scheduleTestFunction @ VM:3 (anonymous) @ VM:1 rethrow-error-from-bindings-crash.js:29 Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'. - at f2 (rethrow-error-from-bindings-crash.js:29) + at f2 (rethrow-error-from-b…ings-crash.js:29:23) f2 @ rethrow-error-from-bindings-crash.js:29 setTimeout (async) f1 @ rethrow-error-from-bindings-crash.js:23 @@ -31,7 +31,7 @@ scheduleTestFunction @ VM:3 (anonymous) @ VM:1 rethrow-error-from-bindings-crash.js:24 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. - at f1 (rethrow-error-from-bindings-crash.js:24) + at f1 (rethrow-error-from-b…ings-crash.js:24:25) f1 @ rethrow-error-from-bindings-crash.js:24 setTimeout (async) f2 @ rethrow-error-from-bindings-crash.js:28 @@ -44,7 +44,7 @@ scheduleTestFunction @ VM:3 (anonymous) @ VM:1 rethrow-error-from-bindings-crash.js:29 Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'. - at f2 (rethrow-error-from-bindings-crash.js:29) + at f2 (rethrow-error-from-b…ings-crash.js:29:23) f2 @ rethrow-error-from-bindings-crash.js:29 setTimeout (async) f1 @ rethrow-error-from-bindings-crash.js:23 @@ -59,7 +59,7 @@ scheduleTestFunction @ VM:3 (anonymous) @ VM:1 rethrow-error-from-bindings-crash.js:24 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. - at f1 (rethrow-error-from-bindings-crash.js:24) + at f1 (rethrow-error-from-b…ings-crash.js:24:25) f1 @ rethrow-error-from-bindings-crash.js:24 setTimeout (async) f2 @ rethrow-error-from-bindings-crash.js:28 @@ -76,7 +76,7 @@ scheduleTestFunction @ VM:3 (anonymous) @ VM:1 rethrow-error-from-bindings-crash.js:29 Uncaught TypeError: Failed to execute 'compareBoundaryPoints' on 'Range': parameter 2 is not of type 'Range'. - at f2 (rethrow-error-from-bindings-crash.js:29) + at f2 (rethrow-error-from-b…ings-crash.js:29:23) f2 @ rethrow-error-from-bindings-crash.js:29 setTimeout (async) f1 @ rethrow-error-from-bindings-crash.js:23 @@ -95,7 +95,7 @@ scheduleTestFunction @ VM:3 (anonymous) @ VM:1 rethrow-error-from-bindings-crash.js:24 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'. - at f1 (rethrow-error-from-bindings-crash.js:24) + at f1 (rethrow-error-from-b…ings-crash.js:24:25) f1 @ rethrow-error-from-bindings-crash.js:24 setTimeout (async) f2 @ rethrow-error-from-bindings-crash.js:28
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-script-id-expected.txt b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-script-id-expected.txt index ec669246..87c0eb4 100644 --- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-script-id-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-script-id-expected.txt
@@ -1,14 +1,14 @@ Test that checks location resolving mechanics for TimerInstall TimerRemove and FunctionCall events with scriptId. It expects two FunctionCall for InjectedScript, two TimerInstall events, two FunctionCall events and one TimerRemove event to be logged with performActions.js script name and some line number. -detailsTextContent for TimerInstall event: 'performActions.js:33' -details.textContent for TimerInstall event: 'performActions.js:33' -detailsTextContent for TimerInstall event: 'performActions.js:34' -details.textContent for TimerInstall event: 'performActions.js:34' -detailsTextContent for FunctionCall event: 'performActions.js:38' -details.textContent for FunctionCall event: 'intervalTimerWork @ performActions.js:38' -detailsTextContent for FunctionCall event: 'performActions.js:38' -details.textContent for FunctionCall event: 'intervalTimerWork @ performActions.js:38' -detailsTextContent for TimerRemove event: 'performActions.js:41' -details.textContent for TimerRemove event: 'performActions.js:41' +detailsTextContent for TimerInstall event: 'performActions.js:33:20' +details.textContent for TimerInstall event: 'performActions.js:33:20' +detailsTextContent for TimerInstall event: 'performActions.js:34:20' +details.textContent for TimerInstall event: 'performActions.js:34:20' +detailsTextContent for FunctionCall event: 'performActions.js:38:31' +details.textContent for FunctionCall event: 'intervalTimerWork @ performActions.js:38:31' +detailsTextContent for FunctionCall event: 'performActions.js:38:31' +details.textContent for FunctionCall event: 'intervalTimerWork @ performActions.js:38:31' +detailsTextContent for TimerRemove event: 'performActions.js:41:7' +details.textContent for TimerRemove event: 'performActions.js:41:7'
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout-expected.txt b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout-expected.txt index beb14d60..6f3cc681 100644 --- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-layout/timeline-layout-expected.txt
@@ -37,7 +37,7 @@ startTime : <number> type : "Layout" } -Text details for Layout: test://evaluations/0/timeline-layout.js:40 +Text details for Layout: test://evaluations/0/timeline-layout.js:40:32 Layout Properties: { data : { @@ -75,5 +75,5 @@ startTime : <number> type : "Layout" } -Text details for Layout: test://evaluations/0/timeline-layout.js:40 +Text details for Layout: test://evaluations/0/timeline-layout.js:40:32
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-animation-frame-expected.txt b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-animation-frame-expected.txt index f9c7763..114f42d 100644 --- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-animation-frame-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-misc/timeline-animation-frame-expected.txt
@@ -13,7 +13,7 @@ startTime : <number> type : "RequestAnimationFrame" } -Text details for RequestAnimationFrame: test://evaluations/0/timeline-animation-frame.js:14 +Text details for RequestAnimationFrame: test://evaluations/0/timeline-animation-frame.js:14:34 FireAnimationFrame Properties: { data : { @@ -25,7 +25,7 @@ startTime : <number> type : "FireAnimationFrame" } -Text details for FireAnimationFrame: test://evaluations/0/timeline-animation-frame.js:14 +Text details for FireAnimationFrame: test://evaluations/0/timeline-animation-frame.js:14:34 CancelAnimationFrame Properties: { data : { @@ -39,5 +39,5 @@ startTime : <number> type : "CancelAnimationFrame" } -Text details for CancelAnimationFrame: test://evaluations/0/timeline-animation-frame.js:17 +Text details for CancelAnimationFrame: test://evaluations/0/timeline-animation-frame.js:17:22
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-network/timeline-network-resource-details-expected.txt b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-network/timeline-network-resource-details-expected.txt index 2fe5dc7..d3f02a1 100644 --- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-network/timeline-network-resource-details-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-network/timeline-network-resource-details-expected.txt
@@ -7,7 +7,7 @@ Mime Type: string Encoded Data: string Decoded Body: 223 B -Initiator: timeline-network-resource-details.js:19 +Initiator: timeline-network-resource-details.js:19:25 URL: anImage.png Duration: string Request Method: GET
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-time/timeline-timer-expected.txt b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-time/timeline-timer-expected.txt index 7a21102..bd9530e 100644 --- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-time/timeline-timer-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-time/timeline-timer-expected.txt
@@ -15,7 +15,7 @@ startTime : <number> type : "TimerInstall" } -Text details for TimerInstall: test://evaluations/0/timeline-timer.js:14 +Text details for TimerInstall: test://evaluations/0/timeline-timer.js:14:26 TimerInstall Properties: { data : { @@ -31,7 +31,7 @@ startTime : <number> type : "TimerInstall" } -Text details for TimerInstall: test://evaluations/0/timeline-timer.js:15 +Text details for TimerInstall: test://evaluations/0/timeline-timer.js:15:26 TimerFire Properties: { data : { @@ -43,7 +43,7 @@ startTime : <number> type : "TimerFire" } -Text details for TimerFire: test://evaluations/0/timeline-timer.js:14 +Text details for TimerFire: test://evaluations/0/timeline-timer.js:14:26 TimerFire Properties: { data : { @@ -55,7 +55,7 @@ startTime : <number> type : "TimerFire" } -Text details for TimerFire: test://evaluations/0/timeline-timer.js:15 +Text details for TimerFire: test://evaluations/0/timeline-timer.js:15:26 TimerFire Properties: { data : { @@ -67,7 +67,7 @@ startTime : <number> type : "TimerFire" } -Text details for TimerFire: test://evaluations/0/timeline-timer.js:15 +Text details for TimerFire: test://evaluations/0/timeline-timer.js:15:26 TimerRemove Properties: { data : { @@ -81,7 +81,7 @@ startTime : <number> type : "TimerRemove" } -Text details for TimerRemove: test://evaluations/0/timeline-timer.js:22 +Text details for TimerRemove: test://evaluations/0/timeline-timer.js:22:15 FunctionCall Properties: { data : {
diff --git a/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/webstorage/README.txt b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/webstorage/README.txt new file mode 100644 index 0000000..2d846730 --- /dev/null +++ b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/webstorage/README.txt
@@ -0,0 +1,2 @@ +This suite runs webstorage tests with ThirdPartyStoragePartitioning enabled. +
diff --git a/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/webstorage/localstorage-basic-partitioned.tentative.sub-expected.txt b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/webstorage/localstorage-basic-partitioned.tentative.sub-expected.txt new file mode 100644 index 0000000..6cdbef6 --- /dev/null +++ b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/webstorage/localstorage-basic-partitioned.tentative.sub-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Simple test for partitioned localStorage assert_true: IDs pulled from two partitioned iframes are different. expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/wpt_internal/webgpu/cts.html b/third_party/blink/web_tests/wpt_internal/webgpu/cts.html index a52e7885..e792f57d 100644 --- a/third_party/blink/web_tests/wpt_internal/webgpu/cts.html +++ b/third_party/blink/web_tests/wpt_internal/webgpu/cts.html
@@ -1973,6 +1973,7 @@ <meta name=variant content='?q=webgpu:shader,execution,builtin,abs:integer_builtin_functions,abs_unsigned:*'> <meta name=variant content='?q=webgpu:shader,execution,builtin,abs:integer_builtin_functions,abs_signed:*'> <meta name=variant content='?q=webgpu:shader,execution,builtin,abs:float_builtin_functions,abs_float:*'> +<meta name=variant content='?q=webgpu:shader,execution,builtin,ceil:float_builtin_functions,ceil:*'> <meta name=variant content='?q=webgpu:shader,execution,builtin,integer_built_in_functions:integer_builtin_functions,unsigned_clamp:*'> <meta name=variant content='?q=webgpu:shader,execution,builtin,integer_built_in_functions:integer_builtin_functions,signed_clamp:*'> <meta name=variant content='?q=webgpu:shader,execution,builtin,integer_built_in_functions:integer_builtin_functions,count_1_bits:*'>
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index 220959e9..3721aaa 100644 --- a/third_party/freetype/README.chromium +++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@ Name: FreeType URL: http://www.freetype.org/ -Version: VER-2-11-0-129-g8ef8072ba -Revision: 8ef8072ba151dc06214ee70985a7fb03ebc2932f +Version: VER-2-11-0-132-gfde91ab8f +Revision: fde91ab8f19d1f789720afc67e0414a0244490d3 CPEPrefix: cpe:/a:freetype:freetype:2.10.4 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses"
diff --git a/third_party/webgpu-cts/ts_sources.txt b/third_party/webgpu-cts/ts_sources.txt index a3ccc8d..ddf89cdf 100644 --- a/third_party/webgpu-cts/ts_sources.txt +++ b/third_party/webgpu-cts/ts_sources.txt
@@ -29,6 +29,7 @@ src/common/util/navigator_gpu.ts src/common/runtime/helper/sys.ts src/common/runtime/cmdline.ts +src/common/runtime/server.ts src/common/runtime/helper/test_worker.ts src/common/runtime/standalone.ts src/common/runtime/wpt.ts @@ -245,6 +246,7 @@ src/webgpu/shader/execution/zero_init.spec.ts src/webgpu/shader/execution/builtin/builtin.ts src/webgpu/shader/execution/builtin/abs.spec.ts +src/webgpu/shader/execution/builtin/ceil.spec.ts src/webgpu/shader/execution/builtin/float_built_functions.spce.ts src/webgpu/shader/execution/builtin/integer_built_in_functions.spec.ts src/webgpu/shader/execution/builtin/logical_built_in_functions.spec.ts
diff --git a/tools/aggregation_service/aggregation_service_tool.cc b/tools/aggregation_service/aggregation_service_tool.cc index 21229f8..003e7ec 100644 --- a/tools/aggregation_service/aggregation_service_tool.cc +++ b/tools/aggregation_service/aggregation_service_tool.cc
@@ -21,7 +21,6 @@ #include "base/values.h" #include "build/build_config.h" #include "content/public/test/test_aggregation_service.h" -#include "tools/aggregation_service/aggregation_service_tool_network_initializer.h" #include "url/gurl.h" #include "url/origin.h" @@ -29,7 +28,8 @@ AggregationServiceTool::AggregationServiceTool() : agg_service_(content::TestAggregationService::Create( - base::DefaultClock::GetInstance())) {} + base::DefaultClock::GetInstance(), + network_initializer_.shared_url_loader_factory())) {} AggregationServiceTool::~AggregationServiceTool() = default; @@ -90,8 +90,6 @@ const GURL& url) { DCHECK(url.is_valid()); - ToolNetworkInitializer network_initializer(agg_service_.get()); - bool succeeded = false; base::RunLoop run_loop;
diff --git a/tools/aggregation_service/aggregation_service_tool.h b/tools/aggregation_service/aggregation_service_tool.h index ee0a7ee..1f7e47bc 100644 --- a/tools/aggregation_service/aggregation_service_tool.h +++ b/tools/aggregation_service/aggregation_service_tool.h
@@ -9,6 +9,7 @@ #include <string> #include "base/strings/string_split.h" +#include "tools/aggregation_service/aggregation_service_tool_network_initializer.h" class GURL; @@ -54,6 +55,7 @@ bool SetPublicKeysFromFile(const url::Origin& origin, const std::string& json_file_path); + ToolNetworkInitializer network_initializer_; std::unique_ptr<content::TestAggregationService> agg_service_; };
diff --git a/tools/aggregation_service/aggregation_service_tool_network_initializer.cc b/tools/aggregation_service/aggregation_service_tool_network_initializer.cc index af5c884..36cbf146 100644 --- a/tools/aggregation_service/aggregation_service_tool_network_initializer.cc +++ b/tools/aggregation_service/aggregation_service_tool_network_initializer.cc
@@ -15,8 +15,7 @@ namespace aggregation_service { -ToolNetworkInitializer::ToolNetworkInitializer( - content::TestAggregationService* agg_service) { +ToolNetworkInitializer::ToolNetworkInitializer() { // Initialize the network state as this tool runs independently from the // command line. mojo::core::Init(); @@ -45,9 +44,6 @@ shared_url_loader_factory_ = base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( url_loader_factory_.get()); - - DCHECK(agg_service); - agg_service->SetURLLoaderFactory(shared_url_loader_factory_); } ToolNetworkInitializer::~ToolNetworkInitializer() = default;
diff --git a/tools/aggregation_service/aggregation_service_tool_network_initializer.h b/tools/aggregation_service/aggregation_service_tool_network_initializer.h index ca620b03..7f38922 100644 --- a/tools/aggregation_service/aggregation_service_tool_network_initializer.h +++ b/tools/aggregation_service/aggregation_service_tool_network_initializer.h
@@ -8,7 +8,6 @@ #include <memory> #include "base/memory/scoped_refptr.h" -#include "content/public/test/test_aggregation_service.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/network/network_context.h" #include "services/network/network_service.h" @@ -21,13 +20,16 @@ // be kept alive for the duration of network usage. class ToolNetworkInitializer { public: - // `agg_service` must be a non-null pointer to a TestAggregationService. - explicit ToolNetworkInitializer(content::TestAggregationService* agg_service); + ToolNetworkInitializer(); ToolNetworkInitializer(const ToolNetworkInitializer& other) = delete; ToolNetworkInitializer& operator=(const ToolNetworkInitializer& other) = delete; ~ToolNetworkInitializer(); + scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory() { + return shared_url_loader_factory_; + } + private: std::unique_ptr<network::NetworkService> network_service_; std::unique_ptr<network::NetworkContext> network_context_;
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec index 498e924b..4981e25 100644 --- a/tools/gritsettings/resource_ids.spec +++ b/tools/gritsettings/resource_ids.spec
@@ -725,6 +725,10 @@ "META": {"sizes": {"includes": [50],}}, "includes": [3980], }, + "<(SHARED_INTERMEDIATE_DIR)/ash/webui/firmware_update_ui/resources/ash_firmware_update_app_resources.grd": { + "META": {"sizes": {"includes": [200],}}, + "includes": [3990], + }, "<(SHARED_INTERMEDIATE_DIR)/ash/webui/shortcut_customization_ui/resources/ash_shortcut_customization_app_resources.grd": { "META": {"sizes": {"includes": [200],}}, "includes": [4000], @@ -744,6 +748,7 @@ }, "ash/public/cpp/resources/ash_public_unscaled_resources.grd": { "includes": [4100], + "structures": [4101], }, "base/tracing/protos/resources.grd": { "includes": [4120],
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index c284f47..72465a7 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -52230,6 +52230,7 @@ <int value="1111871757" label="ForceUnifiedConsentBump:enabled"/> <int value="1112051724" label="DetectingHeavyPages:enabled"/> <int value="1112817963" label="WebViewConnectionlessSafeBrowsing:enabled"/> + <int value="1112890211" label="SwapAndroidShareHubRows:enabled"/> <int value="1113196543" label="ShowManagedUi:disabled"/> <int value="1113281154" label="enable-raw-draw"/> <int value="1113365156" label="tab-management-experiment-type-chive"/> @@ -53159,6 +53160,7 @@ <int value="1819536169" label="disable-cast-streaming-hw-encoding"/> <int value="1820317896" label="NTPShowGoogleGInOmnibox:disabled"/> <int value="1820442907" label="CrostiniMultiContainer:disabled"/> + <int value="1820445741" label="SwapAndroidShareHubRows:disabled"/> <int value="1820451991" label="enable-offline-auto-reload"/> <int value="1821723343" label="disable-saml-signin"/> <int value="1823102966" label="disable-ipc-flooding-protection"/> @@ -53331,6 +53333,7 @@ <int value="1945031120" label="LanguageSettingsUpdate2:disabled"/> <int value="1946014982" label="MagnifierContinuousMouseFollowingModeSetting:disabled"/> + <int value="1946358032" label="SwapClankShareHubRows:disabled"/> <int value="1947350992" label="drop-sync-credential:disabled"/> <int value="1948978490" label="PaintPreviewDemo:disabled"/> <int value="1949019439"
diff --git a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS index 5e0c2f63..affb7220 100644 --- a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS +++ b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
@@ -40,6 +40,7 @@ nancylingwang@chromium.org nohle@chromium.org nyquist@chromium.org +olivierli@chromium.org olivierrobin@chromium.org poromov@chromium.org pwnall@chromium.org
diff --git a/tools/metrics/histograms/metadata/hang_watcher/OWNERS b/tools/metrics/histograms/metadata/hang_watcher/OWNERS new file mode 100644 index 0000000..55680ad1 --- /dev/null +++ b/tools/metrics/histograms/metadata/hang_watcher/OWNERS
@@ -0,0 +1,5 @@ +per-file OWNERS=file://tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS + +# Prefer sending CLs to the owners listed below. +# Use chromium-metrics-reviews@google.com as a backup. +olivierli@chromium.org
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml index e90503a4..77bc6ea 100644 --- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -9851,6 +9851,7 @@ Kaleidoscope has been turned down. </obsolete> </suffix> + <suffix name="photos" label="Module ID for Google Photos module"/> <suffix name="recipe_tasks" label="Module ID for Recipe Tasks"/> <suffix name="shopping_tasks" label="Module ID for Shopping Tasks"/> <affected-histogram name="NewTabPage.Modules.Dismissed"/>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index 4099a6e3..a8933e2c6 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -3151,38 +3151,39 @@ </histogram> <histogram name="ClientHints.PersistDuration" units="ms" - expires_after="2021-10-25"> + expires_after="2022-10-25"> <owner>yoavweiss@chromium.org</owner> <owner>tbansal@chromium.org</owner> <owner>mkwst@chromium.org</owner> <owner>aarontag@chromium.org</owner> <summary> Duration for which the origin requested the client hints to be persisted. - Collected on the renderer side. + Collected on the renderer side. Collected while navigation responses are + being processed. </summary> </histogram> <histogram name="ClientHints.UpdateEventCount" units="count" - expires_after="2021-10-25"> + expires_after="2022-10-25"> <owner>yoavweiss@chromium.org</owner> <owner>tbansal@chromium.org</owner> <owner>mkwst@chromium.org</owner> <owner>aarontag@chromium.org</owner> <summary> Count of events when the client hints needs to be persisted to the disk by - the browser. + the browser. Collected while navigation responses are being processed. </summary> </histogram> <histogram name="ClientHints.UpdateSize" units="count" - expires_after="2021-10-25"> + expires_after="2022-10-25"> <owner>yoavweiss@chromium.org</owner> <owner>tbansal@chromium.org</owner> <owner>mkwst@chromium.org</owner> <owner>aarontag@chromium.org</owner> <summary> Count of client hints that need to be persisted to the disk. Recorded by the - renderer. + renderer. Collected while navigation responses are being processed. </summary> </histogram>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index b466bba6..f17cb76 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -1677,6 +1677,38 @@ </summary> </histogram> +<histogram name="SafeBrowsing.TailoredSecurityService.OAuthTokenCompletion" + enum="BooleanSuccess" expires_after="2022-09-09"> + <owner>bdea@chromium.org</owner> + <owner>chrome-safebrowsing-alerts@google.com</owner> + <summary> + Safe Browsing needs a token in order to make a request to get the tailored + security service bit. This histogram tracks whether getting a token is + successful or not. + </summary> +</histogram> + +<histogram name="SafeBrowsing.TailoredSecurityService.OAuthTokenErrorState" + enum="GoogleServiceAuthError" expires_after="2022-09-09"> + <owner>bdea@chromium.org</owner> + <owner>chrome-safebrowsing-alerts@google.com</owner> + <summary> + Safe Browsing needs a token in order to make a request to get the tailored + security service bit. This histogram tracks the HTTP code when getting a + token is not successful. + </summary> +</histogram> + +<histogram name="SafeBrowsing.TailoredSecurityService.OAuthTokenResponseCode" + units="code" expires_after="2022-09-09"> + <owner>bdea@chromium.org</owner> + <owner>chrome-safebrowsing-alerts@google.com</owner> + <summary> + HTTP Response code returned by the server when trying to fetch the OAuth + token for a tailored security service query. + </summary> +</histogram> + <histogram name="SafeBrowsing.TokenFetcher.ErrorType" enum="GoogleServiceAuthError" expires_after="2022-04-24"> <owner>xinghuilu@chromium.org</owner>
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index abdd2ff..6c5f889 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -386,4 +386,5 @@ <item id="whats_new_handler" added_in_milestone="94" hash_code="127739401" type="0" content_hash_code="94869759" os_list="linux,windows" file_path="chrome/browser/ui/webui/whats_new/whats_new_handler.cc"/> <item id="worker_script_load" added_in_milestone="72" hash_code="72087791" type="0" content_hash_code="24889169" os_list="linux,windows" file_path="content/browser/worker_host/worker_script_fetcher.cc"/> <item id="xmpp_signal_strategy" added_in_milestone="66" hash_code="88906454" type="0" deprecated="2019-07-16" content_hash_code="88958321" file_path=""/> + <item id="tailored_security_service" added_in_milestone="97" hash_code="126267513" type="0" content_hash_code="35290543" os_list="linux,windows" file_path="components/safe_browsing/core/tailored_security_service/tailored_security_service.cc"/> </annotations>
diff --git a/tools/traffic_annotation/summary/grouping.xml b/tools/traffic_annotation/summary/grouping.xml index 5968908..61ec17b 100644 --- a/tools/traffic_annotation/summary/grouping.xml +++ b/tools/traffic_annotation/summary/grouping.xml
@@ -222,7 +222,8 @@ <traffic_annotation unique_id="sct_auditing"/> <traffic_annotation unique_id="unwanted_software_report"/> <traffic_annotation unique_id="ppapi_download_request"/> - </sender> + <traffic_annotation unique_id="tailored_security_service"/> + </sender> </group> <group name="Cookieless Ads"> <sender name="Conversion Measurements">
diff --git a/ui/webui/resources/BUILD.gn b/ui/webui/resources/BUILD.gn index ee52ec1..94f528e 100644 --- a/ui/webui/resources/BUILD.gn +++ b/ui/webui/resources/BUILD.gn
@@ -182,7 +182,7 @@ if (is_chromeos) { checked_in_dts_files += - [ "cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.m.d.ts" ] + [ "cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.d.ts" ] } # Copies checked-in .d.ts files to the preprocess folder so that they are
diff --git a/ui/webui/resources/cr_components/BUILD.gn b/ui/webui/resources/cr_components/BUILD.gn index e7cdb2b..f13b3cd 100644 --- a/ui/webui/resources/cr_components/BUILD.gn +++ b/ui/webui/resources/cr_components/BUILD.gn
@@ -95,6 +95,7 @@ "chromeos/bluetooth/bluetooth_types.js", "chromeos/bluetooth/bluetooth_metrics_utils.js", "chromeos/bluetooth/cros_bluetooth_config.js", + "chromeos/smb_shares/smb_browser_proxy.js", "most_visited/browser_proxy.js", "most_visited/window_proxy.js", ] @@ -211,8 +212,7 @@ "chromeos/quick_unlock/pin_keyboard_icon.m.js", "chromeos/quick_unlock/pin_keyboard.m.js", "chromeos/quick_unlock/setup_pin_keyboard.m.js", - "chromeos/smb_shares/add_smb_share_dialog.m.js", - "chromeos/smb_shares/smb_browser_proxy.m.js", + "chromeos/smb_shares/add_smb_share_dialog.js", "chromeos/traffic_counters/traffic_counters.js", ] } @@ -375,10 +375,6 @@ "chromeos/quick_unlock/pin_keyboard.js", "chromeos/quick_unlock/setup_pin_keyboard.html", "chromeos/quick_unlock/setup_pin_keyboard.js", - "chromeos/smb_shares/add_smb_share_dialog.html", - "chromeos/smb_shares/add_smb_share_dialog.js", - "chromeos/smb_shares/smb_browser_proxy.html", - "chromeos/smb_shares/smb_browser_proxy.js", ] } }
diff --git a/ui/webui/resources/cr_components/chromeos/BUILD.gn b/ui/webui/resources/cr_components/chromeos/BUILD.gn index f9dceb9..5502a70 100644 --- a/ui/webui/resources/cr_components/chromeos/BUILD.gn +++ b/ui/webui/resources/cr_components/chromeos/BUILD.gn
@@ -32,7 +32,7 @@ "network:polymer3_elements", "network_health:polymer3_elements", "quick_unlock:polymer3_elements", - "smb_shares:polymer3_elements", + "smb_shares:web_components", "traffic_counters:web_components", ] }
diff --git a/ui/webui/resources/cr_components/chromeos/smb_shares/BUILD.gn b/ui/webui/resources/cr_components/chromeos/smb_shares/BUILD.gn index 855cc63..a5aeb3a 100644 --- a/ui/webui/resources/cr_components/chromeos/smb_shares/BUILD.gn +++ b/ui/webui/resources/cr_components/chromeos/smb_shares/BUILD.gn
@@ -3,26 +3,21 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") -import("//tools/polymer/polymer.gni") -import("//ui/webui/resources/tools/js_modulizer.gni") +import("//tools/polymer/html_to_js.gni") assert(is_chromeos, "SMB Shares is Chrome OS only.") -# TODO(crbug.com/1031947): Fully convert this component to Polymer 3 once -# chrome://os-settings has been migrated. - js_type_check("closure_compile_module") { is_polymer3 = true deps = [ - ":add_smb_share_dialog.m", - ":smb_browser_proxy.m", + ":add_smb_share_dialog", + ":smb_browser_proxy", ] } -js_library("add_smb_share_dialog.m") { - sources = [ "$root_gen_dir/ui/webui/resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.m.js" ] +js_library("add_smb_share_dialog") { deps = [ - ":smb_browser_proxy.m", + ":smb_browser_proxy", "//ui/webui/resources/cr_elements/cr_button:cr_button.m", "//ui/webui/resources/cr_elements/cr_checkbox:cr_checkbox.m", "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m", @@ -32,31 +27,12 @@ "//ui/webui/resources/js:load_time_data.m", "//ui/webui/resources/js:web_ui_listener_behavior.m", ] - extra_deps = [ ":add_smb_share_dialog_module" ] } -js_library("smb_browser_proxy.m") { +js_library("smb_browser_proxy") { deps = [ "//ui/webui/resources/js:cr.m" ] - sources = [ "$root_gen_dir/ui/webui/resources/cr_components/chromeos/smb_shares/smb_browser_proxy.m.js" ] - extra_deps = [ ":smb_browser_proxy_module" ] } -js_modulizer("smb_browser_proxy_module") { - input_files = [ "smb_browser_proxy.js" ] - namespace_rewrites = [ "smb_shares.SmbBrowserProxy|SmbBrowserProxy" ] -} - -polymer_modulizer("add_smb_share_dialog") { - js_file = "add_smb_share_dialog.js" - html_file = "add_smb_share_dialog.html" - html_type = "dom-module" - namespace_rewrites = [ "smb_shares.SmbBrowserProxy|SmbBrowserProxy" ] - auto_imports = [ "ui/webui/resources/cr_components/chromeos/smb_shares/smb_browser_proxy.html|SmbAuthMethod,SmbBrowserProxy,SmbBrowserProxyImpl,SmbMountResult" ] -} - -group("polymer3_elements") { - public_deps = [ - ":add_smb_share_dialog_module", - ":smb_browser_proxy_module", - ] +html_to_js("web_components") { + js_files = [ "add_smb_share_dialog.js" ] }
diff --git a/ui/webui/resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.html b/ui/webui/resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.html index 1681a659..69e3462 100644 --- a/ui/webui/resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.html +++ b/ui/webui/resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.html
@@ -1,22 +1,3 @@ -<link rel="import" href="../../../html/polymer.html"> - -<link rel="import" href="../../../cr_elements/cr_button/cr_button.html"> -<link rel="import" href="../../../cr_elements/cr_checkbox/cr_checkbox.html"> -<link rel="import" href="../../../cr_elements/cr_dialog/cr_dialog.html"> -<link rel="import" href="../../../cr_elements/cr_input/cr_input.html"> -<link rel="import" href="../../../cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.html"> -<link rel="import" href="../../../cr_elements/icons.html"> -<link rel="import" href="../../../cr_elements/shared_style_css.html"> -<link rel="import" href="../../../cr_elements/shared_vars_css.html"> -<link rel="import" href="../../../html/i18n_behavior.html"> -<link rel="import" href="../../../html/load_time_data.html"> -<link rel="import" href="../../../cr_elements/md_select_css.html"> -<link rel="import" href="../../../html/web_ui_listener_behavior.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> -<link rel="import" href="smb_browser_proxy.html"> - -<dom-module id="add-smb-share-dialog"> - <template> <style include="cr-shared-style md-select"> cr-dialog::part(wrapper) { /* Subtract the internal padding in <cr-dialog>. */ @@ -132,6 +113,3 @@ </cr-button> </div> </cr-dialog> - </template> - <script src="add_smb_share_dialog.js"></script> -</dom-module>
diff --git a/ui/webui/resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.js b/ui/webui/resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.js index 4396fe7..20c0b55 100644 --- a/ui/webui/resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.js +++ b/ui/webui/resources/cr_components/chromeos/smb_shares/add_smb_share_dialog.js
@@ -9,6 +9,25 @@ * destroyed when finished, and re-created when shown again. */ +import '../../../cr_elements/cr_button/cr_button.m.js'; +import '../../../cr_elements/cr_checkbox/cr_checkbox.m.js'; +import '../../../cr_elements/cr_dialog/cr_dialog.m.js'; +import '../../../cr_elements/cr_input/cr_input.m.js'; +import '../../../cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.js'; +import '../../../cr_elements/icons.m.js'; +import '../../../cr_elements/shared_style_css.m.js'; +import '../../../cr_elements/shared_vars_css.m.js'; +import '../../../cr_elements/md_select_css.m.js'; +import '//resources/polymer/v3_0/iron-icon/iron-icon.js'; + +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {I18nBehavior} from '../../../js/i18n_behavior.m.js'; +import {loadTimeData} from '../../../js/load_time_data.m.js'; +import {WebUIListenerBehavior} from '../../../js/web_ui_listener_behavior.m.js'; + +import {SmbAuthMethod, SmbBrowserProxy, SmbBrowserProxyImpl, SmbMountResult} from './smb_browser_proxy.js'; + /** @enum{number} */ const MountErrorType = { NO_ERROR: 0, @@ -30,6 +49,8 @@ Polymer({ is: 'add-smb-share-dialog', + _template: html`{__html_template__}`, + behaviors: [I18nBehavior, WebUIListenerBehavior], properties: { @@ -142,12 +163,12 @@ }, }, - /** @private {?smb_shares.SmbBrowserProxy} */ + /** @private {?SmbBrowserProxy} */ browserProxy_: null, /** @override */ created() { - this.browserProxy_ = smb_shares.SmbBrowserProxyImpl.getInstance(); + this.browserProxy_ = SmbBrowserProxyImpl.getInstance(); }, /** @override */
diff --git a/ui/webui/resources/cr_components/chromeos/smb_shares/smb_browser_proxy.js b/ui/webui/resources/cr_components/chromeos/smb_shares/smb_browser_proxy.js index 9645852..9f962606 100644 --- a/ui/webui/resources/cr_components/chromeos/smb_shares/smb_browser_proxy.js +++ b/ui/webui/resources/cr_components/chromeos/smb_shares/smb_browser_proxy.js
@@ -7,14 +7,14 @@ * interact with the browser. Used only on Chrome OS. */ -// #import {addSingletonGetter, sendWithPromise} from '../../../js/cr.m.js'; +import {addSingletonGetter, sendWithPromise} from '../../../js/cr.m.js'; /** * @enum {number} * These values must be kept in sync with the SmbMountResult enum in * chrome/browser/ash/smb_client/smb_errors.h. */ -/* #export */ const SmbMountResult = { +export const SmbMountResult = { SUCCESS: 0, UNKNOWN_FAILURE: 1, AUTHENTICATION_FAILED: 2, @@ -33,72 +33,63 @@ }; /** @enum {string} */ -/* #export */ const SmbAuthMethod = { +export const SmbAuthMethod = { KERBEROS: 'kerberos', CREDENTIALS: 'credentials', }; -cr.define('smb_shares', function() { - /** @interface */ - /* #export */ class SmbBrowserProxy { - /** - * Attempts to mount an Smb filesystem with the provided url. - * @param {string} smbUrl File Share URL. - * @param {string} smbName Display name for the File Share. - * @param {string} username - * @param {string} password - * @param {string} authMethod - * @param {boolean} shouldOpenFileManagerAfterMount - * @param {boolean} saveCredentials - * @return {!Promise<SmbMountResult>} - */ - smbMount( - smbUrl, smbName, username, password, authMethod, - shouldOpenFileManagerAfterMount, saveCredentials) {} +/** @interface */ +export class SmbBrowserProxy { + /** + * Attempts to mount an Smb filesystem with the provided url. + * @param {string} smbUrl File Share URL. + * @param {string} smbName Display name for the File Share. + * @param {string} username + * @param {string} password + * @param {string} authMethod + * @param {boolean} shouldOpenFileManagerAfterMount + * @param {boolean} saveCredentials + * @return {!Promise<SmbMountResult>} + */ + smbMount( + smbUrl, smbName, username, password, authMethod, + shouldOpenFileManagerAfterMount, saveCredentials) {} - /** - * Starts the file share discovery process. - */ - startDiscovery() {} + /** + * Starts the file share discovery process. + */ + startDiscovery() {} - /** - * Updates the credentials for a mounted share. - * @param {string} mountId - * @param {string} username - * @param {string} password - */ - updateCredentials(mountId, username, password) {} + /** + * Updates the credentials for a mounted share. + * @param {string} mountId + * @param {string} username + * @param {string} password + */ + updateCredentials(mountId, username, password) {} +} + +/** @implements {SmbBrowserProxy} */ +export class SmbBrowserProxyImpl { + /** @override */ + smbMount( + smbUrl, smbName, username, password, authMethod, + shouldOpenFileManagerAfterMount, saveCredentials) { + return sendWithPromise( + 'smbMount', smbUrl, smbName, username, password, + authMethod === SmbAuthMethod.KERBEROS, shouldOpenFileManagerAfterMount, + saveCredentials); } - /** @implements {smb_shares.SmbBrowserProxy} */ - /* #export */ class SmbBrowserProxyImpl { - /** @override */ - smbMount( - smbUrl, smbName, username, password, authMethod, - shouldOpenFileManagerAfterMount, saveCredentials) { - return cr.sendWithPromise( - 'smbMount', smbUrl, smbName, username, password, - authMethod === SmbAuthMethod.KERBEROS, - shouldOpenFileManagerAfterMount, saveCredentials); - } - - /** @override */ - startDiscovery() { - chrome.send('startDiscovery'); - } - - /** @override */ - updateCredentials(mountId, username, password) { - chrome.send('updateCredentials', [mountId, username, password]); - } + /** @override */ + startDiscovery() { + chrome.send('startDiscovery'); } - cr.addSingletonGetter(SmbBrowserProxyImpl); + /** @override */ + updateCredentials(mountId, username, password) { + chrome.send('updateCredentials', [mountId, username, password]); + } +} - // #cr_define_end - return { - SmbBrowserProxy: SmbBrowserProxy, - SmbBrowserProxyImpl: SmbBrowserProxyImpl, - }; - -}); +addSingletonGetter(SmbBrowserProxyImpl);
diff --git a/ui/webui/resources/cr_elements/BUILD.gn b/ui/webui/resources/cr_elements/BUILD.gn index 2bea31d..1b0c7e1 100644 --- a/ui/webui/resources/cr_elements/BUILD.gn +++ b/ui/webui/resources/cr_elements/BUILD.gn
@@ -116,14 +116,6 @@ "shared_vars_css.html", ] - # TODO(crbug.com/1184053): Fully remove once no longer used by CrOS. - if (is_chromeos) { - in_files += [ - "cr_searchable_drop_down/cr_searchable_drop_down.html", - "cr_searchable_drop_down/cr_searchable_drop_down.js", - ] - } - if (is_chromeos_ash) { in_files += [ "chromeos/cros_color_overrides.html", @@ -205,9 +197,8 @@ "shared_vars_css.m.js", ] - # TODO(crbug.com/1184053): Fully remove once no longer used by CrOS. if (is_chromeos) { - in_files += [ "cr_searchable_drop_down/cr_searchable_drop_down.m.js" ] + in_files += [ "cr_searchable_drop_down/cr_searchable_drop_down.js" ] } if (is_chromeos_ash) { @@ -277,7 +268,6 @@ # cr-searchable-drop-down is only used in smb and cups dialogs, both of # which are chromeos only. - "cr_searchable_drop_down:closure_compile", "cr_searchable_drop_down:closure_compile_module", ] } @@ -408,7 +398,7 @@ # cr-searchable-drop-down is only used in smb and cups dialogs, both of # which are chromeos only. - "cr_searchable_drop_down:cr_searchable_drop_down_module", + "cr_searchable_drop_down:web_components", ] } }
diff --git a/ui/webui/resources/cr_elements/cr_nav_menu_item_style.html b/ui/webui/resources/cr_elements/cr_nav_menu_item_style.html index 7d67283..5cbb718 100644 --- a/ui/webui/resources/cr_elements/cr_nav_menu_item_style.html +++ b/ui/webui/resources/cr_elements/cr_nav_menu_item_style.html
@@ -86,6 +86,14 @@ outline: auto 5px -webkit-focus-ring-color; } + :host-context([enable-branding-update]) .cr-nav-menu-item:focus { + /** + * A non-zero z-index to force the outline to appear above the fill + * background of selected item. + */ + z-index: 1; + } + .cr-nav-menu-item iron-icon { margin-inline-end: 24px; pointer-events: none;
diff --git a/ui/webui/resources/cr_elements/cr_searchable_drop_down/BUILD.gn b/ui/webui/resources/cr_elements/cr_searchable_drop_down/BUILD.gn index ce8dfdc..450e4ee 100644 --- a/ui/webui/resources/cr_elements/cr_searchable_drop_down/BUILD.gn +++ b/ui/webui/resources/cr_elements/cr_searchable_drop_down/BUILD.gn
@@ -3,41 +3,23 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") -import("//tools/polymer/polymer.gni") +import("//tools/polymer/html_to_js.gni") -js_type_check("closure_compile") { - uses_legacy_modules = true +js_type_check("closure_compile_module") { + is_polymer3 = true deps = [ ":cr_searchable_drop_down" ] } js_library("cr_searchable_drop_down") { deps = [ - "//third_party/polymer/v1_0/components-chromium/iron-dropdown:iron-dropdown-extracted", - "//third_party/polymer/v1_0/components-chromium/iron-icon:iron-icon-extracted", - "//third_party/polymer/v1_0/components-chromium/paper-spinner:paper-spinner-lite-extracted", - "//ui/webui/resources/cr_elements/cr_input:cr_input", - ] -} - -polymer_modulizer("cr_searchable_drop_down") { - js_file = "cr_searchable_drop_down.js" - html_file = "cr_searchable_drop_down.html" - html_type = "dom-module" -} - -js_type_check("closure_compile_module") { - is_polymer3 = true - deps = [ ":cr_searchable_drop_down.m" ] -} - -js_library("cr_searchable_drop_down.m") { - sources = [ "$root_gen_dir/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.m.js" ] - deps = [ "//third_party/polymer/v3_0/components-chromium/iron-dropdown", "//third_party/polymer/v3_0/components-chromium/iron-icon", "//third_party/polymer/v3_0/components-chromium/paper-spinner:paper-spinner-lite", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_input:cr_input.m", ] - extra_deps = [ ":cr_searchable_drop_down_module" ] +} + +html_to_js("web_components") { + js_files = [ "cr_searchable_drop_down.js" ] }
diff --git a/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.m.d.ts b/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.d.ts similarity index 100% rename from ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.m.d.ts rename to ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.d.ts
diff --git a/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.html b/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.html index 0bbba48f..8bea907 100644 --- a/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.html +++ b/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.html
@@ -1,16 +1,3 @@ -<link rel="import" href="../../html/polymer.html"> - -<link rel="import" href="../cr_input/cr_input.html"> -<link rel="import" href="../hidden_style_css.html"> -<link rel="import" href="../icons.html"> -<link rel="import" href="../shared_style_css.html"> -<link rel="import" href="../shared_vars_css.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-dropdown/iron-dropdown.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html"> - -<dom-module id="cr-searchable-drop-down"> - <template> <style include="cr-shared-style cr-hidden-style"> :host(:not([error-message-allowed])) cr-input { --cr-input-error-display: none; @@ -163,6 +150,3 @@ </div> </div> </cr-input> - </template> - <script src="cr_searchable_drop_down.js"></script> -</dom-module>
diff --git a/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.js b/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.js index ff4fc19..5773096 100644 --- a/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.js +++ b/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.js
@@ -14,9 +14,22 @@ * dropdown matches the previously saved dropdown value. This property can be * used to disable certain user actions when the dropdown is invalid. */ +import '../cr_input/cr_input.m.js'; +import '../hidden_style_css.m.js'; +import '../icons.m.js'; +import '../shared_style_css.m.js'; +import '../shared_vars_css.m.js'; +import '//resources/polymer/v3_0/iron-dropdown/iron-dropdown.js'; +import '//resources/polymer/v3_0/iron-icon/iron-icon.js'; +import '//resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js'; + +import {html, Polymer} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + Polymer({ is: 'cr-searchable-drop-down', + _template: html`{__html_template__}`, + properties: { autofocus: { type: Boolean, @@ -479,4 +492,3 @@ !this.updateValueOnInput && (this.value !== this.$.search.value); }, }); -/* #ignore */ console.warn('crbug/1173575, non-JS module files deprecated.');
diff --git a/ui/webui/resources/cr_elements/cr_tabs/cr_tabs.html b/ui/webui/resources/cr_elements/cr_tabs/cr_tabs.html index a51e932..1005206 100644 --- a/ui/webui/resources/cr_elements/cr_tabs/cr_tabs.html +++ b/ui/webui/resources/cr_elements/cr_tabs/cr_tabs.html
@@ -1,24 +1,14 @@ <style include="cr-hidden-style"> :host { - --cr-tabs-height: 48px; - --cr-tabs-icon-margin-end: var(--cr-icon-size); - --cr-tabs-icon-size: var(--cr-icon-size); - --cr-tabs-selected-color: var(--google-blue-600); cursor: pointer; display: flex; flex-direction: row; font-size: var(--cr-tabs-font-size, 14px); font-weight: 500; - height: var(--cr-tabs-height); + height: var(--cr-tabs-height, 48px); user-select: none; } - @media (prefers-color-scheme: dark) { - :host { - --cr-tabs-selected-color: var(--google-blue-refresh-300); - } - } - .tab { align-items: center; color: var(--cr-secondary-text-color); @@ -26,9 +16,8 @@ flex: auto; height: 100%; justify-content: center; - margin-inline-end: var(--cr-tabs-margin-end); - margin-inline-start: var(--cr-tabs-margin-start); opacity: .8; + padding: 0 var(--cr-tabs-tab-inline-padding, 0); position: relative; transition: opacity 100ms cubic-bezier(.4, 0, 1, 1); } @@ -42,10 +31,16 @@ } .selected { - color: var(--cr-tabs-selected-color); + color: var(--cr-tabs-selected-color, var(--google-blue-600)); opacity: 1; } + @media (prefers-color-scheme: dark) { + .selected { + color: var(--cr-tabs-selected-color, var(--google-blue-refresh-300)); + } + } + .selected:focus { font-weight: var(--cr-tabs-selected-tab-focused-font-weight, 700); } @@ -53,27 +48,36 @@ .tab-icon { -webkit-mask-position: center; -webkit-mask-repeat: no-repeat; - -webkit-mask-size: var(--cr-tabs-icon-size); + -webkit-mask-size: var(--cr-tabs-icon-size, var(--cr-icon-size)); background-color: var(--cr-secondary-text-color); display: none; - height: var(--cr-tabs-icon-size); - margin-inline-end: var(--cr-tabs-icon-margin-end); - width: var(--cr-tabs-icon-size); + height: var(--cr-tabs-icon-size, var(--cr-icon-size)); + margin-inline-end: var(--cr-tabs-icon-margin-end, var(--cr-icon-size)); + width: var(--cr-tabs-icon-size, var(--cr-icon-size)); } .selected .tab-icon { - background-color: var(--cr-tabs-selected-color); + background-color: var(--cr-tabs-selected-color, var(--google-blue-600)); + } + + @media (prefers-color-scheme: dark) { + .selected .tab-icon { + background-color: var(--cr-tabs-selected-color, var(--google-blue-refresh-300)); + } } .tab-indicator { - background: var(--google-blue-600); + background: var(--cr-tabs-selected-color, var(--google-blue-600)); + border-top-left-radius: var(--cr-tabs-selection-bar-width, 2px); + border-top-right-radius: var(--cr-tabs-selection-bar-width, 2px); bottom: 0; height: var(--cr-tabs-selection-bar-width, 2px); + left: var(--cr-tabs-tab-inline-padding, 0); opacity: 0; position: absolute; + right: var(--cr-tabs-tab-inline-padding, 0); transform-origin: left center; transition: transform; - width: 100%; } .selected .tab-indicator { @@ -92,7 +96,7 @@ @media (prefers-color-scheme: dark) { .tab-indicator { - background: var(--google-blue-refresh-300); + background: var(--cr-tabs-selected-color, var(--google-blue-refresh-300)); } } </style>
diff --git a/ui/webui/resources/images/200-logo_chrome.png b/ui/webui/resources/images/200-logo_chrome.png deleted file mode 100644 index 44f808e..0000000 --- a/ui/webui/resources/images/200-logo_chrome.png +++ /dev/null Binary files differ
diff --git a/ui/webui/resources/images/2x/laptop_small.png b/ui/webui/resources/images/2x/laptop_small.png deleted file mode 100644 index cad2991..0000000 --- a/ui/webui/resources/images/2x/laptop_small.png +++ /dev/null Binary files differ
diff --git a/ui/webui/resources/images/2x/phone_small.png b/ui/webui/resources/images/2x/phone_small.png deleted file mode 100644 index 7fa82f3..0000000 --- a/ui/webui/resources/images/2x/phone_small.png +++ /dev/null Binary files differ
diff --git a/ui/webui/resources/images/2x/tablet_small.png b/ui/webui/resources/images/2x/tablet_small.png deleted file mode 100644 index 7ecb245e..0000000 --- a/ui/webui/resources/images/2x/tablet_small.png +++ /dev/null Binary files differ
diff --git a/ui/webui/resources/images/2x/x-hover.png b/ui/webui/resources/images/2x/x-hover.png deleted file mode 100644 index 48b72a8..0000000 --- a/ui/webui/resources/images/2x/x-hover.png +++ /dev/null Binary files differ
diff --git a/ui/webui/resources/images/2x/x-pressed.png b/ui/webui/resources/images/2x/x-pressed.png deleted file mode 100644 index ef38fff..0000000 --- a/ui/webui/resources/images/2x/x-pressed.png +++ /dev/null Binary files differ
diff --git a/ui/webui/resources/images/x-hover.png b/ui/webui/resources/images/x-hover.png deleted file mode 100644 index ee30e556..0000000 --- a/ui/webui/resources/images/x-hover.png +++ /dev/null Binary files differ
diff --git a/ui/webui/resources/images/x-pressed.png b/ui/webui/resources/images/x-pressed.png deleted file mode 100644 index c2e9f4c..0000000 --- a/ui/webui/resources/images/x-pressed.png +++ /dev/null Binary files differ